[SCM] Samba Shared Repository - branch master updated

Andreas Schneider asn at samba.org
Tue Mar 13 05:24:03 MDT 2012


The branch, master has been updated
       via  7d4ed89 s3-rpc: Decrypt with the proper session key in CreateTrustedDomainEx2.
      from  e25f830 selftest: samba3.smbtorture_s3.LOCAL-TALLOC-DICT works now

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


- Log -----------------------------------------------------------------
commit 7d4ed899831a853ec2eef8dcd82d74fdbf568f0e
Author: Alexander Bokovoy <ab at samba.org>
Date:   Fri Mar 2 16:18:16 2012 +0200

    s3-rpc: Decrypt with the proper session key in CreateTrustedDomainEx2.
    
    On LSA and SAMR pipes session_key is truncated to 16 byte when doing encryption/decryption.
    However, this was not done for trusted domain-related modifying operations.
    
    As result, Samba 4 client libraries do not work against Samba 3 while working
    against Windows 2008 r2.
    
    Solved this by introducing "session_extract_session_key()" function that allows to specify
    intent of use of the key.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User: Andreas Schneider <asn at cryptomilk.org>
    Autobuild-Date: Tue Mar 13 12:23:44 CET 2012 on sn-devel-104

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

Summary of changes:
 source3/auth/auth_util.c              |   28 +++++++
 source3/auth/proto.h                  |    1 +
 source3/include/auth.h                |    6 ++
 source3/rpc_server/lsa/srv_lsa_nt.c   |  127 +++++++++++++++++----------------
 source3/rpc_server/samr/srv_samr_nt.c |   37 +++++-----
 5 files changed, 120 insertions(+), 79 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 21a8642..4f6ebfa 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -1618,3 +1618,31 @@ NTSTATUS do_map_to_guest_server_info(NTSTATUS status,
 
 	return status;
 }
+
+/*
+  Extract session key from a session info and return it in a blob
+  if intent is KEY_USE_16BYTES, truncate it to 16 bytes
+
+  See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
+  Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
+
+  Note that returned session_key is referencing the original key, it is supposed to be
+  short-lived. If original session_info->session_key is gone, the reference will be broken.
+*/
+NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
+{
+
+	if (session_key == NULL || session_info == NULL) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (session_info->session_key.length == 0) {
+		return NT_STATUS_NO_USER_SESSION_KEY;
+	}
+
+	*session_key = session_info->session_key;
+	if (intent == KEY_USE_16BYTES) {
+		session_key->length = MIN(session_info->session_key.length, 16);
+	}
+	return NT_STATUS_OK;
+}
diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index 01e2934..44ae909 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -248,6 +248,7 @@ NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
 					  struct auth_serversupplied_info **server_info);
 void free_user_info(struct auth_usersupplied_info **user_info);
 bool is_trusted_domain(const char* dom_name);
+NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent);
 
 /* The following definitions come from auth/user_info.c  */
 
diff --git a/source3/include/auth.h b/source3/include/auth.h
index 7f2c3e5..693a0df 100644
--- a/source3/include/auth.h
+++ b/source3/include/auth.h
@@ -128,6 +128,12 @@ struct auth_init_function_entry {
 
 extern const struct gensec_security_ops gensec_ntlmssp3_server_ops;
 
+/* Intent of use for session key. LSA and SAMR pipes use 16 bytes of session key when doing create/modify calls */
+enum session_key_use_intent {
+	KEY_USE_FULL = 0,
+	KEY_USE_16BYTES
+};
+
 /* Changed from 1 -> 2 to add the logon_parameters field. */
 /* Changed from 2 -> 3 when we reworked many auth structures to use IDL or be in common with Samba4 */
 #define AUTH_INTERFACE_VERSION 3
diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c
index 0a5cda5..48bdfdb 100644
--- a/source3/rpc_server/lsa/srv_lsa_nt.c
+++ b/source3/rpc_server/lsa/srv_lsa_nt.c
@@ -287,7 +287,7 @@ static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
 			return NT_STATUS_NO_MEMORY;
 		}
 
-		DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
+		DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name));
 
 		if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
 				 &sid, &type)) {
@@ -300,12 +300,12 @@ static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
 		case SID_NAME_DOMAIN:
 		case SID_NAME_ALIAS:
 		case SID_NAME_WKN_GRP:
-			DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
+			DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name));
 			/* Leave these unchanged */
 			break;
 		default:
 			/* Don't hand out anything but the list above */
-			DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
+			DEBUG(5, ("lookup_lsa_sids: %s not found\n", full_name));
 			type = SID_NAME_UNKNOWN;
 			break;
 		}
