[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Thu Aug 23 02:02:04 MDT 2012


The branch, master has been updated
       via  069db9b s3:smb2_break: encrypt OPLOCK BREAK notifications
       via  54dfd08 s3:smb2_server: use smbXsrv_session->nonce_*
       via  6f9610e smbXsrv.idl: add nonce_* to smbsrv_session
       via  6c7ffa9 s3:smb2_server: remove dump_data() from smbd_smb2_request_pending_timer()
      from  27bc6cf Extending space for fqdn in wbinfo --trusted-domains in verbose mode

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


- Log -----------------------------------------------------------------
commit 069db9b630b19835e8a008b50c0bed4d7245bf51
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 22 10:33:07 2012 +0200

    s3:smb2_break: encrypt OPLOCK BREAK notifications
    
    metze
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Thu Aug 23 10:01:14 CEST 2012 on sn-devel-104

commit 54dfd08cb2970fcf2ad915f1ac0caec626cdd44e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 22 10:30:52 2012 +0200

    s3:smb2_server: use smbXsrv_session->nonce_*
    
    metze

commit 6f9610e618a6abbdd41c135e4a3d306fb8ce8743
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 22 10:29:21 2012 +0200

    smbXsrv.idl: add nonce_* to smbsrv_session
    
    metze

commit 6c7ffa90925f074fb93f578b7c0582394aee557d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 22 10:32:09 2012 +0200

    s3:smb2_server: remove dump_data() from smbd_smb2_request_pending_timer()
    
    This was just for debugging...
    
    metze

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

Summary of changes:
 source3/librpc/idl/smbXsrv.idl |    2 +
 source3/smbd/globals.h         |    5 +-
 source3/smbd/smb2_break.c      |   27 +++++++-
 source3/smbd/smb2_server.c     |  143 +++++++++++++++++++++++++++++-----------
 source3/smbd/smb2_sesssetup.c  |    3 +
 5 files changed, 136 insertions(+), 44 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index b3f2250..90572e5 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -145,6 +145,8 @@ interface smbXsrv
 		[ref] smbXsrv_session_global0		*global;
 		NTSTATUS				status;
 		NTTIME					idle_time;
+		hyper					nonce_high;
+		hyper					nonce_low;
 		[ignore] gensec_security		*gensec;
 		[ignore] user_struct			*compat;
 		[ignore] smbXsrv_tcon_table		*tcon_table;
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index b024fb3..6af17a4 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -235,8 +235,9 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
 	smbd_smb2_request_done_ex(req, NT_STATUS_OK, body, dyn, __location__)
 
 NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
-				     uint64_t file_id_persistent,
-				     uint64_t file_id_volatile,
+				     struct smbXsrv_session *session,
+				     struct smbXsrv_tcon *tcon,
+				     struct smbXsrv_open *op,
 				     uint8_t oplock_level);
 
 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c
index 8143b8b..8db9e6d 100644
--- a/source3/smbd/smb2_break.c
+++ b/source3/smbd/smb2_break.c
@@ -235,6 +235,26 @@ void send_break_message_smb2(files_struct *fsp, int level)
 				SMB2_OPLOCK_LEVEL_II :
 				SMB2_OPLOCK_LEVEL_NONE;
 	NTSTATUS status;
