The branch, master has been updated
       via  bf09de7922d Update WHATSNEW with kerberos changes
       via  952f0365b49 ci:autobuild: add MIT schema_dc krb5 tests
       via  5d0a4d78034 pytest:krb5:as_req: adjust for 'require 
canonicalization'
       via  e1757704e5d pytest:krb5:ms_kile: adjust for 'require 
canonicalization'
       via  25da167403f pytest:krb5: as_canonicalization recognises require 
canon option
       via  955ae6ba935 s4:test: fix kdc-canon-heimdal tests for 'require 
canonicalization'
       via  f64ba78b8b7 s4:test: fix kdc-heimdal simple tests for 'require 
canonicalization'
       via  ef4160280d2 pytest:krb5: notice require canonicalization option
       via  e2708807597 tests: schema_dc krb5 tests with 'require 
canonicalization = yes'
       via  2cfb2041dea s4:kdc: honour "kdc require canonicalization = yes"
       via  d803e2055b1 loadparm: add "kdc require canonicalization"
       via  f0666d91964 pytest:krb5 as_canonicalization checks no implicit $ 
return code
       via  f71398c194a tests: run more kdc tests with no implicit $ without 
canonicalization
       via  e904e8b229b kdc: match implicit dollar without canon affects AS_REQ 
client only
       via  d979cc40a94 pytest:krb5:as_canonicalization debug formatting
       via  a3b12b47a6f samba-tool gpo: remove unused import
       via  12a6a3fef3d torture: do not zero members more than once
       via  b57a1db749b selftest: we no longer use 'testscenarios' or 
'subunit.tests.testsuite'
       via  ce196e7828b selftest: Disable ‘krb5 acceptor report canonical 
client name’ for fl2008r2dc environment
       via  cfbe8815b04 s4:auth: Implement ‘krb5 acceptor report canonical 
client name’ option for Heimdal
       via  f43d957ea08 s4:torture:auth: Do not break client principal
       via  3e6985f2745 auth:kerberos: Do not fail if PAC account name doesn’t 
match ticket principal name
       via  b9692a8bf0d loadparm: Add ‘krb5 acceptor report canonical client 
name’ option
       via  9f1beaf7e19 s4:selftest: Remove ‘extra_options’
       via  e744fa11b1a s4:torture: Fix code spelling
       via  e8edf61a27c s4:torture: Simplify booleans
       via  5bd1ddb9064 s4:torture:auth: Fix PAC checksum test
       via  a5eddef8ec4 WHATSNEW: update for policy hints
       via  04039fdd835 dsdb:password_hash: fix policy_hint controlled reset 
return codes
       via  e1188962aa9 dsdb:password_hash: policy_hints control makes resets 
check history
       via  cdf2defdc57 dsdb:password_hash: "policy hints" resets honour 
minPwdAge
       via  0da540f4d83 pytest:dsdb:password: test policy_hints oid
       via  d588c7969ee pytest:dsdb:passwords: guess ldaps and ldap hosts from 
each other
       via  aff40feb3d7 dsdb:password_hash: notice "policy hints" control
       via  b003beb85a6 ldb: add "policy hints" controls to be used by 
password_hash module
       via  49001e81589 dsdb:password_hash: reject password reset with 
UNWILLING_TO_PERFORM
       via  d90ac9b93ad dsdb:password_hash: fix a typo
       via  55c22996649 python subunit: add dummy addDuration methods
       via  ecb7131c66b s3:vfs_ceph_new: use #ifdef, not #if HAVE_CEPH_ASYNCIO
       via  fdb840b3662 manpages:smb.conf:nt hash store: remove a stray word
      from  c93f33374b3 lib: Fix the build on solaris

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


- Log -----------------------------------------------------------------
commit bf09de7922d9bd590837ba6fe2f5b555787adbc2
Author: Gary Lockyer <[email protected]>
Date:   Tue Dec 23 13:37:19 2025 +1300

    Update WHATSNEW with kerberos changes
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Signed-off-by: Douglas Bagnall <[email protected]>
    
    Autobuild-User(master): Douglas Bagnall <[email protected]>
    Autobuild-Date(master): Thu Jan 15 02:50:59 UTC 2026 on atb-devel-224

commit 952f0365b497d3deb5700b66b0d2d6d7e858bdb4
Author: Douglas Bagnall <[email protected]>
Date:   Sun Dec 21 11:23:15 2025 +1300

    ci:autobuild: add MIT schema_dc krb5 tests
    
    The schema_dc environment has the 'require canonicalization = yes' option,
    which we want to test with MIT kerberos, but only with relevant tests.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit 5d0a4d78034c0afc8a9f144eca11edd10336023a
Author: Douglas Bagnall <[email protected]>
Date:   Fri Dec 12 03:14:02 2025 +0000

    pytest:krb5:as_req: adjust for 'require canonicalization'
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit e1757704e5d2563bcc0e32138c5ea10d28bba9e3
Author: Douglas Bagnall <[email protected]>
Date:   Wed Dec 17 15:19:55 2025 +1300

    pytest:krb5:ms_kile: adjust for 'require canonicalization'
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit 25da167403fbe1cfcb64561885da8894a04c3d45
Author: Douglas Bagnall <[email protected]>
Date:   Thu Jan 8 11:53:58 2026 +1300

    pytest:krb5: as_canonicalization recognises require canon option
    
    If the test is run against a
    
      require canonicalization = yes
    
    server, requests that do not use the canonicalize flag will be
    rejected at the preauth stage, so we check that and nothing more.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit 955ae6ba935545e862f6b0a8e66b76b27fd2fe14
