[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Wed Oct 20 12:55:01 UTC 2021


The branch, master has been updated
       via  5eeb441b771 dsdb: Allow special chars like "@" in samAccountName when generating the salt
       via  46039baa813 tests/krb5: Add tests for account salt calculation
       via  25bdf4c994e tests/krb5: Fix account salt calculation to match Windows
       via  889476d1754 tests/krb5: Allow specifying the UPN for test accounts
       via  f4785ccfefe tests/krb5: Allow creating machine accounts without a trailing dollar
       via  7e39994ed34 tests/krb5: Allow specifying prefix or suffix for test account names
       via  a5a6296e57c tests/krb5: Decrease length of test account prefix
       via  4dc3c68c9a2 selftest/Samba3: replace (winbindd => "yes", skip_wait => 1) with (winbindd => "offline")
       via  d998f7f8df2 selftest/Samba3: remove unused close(USERMAP); calls
       via  5d8e794551b waf: Allow building with MIT KRB5 >= 1.20
       via  459200caba0 selftest: Improve error handling and perl style when setting up users in Samba4.pm
       via  2c0658d408f selftest: Remove duplicate setup of $base_dn and $ldbmodify
       via  d4a75eead05 pytest: s3_net_join: avoid name clash
       via  49306f74eb2 selftest: krb5 account creation: clarify account type as an enum
       via  aacb18f9203 pytest: dynamic tests optionally add __doc__
       via  6292f0597f2 selftest: Increase account lockout windows to make test more realiable
       via  a169e013e66 pytest/rodc_rwdc: try to avoid race.
      from  7e961f3f7a8 HEIMDAL:kdc: Fix transit path validation CVE-2017-6594

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


- Log -----------------------------------------------------------------
commit 5eeb441b771a1ffe1ba1c69b72e8795f525a58ed
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Oct 19 16:01:36 2021 +1300

    dsdb: Allow special chars like "@" in samAccountName when generating the salt
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Wed Oct 20 12:54:54 UTC 2021 on sn-devel-184

commit 46039baa81377df10e5b134e4bb064ed246795e4
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Oct 20 12:46:36 2021 +1300

    tests/krb5: Add tests for account salt calculation
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 25bdf4c994e4fdb74abbacb1e22237f3f2cc37fe
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Oct 20 12:45:47 2021 +1300

    tests/krb5: Fix account salt calculation to match Windows
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 889476d1754f8ce2a41557ed3bf5242c1293584e
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Oct 20 12:45:08 2021 +1300

    tests/krb5: Allow specifying the UPN for test accounts
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit f4785ccfefe7c89f84ad847ca3c12f604172b321
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Oct 20 12:44:19 2021 +1300

    tests/krb5: Allow creating machine accounts without a trailing dollar
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 7e39994ed341883ac4c8c257220c19dbf70c7bc5
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Oct 20 12:41:39 2021 +1300

    tests/krb5: Allow specifying prefix or suffix for test account names
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit a5a6296e57cab2b53617d997c37b4e92d4124cc7
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Oct 20 12:39:05 2021 +1300

    tests/krb5: Decrease length of test account prefix
    
    This allows us more room to test with different account names.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14874
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 4dc3c68c9a28f71888e3d6dd3b1f0bcdb8fa45de
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Oct 5 16:42:00 2021 +0200

    selftest/Samba3: replace (winbindd => "yes", skip_wait => 1) with (winbindd => "offline")
    
    This is much more flexible and concentrates the logic in a single place.
    
    We'll use winbindd => "offline" in other places soon.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14870
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d998f7f8df215866ab32e05be772e24fc0b2131c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Oct 8 18:04:55 2021 +0200

    selftest/Samba3: remove unused close(USERMAP); calls
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5d8e794551b5df835f07e2bd8348fef746144601
Author: Andreas Schneider <asn at samba.org>
Date:   Mon Oct 4 13:02:35 2021 +0200

    waf: Allow building with MIT KRB5 >= 1.20
    
    gssrpc/xdr.h:105:1: error: function declaration isn’t a prototype
    [-Werror=strict-prototypes]
      105 | typedef bool_t (*xdrproc_t)();
          | ^~~~~~~
    
    This can't be fixed, as the protoype is variadic. It can take up to three
    arguments.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14870
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 459200caba04fd83ed650b9cdfe5b158cf9a149f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Oct 18 11:55:14 2021 +1300

    selftest: Improve error handling and perl style when setting up users in Samba4.pm
    
    This catches errors and avoids using global varibles (the old
    style file handles are global).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 2c0658d408f17af2abc223b0cb18d8d33e0ecd1a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Oct 18 20:44:54 2021 +1300

    selftest: Remove duplicate setup of $base_dn and $ldbmodify
    
    These are already set up to the same values above for the full
    DC and correct values for the (strange) s4member environment.
    
    By not setting $base_dn again we avoid an error once we start
    checking for them.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit d4a75eead058879b11c8a0901d7277052123d13b
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Fri Aug 20 11:26:02 2021 +1200

    pytest: s3_net_join: avoid name clash
    
    The net_join test uses "NetJoinTest" (and doesn't properly clean up),
    we must use a unique name for this test in s3_net_join.py.
    
    [abartlet at samba.org The hilarious naming conventions come from a time when samba-tool
    was known as "net" in the s4 branch]
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 49306f74eb29a2192019fab9260f9d242f9d5fd9
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Fri Oct 8 15:40:09 2021 +1300

    selftest: krb5 account creation: clarify account type as an enum
    
    This makes the code clearer with a symbolic constant rather
    than a True/False boolean.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit aacb18f920349e13b562c7c97901a0be7b273137
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Fri Aug 6 11:08:10 2021 +1200

    pytest: dynamic tests optionally add __doc__
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14869
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 6292f0597f208d7953382341380921cf0fd0a8a8
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Mon Sep 20 16:27:40 2021 +1200

    selftest: Increase account lockout windows to make test more realiable
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14868
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit a169e013e66bab15e594ce49b805edebfcd503cf
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Sep 8 17:01:26 2021 +1200

    pytest/rodc_rwdc: try to avoid race.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14868
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

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

Summary of changes:
 auth/credentials/credentials_krb5.c                |  12 +-
 lib/krb5_wrap/krb5_samba.c                         | 192 +++++++++---
 lib/krb5_wrap/krb5_samba.h                         |  13 +-
 python/samba/tests/__init__.py                     |   3 +-
 .../samba/tests/krb5/as_canonicalization_tests.py  |   7 +-
 python/samba/tests/krb5/as_req_tests.py            |  10 +
 python/samba/tests/krb5/kdc_base_test.py           |  87 ++++--
 python/samba/tests/krb5/kdc_tgs_tests.py           |   7 +-
 .../krb5/ms_kile_client_principal_lookup_tests.py  |  36 ++-
 python/samba/tests/krb5/raw_testcase.py            |  20 +-
 python/samba/tests/krb5/rodc_tests.py              |   4 +-
 python/samba/tests/krb5/s4u_tests.py               |  35 ++-
 python/samba/tests/krb5/salt_tests.py              | 327 +++++++++++++++++++++
 python/samba/tests/krb5/test_ccache.py             |  11 +-
 python/samba/tests/s3_net_join.py                  |   2 +-
 python/samba/tests/usage.py                        |   1 +
 selftest/knownfail.d/kdc-salt                      |   1 +
 selftest/target/Samba3.pm                          |  43 +--
 selftest/target/Samba4.pm                          |  76 +++--
 source3/passdb/machine_account_secrets.c           |  10 +-
 source4/dsdb/samdb/ldb_modules/password_hash.c     |  23 +-
 source4/dsdb/tests/python/rodc_rwdc.py             |   8 +-
 source4/kdc/wscript_build                          |   1 +
 source4/selftest/tests.py                          |   8 +
 24 files changed, 751 insertions(+), 186 deletions(-)
 create mode 100755 python/samba/tests/krb5/salt_tests.py
 create mode 100644 selftest/knownfail.d/kdc-salt


Changeset truncated at 500 lines:

diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
index c03d80ac440..d2e7a76a69e 100644
--- a/auth/credentials/credentials_krb5.c
+++ b/auth/credentials/credentials_krb5.c
@@ -1200,12 +1200,12 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
 		break;
 	}
 
-	ret = smb_krb5_salt_principal(realm,
-				      username, /* sAMAccountName */
-				      upn, /* userPrincipalName */
-				      uac_flags,
-				      mem_ctx,
-				      &salt_principal);
+	ret = smb_krb5_salt_principal_str(realm,
+					  username, /* sAMAccountName */
+					  upn, /* userPrincipalName */
+					  uac_flags,
+					  mem_ctx,
+					  &salt_principal);
 	if (ret) {
 		talloc_free(mem_ctx);
 		return ret;
diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
index 20ce86c708d..63a6e951f80 100644
--- a/lib/krb5_wrap/krb5_samba.c
+++ b/lib/krb5_wrap/krb5_samba.c
@@ -456,19 +456,20 @@ int smb_krb5_get_pw_salt(krb5_context context,
  *
  * @see smb_krb5_salt_principal2data
  */
-int smb_krb5_salt_principal(const char *realm,
+int smb_krb5_salt_principal(krb5_context krb5_ctx,
+			    const char *realm,
 			    const char *sAMAccountName,
 			    const char *userPrincipalName,
 			    uint32_t uac_flags,
-			    TALLOC_CTX *mem_ctx,
-			    char **_salt_principal)
+			    krb5_principal *salt_princ)
 {
 	TALLOC_CTX *frame = talloc_stackframe();
 	char *upper_realm = NULL;
 	const char *principal = NULL;
 	int principal_len = 0;
+	krb5_error_code krb5_ret;
 
-	*_salt_principal = NULL;
+	*salt_princ = NULL;
 
 	if (sAMAccountName == NULL) {
 		TALLOC_FREE(frame);
@@ -512,7 +513,6 @@ int smb_krb5_salt_principal(const char *realm,
 	 */
 	if (uac_flags & UF_TRUST_ACCOUNT_MASK) {
 		int computer_len = 0;
-		char *tmp = NULL;
 
 		computer_len = strlen(sAMAccountName);
 		if (sAMAccountName[computer_len-1] == '$') {
@@ -520,60 +520,186 @@ int smb_krb5_salt_principal(const char *realm,
 		}
 
 		if (uac_flags & UF_INTERDOMAIN_TRUST_ACCOUNT) {
-			principal = talloc_asprintf(frame, "krbtgt/%*.*s",
-						    computer_len, computer_len,
-						    sAMAccountName);
-			if (principal == NULL) {
+			const char *krbtgt = "krbtgt";
+			krb5_ret = krb5_build_principal_ext(krb5_ctx,
+							    salt_princ,
+							    strlen(upper_realm),
+							    upper_realm,
+							    strlen(krbtgt),
+							    krbtgt,
+							    computer_len,
+							    sAMAccountName,
+							    0);
+			if (krb5_ret != 0) {
 				TALLOC_FREE(frame);
-				return ENOMEM;
+				return krb5_ret;
 			}
 		} else {
-
-			tmp = talloc_asprintf(frame, "host/%*.*s.%s",
-					      computer_len, computer_len,
-					      sAMAccountName, realm);
+			const char *host = "host";
+			char *tmp = NULL;
+			char *tmp_lower = NULL;
+
+			tmp = talloc_asprintf(frame, "%*.*s.%s",
+					      computer_len,
+					      computer_len,
+					      sAMAccountName,
+					      realm);
 			if (tmp == NULL) {
 				TALLOC_FREE(frame);
 				return ENOMEM;
 			}
 
-			principal = strlower_talloc(frame, tmp);
-			TALLOC_FREE(tmp);
-			if (principal == NULL) {
+			tmp_lower = strlower_talloc(frame, tmp);
+			if (tmp_lower == NULL) {
 				TALLOC_FREE(frame);
 				return ENOMEM;
 			}
-		}
 
-		principal_len = strlen(principal);
+			krb5_ret = krb5_build_principal_ext(krb5_ctx,
+							    salt_princ,
+							    strlen(upper_realm),
+							    upper_realm,
+							    strlen(host),
+							    host,
+							    strlen(tmp_lower),
+							    tmp_lower,
+							    0);
+			if (krb5_ret != 0) {
+				TALLOC_FREE(frame);
+				return krb5_ret;
+			}
+		}
 
 	} else if (userPrincipalName != NULL) {
-		char *p;
+		/*
+		 * We parse the name not only to allow an easy
+		 * replacement of the realm (no matter the realm in
+		 * the UPN, the salt comes from the upper-case real
+		 * realm, but also to correctly provide a salt when
+		 * the UPN is host/foo.bar
+		 *
+		 * This can fail for a UPN of the form foo at bar@REALM
+		 * (which is accepted by windows) however.
+		 */
+		krb5_ret = krb5_parse_name(krb5_ctx,
+					   userPrincipalName,
+					   salt_princ);
 
-		principal = userPrincipalName;
-		p = strchr(principal, '@');
-		if (p != NULL) {
-			principal_len = PTR_DIFF(p, principal);
-		} else {
-			principal_len = strlen(principal);
+		if (krb5_ret != 0) {
+			TALLOC_FREE(frame);
+			return krb5_ret;
+		}
+
+		/*
+		 * No matter what realm (including none) in the UPN,
+		 * the realm is replaced with our upper-case realm
+		 */
+		smb_krb5_principal_set_realm(krb5_ctx,
+					     *salt_princ,
+					     upper_realm);
+		if (krb5_ret != 0) {
+			krb5_free_principal(krb5_ctx, *salt_princ);
+			TALLOC_FREE(frame);
+			return krb5_ret;
 		}
 	} else {
 		principal = sAMAccountName;
 		principal_len = strlen(principal);
-	}
 
-	*_salt_principal = talloc_asprintf(mem_ctx, "%*.*s@%s",
-					   principal_len, principal_len,
-					   principal, upper_realm);
-	if (*_salt_principal == NULL) {
-		TALLOC_FREE(frame);
-		return ENOMEM;
+		krb5_ret = krb5_build_principal_ext(krb5_ctx,
+						    salt_princ,
+						    strlen(upper_realm),
+						    upper_realm,
+						    principal_len,
+						    principal,
+						    0);
+		if (krb5_ret != 0) {
+			TALLOC_FREE(frame);
+			return krb5_ret;
+		}
 	}
 
 	TALLOC_FREE(frame);
 	return 0;
 }
 
+/**
+ * @brief This constructs the salt principal used by active directory
+ *
+ * Most Kerberos encryption types require a salt in order to
+ * calculate the long term private key for user/computer object
+ * based on a password.
+ *
+ * The returned _salt_principal is a string in forms like this:
+ * - host/somehost.example.com at EXAMPLE.COM
+ * - SomeAccount at EXAMPLE.COM
+ * - SomePrincipal at EXAMPLE.COM
+ *
+ * This is not the form that's used as salt, it's just
+ * the human readable form. It needs to be converted by
+ * smb_krb5_salt_principal2data().
+ *
+ * @param[in]  realm              The realm the user/computer is added too.
+ *
+ * @param[in]  sAMAccountName     The sAMAccountName attribute of the object.
+ *
+ * @param[in]  userPrincipalName  The userPrincipalName attribute of the object
+ *                                or NULL is not available.
+ *
+ * @param[in]  uac_flags          UF_ACCOUNT_TYPE_MASKed userAccountControl field
+ *
+ * @param[in]  mem_ctx            The TALLOC_CTX to allocate _salt_principal.
+ *
+ * @param[out]  _salt_principal   The resulting principal as string.
+ *
+ * @retval 0 Success; otherwise - Kerberos error codes
+ *
+ * @see smb_krb5_salt_principal2data
+ */
+int smb_krb5_salt_principal_str(const char *realm,
+				const char *sAMAccountName,
+				const char *userPrincipalName,
+				uint32_t uac_flags,
+				TALLOC_CTX *mem_ctx,
+				char **_salt_principal_str)
+{
+	krb5_principal salt_principal = NULL;
+	char *salt_principal_malloc;
+	krb5_context krb5_ctx;
+	krb5_error_code krb5_ret
+		= smb_krb5_init_context_common(&krb5_ctx);
+	if (krb5_ret != 0) {
+		DBG_ERR("kerberos init context failed (%s)\n",
+			error_message(krb5_ret));
+		return krb5_ret;
+	}
+
+	krb5_ret = smb_krb5_salt_principal(krb5_ctx,
+					   realm,
+					   sAMAccountName,
+					   userPrincipalName,
+					   uac_flags,
+					   &salt_principal);
+
+	krb5_ret = krb5_unparse_name(krb5_ctx, salt_principal,
+				     &salt_principal_malloc);
+	if (krb5_ret != 0) {
+		krb5_free_principal(krb5_ctx, salt_principal);
+		DBG_ERR("kerberos unparse of salt principal failed (%s)\n",
+			error_message(krb5_ret));
+		return krb5_ret;
+	}
+	krb5_free_principal(krb5_ctx, salt_principal);
+	*_salt_principal_str
+		= talloc_strdup(mem_ctx, salt_principal_malloc);
+	krb5_free_unparsed_name(krb5_ctx, salt_principal_malloc);
+
+	if (*_salt_principal_str == NULL) {
+		return ENOMEM;
+	}
+	return 0;
+}
+
 /**
  * @brief Converts the salt principal string into the salt data blob
  *
diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h
index 01a9806b670..a66b7465530 100644
--- a/lib/krb5_wrap/krb5_samba.h
+++ b/lib/krb5_wrap/krb5_samba.h
@@ -340,12 +340,19 @@ krb5_error_code ms_suptypes_to_ietf_enctypes(TALLOC_CTX *mem_ctx,
 int smb_krb5_get_pw_salt(krb5_context context,
 			 krb5_const_principal host_princ,
 			 krb5_data *psalt);
-int smb_krb5_salt_principal(const char *realm,
+int smb_krb5_salt_principal(krb5_context krb5_ctx,
+			    const char *realm,
 			    const char *sAMAccountName,
 			    const char *userPrincipalName,
 			    uint32_t uac_flags,
-			    TALLOC_CTX *mem_ctx,
-			    char **_salt_principal);
+			    krb5_principal *salt_princ);
+
+int smb_krb5_salt_principal_str(const char *realm,
+				const char *sAMAccountName,
+				const char *userPrincipalName,
+				uint32_t uac_flags,
+				TALLOC_CTX *mem_ctx,
+				char **_salt_principal);
 int smb_krb5_salt_principal2data(krb5_context context,
 				 const char *salt_principal,
 				 TALLOC_CTX *mem_ctx,
diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py
index 2c7e7784966..1b1fd984251 100644
--- a/python/samba/tests/__init__.py
+++ b/python/samba/tests/__init__.py
@@ -68,7 +68,7 @@ class TestCase(unittest.TestCase):
     """A Samba test case."""
 
     @classmethod
-    def generate_dynamic_test(cls, fnname, suffix, *args):
+    def generate_dynamic_test(cls, fnname, suffix, *args, doc=None):
         """
         fnname is something like "test_dynamic_sum"
         suffix is something like "1plus2"
@@ -81,6 +81,7 @@ class TestCase(unittest.TestCase):
         """
         def fn(self):
             getattr(self, "_%s_with_args" % fnname)(*args)
+        fn.__doc__ = doc
         setattr(cls, "%s_%s" % (fnname, suffix), fn)
 
     @classmethod
diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py b/python/samba/tests/krb5/as_canonicalization_tests.py
index 9538d0ae3cf..674fcb37101 100755
--- a/python/samba/tests/krb5/as_canonicalization_tests.py
+++ b/python/samba/tests/krb5/as_canonicalization_tests.py
@@ -171,9 +171,10 @@ class KerberosASCanonicalizationTests(KDCBaseTest):
     def machine_account_creds(self):
         if self.machine_creds is None:
             samdb = self.get_samdb()
-            self.machine_creds, _ = self.create_account(samdb,
-                                                        MACHINE_NAME,
-                                                        machine_account=True)
+            self.machine_creds, _ = self.create_account(
+                samdb,
+                MACHINE_NAME,
+                account_type=self.AccountType.COMPUTER)
             self.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA)
             self.machine_creds.set_kerberos_state(DONT_USE_KERBEROS)
 
diff --git a/python/samba/tests/krb5/as_req_tests.py b/python/samba/tests/krb5/as_req_tests.py
index 7d7baaebf24..08081928363 100755
--- a/python/samba/tests/krb5/as_req_tests.py
+++ b/python/samba/tests/krb5/as_req_tests.py
@@ -113,6 +113,13 @@ class AsReqKerberosTests(KDCBaseTest):
 
     def test_as_req_enc_timestamp(self):
         client_creds = self.get_client_creds()
+        self._run_as_req_enc_timestamp(client_creds)
+
+    def test_as_req_enc_timestamp_mac(self):
+        client_creds = self.get_mach_creds()
+        self._run_as_req_enc_timestamp(client_creds)
+
+    def _run_as_req_enc_timestamp(self, client_creds):
         client_account = client_creds.get_username()
         client_as_etypes = self.get_default_enctypes()
         client_kvno = client_creds.get_kvno()
@@ -197,6 +204,9 @@ class AsReqKerberosTests(KDCBaseTest):
             pac_request=True)
         self.assertIsNotNone(as_rep)
 
+        return etype_info2
+
+
 if __name__ == "__main__":
     global_asn1_print = False
     global_hexdump = False
diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py
index 1fc15315b0b..b24c6376ab0 100644
--- a/python/samba/tests/krb5/kdc_base_test.py
+++ b/python/samba/tests/krb5/kdc_base_test.py
@@ -23,6 +23,7 @@ import tempfile
 import binascii
 import collections
 import secrets
+from enum import Enum, auto
 
 from collections import namedtuple
 import ldb
@@ -90,6 +91,10 @@ class KDCBaseTest(RawKerberosTest):
     """ Base class for KDC tests.
     """
 
+    class AccountType(Enum):
+        USER = auto()
+        COMPUTER = auto()
+
     @classmethod
     def setUpClass(cls):
         super().setUpClass()
@@ -103,7 +108,7 @@ class KDCBaseTest(RawKerberosTest):
         # An identifier to ensure created accounts have unique names. Windows
         # caches accounts based on usernames, so account names being different
         # across test runs avoids previous test runs affecting the results.
-        cls.account_base = f'krb5_{secrets.token_hex(5)}_'
+        cls.account_base = f'{secrets.token_hex(4)}_'
         cls.account_id = 0
 
         # A set containing DNs of accounts created as part of testing.
@@ -230,16 +235,18 @@ class KDCBaseTest(RawKerberosTest):
 
         return default_enctypes
 
-    def create_account(self, samdb, name, machine_account=False,
+    def create_account(self, samdb, name, account_type=AccountType.USER,
                        spn=None, upn=None, additional_details=None,
-                       ou=None, account_control=0):
+                       ou=None, account_control=0, add_dollar=True):
         '''Create an account for testing.
            The dn of the created account is added to self.accounts,
            which is used by tearDownClass to clean up the created accounts.
         '''
         if ou is None:
-            guid = (DS_GUID_COMPUTERS_CONTAINER if machine_account
-                    else DS_GUID_USERS_CONTAINER)
+            if account_type is account_type.COMPUTER:
+                guid = DS_GUID_COMPUTERS_CONTAINER
+            else:
+                guid = DS_GUID_USERS_CONTAINER
 
             ou = samdb.get_wellknown_dn(samdb.get_default_basedn(), guid)
 
@@ -248,14 +255,18 @@ class KDCBaseTest(RawKerberosTest):
         # remove the account if it exists, this will happen if a previous test
         # run failed
         delete_force(samdb, dn)
-        if machine_account:
-            object_class = "computer"
-            account_name = "%s$" % name
-            account_control |= UF_WORKSTATION_TRUST_ACCOUNT
-        else:
+        account_name = name
+        if account_type is self.AccountType.USER:
             object_class = "user"
-            account_name = name
             account_control |= UF_NORMAL_ACCOUNT
+        else:
+            object_class = "computer"
+            if add_dollar:
+                account_name += '$'
+            if account_type is self.AccountType.COMPUTER:
+                account_control |= UF_WORKSTATION_TRUST_ACCOUNT
+            else:
+                self.fail()
 
         password = generate_random_password(32, 32)
         utf16pw = ('"%s"' % password).encode('utf-16-le')
@@ -267,6 +278,10 @@ class KDCBaseTest(RawKerberosTest):
             "userAccountControl": str(account_control),
             "unicodePwd": utf16pw}
         if spn is not None:
+            if isinstance(spn, str):
+                spn = spn.format(account=account_name)
+            else:
+                spn = tuple(s.format(account=account_name) for s in spn)
             details["servicePrincipalName"] = spn
         if upn is not None:
             details["userPrincipalName"] = upn
@@ -280,11 +295,12 @@ class KDCBaseTest(RawKerberosTest):
         creds.set_domain(samdb.domain_netbios_name().upper())
         creds.set_password(password)
         creds.set_username(account_name)
-        if machine_account:
-            creds.set_workstation(name)
-        else:
+        if account_type is self.AccountType.USER:
             creds.set_workstation('')
+        else:
+            creds.set_workstation(name)
         creds.set_dn(ldb.Dn(samdb, dn))
+        creds.set_upn(upn)
         creds.set_spn(spn)
         #
         # Save the account name so it can be deleted in tearDownClass
@@ -609,13 +625,18 @@ class KDCBaseTest(RawKerberosTest):
         return cleanup
 
     def get_cached_creds(self, *,
-                         machine_account,
+                         account_type,
                          opts=None,
                          use_cache=True):
         if opts is None:
             opts = {}
 
         opts_default = {
+            'name_prefix': None,
+            'name_suffix': None,
+            'add_dollar': True,
+            'upn': None,
+            'spn': None,
             'allowed_replication': False,
             'allowed_replication_mock': False,
             'denied_replication': False,
@@ -632,7 +653,7 @@ class KDCBaseTest(RawKerberosTest):
         }
 
         account_opts = {


-- 
Samba Shared Repository



More information about the samba-cvs mailing list