+	struct smbXsrv_session *session = NULL;
+	struct timeval tv = timeval_current();
+	NTTIME now = timeval_to_nttime(&tv);
+
+	status = smb2srv_session_lookup(fsp->conn->sconn->conn,
+					fsp->vuid,
+					now,
+					&session);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED) ||
+	    (session == NULL))
+	{
+
+		DEBUG(10,("send_break_message_smb2: skip oplock break "
+			"for file %s, %s, smb2 level %u session %llu not found\n",
+			fsp_str_dbg(fsp),
+			fsp_fnum_dbg(fsp),
+			(unsigned int)smb2_oplock_level,
+			(unsigned long long)fsp->vuid));
+		return;
+	}
 
 	DEBUG(10,("send_break_message_smb2: sending oplock break "
 		"for file %s, %s, smb2 level %u\n",
@@ -243,9 +263,10 @@ void send_break_message_smb2(files_struct *fsp, int level)
 		(unsigned int)smb2_oplock_level ));
 
 	status = smbd_smb2_send_oplock_break(fsp->conn->sconn,
-					fsp->op->global->open_persistent_id,
-					fsp->op->global->open_volatile_id,
-					smb2_oplock_level);
+					     session,
+					     fsp->conn->tcon,
+					     fsp->op,
+					     smb2_oplock_level);
 	if (!NT_STATUS_IS_OK(status)) {
 		smbd_server_connection_terminate(fsp->conn->sconn,
 				 nt_errstr(status));
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 106e6ac..be7997f 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -1431,8 +1431,8 @@ static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
 	uint32_t flags = 0;
 	uint64_t session_id = 0;
 	uint64_t message_id = 0;
-	uint64_t nonce_high;
-	uint64_t nonce_low;
+	uint64_t nonce_high = 0;
+	uint64_t nonce_low = 0;
 	uint64_t async_id = 0;
 	struct tevent_req *subreq = NULL;
 
@@ -1476,15 +1476,18 @@ static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
 	body = hdr + SMB2_HDR_BODY;
 	dyn = body + 8;
 
-	/*
-	 * We may have 2 responses (PENDING, FINAL),
-	 * so alter the nonce.
-	 *
-	 * The PENDING response has the SMB2_HDR_FLAG_ASYNC bit
-	 * set.
-	 */
-	nonce_high = session_id | SMB2_HDR_FLAG_ASYNC;
-	nonce_low = message_id;
+	if (req->do_encryption) {
+		struct smbXsrv_session *x = req->session;
+
+		nonce_high = x->nonce_high;
+		nonce_low = x->nonce_low;
+
+		x->nonce_low += 1;
+		if (x->nonce_low == 0) {
+			x->nonce_low += 1;
+			x->nonce_high += 1;
+		}
+	}
 
 	SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
 	SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
@@ -1553,7 +1556,6 @@ static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
 				(unsigned int)i,
 				(unsigned int)ARRAY_SIZE(state->vector),
 				(unsigned int)state->vector[i].iov_len);
-			dump_data(0, state->vector[i].iov_base, state->vector[i].iov_len);
 		}
 	}
 