Author: Douglas Bagnall <[email protected]>
Date:   Wed Dec 17 15:17:23 2025 +1300

    s4:test: fix kdc-canon-heimdal tests for 'require canonicalization'
    
    The combination of the server 'require canonicalization' option with a
    lack of a 'canonicalize' flag from the client will result in AS_REPs
    with PRINCIPAL UNKNOWN.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit f64ba78b8b79152cf67bc69b41d27b806675c310
Author: Douglas Bagnall <[email protected]>
Date:   Fri Dec 5 12:04:59 2025 +1300

    s4:test: fix kdc-heimdal simple tests for 'require canonicalization'
    
    The client doesn't request canonicalization here, so we always expect
    its AS_REP to be C_PRINCIPAL_UNKNOWN.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit ef4160280d22f4b994be71e4f0284832a0c5a81e
Author: Douglas Bagnall <[email protected]>
Date:   Wed Dec 17 15:19:47 2025 +1300

    pytest:krb5: notice require canonicalization option
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit e270880759781ac235466be6f7e4a6e275f1255c
Author: Douglas Bagnall <[email protected]>
Date:   Fri Dec 19 11:37:25 2025 +1300

    tests: schema_dc krb5 tests with 'require canonicalization = yes'
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit 2cfb2041deaccb38d144f59527a11673d7a0fd6d
Author: Douglas Bagnall <[email protected]>
Date:   Thu Nov 27 09:29:00 2025 +1300

    s4:kdc: honour "kdc require canonicalization = yes"
    
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit d803e2055b168b1c807325b0da54d3bbf6e5570a
Author: Douglas Bagnall <[email protected]>
Date:   Wed Nov 26 16:48:35 2025 +1300

    loadparm: add "kdc require canonicalization"
    
    Has no effect yet.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit f0666d9196448e90a928502a7535fd732bd8ac2a
