[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Tue Nov 2 05:46:01 MDT 2010


The branch, master has been updated
       via  46e70a2 s4-selftest Run RPC-PAC against all the DC environments.
       via  a26d919 s4-process_model Fix valgrind-found use of un-initialised variable
       via  4199976 s4-torture Add tests for DES-only accounts PAC behaviour/validation.
       via  b8a0eb7 s4-selftest Allow weak crypto so we can test DES-only behaviour.
       via  18732b1 heimdal Add handling for PAC signatures over all encryption types
      from  b717ec2 s3-param Fix up lp_set_cmdline() not to re-store cmdline options on each reload

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


- Log -----------------------------------------------------------------
commit 46e70a21006094a8b0575755a47201f1c07e753a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Nov 2 21:57:13 2010 +1100

    s4-selftest Run RPC-PAC against all the DC environments.
    
    This is important, as it will validate that the PAC handling is
    correct with the different encryption types.
    
    Andrew Bartlett
    
    Autobuild-User: Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date: Tue Nov  2 11:45:50 UTC 2010 on sn-devel-104

commit a26d9194ffc45e1c95899ee33bc5dd4d35a0dd10
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Nov 2 20:55:18 2010 +1100

    s4-process_model Fix valgrind-found use of un-initialised variable
    
    The relloc didn't zero the structure for the new process modal, and so
    m->initialised wasn't initialised.
    
    Andrew Bartlett

commit 41999761f1bd018dd039421e2cfe498e173e2f79
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Nov 2 17:14:55 2010 +1100

    s4-torture Add tests for DES-only accounts PAC behaviour/validation.
    
    Previously we didn't support DES-only in a Samba4 domain.  This is
    important for some legacy systems that have not yet migrated from this
    weak crypto.
    
    Andrew Bartlett

commit b8a0eb749fff7c462f4841b12c3977108fba3925
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Nov 2 17:10:47 2010 +1100

    s4-selftest Allow weak crypto so we can test DES-only behaviour.
    
    Andrew Bartlett

commit 18732b1a4b587ea8317f6239a47b205aa5a6cea2
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Nov 2 17:08:34 2010 +1100

    heimdal Add handling for PAC signatures over all encryption types
    
    There are exceptions from the expected behaviour of 'checksum type
    matches key type' that we must deal with here, or else we can't serve
    DES-only servers.
    
    Andrew Bartlett

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

Summary of changes:
 selftest/target/Samba4.pm         |    1 +
 source4/heimdal/lib/krb5/crypto.c |   32 ++++++++++++++
 source4/heimdal/lib/krb5/pac.c    |   81 ++++++++++++++++++++++++++-----------
 source4/selftest/tests.py         |    4 +-
 source4/smbd/process_model.c      |    1 +
 source4/torture/rpc/remote_pac.c  |   45 +++++++++++++++++++-
 source4/torture/rpc/rpc.c         |   35 ++++++++++++++++
 source4/torture/rpc/torture_rpc.h |    6 +++
 8 files changed, 177 insertions(+), 28 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index e310f37..4676ad8 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -639,6 +639,7 @@ sub provision_raw_step1($$)
  dns_lookup_kdc = false
  ticket_lifetime = 24h
  forwardable = yes
+ allow_weak_crypto = yes
 
 [realms]
  $ctx->{realm} = {
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index 2502cc6..006028b 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -1496,6 +1496,8 @@ SP_HMAC_SHA1_checksum(krb5_context context,
 
 /*
  * checksum according to section 5. of draft-brezak-win2k-krb-rc4-hmac-03.txt
+ *
+ * This function made available to PAC routines
  */
 
 static krb5_error_code
@@ -1547,6 +1549,36 @@ HMAC_MD5_checksum(krb5_context context,
     return 0;
 }
 
+/* HMAC-MD5 checksum over any key (needed for the PAC routines) */
+krb5_error_code
+HMAC_MD5_any_checksum(krb5_context context,
+		      const krb5_keyblock *key,
+		      const void *data,
+		      size_t len,
+		      unsigned usage,
+		      Checksum *result)
+{
+	krb5_error_code ret;
+	struct key_data local_key;
+	ret = krb5_copy_keyblock(context, key, &local_key.key);
+	if (ret)
+	    return ret;
+
+	local_key.schedule = NULL;
+	ret = krb5_data_alloc (&result->checksum, 16);
+	if (ret)
+	    return ret;
+
+	result->cksumtype = CKSUMTYPE_HMAC_MD5;
+	ret = HMAC_MD5_checksum(context, &local_key, data, len, usage, result);
+
+	if (ret)
+		krb5_data_free(&result->checksum);
+
+	krb5_free_keyblock(context, local_key.key);
+	return ret;
+}
+
 static struct checksum_type checksum_none = {
     CKSUMTYPE_NONE,
     "none",
diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c
index b66e799..69d9879 100644
--- a/source4/heimdal/lib/krb5/pac.c
+++ b/source4/heimdal/lib/krb5/pac.c
@@ -412,7 +412,6 @@ verify_checksum(krb5_context context,
 		void *ptr, size_t len,
 		const krb5_keyblock *key)
 {
-    krb5_crypto crypto = NULL;
     krb5_storage *sp = NULL;
     uint32_t type;
     krb5_error_code ret;
@@ -452,14 +451,40 @@ verify_checksum(krb5_context context,
 	goto out;
     }
 
-    ret = krb5_crypto_init(context, key, 0, &crypto);
-    if (ret)
-	goto out;
+    /* If the checksum is HMAC-MD5, the checksum type is not tied to
+     * the key type, instead the HMAC-MD5 checksum is applied blindly
+     * on whatever key is used for this connection, avoiding issues
+     * with unkeyed checksums on des-cbc-md5 and des-cbc-crc.  See
+     * http://comments.gmane.org/gmane.comp.encryption.kerberos.devel/8743
+     * for the same issue in MIT, and
+     * http://blogs.msdn.com/b/openspecification/archive/2010/01/01/verifying-the-server-signature-in-kerberos-privilege-account-certificate.aspx
+     * for Microsoft's explaination */
+    if (cksum.cksumtype == CKSUMTYPE_HMAC_MD5) {
+	Checksum local_checksum;
+
+	ret = HMAC_MD5_any_checksum(context, key, ptr, len, KRB5_KU_OTHER_CKSUM, &local_checksum);
+
+	if(local_checksum.checksum.length != cksum.checksum.length ||
+	   ct_memcmp(local_checksum.checksum.data, cksum.checksum.data, local_checksum.checksum.length)) {
+	    ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+	    krb5_set_error_message(context, ret,
+				   N_("PAC integrity check failed for hmac-md5 checksum", ""));
+	} else {
+		ret = 0;
+	}
+	krb5_data_free(&local_checksum.checksum);
+   } else {
+	krb5_crypto crypto = NULL;
 
-    ret = krb5_verify_checksum(context, crypto, KRB5_KU_OTHER_CKSUM,
-			       ptr, len, &cksum);
+	ret = krb5_crypto_init(context, key, 0, &crypto);
+	if (ret)
+		goto out;
+
+	ret = krb5_verify_checksum(context, crypto, KRB5_KU_OTHER_CKSUM,
+				   ptr, len, &cksum);
+	krb5_crypto_destroy(context, crypto);
+    }
     free(cksum.checksum.data);
-    krb5_crypto_destroy(context, crypto);
     krb5_storage_free(sp);
 
     return ret;
@@ -469,14 +494,13 @@ out:
 	free(cksum.checksum.data);
     if (sp)
 	krb5_storage_free(sp);
-    if (crypto)
-	krb5_crypto_destroy(context, crypto);
     return ret;
 }
 
 static krb5_error_code
 create_checksum(krb5_context context,
 		const krb5_keyblock *key,
+		uint32_t cksumtype,
 		void *data, size_t datalen,
 		void *sig, size_t siglen)
 {
@@ -484,16 +508,27 @@ create_checksum(krb5_context context,
     krb5_error_code ret;
     Checksum cksum;
 
-    ret = krb5_crypto_init(context, key, 0, &crypto);
-    if (ret)
-	return ret;
-
-    ret = krb5_create_checksum(context, crypto, KRB5_KU_OTHER_CKSUM, 0,
-			       data, datalen, &cksum);
-    krb5_crypto_destroy(context, crypto);
-    if (ret)
-	return ret;
+    /* If the checksum is HMAC-MD5, the checksum type is not tied to
+     * the key type, instead the HMAC-MD5 checksum is applied blindly
+     * on whatever key is used for this connection, avoiding issues
+     * with unkeyed checksums on des-cbc-md5 and des-cbc-crc.  See
+     * http://comments.gmane.org/gmane.comp.encryption.kerberos.devel/8743
+     * for the same issue in MIT, and
+     * http://blogs.msdn.com/b/openspecification/archive/2010/01/01/verifying-the-server-signature-in-kerberos-privilege-account-certificate.aspx
+     * for Microsoft's explaination */
+    if (cksumtype == CKSUMTYPE_HMAC_MD5) {
+	ret = HMAC_MD5_any_checksum(context, key, data, datalen, KRB5_KU_OTHER_CKSUM, &cksum);
+    } else {
+	ret = krb5_crypto_init(context, key, 0, &crypto);
+	if (ret)
+	    return ret;
 
+	ret = krb5_create_checksum(context, crypto, KRB5_KU_OTHER_CKSUM, 0,
+				   data, datalen, &cksum);
+	krb5_crypto_destroy(context, crypto);
+	if (ret)
+	    return ret;
+    }
     if (cksum.checksum.length != siglen) {
 	krb5_set_error_message(context, EINVAL, "pac checksum wrong length");
 	free_Checksum(&cksum);
@@ -845,8 +880,8 @@ pac_checksum(krb5_context context,
 	return ret;
 
     if (krb5_checksum_is_keyed(context, cktype) == FALSE) {
-	krb5_set_error_message(context, EINVAL, "PAC checksum type is not keyed");
-	return EINVAL;
+	*cksumtype = CKSUMTYPE_HMAC_MD5;
+	*cksumsize = 16;
     }
 
     ret = krb5_checksumsize(context, cktype, cksumsize);
@@ -1026,16 +1061,14 @@ _krb5_pac_sign(krb5_context context,
     }
 
     /* sign */
-
-    ret = create_checksum(context, server_key,
+    ret = create_checksum(context, server_key, server_cksumtype,
 			  d.data, d.length,
 			  (char *)d.data + server_offset, server_size);
     if (ret) {
 	krb5_data_free(&d);
 	goto out;
     }
-
-    ret = create_checksum(context, priv_key,
+    ret = create_checksum(context, priv_key, priv_cksumtype,
 			  (char *)d.data + server_offset, server_size,
 			  (char *)d.data + priv_offset, priv_size);
     if (ret) {
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 9d4d2b3..15a8ab3 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -207,7 +207,7 @@ ncacn_ip_tcp_tests = ["RPC-SCHANNEL", "RPC-JOIN", "RPC-LSA", "RPC-DSSETUP", "RPC
 slow_ncacn_np_tests = ["RPC-SAMLOGON", "RPC-SAMR-USERS", "RPC-SAMR-LARGE-DC", "RPC-SAMR-USERS-PRIVILEGES", "RPC-SAMR-PASSWORDS", "RPC-SAMR-PASSWORDS-PWDLASTSET"]
 slow_ncacn_ip_tcp_tests = ["RPC-SAMR", "RPC-CRACKNAMES"]
 
-all_rpc_tests = ncalrpc_tests + ncacn_np_tests + ncacn_ip_tcp_tests + slow_ncacn_np_tests + slow_ncacn_ip_tcp_tests + ["RPC-LSA-SECRETS", "RPC-SAMBA3-SHARESEC", "RPC-COUNTCALLS"]
+all_rpc_tests = ncalrpc_tests + ncacn_np_tests + ncacn_ip_tcp_tests + slow_ncacn_np_tests + slow_ncacn_ip_tcp_tests + ["RPC-LSA-SECRETS", "RPC-PAC", "RPC-SAMBA3-SHARESEC", "RPC-COUNTCALLS"]
 
 # Make sure all tests get run
 rpc_tests = smb4torture_testsuites("RPC-")
@@ -276,6 +276,8 @@ transports = ["ncacn_np", "ncacn_ip_tcp"]
 
 #Kerberos varies between functional levels, so it is important to check this on all of them
 for env in ["dc", "fl2000dc", "fl2003dc", "fl2008r2dc"]:
+    transport = "ncacn_np"
+    plantestsuite_loadlist("samba4.rpc.pac on %s" % (transport,), env, [smb4torture, "%s:$SERVER[]" % (transport, ), '-U$USERNAME%$PASSWORD', '-W', '$DOMAIN', 'RPC-PAC'])
     for transport in transports:
         plantestsuite_loadlist("samba4.rpc.lsa.secrets on %s with Kerberos" % (transport,), env, [smb4torture, "%s:$SERVER[]" % (transport, ), '-k', 'yes', '-U$USERNAME%$PASSWORD', '-W', '$DOMAIN', '--option=gensec:target_hostname=$NETBIOSNAME', 'RPC-LSA-SECRETS'])
         plantestsuite_loadlist("samba4.rpc.lsa.secrets on %s with Kerberos - use target principal" % (transport,), env, [smb4torture, "%s:$SERVER[]" % (transport, ), '-k', 'yes', '-U$USERNAME%$PASSWORD', '-W', '$DOMAIN', "--option=clientusespnegoprincipal=yes", '--option=gensec:target_hostname=$NETBIOSNAME', 'RPC-LSA-SECRETS'])
diff --git a/source4/smbd/process_model.c b/source4/smbd/process_model.c
index 1696163..7b18f58 100644
--- a/source4/smbd/process_model.c
+++ b/source4/smbd/process_model.c
@@ -92,6 +92,7 @@ _PUBLIC_ NTSTATUS register_process_model(const void *_ops)
 
 	models[num_models].ops = smb_xmemdup(ops, sizeof(*ops));
 	models[num_models].ops->name = smb_xstrdup(ops->name);
+	models[num_models].initialised = false;
 
 	num_models++;
 
diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c
index de6976f..22ea204 100644
--- a/source4/torture/rpc/remote_pac.c
+++ b/source4/torture/rpc/remote_pac.c
@@ -23,15 +23,21 @@
 #include "auth/auth.h"
 #include "auth/auth_sam_reply.h"
 #include "auth/gensec/gensec.h"
+#include "system/kerberos.h"
+#include "auth/kerberos/kerberos.h"
+#include "auth/credentials/credentials.h"
+#include "auth/credentials/credentials_krb5.h"
 #include "lib/cmdline/popt_common.h"
 #include "torture/rpc/torture_rpc.h"
 #include "libcli/auth/libcli_auth.h"
 #include "libcli/security/security.h"
 #include "librpc/gen_ndr/ndr_netlogon_c.h"
+#include "librpc/gen_ndr/ndr_samr_c.h"
 #include "param/param.h"
 
 #define TEST_MACHINE_NAME_BDC "torturepacbdc"
 #define TEST_MACHINE_NAME_WKSTA "torturepacwksta"
+#define TEST_MACHINE_NAME_WKSTA_DES "torturepacwkdes"
 #define TEST_MACHINE_NAME_S2U4SELF_BDC "tests2u4selfbdc"
 #define TEST_MACHINE_NAME_S2U4SELF_WKSTA "tests2u4selfwk"
 
@@ -57,7 +63,6 @@ static bool test_PACVerify(struct torture_context *tctx,
 	struct netr_GenericInfo generic;
 	struct netr_Authenticator auth, auth2;
 	
-
 	struct netlogon_creds_CredentialState *creds;
 	struct gensec_security *gensec_client_context;
 	struct gensec_security *gensec_server_context;
@@ -71,9 +76,7 @@ static bool test_PACVerify(struct torture_context *tctx,
 
 	char *tmp_dir;
 	struct dcerpc_binding_handle *b = p->binding_handle;
-
 	TALLOC_CTX *tmp_ctx = talloc_new(tctx);
-	
 	torture_assert(tctx, tmp_ctx != NULL, "talloc_new() failed");
 
 	if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
@@ -347,6 +350,38 @@ static bool test_PACVerify_workstation(struct torture_context *tctx,
 	return test_PACVerify(tctx, p, credentials, SEC_CHAN_WKSTA, TEST_MACHINE_NAME_WKSTA);
 }
 
+static bool test_PACVerify_workstation_des(struct torture_context *tctx,
+					   struct dcerpc_pipe *p, struct cli_credentials *credentials, struct test_join *join_ctx)
+{
+	struct samr_SetUserInfo r;
+	union samr_UserInfo user_info;
+	struct dcerpc_pipe *samr_pipe = torture_join_samr_pipe(join_ctx);
+	struct smb_krb5_context *smb_krb5_context;
+	krb5_error_code ret;
+
+	ret = cli_credentials_get_krb5_context(cmdline_credentials, tctx->lp_ctx, &smb_krb5_context);
+	torture_assert_int_equal(tctx, ret, 0, "cli_credentials_get_krb5_context() failed");
+
+	if (krb5_config_get_bool_default(smb_krb5_context->krb5_context, NULL, FALSE,
+					 "libdefaults",
+					 "allow_weak_crypto", NULL) == FALSE) {
+		torture_skip(tctx, "Cannot test DES without [libdefaults] allow_weak_crypto = yes");
+	}
+
+	/* Mark this workstation with DES-only */
+	user_info.info16.acct_flags = ACB_USE_DES_KEY_ONLY | ACB_WSTRUST;
+	r.in.user_handle = torture_join_samr_user_policy(join_ctx);
+	r.in.level = 16;
+	r.in.info = &user_info;
+
+	torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(samr_pipe->binding_handle, tctx, &r),
+		"failed to set DES info account flags");
+	torture_assert_ntstatus_ok(tctx, r.out.result,
+		"failed to set DES into account flags");
+
+	return test_PACVerify(tctx, p, credentials, SEC_CHAN_WKSTA, TEST_MACHINE_NAME_WKSTA_DES);
+}
+
 
 /* Check various ways to get the PAC, in particular check the group membership and other details between the PAC from a normal kinit, S2U4Self and a SamLogon */
 static bool test_S2U4Self(struct torture_context *tctx,
@@ -625,6 +660,10 @@ struct torture_suite *torture_rpc_remote_pac(TALLOC_CTX *mem_ctx)
 								      &ndr_table_netlogon, TEST_MACHINE_NAME_WKSTA);
 	torture_rpc_tcase_add_test_creds(tcase, "verify-sig", test_PACVerify_workstation);
 
+	tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon-member-des",
+								      &ndr_table_netlogon, TEST_MACHINE_NAME_WKSTA_DES);
+	torture_rpc_tcase_add_test_join(tcase, "verify-sig", test_PACVerify_workstation_des);
+
 	tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon-bdc",
 							      &ndr_table_netlogon, TEST_MACHINE_NAME_S2U4SELF_BDC);
 	torture_rpc_tcase_add_test_creds(tcase, "s2u4self", test_S2U4Self_bdc);
diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c
index 8d7c51a..7f3ae06 100644
--- a/source4/torture/rpc/rpc.c
+++ b/source4/torture/rpc/rpc.c
@@ -352,6 +352,19 @@ static bool torture_rpc_wrap_test_creds(struct torture_context *tctx,
 	return fn(tctx, tcase_data->pipe, tcase_data->credentials);
 }
 
+static bool torture_rpc_wrap_test_join(struct torture_context *tctx,
+				       struct torture_tcase *tcase,
+				       struct torture_test *test)
+{
+	bool (*fn) (struct torture_context *, struct dcerpc_pipe *, struct cli_credentials *, struct test_join *);
+	struct torture_rpc_tcase_data *tcase_data =
+		(struct torture_rpc_tcase_data *)tcase->data;
+
+	fn = test->fn;
+
+	return fn(tctx, tcase_data->pipe, tcase_data->credentials, tcase_data->join_ctx);
+}
+
 _PUBLIC_ struct torture_test *torture_rpc_tcase_add_test(
 					struct torture_rpc_tcase *tcase, 
 					const char *name, 
@@ -394,6 +407,28 @@ _PUBLIC_ struct torture_test *torture_rpc_tcase_add_test_creds(
 	return test;
 }
 
+_PUBLIC_ struct torture_test *torture_rpc_tcase_add_test_join(
+					struct torture_rpc_tcase *tcase,
+					const char *name,
+					bool (*fn) (struct torture_context *, struct dcerpc_pipe *,
+						    struct cli_credentials *, struct test_join *))
+{
+	struct torture_test *test;
+
+	test = talloc(tcase, struct torture_test);
+
+	test->name = talloc_strdup(test, name);
+	test->description = NULL;
+	test->run = torture_rpc_wrap_test_join;
+	test->dangerous = false;
+	test->data = NULL;
+	test->fn = fn;
+
+	DLIST_ADD(tcase->tcase.tests, test);
+
+	return test;
+}
+
 _PUBLIC_ struct torture_test *torture_rpc_tcase_add_test_ex(
 					struct torture_rpc_tcase *tcase, 
 					const char *name, 
diff --git a/source4/torture/rpc/torture_rpc.h b/source4/torture/rpc/torture_rpc.h
index 8640b56..2f65baa 100644
--- a/source4/torture/rpc/torture_rpc.h
+++ b/source4/torture/rpc/torture_rpc.h
@@ -64,6 +64,12 @@ struct torture_rpc_tcase *torture_suite_add_anon_rpc_iface_tcase(struct torture_
 								const char *name,
 								const struct ndr_interface_table *table);
 
+struct torture_test *torture_rpc_tcase_add_test_join(
+	struct torture_rpc_tcase *tcase,
+	const char *name,
+	bool (*fn) (struct torture_context *, struct dcerpc_pipe *,
+		    struct cli_credentials *, struct test_join *));
+
 struct torture_test *torture_rpc_tcase_add_test_ex(
 					struct torture_rpc_tcase *tcase, 
 					const char *name, 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list