The branch, master has been updated
       via  ba7f4b11674 tdb: Fix parse_hex during `tdbtool storehex`
       via  620e1ff931c selftest: move knownfail.d/krb5-no-dollar to 
expectedfail.d
       via  bd919930df6 autobuild: run ntvfs krb5 tests on MIT build
       via  b3d88b24c88 s4:kdc: avoid reusing a variable name
       via  7b9e22e6968 s4:kdc: do not match principal + '$' if smb.conf says 
not to
       via  fc706e8954f s4:kdc:principal lookup will soon succeed on ad_dc_ntvfs
       via  7e45ca3868e s4/torture:kdc-canon understands no-implicit-dollar 
setting
       via  d776d39c835 pytests: krb5 raw tests use TestCase.get_server_param()
       via  3bc0645d0ab pytest: krb5 alias tests: expect no machine$ match on 
ad_dc_ntvfs
       via  8ff29216761 pytest:krb5: ms-kile-client tests notice lack of dollar 
matching
       via  5436532c7f5 pytest: krb5 tests remember implicit dollar option
       via  fcb39cdcbc8 pytests: add TestCase.get_server_param() method
       via  835f0bb26f6 pytest:krb5: print error names on error
       via  e90184fbdaa pytest:krb5: errcode errors include names
       via  8a9a4f2ff2d pytests: rename KRB_ERR_TKT_NYV as KDC_ERR_TKT_NYV
       via  ea70c5dc630 tests: run krb5.kdc tests on ad_dc_ntvfs without 
implicit dollar match
       via  1db071e7e21 loadparm: add "kdc name match implicit dollar without 
canonicalization"
       via  8652e0d856b s4:kdc: allocate fallback realm later, closer to use
       via  e6414e111c7 s4:kdc: do not fallback to "$$" if user is "$"
       via  ee994902b6f s4:kdc: flatten samba_kdc_lookup_client dollar fallback
       via  6ddf5fd58c0 s4:kdc: avoid a leak on error
       via  c006af9d61b s4:kdc: improve a comment
       via  d3034ae3e28 s4:torture:kdc-canon: test each combination only once
       via  205de481839 pytest: test auth.user_session with principals
       via  628d62e6f47 s4:cracknames: initialise a string variable
       via  aa877f87207 docs-xml:smb.conf: fix a sentence
      from  12ef06836bf s3:ntlm_auth: Fix typo in error message (protools -> 
protocols)

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


- Log -----------------------------------------------------------------
commit ba7f4b1167471cea56f069972f78541b76b58657
Author: Lin Liu <[email protected]>
Date:   Tue Nov 18 05:50:55 2025 +0000

    tdb: Fix parse_hex during `tdbtool storehex`
    
    Fixes: fd0561279
    
    During `tdbtool storehex`, tdbtool check whether the input
    string in hex format.
    
    However, during the check, the index is never moved forward,
    resulting in checking beyond the valid input string.
    
    This patch fix the issue by checking the valid string
    
    Signed-off-by: Lin Liu <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>
    
    Autobuild-User(master): Jennifer Sutton <[email protected]>
    Autobuild-Date(master): Thu Nov 20 22:29:03 UTC 2025 on atb-devel-224

commit 620e1ff931cce23d0753e9c5bb760c6a61b57e82
Author: Douglas Bagnall <[email protected]>
Date:   Thu Nov 20 11:33:30 2025 +1300

    selftest: move knownfail.d/krb5-no-dollar to expectedfail.d
    
    If these fail to fail, there is a problem.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit bd919930df6e326103fdde89d38cb57c98e44219
Author: Douglas Bagnall <[email protected]>
Date:   Sat Nov 15 16:56:49 2025 +1300

    autobuild: run ntvfs krb5 tests on MIT build
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit b3d88b24c88e8d79bf958da576759ea7391237ad
Author: Douglas Bagnall <[email protected]>
Date:   Wed Nov 12 16:56:17 2025 +1300

    s4:kdc: avoid reusing a variable name
    
    fallback_principal was used for two different uses: a copy of the
    original principal from which to derive values, and a new principal
    which has the '$' appended on the account name. We might as well be
    clear and an optimising compiler won't see the difference.
    
    Whether we actually need a temporary principal as opposed to using the
    one that was passed in is a separate question.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 7b9e22e696861100fe154394a006c9eba6bf397d
