[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Sat Aug 4 06:29:03 MDT 2012


The branch, master has been updated
       via  401860c s3:smbd: add support for SMB_EXTENDED_SIGNATURES in SMBtconX
       via  ff75fd9 s3:smbd: setup the application session key with the first tcon on a session
       via  3a0db4d s3:rpc_server/wkssvc: make usage of session_extract_session_key()
       via  396f317 s3:rpc_server/netlogon: make usage of session_extract_session_key()
      from  49d0432 s3:smbd: setup session->global->signing_/application_key during SPNEGO SMB1 session setups

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


- Log -----------------------------------------------------------------
commit 401860cab6ab3d88659361bd333f6667da071d7b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 3 08:44:39 2012 +0200

    s3:smbd: add support for SMB_EXTENDED_SIGNATURES in SMBtconX
    
    metze
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Sat Aug  4 14:28:04 CEST 2012 on sn-devel-104

commit ff75fd9eda805d0d937b442f8221be89504131eb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 3 08:42:43 2012 +0200

    s3:smbd: setup the application session key with the first tcon on a session
    
    Look for Server.Session.SessionKeyState in [MS-SMB].
    The first SMBtconX sets the state to available, which makes it possible
    to protect the session key at that stage, if client and server
    support TREE_CONNECT_ANDX_EXTENDED_SIGNATURE.
    
    metze

commit 3a0db4d865d404ce7ab3ae787c163fef951e2dd9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Aug 4 10:05:51 2012 +0200

    s3:rpc_server/wkssvc: make usage of session_extract_session_key()
    
    This makes sure we return NO_USER_SESSION_KEY if there's no session key.
    
    metze

commit 396f3177cafdf0ed9a42d28c60ac59579864eae1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Aug 4 10:05:51 2012 +0200

    s3:rpc_server/netlogon: make usage of session_extract_session_key()
    
    This makes sure we return NO_USER_SESSION_KEY if there's no session key.
    
    metze

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

Summary of changes:
 source3/rpc_server/netlogon/srv_netlog_nt.c |   10 +++-
 source3/rpc_server/wkssvc/srv_wkssvc_nt.c   |   26 +++++++-
 source3/smbd/reply.c                        |   96 ++++++++++++++++++++++++++-
 source3/smbd/sesssetup.c                    |   32 +--------
 4 files changed, 129 insertions(+), 35 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index 4621590..d992a65 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -1142,9 +1142,17 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
 	struct samr_UserInfo18 info18;
 	DATA_BLOB in,out;
 	int rc;
+	DATA_BLOB session_key;
 
 	ZERO_STRUCT(user_handle);
 
+	status = session_extract_session_key(session_info,
+					     &session_key,
+					     KEY_USE_16BYTES);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto out;
+	}
+
 	rc = tsocket_address_inet_from_strings(mem_ctx,
 					       "ip",
 					       "127.0.0.1",
@@ -1210,7 +1218,7 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
 
 	in = data_blob_const(nt_hash->hash, 16);
 	out = data_blob_talloc_zero(mem_ctx, 16);
-	sess_crypt_blob(&out, &in, &session_info->session_key, true);
+	sess_crypt_blob(&out, &in, &session_key, true);
 	memcpy(info18.nt_pwd.hash, out.data, out.length);
 
 	info18.nt_pwd_active = true;
diff --git a/source3/rpc_server/wkssvc/srv_wkssvc_nt.c b/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
index b40ca0b..ada83ea 100644
--- a/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
+++ b/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
@@ -819,6 +819,8 @@ WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
 	char *admin_account = NULL;
 	WERROR werr;
 	struct security_token *token = p->session_info->security_token;
+	NTSTATUS status;
+	DATA_BLOB session_key;
 
 	if (!r->in.domain_name) {
 		return WERR_INVALID_PARAM;
@@ -841,9 +843,18 @@ WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
 		return WERR_NOT_SUPPORTED;
 	}
 
+	status = session_extract_session_key(p->session_info,
+					     &session_key,
+					     KEY_USE_16BYTES);
+	if(!NT_STATUS_IS_OK(status)) {
+		DEBUG(5,("_wkssvc_NetrJoinDomain2: no session key %s\n",
+			nt_errstr(status)));
+		return WERR_NO_USER_SESSION_KEY;
+	}
+
 	werr = decode_wkssvc_join_password_buffer(
 		p->mem_ctx, r->in.encrypted_password,
-		&p->session_info->session_key, &cleartext_pwd);
+		&session_key, &cleartext_pwd);
 	if (!W_ERROR_IS_OK(werr)) {
 		return werr;
 	}
@@ -896,6 +907,8 @@ WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
 	char *admin_account = NULL;
 	WERROR werr;
 	struct security_token *token = p->session_info->security_token;
+	NTSTATUS status;
+	DATA_BLOB session_key;
 
 	if (!r->in.account || !r->in.encrypted_password) {
 		return WERR_INVALID_PARAM;
@@ -909,9 +922,18 @@ WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
 		return WERR_ACCESS_DENIED;
 	}
 
+	status = session_extract_session_key(p->session_info,
+					     &session_key,
+					     KEY_USE_16BYTES);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(5,("_wkssvc_NetrUnjoinDomain2: no session key %s\n",
+			nt_errstr(status)));
+		return WERR_NO_USER_SESSION_KEY;
+	}
+
 	werr = decode_wkssvc_join_password_buffer(
 		p->mem_ctx, r->in.encrypted_password,
-		&p->session_info->session_key, &cleartext_pwd);
+		&session_key, &cleartext_pwd);
 	if (!W_ERROR_IS_OK(werr)) {
 		return werr;
 	}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index a893380..1b4a162 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -42,6 +42,7 @@
 #include "smbprofile.h"
 #include "../lib/tsocket/tsocket.h"
 #include "lib/tevent_wait.h"
