[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Thu Jul 26 03:57:02 MDT 2012


The branch, master has been updated
       via  a67daa3 s3:smb2_negprot: return the current system time in the SMB2 NEGPROT response
       via  f6592c4 s3:smbd: fix compiler warnings in notify_internal.c
       via  8cb6557 libcli/smb: add basic session->smb2.channel_sequence handling
       via  fdd9867 libcli/smb: add SMB2_HDR_CHANNEL_SEQUENCE
       via  ba14bc5 libcli/smb: introduce a smb2cli_session
      from  df08929 s3:smb2_sesssetup: reject SMB2_SESSION_FLAG_BINDING requests

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit a67daa3aa6ce0e9ba8cf8db34d889fe5c8f65f3f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 26 09:55:29 2012 +0200

    s3:smb2_negprot: return the current system time in the SMB2 NEGPROT response
    
    metze
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Thu Jul 26 11:56:02 CEST 2012 on sn-devel-104

commit f6592c427dbcc347ec7752c8182029a3ba937fbd
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 26 08:37:43 2012 +0200

    s3:smbd: fix compiler warnings in notify_internal.c
    
    metze

commit 8cb6557d22fef2570156f56a8bad00cac6b7e016
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 26 01:54:33 2012 +0200

    libcli/smb: add basic session->smb2.channel_sequence handling
    
    metze

commit fdd98675ac6faa3f4a9cd1d8907796bbbd97b729
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 26 01:54:02 2012 +0200

    libcli/smb: add SMB2_HDR_CHANNEL_SEQUENCE
    
    metze

commit ba14bc52dab26bd9fdf54bbd317f329281cecb52
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jul 26 02:36:37 2012 +0200

    libcli/smb: introduce a smb2cli_session
    
    This maintains the shared state between multiple session
    channels.
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 libcli/smb/smb2_constants.h    |    1 +
 libcli/smb/smbXcli_base.c      |  233 ++++++++++++++++++++++------------------
 libcli/smb/smbXcli_base.h      |    1 +
 source3/smbd/notify_internal.c |    8 +-
 source3/smbd/smb2_negprot.c    |    3 +-
 5 files changed, 135 insertions(+), 111 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb2_constants.h b/libcli/smb/smb2_constants.h
index a00a4a7..6b9ad85 100644
--- a/libcli/smb/smb2_constants.h
+++ b/libcli/smb/smb2_constants.h
@@ -43,6 +43,7 @@
 #define SMB2_HDR_CREDIT_CHARGE	0x06
 #define SMB2_HDR_EPOCH		SMB2_HDR_CREDIT_CHARGE /* TODO: remove this */
 #define SMB2_HDR_STATUS		0x08
+#define SMB2_HDR_CHANNEL_SEQUENCE SMB2_HDR_STATUS /* in requests */
 #define SMB2_HDR_OPCODE		0x0c
 #define SMB2_HDR_CREDIT		0x0e
 #define SMB2_HDR_FLAGS		0x10
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 7a5a0b0..a363b44 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -128,6 +128,20 @@ struct smbXcli_conn {
 	struct smbXcli_session *sessions;
 };
 
+struct smb2cli_session {
+	uint64_t session_id;
+	uint16_t session_flags;
+	DATA_BLOB application_key;
+	DATA_BLOB signing_key;
+	bool should_sign;
+	bool should_encrypt;
+	DATA_BLOB encryption_key;
+	DATA_BLOB decryption_key;
+	uint64_t nonce_high;
+	uint64_t nonce_low;
+	uint16_t channel_sequence;
+};
+
 struct smbXcli_session {
 	struct smbXcli_session *prev, *next;
 	struct smbXcli_conn *conn;
@@ -136,19 +150,11 @@ struct smbXcli_session {
 		uint16_t session_id;
 	} smb1;
 
+	struct smb2cli_session *smb2;
+
 	struct {
-		uint64_t session_id;
-		uint16_t session_flags;
-		DATA_BLOB application_key;
 		DATA_BLOB signing_key;
-		bool should_sign;
-		bool should_encrypt;
-		DATA_BLOB encryption_key;
-		DATA_BLOB decryption_key;
-		uint64_t channel_nonce;
-		uint64_t channel_next;
-		DATA_BLOB channel_signing_key;
-	} smb2;
+	} smb2_channel;
 };
 
 struct smbXcli_tcon {
@@ -905,6 +911,8 @@ static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn)
 
 void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
 {
+	struct smbXcli_session *session;
+
 	tevent_queue_stop(conn->outgoing);
 
 	if (conn->read_fd != -1) {
@@ -916,6 +924,18 @@ void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
 	conn->read_fd = -1;
 	conn->write_fd = -1;
 
+	session = conn->sessions;
+	if (talloc_array_length(conn->pending) == 0) {
+		/*
+		 * if we do not have pending requests
+		 * there is no need to update the channel_sequence
+		 */
+		session = NULL;
+	}
+	for (; session; session = session->next) {
+		smb2cli_session_increment_channel_sequence(session);
+	}
+
 	/*
 	 * Cancel all pending requests. We do not do a for-loop walking
 	 * conn->pending because that array changes in
@@ -2436,6 +2456,8 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
 	uint32_t flags = 0;
 	uint32_t tid = 0;
 	uint64_t uid = 0;
+	bool use_channel_sequence = false;
+	uint16_t channel_sequence = 0;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct smbXcli_req_state);
@@ -2448,19 +2470,29 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
 	state->session = session;
 	state->tcon = tcon;
 
+	if (conn->smb2.server.capabilities & SMB2_CAP_PERSISTENT_HANDLES) {
+		use_channel_sequence = true;
+	} else if (conn->smb2.server.capabilities & SMB2_CAP_MULTI_CHANNEL) {
+		use_channel_sequence = true;
+	}
+
 	if (session) {
-		uid = session->smb2.session_id;
+		uid = session->smb2->session_id;
 
-		state->smb2.should_sign = session->smb2.should_sign;
-		state->smb2.should_encrypt = session->smb2.should_encrypt;
+		if (use_channel_sequence) {
+			channel_sequence = session->smb2->channel_sequence;
+		}
+
+		state->smb2.should_sign = session->smb2->should_sign;
+		state->smb2.should_encrypt = session->smb2->should_encrypt;
 
 		if (cmd == SMB2_OP_SESSSETUP &&
-		    session->smb2.signing_key.length != 0) {
+		    session->smb2->signing_key.length != 0) {
 			state->smb2.should_sign = true;
 		}
 
 		if (cmd == SMB2_OP_SESSSETUP &&
-		    session->smb2.channel_signing_key.length == 0) {
+		    session->smb2_channel.signing_key.length == 0) {
 			state->smb2.should_encrypt = false;
 		}
 	}
@@ -2499,6 +2531,7 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
 	SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID,	SMB2_MAGIC);
 	SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH,		SMB2_HDR_BODY);
 	SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE,		cmd);
+	SSVAL(state->smb2.hdr, SMB2_HDR_CHANNEL_SEQUENCE, channel_sequence);
 	SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS,		flags);
 	SIVAL(state->smb2.hdr, SMB2_HDR_PID,		0); /* reserved */
 	SIVAL(state->smb2.hdr, SMB2_HDR_TID,		tid);
@@ -2644,7 +2677,7 @@ skip_credits:
 			 * already there.
 			 */
 			if (state->smb2.should_sign) {
-				signing_key = &state->session->smb2.channel_signing_key;
+				signing_key = &state->session->smb2_channel.signing_key;
 			}
 
 			/*
@@ -2652,7 +2685,7 @@ skip_credits:
 			 * signing key and try that one.
 			 */
 			if (signing_key && signing_key->length == 0) {
-				signing_key = &state->session->smb2.signing_key;
+				signing_key = &state->session->smb2->signing_key;
 			}
 
 			/*
@@ -2664,7 +2697,7 @@ skip_credits:
 			}
 
 			if (state->smb2.should_encrypt) {
-				encryption_key = &state->session->smb2.encryption_key;
+				encryption_key = &state->session->smb2->encryption_key;
 			}
 		}
 
@@ -2710,9 +2743,17 @@ skip_credits:
 			uint8_t *buf;
 			int vi;
 
-			SBVAL(state->smb2.transform, SMB2_TF_NONCE, mid);
+			SBVAL(state->smb2.transform, SMB2_TF_NONCE,
+			      state->session->smb2->nonce_low);
 			SBVAL(state->smb2.transform, SMB2_TF_NONCE+8,
-			      state->session->smb2.channel_nonce);
+			      state->session->smb2->nonce_high);
+
+			state->session->smb2->nonce_low += 1;
+			if (state->session->smb2->nonce_low == 0) {
+				state->session->smb2->nonce_high += 1;
+				state->session->smb2->nonce_low += 1;
+			}
+
 			SBVAL(state->smb2.transform, SMB2_TF_MSG_SIZE,
 			      reqlen);
 
@@ -2901,7 +2942,7 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn,
 
 			s = conn->sessions;
 			for (; s; s = s->next) {
-				if (s->smb2.session_id != uid) {
+				if (s->smb2->session_id != uid) {
 					continue;
 				}
 				break;
@@ -2918,7 +2959,7 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn,
 			tf_iov[1].iov_base = (void *)hdr;
 			tf_iov[1].iov_len = len;
 
-			status = smb2_signing_decrypt_pdu(s->smb2.decryption_key,
+			status = smb2_signing_decrypt_pdu(s->smb2->decryption_key,
 							  conn->protocol,
 							  tf_iov, 2);
 			if (!NT_STATUS_IS_OK(status)) {
@@ -3125,7 +3166,7 @@ static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 
 				s = state->conn->sessions;
 				for (; s; s = s->next) {
-					if (s->smb2.session_id != uid) {
+					if (s->smb2->session_id != uid) {
 						continue;
 					}
 
@@ -3139,7 +3180,7 @@ static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 			}
 
 			last_session = session;
-			signing_key = &session->smb2.channel_signing_key;
+			signing_key = &session->smb2_channel.signing_key;
 		}
 
 		if (opcode == SMB2_OP_SESSSETUP) {
@@ -3153,7 +3194,7 @@ static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
 			 */
 			if (signing_key && signing_key->length == 0 &&
 			    !NT_STATUS_IS_OK(status)) {
-				signing_key = &session->smb2.signing_key;
+				signing_key = &session->smb2->signing_key;
 			}
 
 			if (signing_key && signing_key->length == 0) {
@@ -4239,6 +4280,11 @@ struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
 	if (session == NULL) {
 		return NULL;
 	}
+	session->smb2 = talloc_zero(session, struct smb2cli_session);
+	if (session->smb2 == NULL) {
+		talloc_free(session);
+		return NULL;
+	}
 	talloc_set_destructor(session, smbXcli_session_destructor);
 
 	DLIST_ADD_END(conn->sessions, session, struct smbXcli_session *);
@@ -4277,12 +4323,12 @@ uint8_t smb2cli_session_security_mode(struct smbXcli_session *session)
 
 uint64_t smb2cli_session_current_id(struct smbXcli_session *session)
 {
-	return session->smb2.session_id;
+	return session->smb2->session_id;
 }
 
 uint16_t smb2cli_session_get_flags(struct smbXcli_session *session)
 {
-	return session->smb2.session_flags;
+	return session->smb2->session_flags;
 }
 
 NTSTATUS smb2cli_session_application_key(struct smbXcli_session *session,
@@ -4291,11 +4337,11 @@ NTSTATUS smb2cli_session_application_key(struct smbXcli_session *session,
 {
 	*key = data_blob_null;
 
-	if (session->smb2.application_key.length == 0) {
+	if (session->smb2->application_key.length == 0) {
 		return NT_STATUS_NO_USER_SESSION_KEY;
 	}
 
-	*key = data_blob_dup_talloc(mem_ctx, session->smb2.application_key);
+	*key = data_blob_dup_talloc(mem_ctx, session->smb2->application_key);
 	if (key->data == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -4307,8 +4353,13 @@ void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
 				      uint64_t session_id,
 				      uint16_t session_flags)
 {
-	session->smb2.session_id = session_id;
-	session->smb2.session_flags = session_flags;
+	session->smb2->session_id = session_id;
+	session->smb2->session_flags = session_flags;
+}
+
+void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session)
+{
+	session->smb2->channel_sequence += 1;
 }
 
 NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
@@ -4326,12 +4377,12 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
 
 	no_sign_flags = SMB2_SESSION_FLAG_IS_GUEST | SMB2_SESSION_FLAG_IS_NULL;
 
-	if (session->smb2.session_flags & no_sign_flags) {
-		session->smb2.should_sign = false;
+	if (session->smb2->session_flags & no_sign_flags) {
+		session->smb2->should_sign = false;
 		return NT_STATUS_OK;
 	}
 
-	if (session->smb2.signing_key.length != 0) {
+	if (session->smb2->signing_key.length != 0) {
 		return NT_STATUS_INVALID_PARAMETER_MIX;
 	}
 
@@ -4339,10 +4390,10 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
 	memcpy(session_key, _session_key.data,
 	       MIN(_session_key.length, sizeof(session_key)));
 
-	session->smb2.signing_key = data_blob_talloc(session,
+	session->smb2->signing_key = data_blob_talloc(session,
 						     session_key,
 						     sizeof(session_key));
-	if (session->smb2.signing_key.data == NULL) {
+	if (session->smb2->signing_key.data == NULL) {
 		ZERO_STRUCT(session_key);
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -4354,12 +4405,12 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
 		smb2_key_derivation(session_key, sizeof(session_key),
 				    label.data, label.length,
 				    context.data, context.length,
-				    session->smb2.signing_key.data);
+				    session->smb2->signing_key.data);
 	}
 
-	session->smb2.encryption_key = data_blob_dup_talloc(session,
-						session->smb2.signing_key);
-	if (session->smb2.encryption_key.data == NULL) {
+	session->smb2->encryption_key = data_blob_dup_talloc(session,
+						session->smb2->signing_key);
+	if (session->smb2->encryption_key.data == NULL) {
 		ZERO_STRUCT(session_key);
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -4371,12 +4422,12 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
 		smb2_key_derivation(session_key, sizeof(session_key),
 				    label.data, label.length,
 				    context.data, context.length,
-				    session->smb2.encryption_key.data);
+				    session->smb2->encryption_key.data);
 	}
 
-	session->smb2.decryption_key = data_blob_dup_talloc(session,
-						session->smb2.signing_key);
-	if (session->smb2.decryption_key.data == NULL) {
+	session->smb2->decryption_key = data_blob_dup_talloc(session,
+						session->smb2->signing_key);
+	if (session->smb2->decryption_key.data == NULL) {
 		ZERO_STRUCT(session_key);
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -4388,12 +4439,12 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
 		smb2_key_derivation(session_key, sizeof(session_key),
 				    label.data, label.length,
 				    context.data, context.length,
-				    session->smb2.decryption_key.data);
+				    session->smb2->decryption_key.data);
 	}
 
-	session->smb2.application_key = data_blob_dup_talloc(session,
-						session->smb2.signing_key);
-	if (session->smb2.application_key.data == NULL) {
+	session->smb2->application_key = data_blob_dup_talloc(session,
+						session->smb2->signing_key);
+	if (session->smb2->application_key.data == NULL) {
 		ZERO_STRUCT(session_key);
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -4405,49 +4456,49 @@ NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
 		smb2_key_derivation(session_key, sizeof(session_key),
 				    label.data, label.length,
 				    context.data, context.length,
-				    session->smb2.application_key.data);
+				    session->smb2->application_key.data);
 	}
 	ZERO_STRUCT(session_key);
 
-	session->smb2.channel_signing_key = data_blob_dup_talloc(session,
-						session->smb2.signing_key);
-	if (session->smb2.channel_signing_key.data == NULL) {
+	session->smb2_channel.signing_key = data_blob_dup_talloc(session,
+						session->smb2->signing_key);
+	if (session->smb2_channel.signing_key.data == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = smb2_signing_check_pdu(session->smb2.channel_signing_key,
+	status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
 					session->conn->protocol,
 					recv_iov, 3);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
 
-	session->smb2.should_sign = false;
-	session->smb2.should_encrypt = false;
+	session->smb2->should_sign = false;
+	session->smb2->should_encrypt = false;
 
 	if (conn->desire_signing) {
-		session->smb2.should_sign = true;
+		session->smb2->should_sign = true;
 	}
 
 	if (conn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
-		session->smb2.should_sign = true;
+		session->smb2->should_sign = true;
 	}
 
-	if (session->smb2.session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
-		session->smb2.should_encrypt = true;
+	if (session->smb2->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
+		session->smb2->should_encrypt = true;
 	}
 
 	if (conn->protocol < PROTOCOL_SMB2_24) {
-		session->smb2.should_encrypt = false;
+		session->smb2->should_encrypt = false;
 	}
 
 	if (!(conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION)) {
-		session->smb2.should_encrypt = false;
+		session->smb2->should_encrypt = false;
 	}
 
-	generate_random_buffer((uint8_t *)&session->smb2.channel_nonce,
-			       sizeof(session->smb2.channel_nonce));
-	session->smb2.channel_next = 1;
+	generate_random_buffer((uint8_t *)&session->smb2->nonce_high,
+			       sizeof(session->smb2->nonce_high));
+	session->smb2->nonce_low = 1;
 
 	return NT_STATUS_OK;
 }
@@ -4459,11 +4510,7 @@ NTSTATUS smb2cli_session_create_channel(TALLOC_CTX *mem_ctx,
 {
 	struct smbXcli_session *session2;
 
-	if (session1->smb2.signing_key.length == 0) {
-		return NT_STATUS_INVALID_PARAMETER_MIX;
-	}
-
-	if (session1->smb2.channel_next == 0) {
+	if (session1->smb2->signing_key.length == 0) {
 		return NT_STATUS_INVALID_PARAMETER_MIX;
 	}
 
@@ -4475,37 +4522,9 @@ NTSTATUS smb2cli_session_create_channel(TALLOC_CTX *mem_ctx,
 	if (session2 == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
-	session2->smb2.session_id = session1->smb2.session_id;
-	session2->smb2.session_flags = session1->smb2.session_flags;
-
-	session2->smb2.signing_key = data_blob_dup_talloc(session2,
-						session1->smb2.signing_key);
-	if (session2->smb2.signing_key.data == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	session2->smb2.application_key = data_blob_dup_talloc(session2,
-						session1->smb2.application_key);
-	if (session2->smb2.application_key.data == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	session2->smb2.should_sign = session1->smb2.should_sign;
-	session2->smb2.should_encrypt = session1->smb2.should_encrypt;
-
-	session2->smb2.channel_nonce = session1->smb2.channel_nonce;
-	session2->smb2.channel_nonce += session1->smb2.channel_next;
-	session1->smb2.channel_next++;
-
-	session2->smb2.encryption_key = data_blob_dup_talloc(session2,
-						session1->smb2.encryption_key);
-	if (session2->smb2.encryption_key.data == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	session2->smb2.decryption_key = data_blob_dup_talloc(session2,
-						session1->smb2.decryption_key);
-	if (session2->smb2.decryption_key.data == NULL) {
+	session2->smb2 = talloc_reference(session2, session1->smb2);
+	if (session2->smb2 == NULL) {
+		talloc_free(session2);
 		return NT_STATUS_NO_MEMORY;
 	}
 
@@ -4529,7 +4548,7 @@ NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
 		return NT_STATUS_INVALID_PARAMETER_MIX;
 	}
 
-	if (session->smb2.channel_signing_key.length != 0) {
+	if (session->smb2_channel.signing_key.length != 0) {
 		return NT_STATUS_INVALID_PARAMETER_MIX;
 	}
 
@@ -4537,10 +4556,10 @@ NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
 	memcpy(channel_key, _channel_key.data,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list