Author: Douglas Bagnall <[email protected]>
Date:   Wed Nov 12 16:22:05 2025 +1300

    s4:kdc: do not match principal + '$' if smb.conf says not to
    
    With this patch we honour
    
     kdc name match implicit dollar without canonicalization = no
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit fc706e8954f509618a22d466e2014979afad8c17
Author: Douglas Bagnall <[email protected]>
Date:   Fri Nov 14 12:46:44 2025 +1300

    s4:kdc:principal lookup will soon succeed on ad_dc_ntvfs
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 7e45ca3868e1efb2b54e55e2f1030a84f9c65426
Author: Douglas Bagnall <[email protected]>
Date:   Wed Nov 5 16:14:12 2025 +1300

    s4/torture:kdc-canon understands no-implicit-dollar setting
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit d776d39c83520d2c7a1197402edab378ddc6bca5
Author: Douglas Bagnall <[email protected]>
Date:   Thu Nov 13 16:44:33 2025 +1300

    pytests: krb5 raw tests use TestCase.get_server_param()
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 3bc0645d0ab73973d5609fd205ffff60ba30f713
Author: Douglas Bagnall <[email protected]>
Date:   Thu Nov 13 16:37:09 2025 +1300

    pytest: krb5 alias tests: expect no machine$ match on ad_dc_ntvfs
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 8ff29216761ce3d0c9fd320eb02dc5944769faf9
Author: Douglas Bagnall <[email protected]>
Date:   Fri Nov 14 20:05:57 2025 +1300

    pytest:krb5: ms-kile-client tests notice lack of dollar matching
    
    In the ad_dc_ntvfs environment.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 5436532c7f5e7f745b348252d847364a6680fc5f
Author: Douglas Bagnall <[email protected]>
Date:   Fri Nov 14 20:10:01 2025 +1300

    pytest: krb5 tests remember implicit dollar option
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit fcb39cdcbc851f087eebc141389969cb0bde1750
Author: Douglas Bagnall <[email protected]>
Date:   Fri Oct 31 09:27:27 2025 +1300

    pytests: add TestCase.get_server_param() method
    
    This makes it easier to get a loadparm value from the server smb.conf
    (rather than the client smb.conf), so you can alter test behaviour
    accordingly.
    
    The class._server_lp attribute is lazily loaded when first needed.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 835f0bb26f6b8cb54419b39b3a7b3735043b44b8
Author: Douglas Bagnall <[email protected]>
Date:   Thu Nov 6 17:37:40 2025 +1300

    pytest:krb5: print error names on error
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit e90184fbdaa2ac1c438548e98dd4953779cb3a60
Author: Douglas Bagnall <[email protected]>
Date:   Wed Nov 5 12:50:31 2025 +1300

    pytest:krb5: errcode errors include names
    
    Before:
    
    > AssertionError: 6 not found in (20,)
    
    After:
    
    > AssertionError: 6 not found in (20,) : KDC_ERR_C_PRINCIPAL_UNKNOWN not in 
['KDC_ERR_TGT_REVOKED']
    
    Useful for people who don't know the codes off by heart.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 8a9a4f2ff2d9f5944d1f41c3d3b0c0f362dfb863
Author: Douglas Bagnall <[email protected]>
Date:   Fri Nov 14 11:30:10 2025 +1300

    pytests: rename KRB_ERR_TKT_NYV as KDC_ERR_TKT_NYV
    
    to be consistent with all the others.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit ea70c5dc63025b3762f23760df1fc11e74e4f797
Author: Douglas Bagnall <[email protected]>
Date:   Wed Nov 12 15:38:24 2025 +1300

    tests: run krb5.kdc tests on ad_dc_ntvfs without implicit dollar match
    
    that is, with "kdc name match with implicit dollar = no"
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 1db071e7e21bc67c0e77dae478d333228bac153a
Author: Douglas Bagnall <[email protected]>
Date:   Wed Nov 12 16:29:13 2025 +1300

    loadparm: add "kdc name match implicit dollar without canonicalization"
    
    This does nothing yet.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 8652e0d856bf0de01595d36ca8c96cafb3d9bd2c
Author: Douglas Bagnall <[email protected]>
Date:   Wed Nov 12 15:56:43 2025 +1300

    s4:kdc: allocate fallback realm later, closer to use
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit e6414e111c785661c494a2dc9626fe716f705d24
Author: Douglas Bagnall <[email protected]>
Date:   Thu Nov 13 11:35:50 2025 +1300

    s4:kdc: do not fallback to "$$" if user is "$"
    
    or from "" to "$", though I am not sure it is easy to get this far
    with an empty account name.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit ee994902b6fe2cc651e565cf461e424b028b00ad
Author: Douglas Bagnall <[email protected]>
Date:   Thu Oct 2 16:58:42 2025 +1300

    s4:kdc: flatten samba_kdc_lookup_client dollar fallback
    
    There is a single linear successful path through the 'num_comp == 1'
    and various NULL checks, but it is written in a branchy fashion as if
    you could skip some portion.
    
    git diff -b is probably useful.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 6ddf5fd58c06d367e61efc308d270c7e88319a2f
