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