@@ -1309,10 +1309,7 @@ NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
 		DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
 	}
 
-	/* Probably the lookup_level is some sort of bitmask. */
-	if (r->in.level == 1) {
-		flags = LOOKUP_NAME_ALL;
-	}
+	flags = lsa_lookup_level_to_flags(r->in.level);
 
 	domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
 	if (!domains) {
@@ -1660,6 +1657,46 @@ NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
 					   r->out.trustdom_handle);
 }
 
+static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
+				       TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
+				       struct trustDomainPasswords *auth_struct)
+{
+	enum ndr_err_code ndr_err;
+	DATA_BLOB lsession_key;
+	NTSTATUS status;
+
+	status = session_extract_session_key(p->session_info, &lsession_key, KEY_USE_16BYTES);
+	if (!NT_STATUS_IS_OK(status)) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	arcfour_crypt_blob(auth_blob->data, auth_blob->length, &lsession_key);
+	ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
+				       auth_struct,
+				       (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
+					 struct trustAuthInOutBlob *iopw,
+					 DATA_BLOB *trustauth_blob)
+{
+	enum ndr_err_code ndr_err;
+
+	ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
+				       iopw,
+				       (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	return NT_STATUS_OK;
+}
+
 /***************************************************************************
  _lsa_CreateTrustedDomainEx2
  ***************************************************************************/
@@ -1674,7 +1711,6 @@ NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
 	size_t sd_size;
 	struct pdb_trusted_domain td;
 	struct trustDomainPasswords auth_struct;
-	enum ndr_err_code ndr_err;
 	DATA_BLOB auth_blob;
 
 	if (!IS_DC) {
@@ -1738,27 +1774,18 @@ NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
 		auth_blob.length = r->in.auth_info_internal->auth_blob.size;
 		auth_blob.data = r->in.auth_info_internal->auth_blob.data;
 
-		arcfour_crypt_blob(auth_blob.data, auth_blob.length,
-				   &p->session_info->session_key);
-
-		ndr_err = ndr_pull_struct_blob(&auth_blob, p->mem_ctx,
-					       &auth_struct,
-					       (ndr_pull_flags_fn_t) ndr_pull_trustDomainPasswords);
-		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = get_trustdom_auth_blob(p, p->mem_ctx, &auth_blob, &auth_struct);
+		if (!NT_STATUS_IS_OK(status)) {
 			return NT_STATUS_UNSUCCESSFUL;
 		}
 
-		ndr_err = ndr_push_struct_blob(&td.trust_auth_incoming, p->mem_ctx,
-					       &auth_struct.incoming,
-					       (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
-		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.incoming, &td.trust_auth_incoming);
+		if (!NT_STATUS_IS_OK(status)) {
 			return NT_STATUS_UNSUCCESSFUL;
 		}
 
-		ndr_err = ndr_push_struct_blob(&td.trust_auth_outgoing, p->mem_ctx,
-					       &auth_struct.outgoing,
-					       (ndr_push_flags_fn_t) ndr_push_trustAuthInOutBlob);
-		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.outgoing, &td.trust_auth_outgoing);
+		if (!NT_STATUS_IS_OK(status)) {
 			return NT_STATUS_UNSUCCESSFUL;
 		}
 	} else {
@@ -2244,6 +2271,7 @@ NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
 	DATA_BLOB cleartext_blob_old = data_blob_null;
 	DATA_BLOB *cleartext_blob_new_p = NULL;
 	DATA_BLOB *cleartext_blob_old_p = NULL;
+	DATA_BLOB session_key;
 
 	if (!find_policy_by_hnd(p, r->in.sec_handle, (void **)(void *)&info)) {
 		return NT_STATUS_INVALID_HANDLE;
@@ -2257,12 +2285,17 @@ NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
+	status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
+	if(!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	if (r->in.new_val) {
 		blob_new = data_blob_const(r->in.new_val->data,
 					   r->in.new_val->length);
 
 		status = sess_decrypt_blob(p->mem_ctx, &blob_new,
-					   &p->session_info->session_key,
+					   &session_key,
 					   &cleartext_blob_new);
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
@@ -2276,7 +2309,7 @@ NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
 					   r->in.old_val->length);
 
 		status = sess_decrypt_blob(p->mem_ctx, &blob_old,
-					   &p->session_info->session_key,
+					   &session_key,
 					   &cleartext_blob_old);
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
@@ -2310,6 +2343,7 @@ NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
 	struct lsa_info *info = NULL;
 	DATA_BLOB blob_new, blob_old;
 	DATA_BLOB blob_new_crypt, blob_old_crypt;
+	DATA_BLOB session_key;
 	NTTIME nttime_new, nttime_old;
 	NTSTATUS status;
 
@@ -2333,6 +2367,11 @@ NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
 		return status;
 	}
 
+	status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
+	if(!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	if (r->in.new_val) {
 		if (blob_new.length) {
 			if (!r->out.new_val->buf) {
@@ -2343,7 +2382,7 @@ NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
 			}
 
 			blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
-							   &p->session_info->session_key);
+							   &session_key);
 			if (!blob_new_crypt.length) {
 				return NT_STATUS_NO_MEMORY;
 			}
@@ -2364,7 +2403,7 @@ NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
 			}
 
 			blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
-							   &p->session_info->session_key);
+							   &session_key);
 			if (!blob_old_crypt.length) {
 				return NT_STATUS_NO_MEMORY;
 			}
@@ -3468,40 +3507,6 @@ static NTSTATUS info_ex_2_pdb_trusted_domain(
 	return NT_STATUS_OK;
 }
 
-static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
-				       TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
-				       struct trustDomainPasswords *auth_struct)
-{
-	enum ndr_err_code ndr_err;
-
-	arcfour_crypt_blob(auth_blob->data, auth_blob->length,
-			   &p->session_info->session_key);
-	ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
-				       auth_struct,
-				       (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
-	return NT_STATUS_OK;
-}
-
-static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
-					 struct trustAuthInOutBlob *iopw,
-					 DATA_BLOB *trustauth_blob)
-{
-	enum ndr_err_code ndr_err;
-
-	ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
-				       iopw,
-				       (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
-	return NT_STATUS_OK;
-}
-
 static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
 					  TALLOC_CTX *mem_ctx,
 					  struct lsa_info *policy,
diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c
index ebe6e45..77888ea 100644
--- a/source3/rpc_server/samr/srv_samr_nt.c
+++ b/source3/rpc_server/samr/srv_samr_nt.c
@@ -5036,6 +5036,7 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 	uint32_t fields = 0;
 	bool ret;
 	char *rhost;
+	DATA_BLOB session_key;
 
 	DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
 
@@ -5193,10 +5194,14 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 			break;
 
 		case 18:
+			status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
+			if(!NT_STATUS_IS_OK(status)) {
+				return status;
+			}
 			/* Used by AS/U JRA. */
 			status = set_user_info_18(&info->info18,
 						  p->mem_ctx,
-						  &p->session_info->session_key,
+						  &session_key,
 						  pwd);
 			break;
 
@@ -5206,18 +5211,20 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 			break;
 
 		case 21:
+			status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
+			if(!NT_STATUS_IS_OK(status)) {
+				return status;
+			}
 			status = set_user_info_21(&info->info21,
 						  p->mem_ctx,
-						  &p->session_info->session_key,
+						  &session_key,
 						  pwd);
 			break;
 
 		case 23:
-			if (!p->session_info->session_key.length) {
-				status = NT_STATUS_NO_USER_SESSION_KEY;
-			}
+			status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
 			arcfour_crypt_blob(info->info23.password.data, 516,
-					   &p->session_info->session_key);
+					   &session_key);
 
 			dump_data(100, info->info23.password.data, 516);
 
@@ -5228,12 +5235,10 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 			break;
 
 		case 24:
-			if (!p->session_info->session_key.length) {
-				status = NT_STATUS_NO_USER_SESSION_KEY;
-			}
+			status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
 			arcfour_crypt_blob(info->info24.password.data,
 					   516,
-					   &p->session_info->session_key);
+					   &session_key);
 
 			dump_data(100, info->info24.password.data, 516);
 
@@ -5243,12 +5248,10 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 			break;
 
 		case 25:
-			if (!p->session_info->session_key.length) {
-				status = NT_STATUS_NO_USER_SESSION_KEY;
-			}
+			status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
 			encode_or_decode_arc4_passwd_buffer(
 				info->info25.password.data,
-				&p->session_info->session_key);
+				&session_key);
 
 			dump_data(100, info->info25.password.data, 532);
 
@@ -5258,12 +5261,10 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 			break;
 
 		case 26:
-			if (!p->session_info->session_key.length) {
-				status = NT_STATUS_NO_USER_SESSION_KEY;
-			}
+			status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
 			encode_or_decode_arc4_passwd_buffer(
 				info->info26.password.data,
-				&p->session_info->session_key);
+				&session_key);
 
 			dump_data(100, info->info26.password.data, 516);
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list