Author: Douglas Bagnall <[email protected]>
Date:   Wed Nov 12 15:59:18 2025 +1300

    s4:kdc: avoid a leak on error
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit c006af9d61bf9b917a782421571f30cb4588e237
Author: Douglas Bagnall <[email protected]>
Date:   Fri Oct 31 11:40:11 2025 +1300

    s4:kdc: improve a comment
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit d3034ae3e2833cb5d5a7dc500df4adf83ff52263
Author: Douglas Bagnall <[email protected]>
Date:   Thu Nov 6 16:08:30 2025 +1300

    s4:torture:kdc-canon: test each combination only once
    
    These tests exhaustively combinations of binary options. With
    492d9f083dc23aff2c1fa12e21765861df1c1b38 ("s4:torture: Remove netbios
    realm and lowercase realm tests") we removed some test flags, reducing
    the number of flags to 8, so there are 256 combinations. But we test
    every bit combination of TEST_ALL which was 10 bits (0x3ff), and each
    test was run 4 times ignoring the 0x4 and 0x10 bits.
    
    So we compact the flags into 8 bits and run each one once.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 205de4818394aa48a360481a998336c23a4067b5
Author: Douglas Bagnall <[email protected]>
Date:   Thu Nov 13 14:17:54 2025 +1300

    pytest: test auth.user_session with principals
    
    This tests authsam_get_session_info_principal() which tests
    sam_get_results_principal() which tests crack_user_principal_name().
    
    sam_get_results_principal() is also used in samba_kdc_lookup_client(),
    and we are sort of testing on behalf of that.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 628d62e6f4789e298068e1ce18de700929d5b481
Author: Douglas Bagnall <[email protected]>
Date:   Fri Oct 3 14:27:18 2025 +1300

    s4:cracknames: initialise a string variable
    
    because later we go
    
        ret = krb5_unparse_name_flags([...],
                                      &unparsed_name_short);
        if (ret) {
                free(unparsed_name_short);
                return WERR_NOT_ENOUGH_MEMORY;
        }
    
    which is bad if a krb5_unparse_name_flags() errors without setting
    unparsed_name_short -- not that I see that happening in MIT or Heimdal.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit aa877f87207e0ec8a03660a8dfd7e32b28a8f8ce
Author: Douglas Bagnall <[email protected]>
Date:   Fri Sep 19 17:15:47 2025 +1200

    docs-xml:smb.conf: fix a sentence
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

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

Summary of changes:
 .../ldap/ldapserverrequirestrongauth.xml           |   2 +-
 ...ematchimplicitdollarwithoutcanonicalization.xml |  39 +++++
 lib/param/loadparm.c                               |   2 +
 lib/tdb/tools/tdbtool.c                            |   4 +-
 python/samba/tests/__init__.py                     |  16 ++
 python/samba/tests/auth.py                         |  46 +++++-
 python/samba/tests/krb5/alias_tests.py             |  10 +-
 python/samba/tests/krb5/kdc_base_test.py           |  16 +-
 python/samba/tests/krb5/kdc_tgs_tests.py           |  10 +-
 .../krb5/ms_kile_client_principal_lookup_tests.py  |  34 ++++
 python/samba/tests/krb5/raw_testcase.py            |  21 ++-
 python/samba/tests/krb5/rfc4120_constants.py       |   4 +-
 script/autobuild.py                                |   3 +
 selftest/expectedfail.d/krb5-no-dollar             |  14 ++
 .../ms-kile-client-principal-lookup                |  12 +-
 selftest/knownfail_mit_kdc.d/alias                 |   8 +-
 .../ms-kile-client-principal-lookup                |  14 +-
 selftest/target/Samba4.pm                          |   1 +
 source3/param/loadparm.c                           |   2 +
 source4/dsdb/samdb/cracknames.c                    |   2 +-
 source4/kdc/db-glue.c                              | 173 +++++++++++++--------
 source4/selftest/tests.py                          |  23 +++
 source4/torture/krb5/kdc-canon-heimdal.c           |  32 +++-
 23 files changed, 375 insertions(+), 113 deletions(-)
 create mode 100644 
docs-xml/smbdotconf/security/kdcnamematchimplicitdollarwithoutcanonicalization.xml
 create mode 100644 selftest/expectedfail.d/krb5-no-dollar


Changeset truncated at 500 lines:

diff --git a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml 
b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml
index 18f8903dcaa..563a52d474f 100644
--- a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml
+++ b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml
@@ -29,7 +29,7 @@
 
        <para>Before support for tls channel bindings existed in Samba,
        a value of <emphasis>allow_sasl_over_tls</emphasis> was possible in 
order
-       to allow sasl binds without tls channel bindings. This now misleading
+       to allow sasl binds without tls channel bindings. This is now misleading
        as a value of <emphasis>yes</emphasis> will now allow sasl binds
        with tls channel bindings. Configurations should be changed to
        <emphasis>yes</emphasis> instead or
diff --git 
a/docs-xml/smbdotconf/security/kdcnamematchimplicitdollarwithoutcanonicalization.xml
 
b/docs-xml/smbdotconf/security/kdcnamematchimplicitdollarwithoutcanonicalization.xml
new file mode 100644
index 00000000000..e1426b191c9
--- /dev/null
+++ 
b/docs-xml/smbdotconf/security/kdcnamematchimplicitdollarwithoutcanonicalization.xml
@@ -0,0 +1,39 @@
+<samba:parameter name="kdc name match implicit dollar without canonicalization"
+                 context="G"
+                 type="boolean"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc";>
+  <description>
+    <para>
+      This option only affect clients that do not request name
+      canonicalization in an AS request, which generally means
+      traditional unix Kerberos clients and not Windows clients.
+    </para>
+
+    <para>
+      The KDC may match the name in an AS request inexactly, for
+      example using a case-insensitive comparison or converting it to
+      a User Principal Name, but the client is not informed of the
+      principal it actually matched unless it set the 'canonicalize'
+      option flag.
+    </para>
+    <para>
+      In Active Directory domains, the default behaviour of the KDC is
+      to append a '$' character if the supplied name does not have one
+      and does not already match. That allows 'foo' to match the
+      machine account 'foo$'. An attacker who is able to create
+      arbitrary machine accounts (which can be a low-privilege
+      operation) is sometimes able to get tickets for unix users by
+      mimicking their names. This is known as the 'dollar ticket
+      attack'.
+    </para>
+    <para>
+      With this option set to 'no', the KDC will not try to match
+      using the appended '$' unless the canonicalize flag is set. This
+      will allow AD-aware clients as usual to connect with
+      canonicalization, but not expose traditional unix clients to the
+      dollar ticket attack.
+    </para>
+</description>
+
+<value type="default">yes</value>
+</samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 125838c53a7..dc4f6829208 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2960,6 +2960,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX 
*mem_ctx)
        lpcfg_do_global_parameter(lp_ctx, "strong certificate binding 
enforcement", "full");
        lpcfg_do_global_parameter(lp_ctx, "certificate backdating 
compensation", "0");
        lpcfg_do_global_parameter(lp_ctx, "kdc always include pac", "True");
+       lpcfg_do_global_parameter(lp_ctx, "kdc name match implicit dollar 
without canonicalization",
+                                 "yes");
 
        lpcfg_do_global_parameter(lp_ctx, "nt status support", "True");
 
diff --git a/lib/tdb/tools/tdbtool.c b/lib/tdb/tools/tdbtool.c
index ecd1bb9b50b..6fcadcaa0f5 100644
--- a/lib/tdb/tools/tdbtool.c
+++ b/lib/tdb/tools/tdbtool.c
@@ -363,13 +363,13 @@ static int store_tdb(char *keyname, size_t keylen, char* 
data, size_t datalen)
 
 static bool parse_hex(const char *src, size_t srclen, uint8_t *dst)
 {
-       size_t i=0;
+       const char *end = src + srclen;
 
        if ((srclen % 2) != 0) {
                return false;
        }
 
-       while (i<srclen) {
+       while (src < end) {
                bool ok = hex_byte(src, dst);
                if (!ok) {
                        return false;
diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py
index dc3c4ab55ae..b1e28f11cb3 100644
--- a/python/samba/tests/__init__.py
+++ b/python/samba/tests/__init__.py
@@ -212,6 +212,22 @@ class TestCase(unittest.TestCase):
     def get_loadparm(cls, s3=False):
         return env_loadparm(s3=s3)
 
+    _server_lp = None
+
+    @classmethod
+    def get_server_param(cls, parameter, default=None):
+        """Get a parameter from the server configuration (which may
+        differ from the client config)."""
+        if cls._server_lp is None:
+            server_conf = env_get_var_value("SERVERCONFFILE")
+            cls._server_lp = 
param.LoadParm(filename_for_non_global_lp=server_conf)
+
+        p = cls._server_lp.get(parameter)
+        print(f"server param '{parameter}' is {p} ({type(p)})")
+        if p is None:
+            return default
+        return p
+
     def get_credentials(self):
         return cmdline_credentials
 
diff --git a/python/samba/tests/auth.py b/python/samba/tests/auth.py
index 3fedd5ec37f..04bcaf3b574 100644
--- a/python/samba/tests/auth.py
+++ b/python/samba/tests/auth.py
@@ -21,7 +21,8 @@ Note that this just tests the bindings work. It does not 
intend to test
 the functionality, that's already done in other tests.
 """
 
-from samba import auth
+from samba import auth, ntstatus, NTSTATUSError
+from samba.samdb import SamDB
 import samba.tests
 
 
@@ -100,3 +101,46 @@ class AuthAdminSessionTests(samba.tests.TestCase):
                          self.lp.get('workgroup').upper() +
                          self.lp.get('winbind separator') + 'Administrator')
         self.assertIsNotNone(self.admin_session.unix_token)
+
+    def test_user_session_principals(self):
+        session = auth.system_session()
+        realm = session.credentials.get_realm()
+        samdb = SamDB(lp=self.lp, session_info=session)
+        samdb.newuser('$$', 'password123!')
+        self.addCleanup(samdb.deleteuser, '$$')
+        for p, expected, upnc in [
+                ('', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                ('Administrator', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                (f'Administrator@{realm.split(".", 2)[-1]}', 
ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                (f'Administrator\n@{realm}', ntstatus.NT_STATUS_NO_SUCH_USER, 
None),
+                (f'Administrator@localdc.{realm}', 
ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                (f'Administrator@{realm.lower()}', 0, True),
+                (f'administrator @ {realm}', 0, True),
+                (f'JOE@{realm.lower()}', 0, False),
+                (f'joe @{realm}', 0, False),
+                (f'joe@ {realm.title()}', 0, False),
+                (f'  joe      @  {realm} ', 0, False),
+                (f'joe$@{realm}', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                (f'@$@{realm} ', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                (f'@{realm}', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                (f'$$@{realm}', 0, False),
+                (f'$@{realm}', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                (f'localdc@{realm}', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                (f'localdc$@{realm}', 0, True),
+                (f'localdc.{realm}', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                (f'{realm}', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                (f'LOCALDC$@{realm}', 0, True),
+                (f'missing$@{realm}', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+                ('localdc$', ntstatus.NT_STATUS_NO_SUCH_USER, None),
+        ]:
+            with self.subTest(p=p):
+                try:
+                    session = auth.user_session(samdb, lp_ctx=self.lp, 
principal=p)
+                except NTSTATUSError as e:
+                    result = e.args[0]
+                else:
+                    # no failure
+                    self.assertEqual(session.info.user_principal_constructed, 
upnc, p)
+                    result = 0
+
+                self.assertEqual(result, expected, p)
diff --git a/python/samba/tests/krb5/alias_tests.py 
b/python/samba/tests/krb5/alias_tests.py
index a6a3d0389fa..6a517c596e4 100755
--- a/python/samba/tests/krb5/alias_tests.py
+++ b/python/samba/tests/krb5/alias_tests.py
@@ -31,6 +31,7 @@ from samba.tests.krb5.kdc_base_test import KDCBaseTest
 from samba.tests.krb5.rfc4120_constants import (
     AES256_CTS_HMAC_SHA1_96,
     ARCFOUR_HMAC_MD5,
+    KDC_ERR_C_PRINCIPAL_UNKNOWN,
     KDC_ERR_TGT_REVOKED,
     NT_PRINCIPAL,
 )
@@ -168,7 +169,14 @@ class AliasTests(KDCBaseTest):
                                              ctype=None)
             return [padata], req_body
 
-        expected_error_mode = KDC_ERR_TGT_REVOKED
+        if self.uncanonicalized_implicit_dollar:
+            expected_error_mode = KDC_ERR_TGT_REVOKED
+        else:
+            # These are machine accounts, but we aren't explicitly
+            # adding the '$', so the ntvfs test will not find the
+            # principal.
+            expected_error_mode = KDC_ERR_C_PRINCIPAL_UNKNOWN
+
 
         # Make a request using S4U2Self. The request should fail.
         kdc_exchange_dict = self.tgs_exchange_dict(
diff --git a/python/samba/tests/krb5/kdc_base_test.py 
b/python/samba/tests/krb5/kdc_base_test.py
index 4cf87fa0ba5..52484787253 100644
--- a/python/samba/tests/krb5/kdc_base_test.py
+++ b/python/samba/tests/krb5/kdc_base_test.py
@@ -138,6 +138,7 @@ from samba.tests.krb5.rfc4120_constants import (
     PADATA_ENC_TIMESTAMP,
     PADATA_ENCRYPTED_CHALLENGE,
     PADATA_ETYPE_INFO2,
+    errmap
 )
 
 global_asn1_print = False
@@ -3386,11 +3387,16 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest):
             error-code specified.
         """
         self.assertIsNotNone(rep)
-        self.assertEqual(rep['msg-type'], KRB_ERROR, "rep = {%s}" % rep)
-        if isinstance(expected, collections.abc.Container):
-            self.assertIn(rep['error-code'], expected, "rep = {%s}" % rep)
-        else:
-            self.assertEqual(rep['error-code'], expected, "rep = {%s}" % rep)
+        self.assertEqual(rep['msg-type'], KRB_ERROR,
+                         f"rep {{{rep}}} is not KRB_ERROR")
+
+        if not isinstance(expected, collections.abc.Container):
+            expected = [expected]
+
+        ec = rep['error-code']
+        self.assertIn(ec, expected,
+                      f"rep {{{rep}}}: error {errmap.get(ec, ec)}, "
+                      f"expected {', '.join(errmap.get(x, x) for x in 
expected)}")
 
     def tgs_req(self, cname, sname, realm, ticket, key, etypes,
                 expected_error_mode=0, padata=None, kdc_options=0,
diff --git a/python/samba/tests/krb5/kdc_tgs_tests.py 
b/python/samba/tests/krb5/kdc_tgs_tests.py
index 64397530caf..1f2d8707aab 100755
--- a/python/samba/tests/krb5/kdc_tgs_tests.py
+++ b/python/samba/tests/krb5/kdc_tgs_tests.py
@@ -53,7 +53,7 @@ from samba.tests.krb5.rfc4120_constants import (
     KDC_ERR_SERVER_NOMATCH,
     KDC_ERR_TKT_EXPIRED,
     KDC_ERR_TGT_REVOKED,
-    KRB_ERR_TKT_NYV,
+    KDC_ERR_TKT_NYV,
     KDC_ERR_WRONG_REALM,
     NT_ENTERPRISE_PRINCIPAL,
     NT_PRINCIPAL,
@@ -1117,22 +1117,22 @@ class KdcTgsTests(KdcTgsBaseTests):
     def test_tgs_req_invalid(self):
         creds = self._get_creds()
         tgt = self._get_tgt(creds, invalid=True)
-        self._run_tgs(tgt, creds, expected_error=KRB_ERR_TKT_NYV)
+        self._run_tgs(tgt, creds, expected_error=KDC_ERR_TKT_NYV)
 
     def test_s4u2self_req_invalid(self):
         creds = self._get_creds()
         tgt = self._get_tgt(creds, invalid=True)
-        self._s4u2self(tgt, creds, expected_error=KRB_ERR_TKT_NYV)
+        self._s4u2self(tgt, creds, expected_error=KDC_ERR_TKT_NYV)
 
     def test_user2user_req_invalid(self):
         creds = self._get_creds()
         tgt = self._get_tgt(creds, invalid=True)
-        self._user2user(tgt, creds, expected_error=KRB_ERR_TKT_NYV)
+        self._user2user(tgt, creds, expected_error=KDC_ERR_TKT_NYV)
 
     def test_fast_req_invalid(self):
         creds = self._get_creds()
         tgt = self._get_tgt(creds, invalid=True)
-        self._fast(tgt, creds, expected_error=KRB_ERR_TKT_NYV,
+        self._fast(tgt, creds, expected_error=KDC_ERR_TKT_NYV,
                    expected_sname=self.get_krbtgt_sname())
 
     def test_tgs_req_no_requester_sid(self):
diff --git a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py 
b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py
index 23a3fce55ed..59be116a6bb 100755
--- a/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py
+++ b/python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py
@@ -165,6 +165,13 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest):
             name_type=NT_SRV_INST, names=["krbtgt", realm])
 
         rep = self.as_req(cname, sname, realm, etype)
+
+        if not self.uncanonicalized_implicit_dollar:
+            # we are explicitly not doing "step 2", so the principal
+            # should not be found.
+            self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN)
+            return
+
         self.check_pre_authentication(rep)
 
         # Do the next AS-REQ
@@ -302,6 +309,11 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest):
             name_type=NT_SRV_INST, names=["krbtgt", realm])
 
         rep = self.as_req(cname, sname, realm, etype)
+        if not self.uncanonicalized_implicit_dollar:
+            # principal should not be found in this case
+            self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN)
+            return
+
         self.check_as_reply(rep)
         salt = "%s%s" % (realm.upper(), user_name)
         key = self.PasswordKey_create(
@@ -356,6 +368,10 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest):
             name_type=NT_SRV_INST, names=["krbtgt", realm])
 
         rep = self.as_req(cname, sname, realm, etype)
+        if not self.uncanonicalized_implicit_dollar:
+            self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN)
+            return
+
         self.check_pre_authentication(rep)
 
         # Do the next AS-REQ
