[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Thu Aug 9 02:00:03 MDT 2012


The branch, master has been updated
       via  0d7b17f s3:smb2_sesssetup: setup global->[en|de]cryption_key
       via  0cb11ef s3:smb2_read: don't try sendfile if encryption is used
       via  a0cf42b s3:smb2_server: add smbd_smb2_request->do_encryption
       via  95e4270 s3:smb2_tcon: set global->encryption_required and enforce it
       via  64dce26 s3:smb2_sesssetup: set global->encryption_required and enforce it
       via  8734887 s3:smbXsrv.idl: add encryption_required to smbXsrv_tcon_global0
       via  b5a72f4 s3:smb2_server: check the session before we could response with an error.
       via  f15d9a6 s3:smb2_server: do central file_id check if the operation requires it
      from  a117fd6 s4-dsdb: Ensure we have indexing enabled during the provision

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


- Log -----------------------------------------------------------------
commit 0d7b17f4db9d271ae41ade7c7b003b8d264cf6bf
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 8 09:32:22 2012 +0200

    s3:smb2_sesssetup: setup global->[en|de]cryption_key
    
    metze
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Thu Aug  9 09:59:02 CEST 2012 on sn-devel-104

commit 0cb11efa873d6e70ef54454240df7fbdd54fd3f2
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 8 06:35:34 2012 +0200

    s3:smb2_read: don't try sendfile if encryption is used
    
    metze

commit a0cf42b7099097121e14cd337ea659a37ec824c4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 8 06:35:03 2012 +0200

    s3:smb2_server: add smbd_smb2_request->do_encryption
    
    For now it's always false...
    
    metze

commit 95e4270813fa8bfda2dc899b1c8537e49fb9c115
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 8 06:25:10 2012 +0200

    s3:smb2_tcon: set global->encryption_required and enforce it
    
    This the account or client doesn't support encryption we should
    reject the tree connect.
    
    metze

commit 64dce265338f325e9fdee6b4a95e918d3b704cbf
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 8 06:25:10 2012 +0200

    s3:smb2_sesssetup: set global->encryption_required and enforce it
    
    This the account or client doesn't support encryption we should
    reject the session setup.
    
    metze

commit 87348873486b01a0367ff9889d8a7b51b7073e26
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 8 06:24:01 2012 +0200

    s3:smbXsrv.idl: add encryption_required to smbXsrv_tcon_global0
    
    metze

commit b5a72f4f35a3aecba6294a3f8c07fb2ea252284b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Aug 8 06:57:45 2012 +0200

    s3:smb2_server: check the session before we could response with an error.
    
    metze

commit f15d9a66701eaf580a0b641cf3f0dec185d6dd48
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Aug 7 09:44:31 2012 +0200

    s3:smb2_server: do central file_id check if the operation requires it
    
    Note that it's fine to call file_fsp_smb2() twice, the 2nd call
    just returns smb2req->compat_chain_fsp without a 2nd lookup.
    
    metze

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

Summary of changes:
 source3/librpc/idl/smbXsrv.idl |    1 +
 source3/smbd/globals.h         |    1 +
 source3/smbd/smb2_read.c       |    1 +
 source3/smbd/smb2_server.c     |   87 +++++++++++++++++++++++++++++++++-------
 source3/smbd/smb2_sesssetup.c  |   58 ++++++++++++++++++++++++++
 source3/smbd/smb2_tcon.c       |   34 +++++++++++++--
 6 files changed, 162 insertions(+), 20 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index be52723..9111b3d 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -224,6 +224,7 @@ interface smbXsrv
 		server_id				server_id;
 		NTTIME					creation_time;
 		[charset(UTF8),string] char		share_name[];
+		boolean8				encryption_required;
 	} smbXsrv_tcon_global0;
 
 	typedef union {
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 7b2d31d..ac8a1b2 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -456,6 +456,7 @@ struct smbd_smb2_request {
 
 	int current_idx;
 	bool do_signing;
+	bool do_encryption;
 	struct tevent_timer *async_te;
 	bool cancelled;
 	bool compound_related;
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index 150bdb8..e0c615a 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -276,6 +276,7 @@ static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
 
 	if (!lp__use_sendfile(SNUM(fsp->conn)) ||
 	    smb2req->do_signing ||
+	    smb2req->do_encryption ||
 	    smb2req->in.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) ||
 	    (fsp->base_fsp != NULL) ||
 	    (fsp->wcp != NULL) ||
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 5242547..a84776a 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -38,6 +38,8 @@ static const struct smbd_smb2_dispatch_table {
 	bool need_session;
 	bool need_tcon;
 	bool as_root;
+	uint16_t fileid_ofs;
+	bool allow_invalid_fileid;
 } smbd_smb2_table[] = {
 #define _OP(o) .opcode = o, .name = #o
 	{
@@ -74,26 +76,33 @@ static const struct smbd_smb2_dispatch_table {
 		_OP(SMB2_OP_CLOSE),
 		.need_session = true,
 		.need_tcon = true,
+		.fileid_ofs = 0x08,
 	},{
 		_OP(SMB2_OP_FLUSH),
 		.need_session = true,
 		.need_tcon = true,
+		.fileid_ofs = 0x08,
 	},{
 		_OP(SMB2_OP_READ),
 		.need_session = true,
 		.need_tcon = true,
+		.fileid_ofs = 0x10,
 	},{
 		_OP(SMB2_OP_WRITE),
 		.need_session = true,
 		.need_tcon = true,
+		.fileid_ofs = 0x10,
 	},{
 		_OP(SMB2_OP_LOCK),
 		.need_session = true,
 		.need_tcon = true,
+		.fileid_ofs = 0x08,
 	},{
 		_OP(SMB2_OP_IOCTL),
 		.need_session = true,
 		.need_tcon = true,
+		.fileid_ofs = 0x08,
+		.allow_invalid_fileid = true,
 	},{
 		_OP(SMB2_OP_CANCEL),
 		.as_root = true,
@@ -104,22 +113,32 @@ static const struct smbd_smb2_dispatch_table {
 		_OP(SMB2_OP_FIND),
 		.need_session = true,
 		.need_tcon = true,
+		.fileid_ofs = 0x08,
 	},{
 		_OP(SMB2_OP_NOTIFY),
 		.need_session = true,
 		.need_tcon = true,
+		.fileid_ofs = 0x08,
 	},{
 		_OP(SMB2_OP_GETINFO),
 		.need_session = true,
 		.need_tcon = true,
+		.fileid_ofs = 0x18,
 	},{
 		_OP(SMB2_OP_SETINFO),
 		.need_session = true,
 		.need_tcon = true,
+		.fileid_ofs = 0x10,
 	},{
 		_OP(SMB2_OP_BREAK),
 		.need_session = true,
 		.need_tcon = true,
+		/*
+		 * we do not set
+		 * .fileid_ofs here
+		 * as LEASE breaks does not
+		 * have a file id
+		 */
 	}
 };
 
@@ -1023,6 +1042,7 @@ static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *re
 
 	newreq->sconn = req->sconn;
 	newreq->session = req->session;
+	newreq->do_encryption = req->do_encryption;
 	newreq->do_signing = req->do_signing;
 	newreq->current_idx = req->current_idx;
 
@@ -1723,21 +1743,6 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 		}
 	}
 
-	call = smbd_smb2_call(opcode);
-	if (call == NULL) {
-		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
-	}
-
-	allowed_flags = SMB2_HDR_FLAG_CHAINED |
-			SMB2_HDR_FLAG_SIGNED |
-			SMB2_HDR_FLAG_DFS;
-	if (opcode == SMB2_OP_CANCEL) {
-		allowed_flags |= SMB2_HDR_FLAG_ASYNC;
-	}
-	if ((flags & ~allowed_flags) != 0) {
-		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
-	}
-
 	/*
 	 * Check if the client provided a valid session id,
 	 * if so smbd_smb2_request_check_session() calls
@@ -1758,6 +1763,21 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 		}
 	}
 
+	call = smbd_smb2_call(opcode);
+	if (call == NULL) {
+		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	}
+
+	allowed_flags = SMB2_HDR_FLAG_CHAINED |
+			SMB2_HDR_FLAG_SIGNED |
+			SMB2_HDR_FLAG_DFS;
+	if (opcode == SMB2_OP_CANCEL) {
+		allowed_flags |= SMB2_HDR_FLAG_ASYNC;
+	}
+	if ((flags & ~allowed_flags) != 0) {
+		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	}
+
 	req->do_signing = false;
 	if (flags & SMB2_HDR_FLAG_SIGNED) {
 		DATA_BLOB signing_key;
@@ -1827,7 +1847,44 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 		}
 	}
 
+	if (call->fileid_ofs != 0) {
+		size_t needed = call->fileid_ofs + 16;
+		const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
+		size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
+		uint64_t file_id_persistent;
+		uint64_t file_id_volatile;
+		struct files_struct *fsp;
+
+		SMB_ASSERT(call->need_tcon);
+
+		if (needed > body_size) {
+			return smbd_smb2_request_error(req,
+					NT_STATUS_INVALID_PARAMETER);
+		}
+
+		file_id_persistent	= BVAL(body, call->fileid_ofs + 0);
+		file_id_volatile	= BVAL(body, call->fileid_ofs + 8);
+
+		fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
+		if (fsp == NULL) {
+			if (!call->allow_invalid_fileid) {
+				return smbd_smb2_request_error(req,
+						NT_STATUS_FILE_CLOSED);
+			}
+
+			if (file_id_persistent != UINT64_MAX) {
+				return smbd_smb2_request_error(req,
+						NT_STATUS_FILE_CLOSED);
+			}
+			if (file_id_volatile != UINT64_MAX) {
+				return smbd_smb2_request_error(req,
+						NT_STATUS_FILE_CLOSED);
+			}
+		}
+	}
+
 	if (call->as_root) {
+		SMB_ASSERT(call->fileid_ofs == 0);
 		/* This call needs to be run as root */
 		change_to_root_user();
 	} else {
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 07a168f..12a9d22 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -190,6 +190,10 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
 		x->global->signing_required = true;
 	}
 
+	if (lp_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) {
+		x->global->encryption_required = true;
+	}
+
 	if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
 		/* we map anonymous to guest internally */
 		*out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
@@ -199,6 +203,24 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
 		guest = true;
 	}
 