Author: Douglas Bagnall <[email protected]>
Date:   Fri Dec 12 09:35:44 2025 +1300

    pytest:krb5 as_canonicalization checks no implicit $ return code
    
    We check here instead of selftest/expectedfail.d/* in part because
    on MIT some of these cases will fail to fail to ask for preauth.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit f71398c194a67f9ff92d9520a66ffe7d3c7269e3
Author: Douglas Bagnall <[email protected]>
Date:   Thu Jan 8 12:13:11 2026 +1300

    tests: run more kdc tests with no implicit $ without canonicalization
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit e904e8b229bd0fb84803adbb60b6a4b0a62addfc
Author: Douglas Bagnall <[email protected]>
Date:   Thu Nov 27 11:12:21 2025 +1300

    kdc: match implicit dollar without canon affects AS_REQ client only
    
    The smb.conf option
    
      kdc name match implicit dollar without canonicalization = no
    
    is supposed to avoid the dollar ticket attack by refusing to consider
    "foo$" as a match for "foo" unless canonicalization is requested.
    
    This was rather blunt however, as the only time we care about this is for
    the client name in an AS_REQ, and we can easily check whether that is the
    case.
    
    This makes the option less intrusive, allowing the use of "SERVER" for a
    server name rather than "SERVER$". A number of tests no longer fail.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit d979cc40a9495c62bb3a5e2c546f0ba976772806
Author: Douglas Bagnall <[email protected]>
Date:   Wed Jan 7 16:58:18 2026 +1300

    pytest:krb5:as_canonicalization debug formatting
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit a3b12b47a6ffc66fc3711afb306b9793347f5065
Author: Douglas Bagnall <[email protected]>
Date:   Fri Dec 5 14:56:02 2025 +1300

    samba-tool gpo: remove unused import
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit 12a6a3fef3d9450c7c10237e43a9ac63ffd0f083
Author: Douglas Bagnall <[email protected]>
Date:   Fri Dec 5 12:07:21 2025 +1300

    torture: do not zero members more than once
    
    three lines up is `*suite = talloc_zero(...)`.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit b57a1db749bacdc6b547af74269c080ebf38b9c0
Author: Douglas Bagnall <[email protected]>
Date:   Fri Dec 5 11:09:26 2025 +1300

    selftest: we no longer use 'testscenarios' or 'subunit.tests.testsuite'
    
    If 'python3-testscenarios' is installed, the test is bound to fail,
    like this:
    
    $ make test TESTS=subunit
    [...]
    [1(0)/2 at 0s] subunit.tests.test_suite
    subunit.tests.test_suite.unittest.loader._FailedTest.subunit(none)
    REASON: Exception: Exception: ImportError: Failed to import test module: 
subunit
    Traceback (most recent call last):
      File "/usr/lib/python3.12/unittest/loader.py", line 137, in 
loadTestsFromName
        module = __import__(module_name)
                 ^^^^^^^^^^^^^^^^^^^^^^^
             ModuleNotFoundError: No module named 'subunit'
    
    I am not certain when "subunit.tests.test_suite" would have
    successfully resolved.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit ce196e7828b7ea8539f82d91bbcb294b1c815d29
Author: Jennifer Sutton <[email protected]>
Date:   Wed Jan 7 15:26:53 2026 +1300

    selftest: Disable ‘krb5 acceptor report canonical client name’ for 
fl2008r2dc environment
    
    So that we test with and without the option enabled.
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit cfbe8815b04fd6edf66990778b6e6613331410c0
Author: Jennifer Sutton <[email protected]>
Date:   Thu Dec 4 12:06:47 2025 +1300

    s4:auth: Implement ‘krb5 acceptor report canonical client name’ option for 
Heimdal
    
    Adjust tests to match the new behaviour.
    
    The implementation is simply to set a flag that is already present
    in upstream Heimdal.
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit f43d957ea081a7adc51911ee5d66e979656cbbb7
Author: Jennifer Sutton <[email protected]>
Date:   Wed Jan 7 14:40:09 2026 +1300

    s4:torture:auth: Do not break client principal
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 3e6985f2745e9b0d67155d6d57e4c1f4f7782bd3
Author: Jennifer Sutton <[email protected]>
Date:   Wed Jan 7 14:56:33 2026 +1300

    auth:kerberos: Do not fail if PAC account name doesn’t match ticket 
principal name
    
    Andrew Bartlett says:
    
    “These days, we can trust that the PAC has been validated by the library, 
and I
    think also that nobody could have put in a false PAC anyway (the KDC should 
stop
    clients setting pre-auth data of that type), so the validation step that 
fails
    isn't doing as much as it did 20 years ago. So I think we could simply patch
    [this] check to accept the canonical name and know that we just are working 
with
    that option [‘krb5 acceptor report canonical client name’] having been set.”
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit b9692a8bf0d036ab8bb7e5b1a8660d16980fc147
Author: Jennifer Sutton <[email protected]>
Date:   Wed Jan 7 10:21:17 2026 +1300

    loadparm: Add ‘krb5 acceptor report canonical client name’ option
    
    It is enabled by default, and does nothing as of yet.
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 9f1beaf7e19ddb054f108687eedd5125a9b24297
Author: Jennifer Sutton <[email protected]>
Date:   Tue Jan 6 09:47:36 2026 +1300

    s4:selftest: Remove ‘extra_options’
    
    These should always be an empty list.
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit e744fa11b1a396f87f82ab8a946391064b2342d8
Author: Jennifer Sutton <[email protected]>
Date:   Wed Dec 10 10:27:15 2025 +1300

    s4:torture: Fix code spelling
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit e8edf61a27c4fe456edd7166c8b9ab61e1154a61
Author: Jennifer Sutton <[email protected]>
Date:   Wed Dec 3 15:36:52 2025 +1300

    s4:torture: Simplify booleans
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 5bd1ddb9064217f238c582086fd66f9bf1f4507e
Author: Jennifer Sutton <[email protected]>
Date:   Tue Jan 6 11:44:13 2026 +1300

    s4:torture:auth: Fix PAC checksum test
    
    This test was supposed to corrupt the KDC signature and ensure that PAC
    verification failed, but it corrupted a harmless padding byte instead. 
However,
    PAC verification still failed as expected because the principal remained
    corrupted from the previous test.
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit a5eddef8ec4d52ea59631a17a05d4db0815f0134
Author: Douglas Bagnall <[email protected]>
Date:   Thu Dec 11 14:47:26 2025 +1300

    WHATSNEW: update for policy hints
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit 04039fdd835690f636906fb58743ff6f91451de8
Author: Douglas Bagnall <[email protected]>
Date:   Sun Jan 11 23:19:35 2026 +1300

    dsdb:password_hash: fix policy_hint controlled reset return codes
    
    Resets are unwilling, not constrained.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12020
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit e1188962aa9cec9ab6cf2f4ddaaf19dce858d2dd
Author: Douglas Bagnall <[email protected]>
Date:   Sun Jan 11 23:17:50 2026 +1300

    dsdb:password_hash: policy_hints control makes resets check history
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12020
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit cdf2defdc573a01b8308dd1710a73bb2a4e088bb
Author: Douglas Bagnall <[email protected]>
Date:   Sun Jan 11 23:15:53 2026 +1300

    dsdb:password_hash: "policy hints" resets honour minPwdAge
    
    As always, a reset returns UNWILLING_TO_PERFORM even though it is
    pretending to be a change due to the control.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12020
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit 0da540f4d8323fb78ba25bedec9fbef5dddd43bf
Author: Douglas Bagnall <[email protected]>
Date:   Thu Oct 9 16:46:09 2025 +1300

    pytest:dsdb:password: test policy_hints oid
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12020
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit d588c7969ee7586d2f76cb1a66b542c63fe7d154
Author: Douglas Bagnall <[email protected]>
Date:   Thu Dec 11 11:07:33 2025 +1300

    pytest:dsdb:passwords: guess ldaps and ldap hosts from each other
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12020
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit aff40feb3d749f019b1c96ba90342a10ae721a7f
Author: Douglas Bagnall <[email protected]>
Date:   Sun Jan 11 23:12:11 2026 +1300

    dsdb:password_hash: notice "policy hints" control
    
    This still doesn't do anything, but it does mean we can set the control
    in tests without hitting unhandled critical control errors.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12020
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit b003beb85a648eae5bfe7e38362abd8d798e8f86
Author: Douglas Bagnall <[email protected]>
Date:   Thu Sep 25 11:45:30 2025 +1200

    ldb: add "policy hints" controls to be used by password_hash module
    
    These won't have any effect yet, but soon they will allow a privileged
    account to perform a password reset that respects constraints on
    password history, age, and length, as if the reset was an ordinary
    password change (that is, where the user provides the old password).
    
    A normal user can't reset their own password using this, if the
    organisation is using a remote service (e.g. Entra ID or Keycloak) to
    manage passwords, that service can use a policy hints control to
    ensure it follows AD password policy.
    
    Entra ID Self Service Password Reset (SSPR) uses the deprecated OID.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12020
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit 49001e81589e8b5e4437b45f25622b07eecc95a5
Author: Douglas Bagnall <[email protected]>
Date:   Sun Jan 11 22:31:04 2026 +1300

    dsdb:password_hash: reject password reset with UNWILLING_TO_PERFORM
    
    This is what Windows does: where a password change would cause
    CONSTRAINT_VIOLATION, a reset causes UNWILLING_TO_PERFORM.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12020
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit d90ac9b93ad90d4e44dffd1f5de623b5c9a23f8c
Author: Douglas Bagnall <[email protected]>
Date:   Sun Jan 11 22:27:58 2026 +1300

    dsdb:password_hash: fix a typo
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit 55c229966497425497ec3d621a37873370ea81f9
Author: Douglas Bagnall <[email protected]>
Date:   Thu Jan 8 15:52:22 2026 +1300

    python subunit: add dummy addDuration methods
    
    preventing this message:
    
    /usr/lib/python3.12/unittest/case.py:580: RuntimeWarning: TestResult has no 
addDuration method
      warnings.warn("TestResult has no addDuration method",
    
    as far as I can tell we have no real use for addDuration, since we
    already measure time in other ways.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit ecb7131c66b9c3fe2b55c946064b1bb4c633524d
Author: Douglas Bagnall <[email protected]>
Date:   Thu Oct 9 09:44:48 2025 +1300

    s3:vfs_ceph_new: use #ifdef, not #if HAVE_CEPH_ASYNCIO
    
    This is one of our half-bit flags; there is no way it can be defined
    to zero. '#if' works because unknown identifiers are considered to be
    zero, but it isn't how we do things.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit fdb840b3662ce1e82b8fd6e690e23a2d37cc8f41
Author: Douglas Bagnall <[email protected]>
Date:   Fri Jan 9 15:53:16 2026 +1300

    manpages:smb.conf:nt hash store: remove a stray word
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

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

Summary of changes:
 WHATSNEW.txt                                       | 163 +++++++++++
 auth/kerberos/kerberos_pac.c                       |   3 -
 .../security/kdcrequirecanonicalization.xml        |  36 +++
 .../krb5acceptorreportcanonicalclientname.xml      |  21 ++
 docs-xml/smbdotconf/security/nt_hash_store.xml     |   2 +-
 lib/ldb/common/ldb_controls.c                      |  46 +++
 lib/ldb/include/ldb.h                              |  30 ++
 lib/param/loadparm.c                               |   2 +
 lib/torture/torture.c                              |   2 -
 python/samba/subunit/run.py                        |   6 +
 python/samba/tests/krb5/alias_tests.py             |   9 +-
 .../samba/tests/krb5/as_canonicalization_tests.py  |  24 +-
 python/samba/tests/krb5/as_req_tests.py            |  72 ++++-
 .../krb5/ms_kile_client_principal_lookup_tests.py  |  66 +++++
 python/samba/tests/krb5/raw_testcase.py            |   3 +
 python/samba/tests/samba_tool/gpo.py               |   1 -
 python/samba/tests/samba_tool/user.py              |   2 +-
 script/autobuild.py                                |   5 +-
 selftest/expectedfail.d/krb5-no-dollar             |  14 -
 selftest/knownfail.d/nt-hash-support-gone          |   4 +
 .../knownfail.d/password-policy-hints              |   0
 .../ms-kile-client-principal-lookup                |  12 +-
 selftest/knownfail_mit_kdc.d/as-canonicalization   |  48 ++--
 selftest/knownfail_mit_kdc.d/krb5-no-dollar        |  19 ++
 .../ms-kile-client-principal-lookup                |   6 +-
 .../no-implicit-dollar-canonicalization            |  10 +
 .../knownfail_mit_kdc.d/require-canonicalization   | 262 +++++++++++++++++
 selftest/subunithelper.py                          |   6 +
 selftest/target/Samba4.pm                          |   4 +-
 selftest/tests.py                                  |   6 -
 source3/modules/vfs_ceph_new.c                     |  18 +-
 source3/param/loadparm.c                           |   2 +
 source4/auth/kerberos/krb5_init_context.c          |   4 +
 source4/dsdb/samdb/ldb_modules/password_hash.c     | 126 +++++++-
 source4/dsdb/tests/python/password_settings.py     |   6 +-
 source4/dsdb/tests/python/passwords.py             | 316 +++++++++++++++++++++
 source4/kdc/db-glue.c                              |  27 +-
 source4/libcli/ldap/ldap_controls.c                |  72 +++++
 source4/selftest/tests.py                          |  38 ++-
 source4/torture/auth/pac.c                         |  46 +--
 source4/torture/krb5/kdc-canon-heimdal.c           |  83 +++++-
 source4/torture/krb5/kdc-heimdal.c                 |  31 +-
 source4/torture/krb5/kdc-mit.c                     |   4 +-
 43 files changed, 1500 insertions(+), 157 deletions(-)
 create mode 100644 docs-xml/smbdotconf/security/kdcrequirecanonicalization.xml
 create mode 100644 
docs-xml/smbdotconf/security/krb5acceptorreportcanonicalclientname.xml
 delete mode 100644 selftest/expectedfail.d/krb5-no-dollar
 copy buildtools/wafsamba/__init__.py => 
selftest/knownfail.d/password-policy-hints (100%)
 create mode 100644 selftest/knownfail_mit_kdc.d/krb5-no-dollar
 create mode 100644 
selftest/knownfail_mit_kdc.d/no-implicit-dollar-canonicalization
 create mode 100644 selftest/knownfail_mit_kdc.d/require-canonicalization


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 66be80f64f2..ef009a63870 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -50,6 +50,163 @@ to a higher value than 1 will allow Samba to shard the 
stream to more
 than one xattr. It has an artificial limit of 16 for a maximum stream
 length of 1MB.
 
+
+Support for remote password management (Entra ID SSPR, Keycloak)
+----------------------------------------------------------------
+
+When a system such as Entra ID or Keycloak wants to change a user's
+password in its own database as well as in AD, it will use a password
+reset, meaning it does not transmit the old password to the domain
+controller. Normally a password reset avoids password history and age
+checks, which would allow a cloud password change to bypass
+on-premises password policies. To address this, a password reset using
+the "policy hints" control should respect password policies, as if it
+were an ordinary password change. Both Entra ID and Keycloak use this,
+but until now Samba did not understand this control, and would reject
+these reset requests.
+
+Now Samba AD will recognise the policy hints control and enforce local
+policy. This allows Microsoft Entra self-service password reset (SSPR)
+to work, and for Keycloak to work with the "password policy hints
+enabled" option.
+
+
+Kerberos PKINIT KeyTrust logon support
+--------------------------------------
+
+Samba servers configured with the embedded heimdal KDC and running as an ADDC,
+now support "Windows Hello for Business Key-Trust logons". This allows the
+PKINIT authentication mechanism to be used with self-signed keys.
+
+The samba-tool computer and user commands have a new "keytrust"
+sub-command which allows for the setting and viewing of the public key
+details for computer and user accounts. This stores the public key
+details in msDS-KeyCredentialLink attribute of the account.
+
+
+msDS-KeyCredentialLink validation
+---------------------------------
+
+Updates to the msDS-KeyCredentialLink attribute are validated against the
+rules specified by MS-ADTS 3.1.1.5.3.1.1.6.
+
+Kerberos PKINIT strong/flexible key mappings
+--------------------------------------------
+
+Samba servers configured with the embedded heimdal KDC and running as an ADDC
+now support "Windows Strong and Flexible key mappings" as outlined in
+Microsoft KB5014754: Certificate-based authentication changes on Windows domain
+controllers.
+
+The default enforcement mode ("full") allows only strong certificate
+mappings. The smb.conf option
+
+  strong certificate binding enforcement = compatibility
+
+will allow weak mappings where the certificate is newer than the user
+account. The option "none" will allow any mappings.
+
+The mappings for an account should be placed in the altSecurityIdentities
+attribute and follow the syntax documented in KB5014754.
+
+
+Kerberos PKINIT SID extension
+-----------------------------
+
+PKINIT authentication now supports certificates containing an Object SID
+extension (extension 1.3.6.1.4.1.311.25.2), this is considered to be a STRONG
+mapping for KB5014754.
+
+The computer and user samba-tool commands have a new sub-command
+"generate-csr" to generate certificate signing requests.
+
+
+KDC includes PAC by default
+---------------------------
+
+Samba will ignore the value provided by the client in "PA-PAC-REQUEST"
+and always include a PAC in responses, unless "kdc always generate
+pac" is set to "no".
+
+
+KDC can insist clients request canonicalization
+-----------------------------------------------
+
+Canonicalization of principal client names is not mandatory in
+Kerberos (per RFC4120), but must be requested by the client. In some
+circumstances allows a client to deceive Active Directory member
+servers (known as the "dollar ticket" attack).
+
+The new configuration option "kdc require canonicalization" can be
+used to require that clients request canonicalization; if they do not,
+their AS_REQ requests will be rejected as if the account was unknown.
+
+The default value is "no", for backward compatibility. Windows clients
+will ask for canonicalization by default, so in Windows-heavy
+environments it is safe and recommended to set this to "yes".
+
+KDC can avoid potentially confusing canonicalization
+----------------------------------------------------
+
+Currently when the client does not request canonicalization, when the
+KDC looks up a name and there is no match it will append a "$" to the
+name and try again. An attacker who can create arbitrary machine
+accounts can sometimes get tickets for Unix users by mimicking their
+names (the "dollar ticket" attack).
+
+The configuration option
+
+  kdc name match implicit dollar without canonicalization = no
+
+can be used to disable this behaviour for clients that do not request
+canonicalization. Probably this only affects traditional Unix clients,
+as Windows clients use canonicalization. If affected clients want a
+ticket for a machine account, they will have to use the full name
+including the dollar (e.g. "server$", not "server").
+
+If the "kdc require canonicalization" option cannot be set to "yes"
+(because some clients do not request canonicalization) setting this
+option to "no" is a good alternative.
+
+
+KDC provides Kerberos acceptors with canonical client names
+-----------------------------------------------------------
+
+By default the KDC will now send Kerberos services the canonicalized
+name (the sAMAccountName from the PAC) rather than trusting the cname.
+
+To return to the old behaviour, use
+
+  krb5 acceptor report canonical client name = no
+
+in the smb.conf.
+
+This currently affects Heimdal KDC only, not MIT.
+
+
+KDC recommended configuration:
+-----------------------------
+strong certificate binding enforcement                            full
+kdc always include pac                                            yes
+kdc require canonicalization                                      yes
+
+If unable to use "kdc require canonicalization" = "yes", then
+"kdc name match implicit dollar without implicit canonicalization" should be
+set to "no" if possible.
+
+samba tool
+----------
+
+Two new sub-commands have been added to the user and computer commands:
+
+user|computer generate-csr
+    Generate a Certificate signing request for an account containing the
+    Object SID extension  (extension 1.3.6.1.4.1.311.25.2)
+
+user|computer keytrust
+   Add the public key details of a self signed certificate to an account.
+   The command supports PEM and DER encoded public keys.
+
 REMOVED FEATURES
 ================
 
@@ -59,6 +216,12 @@ smb.conf changes
 
   Parameter Name                          Description     Default
   --------------                          -----------     -------
+  strong certificate binding enforcement  New             full
+  certificate backdating compensation     New             0
+  kdc always include pac                  New             yes
+  kdc require canonicalization            New             no
+  kdc name match implicit dollar without canonicalization
+                                          New             yes
 
 KNOWN ISSUES
 ============
diff --git a/auth/kerberos/kerberos_pac.c b/auth/kerberos/kerberos_pac.c
index 4c61cfe838f..321c6cafb37 100644
--- a/auth/kerberos/kerberos_pac.c
+++ b/auth/kerberos/kerberos_pac.c
@@ -405,9 +405,6 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
                                  "in ticket [%s]\n",
                                  logon_name->account_name,
                                  client_principal_string));
-                       SAFE_FREE(client_principal_string);
-                       status = NT_STATUS_ACCESS_DENIED;
-                       goto out;
                }
                SAFE_FREE(client_principal_string);
 
diff --git a/docs-xml/smbdotconf/security/kdcrequirecanonicalization.xml 
b/docs-xml/smbdotconf/security/kdcrequirecanonicalization.xml
new file mode 100644
index 00000000000..e960b613e71
--- /dev/null
+++ b/docs-xml/smbdotconf/security/kdcrequirecanonicalization.xml
@@ -0,0 +1,36 @@
+<samba:parameter name="kdc require canonicalization"
+                 context="G"
+                 type="boolean"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc";>
+  <description>
+    <para>
+      Require that Kerberos clients use the canonicalization flag.
+    </para>
+
+    <para>
+      Clients that do not use the Kerberos canonicalization flag (see
+      RFC 6806) will get a TGT for the name they requested, which may
+      not exactly match the name in the Samba database. For example, a
+      client may request a ticket for 'root', and if there is a
+      computer called 'ROOT$' in the database, the KDC will issue a
+      ticket for 'root', using the standard matching rules for AD
+      Kerberos. A member server that is Kerberos-aware but not
+      AD-aware might accept this ticket as valid for the local root
+      user. This option avoids the problem by refusing to honour
+      requests without the canonicalization flag.
+    </para>
+    <para>
+      This is a reasonable option if all expected clients request
+      canonicalization (as Windows clients do), and there are member
+      servers that might be confused by this issue. Typically that
+      means unix servers expecting to be in an MIT Kerberos domain.
+    </para>
+    <para>
+      See also the "kdc name match implicit dollar without
+      canonicalization" option, which is more useful if you expect
+      Kerberos clients that will not use the canonicalize flag.
+    </para>
+</description>
+
+<value type="default">no</value>
+</samba:parameter>
diff --git 
a/docs-xml/smbdotconf/security/krb5acceptorreportcanonicalclientname.xml 
b/docs-xml/smbdotconf/security/krb5acceptorreportcanonicalclientname.xml
new file mode 100644
index 00000000000..d36afaaeb0b
--- /dev/null
+++ b/docs-xml/smbdotconf/security/krb5acceptorreportcanonicalclientname.xml
@@ -0,0 +1,21 @@
+<samba:parameter name="krb5 acceptor report canonical client name"
+                 type="boolean"
+                 context="G"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc";>
+<description>
+    <para>
+        This option affects the client name provided to Kerberos acceptors for
+        incoming Kerberos tickets. If set to ‘yes’, the client name in the
+        ticket will be replaced with the canonical client name (the
+        sAMAccountName). Otherwise, it will be left unchanged.
+       </para>
+
+    <para>
+        This option currently only applies if the embedded Heimdal
+        KDC is used.
+    </para>
+
+</description>
+
+<value type="default">yes</value>
+</samba:parameter>
diff --git a/docs-xml/smbdotconf/security/nt_hash_store.xml 
b/docs-xml/smbdotconf/security/nt_hash_store.xml
index d7ed705de58..5fd9c5c7eb9 100644
--- a/docs-xml/smbdotconf/security/nt_hash_store.xml
+++ b/docs-xml/smbdotconf/security/nt_hash_store.xml
@@ -11,7 +11,7 @@
 
     <para>If so configured, the Samba Active Directory Domain Controller,
     will, except for trust accounts (computers, domain
-    controllers and inter-domain trusts) the
+    controllers and inter-domain trusts),
     <emphasis>NOT store the NT hash</emphasis>
     for new and changed accounts in the sam.ldb database.</para>
 
diff --git a/lib/ldb/common/ldb_controls.c b/lib/ldb/common/ldb_controls.c
index 3bf89d844f9..a80c89964c3 100644
--- a/lib/ldb/common/ldb_controls.c
+++ b/lib/ldb/common/ldb_controls.c
@@ -1296,6 +1296,52 @@ struct ldb_control *ldb_parse_control_from_string(struct 
ldb_context *ldb, TALLO
                ctrl->data = control;
                return ctrl;
        }
+
+       if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_POLICY_HINTS_NAME) == 
0) {
+               const char *p = NULL;
+               int crit, val, ret;
+
+               p = &(control_strings[sizeof(LDB_CONTROL_POLICY_HINTS_NAME)]);
+               ret = sscanf(p, "%d:%d", &crit, &val);
+               if ((ret != 2) || (crit < 0) || (crit > 1)) {
+                       ldb_set_errstring(ldb,
+                                         "invalid pwd_policy_hints control 
syntax\n"
+                                         " syntax: crit(b):flags(n)\n"
+                                         "   note: b = boolean, n = number");
+                       talloc_free(ctrl);
+                       return NULL;
+               }
+
+               ctrl->oid = LDB_CONTROL_POLICY_HINTS_OID;
+               ctrl->critical = crit;
+               ctrl->data = talloc(ctrl, int);
+               *((int*)ctrl->data) = val;
+               return ctrl;
+       }
+
+       if (LDB_CONTROL_CMP(control_strings, 
LDB_CONTROL_POLICY_HINTS_DEPRECATED_NAME) == 0) {
+               const char *p = NULL;
+               int crit, val, ret;
+
+               p = 
&(control_strings[sizeof(LDB_CONTROL_POLICY_HINTS_DEPRECATED_NAME)]);
+               ret = sscanf(p, "%d:%d", &crit, &val);
+               if ((ret != 2) || (crit < 0) || (crit > 1)) {
+                       ldb_set_errstring(ldb,
+                                         "invalid pwd_policy_hints control 
syntax\n"
+                                         " syntax: crit(b):flags(n)\n"
+                                         "   note: b = boolean, n = number");
+                       talloc_free(ctrl);
+                       return NULL;
+               }
+
+               ctrl->oid = LDB_CONTROL_POLICY_HINTS_DEPRECATED_OID;
+               ctrl->critical = crit;
+               ctrl->data = talloc(ctrl, int);
+               *((int*)ctrl->data) = val;
+               return ctrl;
+       }
+
+
        /*
         * When no matching control has been found.
         */
diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h
index 0d1d455d0cf..4cd6ada194e 100644
--- a/lib/ldb/include/ldb.h
+++ b/lib/ldb/include/ldb.h
@@ -808,6 +808,36 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, 
void *opaque);
 */
 #define LDB_EXTENDED_WHOAMI_OID                "1.3.6.1.4.1.4203.1.11.3"
 
+/**
+   OID used to enforce password history length constraints in password reset
+
+   If this is control as the value 0x1 on a password set operation,
+   the password history constraints in MS-SAMR 3.1.1.7.1 "General
+   Password Policy" apply as if this was a password change. This may
+   be used by Entra ID or Keycloak.
+
+   LDB_CONTROL_POLICY_HINTS_DEPRECATED_OID (below) does exactly the
+   same thing and seems to be more widely used in practice.
+*/
+#define LDB_CONTROL_POLICY_HINTS_OID           "1.2.840.113556.1.4.2239"
+#define LDB_CONTROL_POLICY_HINTS_NAME           "policy_hints"
+
+/**
+   Another OID used to enforce password history length constraints in password 
reset
+
+   This works just like LDB_CONTROL_POLICY_HINTS_OID (above): if the
+   control value is 0x1 on a password set operation, the password
+   history constraints in MS-SAMR 3.1.1.7.1 "General Password Policy"
+   apply as if this was a password change.
+
+   This is used by Entra ID in a password change.
+
+   It is also the OID for the ms-DS-Required-Domain-Behavior-Version
+   attribute), which is unlikely to cause confusion given the contexts.
+*/
+#define LDB_CONTROL_POLICY_HINTS_DEPRECATED_OID      "1.2.840.113556.1.4.2066"
+#define LDB_CONTROL_POLICY_HINTS_DEPRECATED_NAME     "policy_hints_deprecated"
+
 struct ldb_sd_flags_control {
        /*
         * request the owner    0x00000001
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index dc4f6829208..e3d9a0a0e5a 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2962,6 +2962,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX 
*mem_ctx)
        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, "kdc require canonicalization", "no");
+       lpcfg_do_global_parameter(lp_ctx, "krb5 acceptor report canonical 
client name", "yes");
 
        lpcfg_do_global_parameter(lp_ctx, "nt status support", "True");
 
diff --git a/lib/torture/torture.c b/lib/torture/torture.c
index 930b6036325..2125de47f3d 100644
--- a/lib/torture/torture.c
+++ b/lib/torture/torture.c
@@ -272,8 +272,6 @@ struct torture_suite *torture_suite_create(TALLOC_CTX *ctx, 
const char *name)
        struct torture_suite *suite = talloc_zero(ctx, struct torture_suite);
 
        suite->name = talloc_strdup(suite, name);
-       suite->testcases = NULL;
-       suite->children = NULL;
 
        return suite;
 }
diff --git a/python/samba/subunit/run.py b/python/samba/subunit/run.py
index dc3f9316fcb..39fbfdb09fc 100755
--- a/python/samba/subunit/run.py
+++ b/python/samba/subunit/run.py
@@ -81,6 +81,9 @@ class TestProtocolClient(unittest.TestResult):
         self._stream.write("test: " + test.id() + "\n")
         self._stream.flush()
 
+    def addDuration(self, *args):
+        pass
+
     def stopTest(self, test):
         """Mark a test as having finished its test run."""
         super().stopTest(test)
@@ -454,6 +457,9 @@ class 
AutoTimingTestResultDecorator(HookedTestResultDecorator):
         self._time = a_datetime
         return self.decorated.time(a_datetime)
 
+    def addDuration(self, *args):
+        pass
+
 
 class SubunitTestRunner(object):
 
diff --git a/python/samba/tests/krb5/alias_tests.py 
b/python/samba/tests/krb5/alias_tests.py
index 6a517c596e4..84612eb9e23 100755
--- a/python/samba/tests/krb5/alias_tests.py
+++ b/python/samba/tests/krb5/alias_tests.py
@@ -169,14 +169,7 @@ class AliasTests(KDCBaseTest):
                                              ctype=None)
             return [padata], req_body
 
-        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
-
+        expected_error_mode = KDC_ERR_TGT_REVOKED
 
         # Make a request using S4U2Self. The request should fail.
         kdc_exchange_dict = self.tgs_exchange_dict(
diff --git a/python/samba/tests/krb5/as_canonicalization_tests.py 
b/python/samba/tests/krb5/as_canonicalization_tests.py
index dd94cb632da..3b25bc7f5cb 100755
--- a/python/samba/tests/krb5/as_canonicalization_tests.py
+++ b/python/samba/tests/krb5/as_canonicalization_tests.py
@@ -47,6 +47,7 @@ from samba.tests.krb5.rfc4120_constants import (
     NT_ENTERPRISE_PRINCIPAL,
     NT_PRINCIPAL,
     NT_SRV_INST,
+    KDC_ERR_C_PRINCIPAL_UNKNOWN,
 )
 
 global_asn1_print = False
@@ -124,7 +125,7 @@ class TestData:
     def __repr__(self):
         rep = "Test Data: "
         rep += "options = '" + "{:08b}".format(self.options) + "'"
-        rep += "user name = '" + self.user_name + "'"
+        rep += ", user name = '" + self.user_name + "'"
         rep += ", realm = '" + self.realm + "'"
         rep += ", cname = '" + str(self.cname) + "'"
         rep += ", sname = '" + str(self.sname) + "'"
@@ -309,6 +310,27 @@ class KerberosASCanonicalizationTests(KDCBaseTest):
         self.assertEqual(
             rep['msg-type'], KRB_ERROR, "Data {0}".format(str(data)))
 
+        if (not self.uncanonicalized_implicit_dollar and
+            not data.canonicalize and
+            TestOptions.RemoveDollar.is_set(data.options) and
+            user_creds.get_username().endswith('$')):
+            # We expect the principal not to be found because
+            # a) smb.conf asked for foo -> foo$ to only match with 
canonicalization
+            # b) we as client are not requesting canonicalization
+            # c) we have removed a '$' from the true name
+            #
+            # These are the tests that combine "MachineCredentials"
+            # with "RemoveDollar" but not "Canonicalize".
+            self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN)
+            return (None, None)
+
+        if self.require_canonicalization and not data.canonicalize:
+            self.check_error_rep(rep, KDC_ERR_C_PRINCIPAL_UNKNOWN)
+            # by returning None for the preauth rep, we avoid further
+            # checks of the as_rep (second argument), which we don't
+            # have.
+            return (None, None)
+
         self.assertEqual(
             rep['error-code'],
             KDC_ERR_PREAUTH_REQUIRED,
diff --git a/python/samba/tests/krb5/as_req_tests.py 
b/python/samba/tests/krb5/as_req_tests.py
index 55c27a2bed3..e4e677223d5 100755
--- a/python/samba/tests/krb5/as_req_tests.py
+++ b/python/samba/tests/krb5/as_req_tests.py
@@ -50,6 +50,19 @@ global_asn1_print = False
 global_hexdump = False


-- 
Samba Shared Repository


Reply via email to