@@ -421,6 +437,9 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest):
             name_type=NT_SRV_INST, names=["krbtgt", realm])
 
         rep = self.as_req(cname, sname, realm, etype)
+        if not self.uncanonicalized_implicit_dollar:
+            self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN)
+            return
         self.check_pre_authentication(rep)
 
         # Do the next AS-REQ
@@ -590,6 +609,10 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest):
             name_type=NT_SRV_INST, names=["krbtgt", realm])
 
         rep = self.as_req(cname, sname, realm, etype)
+        if not self.uncanonicalized_implicit_dollar:
+            self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN)
+            return
+
         self.check_pre_authentication(rep)
 
         # Do the next AS-REQ
@@ -664,6 +687,10 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest):
             name_type=NT_SRV_INST, names=["krbtgt", realm])
 
         rep = self.as_req(cname, sname, realm, etype)
+        if not self.uncanonicalized_implicit_dollar:
+            self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN)
+            return
+
         self.check_as_reply(rep)
         salt = "%s%s" % (realm.upper(), user_name)
         key = self.PasswordKey_create(
@@ -720,6 +747,10 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest):
             name_type=NT_SRV_INST, names=["krbtgt", realm])
 
         rep = self.as_req(cname, sname, realm, etype)
+        if not self.uncanonicalized_implicit_dollar:
+            self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN)
+            return
+
         self.check_pre_authentication(rep)
 
         # Do the next AS-REQ