+	if (guest && x->global->encryption_required) {
+		DEBUG(1,("reject guest session as encryption is required\n"));
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	if (!(conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION)) {
+		if (x->global->encryption_required) {
+			DEBUG(1,("reject session with dialect[0x%04X] "
+				 "as encryption is required\n",
+				 conn->smb2.server.dialect));
+			return NT_STATUS_ACCESS_DENIED;
+		}
+	}
+
+	if (x->global->encryption_required) {
+		*out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
+	}
+
 	ZERO_STRUCT(session_key);
 	memcpy(session_key, session_info->session_key.data,
 	       MIN(session_info->session_key.length, sizeof(session_key)));
@@ -221,6 +243,42 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
 				    x->global->signing_key.data);
 	}
 
+	if (conn->protocol >= PROTOCOL_SMB2_24) {
+		const DATA_BLOB label = data_blob_string_const_null("SMB2AESCCM");
+		const DATA_BLOB context = data_blob_string_const_null("ServerIn ");
+
+		x->global->decryption_key = data_blob_talloc(x->global,
+							     session_key,
+							     sizeof(session_key));
+		if (x->global->decryption_key.data == NULL) {
+			ZERO_STRUCT(session_key);
+			return NT_STATUS_NO_MEMORY;
+		}
+
+		smb2_key_derivation(session_key, sizeof(session_key),
+				    label.data, label.length,
+				    context.data, context.length,
+				    x->global->decryption_key.data);
+	}
+
+	if (conn->protocol >= PROTOCOL_SMB2_24) {
+		const DATA_BLOB label = data_blob_string_const_null("SMB2AESCCM");
+		const DATA_BLOB context = data_blob_string_const_null("ServerOut");
+
+		x->global->encryption_key = data_blob_talloc(x->global,
+							     session_key,
+							     sizeof(session_key));
+		if (x->global->encryption_key.data == NULL) {
+			ZERO_STRUCT(session_key);
+			return NT_STATUS_NO_MEMORY;
+		}
+
+		smb2_key_derivation(session_key, sizeof(session_key),
+				    label.data, label.length,
+				    context.data, context.length,
+				    x->global->encryption_key.data);
+	}
+
 	x->global->application_key = data_blob_dup_talloc(x->global,
 						x->global->signing_key);
 	if (x->global->application_key.data == NULL) {
diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index a6b47d3..2cf91af 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -175,6 +175,7 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 				       uint32_t *out_maximal_access,
 				       uint32_t *out_tree_id)
 {
+	struct smbXsrv_connection *conn = req->sconn->conn;
 	const char *share = in_path;
 	char *service = NULL;
 	int snum = -1;
@@ -183,6 +184,8 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 	connection_struct *compat_conn = NULL;
 	struct user_struct *compat_vuser = req->session->compat;
 	NTSTATUS status;
+	bool encryption_required = req->session->global->encryption_required;
+	bool guest_session = false;
 
 	if (strncmp(share, "\\\\", 2) == 0) {
 		const char *p = strchr(share+2, '\\');
@@ -230,11 +233,26 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 	}
 
 	if (lp_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) {
-		status = NT_STATUS_ACCESS_DENIED;
-		DEBUG(3,("smbd_smb2_tree_connect: "
-			 "service %s needs encryption - %s\n",
-			 service, nt_errstr(status)));
-		return status;
+		encryption_required = true;
+	}
+
+	if (security_session_user_level(compat_vuser->session_info, NULL) < SECURITY_USER) {
+		guest_session = true;
+	}
+
+	if (guest_session && encryption_required) {
+		DEBUG(1,("reject guest as encryption is required for service %s\n",
+			 service));
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	if (!(conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION)) {
+		if (encryption_required) {
+			DEBUG(1,("reject tcon with dialect[0x%04X] "
+				 "as encryption is required for service %s\n",
+				 conn->smb2.server.dialect, service));
+			return NT_STATUS_ACCESS_DENIED;
+		}
 	}
 
 	/* create a new tcon as child of the session */
@@ -243,6 +261,8 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 		return status;
 	}
 
+	tcon->global->encryption_required = encryption_required;
+
 	compat_conn = make_connection_smb2(req->sconn,
 					tcon, snum,
 					req->session->compat,
@@ -309,6 +329,10 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 		*out_share_flags |= SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM;
 	}
 
+	if (encryption_required) {
+		*out_share_flags |= SMB2_SHAREFLAG_ENCRYPT_DATA;
+	}
+
 	*out_maximal_access = tcon->compat->share_access;
 
 	*out_tree_id = tcon->global->tcon_wire_id;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list