@@ -2311,22 +2313,18 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
 	{
 		DATA_BLOB encryption_key = req->session->global->encryption_key;
 		uint8_t *tf;
-		const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
 		uint64_t session_id = req->session->global->session_wire_id;
-		uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
-		uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
-		/*
-		 * We may have 2 responses (PENDING, FINAL),
-		 * so alter the nonce.
-		 *
-		 * The FINAL response has the SMB2_HDR_FLAG_ASYNC bit
-		 * cleared.
-		 */
-		uint64_t nonce_high = session_id & ~SMB2_HDR_FLAG_ASYNC;
-		uint64_t nonce_low = message_id;
+		struct smbXsrv_session *x = req->session;
+		uint64_t nonce_high;
+		uint64_t nonce_low;
+
+		nonce_high = x->nonce_high;
+		nonce_low = x->nonce_low;
 
-		if (nonce_low == 0) {
-			nonce_low = async_id;
+		x->nonce_low += 1;
+		if (x->nonce_low == 0) {
+			x->nonce_low += 1;
+			x->nonce_high += 1;
 		}
 
 		/*
@@ -2696,21 +2694,35 @@ NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
 
 struct smbd_smb2_send_oplock_break_state {
 	struct smbd_server_connection *sconn;
-	uint8_t buf[4 + SMB2_HDR_BODY + 0x18];
-	struct iovec vector;
+	uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x18];
+	struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
 };
 
 static void smbd_smb2_oplock_break_writev_done(struct tevent_req *subreq);
 
 NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
-				     uint64_t file_id_persistent,
-				     uint64_t file_id_volatile,
+				     struct smbXsrv_session *session,
+				     struct smbXsrv_tcon *tcon,
+				     struct smbXsrv_open *op,
 				     uint8_t oplock_level)
 {
 	struct smbd_smb2_send_oplock_break_state *state;
+	struct smbXsrv_connection *conn = sconn->conn;
 	struct tevent_req *subreq;
+	uint8_t *tf;
+	size_t tf_len;
 	uint8_t *hdr;
 	uint8_t *body;
+	size_t body_len;
+	uint8_t *dyn;
+	size_t dyn_len;
+	bool do_encryption = session->global->encryption_required;
+	uint64_t nonce_high = 0;
+	uint64_t nonce_low = 0;
+
+	if (tcon->global->encryption_required) {
+		do_encryption = true;
+	}
 
 	state = talloc(sconn, struct smbd_smb2_send_oplock_break_state);
 	if (state == NULL) {
@@ -2718,12 +2730,29 @@ NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
 	}
 	state->sconn = sconn;
 
-	state->vector.iov_base = (void *)state->buf;
-	state->vector.iov_len = sizeof(state->buf);
-
-	_smb2_setlen(state->buf, sizeof(state->buf) - 4);
-	hdr = state->buf + 4;
+	tf = state->buf + NBT_HDR_SIZE;
+	tf_len = SMB2_TF_HDR_SIZE;
+	hdr = tf + tf_len;
 	body = hdr + SMB2_HDR_BODY;
+	body_len = 0x18;
+	dyn = body + body_len;
+	dyn_len = 0;
+
+	if (do_encryption) {
+		nonce_high = session->nonce_high;
+		nonce_low = session->nonce_low;
+
+		session->nonce_low += 1;
+		if (session->nonce_low == 0) {
+			session->nonce_low += 1;
+			session->nonce_high += 1;
+		}
+	}
+
+	SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
+	SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
+	SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
+	SBVAL(tf, SMB2_TF_SESSION_ID, session->global->session_wire_id);
 
 	SIVAL(hdr, 0,				SMB2_MAGIC);
 	SSVAL(hdr, SMB2_HDR_LENGTH,		SMB2_HDR_BODY);
@@ -2739,19 +2768,55 @@ NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
 	SBVAL(hdr, SMB2_HDR_SESSION_ID,		0);
 	memset(hdr+SMB2_HDR_SIGNATURE, 0, 16);
 
-	SSVAL(body, 0x00, 0x18);
+	SSVAL(body, 0x00, body_len);
 
 	SCVAL(body, 0x02, oplock_level);
 	SCVAL(body, 0x03, 0);		/* reserved */
 	SIVAL(body, 0x04, 0);		/* reserved */
-	SBVAL(body, 0x08, file_id_persistent);
-	SBVAL(body, 0x10, file_id_volatile);
+	SBVAL(body, 0x08, op->global->open_persistent_id);
+	SBVAL(body, 0x10, op->global->open_volatile_id);
+
+	state->vector[0].iov_base = (void *)state->buf;
+	state->vector[0].iov_len = NBT_HDR_SIZE;
+
+	if (do_encryption) {
+		state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
+		state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = tf_len;
+	} else {
+		state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
+		state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
+	}
+
+	state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
+	state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
+
+	state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
+	state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len  = body_len;
+
+	state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
+	state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len   = dyn_len;
+
+	smb2_setup_nbt_length(state->vector, 1 + SMBD_SMB2_NUM_IOV_PER_REQ);
+
+	if (do_encryption) {
+		NTSTATUS status;
+		DATA_BLOB encryption_key = session->global->encryption_key;
+
+		status = smb2_signing_encrypt_pdu(encryption_key,
+					conn->protocol,
+					&state->vector[1+SMBD_SMB2_TF_IOV_OFS],
+					SMBD_SMB2_NUM_IOV_PER_REQ);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+	}
 
 	subreq = tstream_writev_queue_send(state,
 					   sconn->ev_ctx,
 					   sconn->smb2.stream,
 					   sconn->smb2.send_queue,
-					   &state->vector, 1);
+					   state->vector,
+					   ARRAY_SIZE(state->vector));
 	if (subreq == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 12a9d22..a03abf7 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -277,6 +277,9 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
 				    label.data, label.length,
 				    context.data, context.length,
 				    x->global->encryption_key.data);
+
+		generate_random_buffer((uint8_t *)&x->nonce_high, sizeof(x->nonce_high));
+		x->nonce_low = 1;
 	}
 
 	x->global->application_key = data_blob_dup_talloc(x->global,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list