@@ -786,6 +817,9 @@ class MS_Kile_Client_Principal_Lookup_Tests(KDCBaseTest):
             name_type=NT_SRV_INST, names=["krbtgt", realm])
 
         rep = self.as_req(cname, sname, realm, etype)
+        if not self.uncanonicalized_implicit_dollar:
+            self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN)
+            return
         self.check_pre_authentication(rep)
 
         # Do the next AS-REQ
diff --git a/python/samba/tests/krb5/raw_testcase.py 
b/python/samba/tests/krb5/raw_testcase.py
index 07bf4490104..d2b3e8d9d4d 100644
--- a/python/samba/tests/krb5/raw_testcase.py
+++ b/python/samba/tests/krb5/raw_testcase.py
@@ -130,6 +130,7 @@ from samba.tests.krb5.rfc4120_constants import (
     PADATA_REQ_ENC_PA_REP,
     PADATA_SUPPORTED_ETYPES,
     TD_CMS_DIGEST_ALGORITHMS,
+    errmap
 )
 import samba.tests.krb5.kcrypto as kcrypto
 
@@ -863,6 +864,9 @@ class RawKerberosTest(TestCase):
             padata_checking = '1'
         cls.padata_checking = bool(int(padata_checking))
 
+        cls.uncanonicalized_implicit_dollar = cls.get_server_param(
+            "kdc name match implicit dollar without canonicalization", True)
+
         using_embedded_heimdal = samba.tests.env_get_var_value(
             'USING_EMBEDDED_HEIMDAL',
             allow_missing=True)