+#include "libcli/smb/smb_signing.h"
 
 /****************************************************************************
  Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
@@ -721,7 +722,11 @@ void reply_tcon_and_X(struct smb_request *req)
 	int passlen;
 	char *path = NULL;
 	const char *p, *q;
-	uint16 tcon_flags;
+	uint16_t tcon_flags;
+	struct smbXsrv_session *session = NULL;
+	NTTIME now = timeval_to_nttime(&req->request_time);
+	bool session_key_updated = false;
+	uint16_t optional_support = 0;
 	struct smbd_server_connection *sconn = req->sconn;
 
 	START_PROFILE(SMBtconX);
@@ -812,11 +817,99 @@ void reply_tcon_and_X(struct smb_request *req)
 
 	DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
 
+	nt_status = smb1srv_session_lookup(req->sconn->conn,
+					   req->vuid, now, &session);
+	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_USER_SESSION_DELETED)) {
+		reply_force_doserror(req, ERRSRV, ERRbaduid);
+		END_PROFILE(SMBtconX);
+		return;
+	}
+	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
+		reply_nterror(req, nt_status);
+		END_PROFILE(SMBtconX);
+		return;
+	}
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+		END_PROFILE(SMBtconX);
+		return;
+	}
+
+	if (session->global->auth_session_info == NULL) {
+		reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+		END_PROFILE(SMBtconX);
+		return;
+	}
+
+	/*
+	 * If there is no application key defined yet
+	 * we create one.
+	 *
+	 * This means we setup the application key on the
+	 * first tcon that happens via the given session.
+	 *
+	 * Once the application key is defined, it does not
+	 * change any more.
+	 */
+	if (session->global->application_key.length == 0 &&
+	    session->global->signing_key.length > 0)
+	{
+		struct smbXsrv_session *x = session;
+		struct auth_session_info *session_info =
+			session->global->auth_session_info;
+		uint8_t session_key[16];
+
+		ZERO_STRUCT(session_key);
+		memcpy(session_key, x->global->signing_key.data,
+		       MIN(x->global->signing_key.length, sizeof(session_key)));
+
+		/*
+		 * The application key is truncated/padded to 16 bytes
+		 */
+		x->global->application_key = data_blob_talloc(x->global,
+							     session_key,
+							     sizeof(session_key));
+		ZERO_STRUCT(session_key);
+		if (x->global->application_key.data == NULL) {
+			reply_nterror(req, NT_STATUS_NO_MEMORY);
+			END_PROFILE(SMBtconX);
+			return;
+		}
+
+		if (tcon_flags & TCONX_FLAG_EXTENDED_SIGNATURES) {
+			smb_key_derivation(x->global->application_key.data,
+					   x->global->application_key.length,
+					   x->global->application_key.data);
+			optional_support |= SMB_EXTENDED_SIGNATURES;
+		}
+
+		/*
+		 * Place the application key into the session_info
+		 */
+		data_blob_clear_free(&session_info->session_key);
+		session_info->session_key = data_blob_dup_talloc(session_info,
+						x->global->application_key);
+		if (session_info->session_key.data == NULL) {
+			data_blob_clear_free(&x->global->application_key);
+			reply_nterror(req, NT_STATUS_NO_MEMORY);
+			END_PROFILE(SMBtconX);
+			return;
+		}
+		session_key_updated = true;
+	}
+
 	conn = make_connection(sconn, service, client_devicetype,
 			       req->vuid, &nt_status);
 	req->conn =conn;
 
 	if (!conn) {
+		if (session_key_updated) {
+			struct smbXsrv_session *x = session;
+			struct auth_session_info *session_info =
+				session->global->auth_session_info;
+			data_blob_clear_free(&x->global->application_key);
+			data_blob_clear_free(&session_info->session_key);
+		}
 		reply_nterror(req, nt_status);
 		END_PROFILE(SMBtconX);
 		return;
@@ -840,7 +933,6 @@ void reply_tcon_and_X(struct smb_request *req)
 	} else {
 		/* NT sets the fstype of IPC$ to the null string */
 		const char *fstype = IS_IPC(conn) ? "" : lp_fstype(ctx, SNUM(conn));
-		uint16_t optional_support = 0;
 
 		if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
 			/* Return permissions. */
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index cf9c2e7..f47a22d 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -301,38 +301,10 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
 			}
 
 			/*
-			 * The application key is truncated/padded to 16 bytes
-			 */
-			ZERO_STRUCT(session_key);
-			memcpy(session_key, x->global->signing_key.data,
-			       MIN(x->global->signing_key.length,
-				   sizeof(session_key)));
-			x->global->application_key =
-				data_blob_talloc(x->global,
-						 session_key,
-						 sizeof(session_key));
-			ZERO_STRUCT(session_key);
-			if (x->global->application_key.data == NULL) {
-				data_blob_free(&out_blob);
-				TALLOC_FREE(session);
-				reply_nterror(req, NT_STATUS_NO_MEMORY);
-				return;
-			}
-
-			/*
-			 * Place the application key into the session_info
+			 * clear the session key
+			 * the first tcon will add setup the application key
 			 */
 			data_blob_clear_free(&session_info->session_key);
-			session_info->session_key =
-				data_blob_dup_talloc(session_info,
-						     x->global->application_key);
-			if (session_info->session_key.data == NULL) {
-				data_blob_clear_free(&x->global->application_key);
-				data_blob_free(&out_blob);
-				TALLOC_FREE(session);
-				reply_nterror(req, NT_STATUS_NO_MEMORY);
-				return;
-			}
 		}
 
 		session->compat = talloc_zero(session, struct user_struct);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list