@@ -874,16 +878,9 @@ class RawKerberosTest(TestCase):
         # Always generating the PAC is currently only supported by
         # the Embedded heimdal
         if using_embedded_heimdal:
-            # get_loadparm loads the client smb.conf
-            # we need to load the server smb.conf to get the server
-            # settings.
-            server_conf = samba.tests.env_get_var_value('SERVERCONFFILE')
-            lp = LoadParm(filename_for_non_global_lp=server_conf)
-            always_include = lp.get("kdc always include pac")
-            if always_include is None:
-                always_include = "True"
-
-            cls.always_include_pac = bool(always_include)
+            cls.always_include_pac = cls.get_server_param(
+                "kdc always include pac",
+                True)
 
         kadmin_is_tgs = samba.tests.env_get_var_value('KADMIN_IS_TGS',
                                                       allow_missing=True)
@@ -5080,7 +5077,9 @@ class RawKerberosTest(TestCase):
         self.assertElementEqual(rep, 'pvno', 5)
         self.assertElementEqual(rep, 'msg-type', KRB_ERROR)
         error_code = self.getElementValue(rep, 'error-code')
-        self.assertIn(error_code, expected_error_mode)
+        self.assertIn(error_code, expected_error_mode,
+                      f"{errmap.get(error_code)} not in "
+                      f"{[errmap.get(e) for e in expected_error_mode]}")
         if self.strict_checking:
             self.assertElementMissing(rep, 'ctime')
             self.assertElementMissing(rep, 'cusec')
diff --git a/python/samba/tests/krb5/rfc4120_constants.py 
b/python/samba/tests/krb5/rfc4120_constants.py
index 2e2de74b21b..a643f40c4af 100644
--- a/python/samba/tests/krb5/rfc4120_constants.py
+++ b/python/samba/tests/krb5/rfc4120_constants.py
@@ -106,7 +106,7 @@ KDC_ERR_SERVER_NOMATCH = 26
 KDC_ERR_PATH_NOT_ACCEPTED = 28
 KDC_ERR_BAD_INTEGRITY = 31
 KDC_ERR_TKT_EXPIRED = 32
-KRB_ERR_TKT_NYV = 33
+KDC_ERR_TKT_NYV = 33
 KDC_ERR_NOT_US = 35
 KDC_ERR_BADMATCH = 36
 KDC_ERR_SKEW = 37
@@ -132,6 +132,8 @@ KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED = 81
 KDC_ERR_PREAUTH_EXPIRED = 90
 KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTIONS = 93
 
+errmap = {v: k for k, v in globals().items() if k[:8] == 'KDC_ERR_'}
+
 # Kpasswd error codes
 KPASSWD_SUCCESS = 0
 KPASSWD_MALFORMED = 1
diff --git a/script/autobuild.py b/script/autobuild.py
index 08abd398810..b449a364868 100755
--- a/script/autobuild.py
+++ b/script/autobuild.py
@@ -793,6 +793,9 @@ tasks = {
             "ad_member_oneway",
             "fl2003dc",
             ])),
+            ("quick-test-ntvf-krb5s",
+             make_test(include_envs=["ad_dc_ntvfs"],
+                       TESTS='krb5')),
             ("lcov", LCOV_CMD),
             ("check-clean-tree", CLEAN_SOURCE_TREE_CMD),
         ],
diff --git a/selftest/expectedfail.d/krb5-no-dollar 
b/selftest/expectedfail.d/krb5-no-dollar
new file mode 100644
index 00000000000..53acc75dab1
--- /dev/null
+++ b/selftest/expectedfail.d/krb5-no-dollar
@@ -0,0 +1,14 @@
+# We expect some Kerberos name matching tests to fail in the
+# ad_dc_ntvfs environment, because it has
+#
+#  kdc name match implicit dollar without canonicalization = no
+#
+# set, meaning tests that assert 'foo' matches 'foo$' in principal
+# lookups will fail.
+
+^samba4\.krb5\.kdc\ with\ machine\ account\ no\ dollar\ 
extension\.canon\.canon\.enterprise\.lc\-user\.no\-win2k\.removedollar\.s4u2self\.canon\.enterprise\.lc\-user\.no\-win2k\.removedollar\.s4u2self\(ad_dc_ntvfs:local\)
+^samba4\.krb5\.kdc\ with\ machine\ account\ no\ dollar\ 
extension\.canon\.canon\.enterprise\.uc\-user\.no\-win2k\.removedollar\.s4u2self\.canon\.enterprise\.uc\-user\.no\-win2k\.removedollar\.s4u2self\(ad_dc_ntvfs:local\)
+
+
+^samba4\.krb5\.kdc\ with\ machine\ account\ no\ dollar\ 
extension\.canon\.canon\.enterprise\.lc\-user\.win2k\.removedollar\.s4u2self\.canon\.enterprise\.lc\-user\.win2k\.removedollar\.s4u2self\(ad_dc_ntvfs:local\)
+^samba4\.krb5\.kdc\ with\ machine\ account\ no\ dollar\ 
extension\.canon\.canon\.enterprise\.uc\-user\.win2k\.removedollar\.s4u2self\.canon\.enterprise\.uc\-user\.win2k\.removedollar\.s4u2self\(ad_dc_ntvfs:local\)
diff --git a/selftest/knownfail_heimdal_kdc.d/ms-kile-client-principal-lookup 
b/selftest/knownfail_heimdal_kdc.d/ms-kile-client-principal-lookup
index cc163386643..3231a68e340 100644
--- a/selftest/knownfail_heimdal_kdc.d/ms-kile-client-principal-lookup
+++ b/selftest/knownfail_heimdal_kdc.d/ms-kile-client-principal-lookup
@@ -1,9 +1,9 @@
 #
 # Heimdal currently fails the following MS-KILE client principal lookup
 # tests
-^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_6_a
-^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_enterprise_principal_step_6_b
-^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_a
-^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_b
-^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_4_c
-^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_principal_step_6_c
+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_enterprise_principal_step_6_a(?!.ad_dc_ntvfs.)
+^samba.tests.krb5.ms_kile_client_principal_lookup_tests.samba.tests.krb5.ms_kile_client_principal_lookup_tests.MS_Kile_Client_Principal_Lookup_Tests.test_nt_enterprise_principal_step_6_b(?!.ad_dc_ntvfs.)


-- 
Samba Shared Repository


Reply via email to