[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Mon Jun 10 05:33:01 UTC 2024
The branch, master has been updated
via 469b22b849a python/samba/tests/krb5: Allow PkInitTests.test_pkinit_ntlm_from_pac_must_change_now to pass on Samba/Heimdal
via 15686fec981 python/samba/tests/krb5: Expand test without UF_SMARTCARD_REQUIRED to show rotation is not done
via f3528808aba WHATSNEW: Mention msDS-ExpirePasswordsOnSmartCardOnlyAccounts behaviour
via 2854ef29b82 provision: Match Windows 2022 and set msDS-ExpirePasswordsOnSmartCardOnlyAccounts by default
via dee3c7be584 selftest: Add test that msDS-ExpirePasswordsOnSmartCardOnlyAccounts=TRUE is set
via 491b79d445d kdc: Rotate smart-card only underlying password in 2nd half of lifetime
via 8afe27058b0 kdc: Track the pwdLastSet of expired UF_SMARTCARD_REQUIRED accounts
via 1e1c80656f7 kdc: Detect (about to) expire UF_SMARTCARD_REQUIRED accounts and rotate passwords
via d03b3faeb8e s4-auth: Use consistant externally-supplied time in auth stack
via 1dcd8be8f06 kdc: Use a consistent, stable time throughout the Heimdal KDC
via fe61009002d kdc: Mark KDC sam.ldb as not to use ldb_wrap cache
via e178f6b0e96 ldb_wrap: Provide a way to avoid Samba using ldb_wrap()
via 9ba5ebf4af7 kdc: Remove confusing duplicate open of sam.ldb to find RODC status
via 09ae48b415b dsdb: Prepare to handle smartcard password rollover
via 1bcc9f00157 dsdb: Use dsdb_gmsa_current_time() in construct_msds_user_account_control_computed
via cc3ea4ed571 dsdb: UF_SMARTCARD_REQUIRED can have a password expiry, if configured!
via 3669479f22f dsdb: Reduce minimum maxPwdAge from 1 day to nil
via 302619f66f9 dsdb: Change the magic smartcard_reset to set AES keys like the krbtgt mode
via 7c79abbab46 python/samba/tests/krb5: PKINIT tests of passwords that are naturally expired
via 044cc538605 python/test/krb5: Use assertAlmostEqual in check_ticket_times()
via 68fa90754fd python/tests/krb5: Move check_ticket_times() to kdc_base_test.py
via 48bff4b95f8 python/samba/krb5: Add test for password rotation on UF_SMARCARD_REQUIRED accounts
via a85f4c661b1 python/tests/krb5: Remove unused utf16pw variable
via 504a47ecfd6 python/tests/krb5: Expect AES keys for UF_SMARTCARD_REQUIRED
via dc6c4b215e2 python/samba/tests/krb5: Extend PKINIT tests to show kpasswd still works
via 4ec24a20764 python/samba/tests/krb5: Move get_kpasswd_sname() into raw_testcase() to allow broader use
via b664392208c s4-auth: Use msDS-User-Account-Control-Computed for PW expiry check
via 737f2414062 s4-auth: Update comment to mention 60mins in the NTLM grace period
via e04eb9bb170 dsdb: Make argument order of dsdb_update_gmsa_{entry_,}keys() consistant with other uses
from a9b3522f53a smbd: Ensure we grant owner sid in check_parent_access_fsp()
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 469b22b849aa6a76739dc21d8a2d80907cdf8d73
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue Jun 4 13:26:18 2024 +1200
python/samba/tests/krb5: Allow PkInitTests.test_pkinit_ntlm_from_pac_must_change_now to pass on Samba/Heimdal
This flexiblity in the tests avoids requiring Samba/Heimdal to omit an NTSTATUS error
return and just be consistent between the different authentication paths.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Mon Jun 10 05:32:54 UTC 2024 on atb-devel-224
commit 15686fec9819267f69a600cff859e52f77a64cef
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue Jun 4 11:36:53 2024 +1200
python/samba/tests/krb5: Expand test without UF_SMARTCARD_REQUIRED to show rotation is not done
This makes sense as otherwise the user would suddenly not know their password
for use when they do not use their smartcard.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit f3528808aba9419c0895bdb709e1b0dc0bdced1e
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon May 27 11:51:59 2024 +1200
WHATSNEW: Mention msDS-ExpirePasswordsOnSmartCardOnlyAccounts behaviour
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 2854ef29b82d89fb5b5c9d8414227988783120b9
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon May 27 11:30:29 2024 +1200
provision: Match Windows 2022 and set msDS-ExpirePasswordsOnSmartCardOnlyAccounts by default
We do this by telling the Domain Functional Level upgrade code that
this is a new install.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit dee3c7be5846ae7c0952b1ace94dee23241dc794
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon May 27 11:53:15 2024 +1200
selftest: Add test that msDS-ExpirePasswordsOnSmartCardOnlyAccounts=TRUE is set
This assures us that the new provision sets the value by default.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 491b79d445d54f56ba8dfea978da322e1fc16c44
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri May 17 17:34:36 2024 +1200
kdc: Rotate smart-card only underlying password in 2nd half of lifetime
This is a measure to avoid multiple servers rotating the password
but means that the maximum password age really must be set to
twice the TGT lifetime, eg a default of 20 hours. The internet
suggestions of 1 day for this feature should work fine.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 8afe27058b08ff30d2650bb4fec92f56fa418e6a
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu May 9 16:24:31 2024 +1200
kdc: Track the pwdLastSet of expired UF_SMARTCARD_REQUIRED accounts
This is to gracefully deal with races and to avoid additional password
rollover in situations where the TGT lifetime is longer than the
maximum password lifetime. This is not a sensible combination, so
we just avoid the extra DB write, and update it only once per AS-REQ
in this case.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 1e1c80656f7d19d1cfde118bdba75a576da978f7
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue May 21 11:14:50 2024 +1200
kdc: Detect (about to) expire UF_SMARTCARD_REQUIRED accounts and rotate passwords
This ensures that before the KDC starts to process the entry
we check if it is expired and rotate it. As an account with
UF_SMARTCARD_REQUIRED simply can not expire unless
msDS-ExpirePasswordsOnSmartCardOnlyAccounts is set and
the Domain Functional Level is >= 2016 we do not need
to do configuration checks here.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Signed-off-by: Jo Sutton <josutton at catalyst.net.nz>
Pair-programmed-by: Jo Sutton <josutton at catalyst.net.nz>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit d03b3faeb8e6e3446c606b3f167d2e9917514fda
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed May 29 14:51:01 2024 +1200
s4-auth: Use consistant externally-supplied time in auth stack
This makes the time during authentication stay consistent in the KDC
and follows the fake time when we are testing gMSA accounts. By having
the account expiry follow exactly the same clock as the password expiry
we can hope for less supprises.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 1dcd8be8f06066f8aed7765c4e92259ce1371991
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue May 28 12:53:19 2024 +1200
kdc: Use a consistent, stable time throughout the Heimdal KDC
The MIT KDC has a fallback to a consistent time per fetch call, and
both implementations then follow the time in each 'struct
samba_kdc_entry'.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit fe61009002db897fb8632954af8203de28c24d7d
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu May 30 11:43:04 2024 +1200
kdc: Mark KDC sam.ldb as not to use ldb_wrap cache
This will ensure that the time which will be is passed in an opaque is
not used by other parts of Samba
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit e178f6b0e962b0ac96d447196765c21c770ede63
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu May 30 11:23:01 2024 +1200
ldb_wrap: Provide a way to avoid Samba using ldb_wrap()
ldb_wrap is a caching mechansim, and it should probably be removed
but for now provide a way to avoid it in specific cases where we
know it is harmful.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 9ba5ebf4af7c5170dc2abf2307e3c47d7d250f5f
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu May 30 11:40:16 2024 +1200
kdc: Remove confusing duplicate open of sam.ldb to find RODC status
Instead, make this query after we open the DB in common with the MIT code.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 09ae48b415b2b50dbf4600e9c7f9cb4ec65a6263
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon May 20 13:51:23 2024 +1200
dsdb: Prepare to handle smartcard password rollover
We do this by allowing the password change control to indicate
that the password is to be randomised, bypassing the quality
checks (as true random passwords often fail these) and
re-randomising with the same code as is used for the KDC.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 1bcc9f00157884a8870e32dda258640c2c3a0c79
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri May 17 15:10:18 2024 +1200
dsdb: Use dsdb_gmsa_current_time() in construct_msds_user_account_control_computed
This both allows the time to be overriden in some future unit tests
(which is incredibly helpful in testing) and gets a full NTTIME
rather than just a time_t based time, so we do not need to wait
an extra second for the NTTIME to change.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit cc3ea4ed571ca033c357cebeea4511ba6dd9fa81
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed Apr 3 11:54:00 2024 +1300
dsdb: UF_SMARTCARD_REQUIRED can have a password expiry, if configured!
While the passwords are random and rolled on the server, we can tell
about the expiry by setting pwdLastSet to 0.
Samba now honours the password expiry.
This is only enabled for domain functional level 2016 and when
msDS-ExpirePasswordsOnSmartCardOnlyAccounts is set to TRUE.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 3669479f22f2109a64250ffabd1f6453882d29f1
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri May 17 14:19:31 2024 +1200
dsdb: Reduce minimum maxPwdAge from 1 day to nil
This allows us to have tests, which pass on Windows, that
use a very short maxPwdAge.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 302619f66f94c981e30b1c2325e1c7c4e5ac963d
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon May 20 17:13:53 2024 +1200
dsdb: Change the magic smartcard_reset to set AES keys like the krbtgt mode
This is because the smartcard reset now generates all the keys
on Windows, so we want to match Windows 2022 as at April 2024
behaviour.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 7c79abbab46193d8f84ac6f41b55b61228cf528f
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri May 10 16:51:27 2024 +1200
python/samba/tests/krb5: PKINIT tests of passwords that are naturally expired
The tests of passwords that will expire in the TGT lifetime fail against
windows, we do not see the rotation in that case.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 044cc5386058e61cf2ec6842010dfb41e50495d1
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri May 17 12:17:40 2024 +1200
python/test/krb5: Use assertAlmostEqual in check_ticket_times()
This allows Windows behaviour with clock skew to be allowed for.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 68fa90754fd0cee62af636ce37c212da07cd8c46
Author: Andrew Bartlett <abartlet at samba.org>
Date: Fri May 17 12:25:17 2024 +1200
python/tests/krb5: Move check_ticket_times() to kdc_base_test.py
This will allow other parts of the testsuite to use this helpful function.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 48bff4b95f80c02f6701c0b4f5323e022e827a3e
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed Apr 3 10:53:11 2024 +1300
python/samba/krb5: Add test for password rotation on UF_SMARCARD_REQUIRED accounts
This demonstrates behaviour against a server presumed to be in FL 2016
what the impact of the msDS-ExpirePasswordsOnSmartCardOnlyAccounts
attribute is.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit a85f4c661b14cf3b007fa1dae2b08464055ca025
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed Apr 3 08:26:04 2024 +1300
python/tests/krb5: Remove unused utf16pw variable
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 504a47ecfd6ddcca421549760caea8e2cd2448d2
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu May 2 16:02:58 2024 +1200
python/tests/krb5: Expect AES keys for UF_SMARTCARD_REQUIRED
Windows 2022 at April 2024 has change and now includes the
AES keys for accounts with UF_SMARTCARD_REQUIRED, so revert
part of the change in b2fe1ea1c6aba116b31a1c803b4e0d36ac1a32ee.
(This is an improvement to Windows security).
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit dc6c4b215e2b191945f5ad0202133cd3c47925e6
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon May 27 18:53:42 2024 +1200
python/samba/tests/krb5: Extend PKINIT tests to show kpasswd still works
We have had confirmed from MS that this behaviour is both deliberate
and required. Possession of the credential is (by the returned PAC
containing the NT hash) possession of the password, and it must be
possible to change the password to a known value otherwise DPAPI
(local keychain) secured by this value can fail on the client.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15045
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 4ec24a207648d9207649cd1c4364a1124db6f24d
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon May 27 18:46:49 2024 +1200
python/samba/tests/krb5: Move get_kpasswd_sname() into raw_testcase() to allow broader use
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit b664392208c90fff63047b5faf30a33f95777ee2
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon May 20 14:07:46 2024 +1200
s4-auth: Use msDS-User-Account-Control-Computed for PW expiry check
This centralises the check rather than checking the time in
multiple spots.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit 737f2414062d694e54f60f0c6ef94b6ab4f33d19
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed Apr 3 11:52:28 2024 +1300
s4-auth: Update comment to mention 60mins in the NTLM grace period
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
commit e04eb9bb17000c6fa0be0e2e4f8ab17077bd4b38
Author: Andrew Bartlett <abartlet at samba.org>
Date: Tue Apr 23 16:17:04 2024 +1200
dsdb: Make argument order of dsdb_update_gmsa_{entry_,}keys() consistant with other uses
Other functions in this file are TALLOC_CTX, struct ldb_context *, not
the other way around.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Jo Sutton <josutton at catalyst.net.nz>
-----------------------------------------------------------------------
Summary of changes:
WHATSNEW.txt | 26 +-
lib/ldb/include/ldb.h | 6 +
python/samba/domain_update.py | 23 +-
python/samba/provision/__init__.py | 4 +-
python/samba/tests/dsdb_quiet_provision_tests.py | 10 +
python/samba/tests/krb5/authn_policy_tests.py | 30 --
python/samba/tests/krb5/kdc_base_test.py | 34 +-
python/samba/tests/krb5/kpasswd_tests.py | 4 -
python/samba/tests/krb5/pkinit_tests.py | 630 +++++++++++++++++++++--
python/samba/tests/krb5/raw_testcase.py | 12 +-
selftest/knownfail_heimdal_kdc | 2 -
selftest/knownfail_mit_kdc_1_20 | 6 +
source4/auth/auth.h | 1 +
source4/auth/ntlm/auth_sam.c | 33 +-
source4/auth/sam.c | 5 +-
source4/dsdb/common/util.c | 12 +-
source4/dsdb/gmsa/util.c | 23 +-
source4/dsdb/gmsa/util.h | 8 +-
source4/dsdb/samdb/ldb_modules/operational.c | 156 ++++--
source4/dsdb/samdb/ldb_modules/password_hash.c | 116 +++--
source4/dsdb/samdb/samdb.c | 7 +-
source4/dsdb/samdb/samdb.h | 17 +-
source4/kdc/db-glue.c | 293 ++++++++++-
source4/kdc/hdb-samba4.c | 13 +-
source4/kdc/kdc-glue.h | 3 +-
source4/kdc/kdc-heimdal.c | 47 +-
source4/kdc/kdc-proxy.c | 8 +-
source4/kdc/kdc-server.h | 2 +-
source4/kdc/kdc-service-mit.c | 13 -
source4/kdc/mit_kdc_irpc.c | 15 +
source4/kdc/mit_samba.c | 54 ++
source4/kdc/pac-glue.c | 1 +
source4/kdc/samba_kdc.h | 13 +
source4/kdc/wscript_build | 2 +-
source4/ldap_server/ldap_backend.c | 5 +-
source4/libcli/ldap/ldap_controls.c | 1 +
source4/libnet/libnet_export_keytab.c | 32 ++
source4/setup/schema_samba4.ldif | 2 +-
38 files changed, 1382 insertions(+), 287 deletions(-)
Changeset truncated at 500 lines:
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 6d1368c42b1..be93dd5ae61 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -139,6 +139,31 @@ authentication and DNS functions.
This is not supported in samba-tool yet.
+Samba AD will rotate expired passwords on smartcard-required accounts
+---------------------------------------------------------------------
+
+Traditionally in AD, accounts set to be "smart card require for logon"
+will have a password for NTLM fallback and local profile encryption
+(Windows DPAPI). This password previously would not expire.
+
+Matching Windows behaviour, when the DC in a FL 2016 domain and the
+msDS-ExpirePasswordsOnSmartCardOnlyAccounts attribute on the domain
+root is set to TRUE, Samba will now expire these passwords and rotate
+them shortly before they expire.
+
+Note that the password expiry time must be set to twice the TGT lifetime for
+smooth operation, e.g. daily expiry given a default 10 hour TGT
+lifetime, as the password is only rotated in the second half of its
+life. Again, this matches the Windows behaviour.
+
+Provided the default 2016 schema is used, new Samba domains
+provisioned with Samba 4.21 will have this enabled once the domain
+functional level is set to 2016.
+
+NOTE: Domains upgraded from older Samba versions will not have this
+set, even after the functional level preparation, matching the
+behaviour of upgraded Windows AD domains.
+
REMOVED FEATURES
================
@@ -181,4 +206,3 @@ database (https://bugzilla.samba.org/).
== Our Code, Our Bugs, Our Responsibility.
== The Samba Team
======================================================================
-
diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h
index 0a93b560180..f29392ad4ea 100644
--- a/lib/ldb/include/ldb.h
+++ b/lib/ldb/include/ldb.h
@@ -273,6 +273,12 @@ enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR,
*/
#define LDB_FLG_DONT_CREATE_DB 64
+/**
+ * Allow DB create time flags that have meaning only to our
+ * calling application or modules. These must be in this range:
+ */
+#define LDB_FLG_PRIVATE_MASK 0xff000000
+
/*
structures for ldb_parse_tree handling code
*/
diff --git a/python/samba/domain_update.py b/python/samba/domain_update.py
index e91bdf40dbb..2277cc10c18 100644
--- a/python/samba/domain_update.py
+++ b/python/samba/domain_update.py
@@ -92,15 +92,18 @@ class DomainUpdate(object):
"""Check and update a SAM database for domain updates"""
def __init__(self, samdb, fix=False,
+ new_install=False,
add_update_container=True):
"""
:param samdb: LDB database
:param fix: Apply the update if the container is missing
+ :param new_install: Apply the update as per a new install (see op 88)
:param add_update_container: Add the container at the end of the change
:raise DomainUpdateException:
"""
self.samdb = samdb
self.fix = fix
+ self.new_install = new_install
self.add_update_container = add_update_container
# TODO: In future we should check for inconsistencies when it claims it has been done
self.check_update_applied = False
@@ -521,19 +524,29 @@ otherWellKnownObjects: B:32:683A24E2E8164BD3AF86AC3C2CF3F981:%s
## Operation 88: {434bb40d-dbc9-4fe7-81d4-d57229f7b080}
##
## Add "msDS-ExpirePasswordsOnSmartCardOnlyAccounts" on the domain NC object
- ## and set default value to FALSE
+ ## and set default value to FALSE (upgrades) or TRUE (new installs)
+ ##
+ ## See
+ ## https://learn.microsoft.com/en-us/windows-server/get-started/whats-new-in-windows-server-2016#rolling-public-key-only-users-ntlm-secrets
+ ## for justification of the observed behaviour that new installs
+ ## have this set to TRUE
##
def operation_88(self, op):
if self.update_exists(op):
return
self.raise_if_not_fix(op)
- ldif = """
-dn: %s
+ if self.new_install:
+ expire_value = "TRUE"
+ else:
+ expire_value = "FALSE"
+
+ ldif = f"""
+dn: {self.domain_dn}
changetype: modify
add: msDS-ExpirePasswordsOnSmartCardOnlyAccounts
-msDS-ExpirePasswordsOnSmartCardOnlyAccounts: FALSE
-""" % str(self.domain_dn)
+msDS-ExpirePasswordsOnSmartCardOnlyAccounts: {expire_value}
+"""
self.samdb.modify_ldif(ldif)
diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py
index 80684c47522..dea50aa364e 100644
--- a/python/samba/provision/__init__.py
+++ b/python/samba/provision/__init__.py
@@ -2392,7 +2392,9 @@ def provision(logger, session_info, smbconf=None,
try:
from samba.domain_update import DomainUpdate
- DomainUpdate(samdb, fix=True).check_updates_functional_level(
+ DomainUpdate(samdb,
+ new_install=True,
+ fix=True).check_updates_functional_level(
adprep_level,
DS_DOMAIN_FUNCTION_2008,
update_revision=True,
diff --git a/python/samba/tests/dsdb_quiet_provision_tests.py b/python/samba/tests/dsdb_quiet_provision_tests.py
index 81ef3ceb74f..a7c9fbec83e 100644
--- a/python/samba/tests/dsdb_quiet_provision_tests.py
+++ b/python/samba/tests/dsdb_quiet_provision_tests.py
@@ -67,3 +67,13 @@ class DsdbQuietProvisionTests(TestCase):
expression=f"(&(objectClass = msKds-ProvRootKey)(msKds-UseStartTime<={min_use_start_time}))")
self.assertGreater(len(res), 0)
+
+ def test_dsdb_smartcard_expire_set(self):
+ """In provision we set msDS-ExpirePasswordsOnSmartCardOnlyAccounts: TRUE for a new 2016 provision
+ """
+ dn = self.samdb.get_default_basedn()
+ res = self.samdb.search(dn,
+ scope=ldb.SCOPE_BASE,
+ expression="(msDS-ExpirePasswordsOnSmartCardOnlyAccounts=TRUE)")
+
+ self.assertEqual(len(res), 1)
diff --git a/python/samba/tests/krb5/authn_policy_tests.py b/python/samba/tests/krb5/authn_policy_tests.py
index 455ad36d479..a1a38a19449 100755
--- a/python/samba/tests/krb5/authn_policy_tests.py
+++ b/python/samba/tests/krb5/authn_policy_tests.py
@@ -1067,36 +1067,6 @@ class AuthnPolicyBaseTests(AuthLogTestBase, KdcTgsBaseTests):
audit_event=server_policy_event,
reason=server_policy_reason)
- def check_ticket_times(self,
- ticket_creds,
- expected_life=None,
- expected_renew_life=None):
- ticket = ticket_creds.ticket_private
-
- authtime = ticket['authtime']
- starttime = ticket.get('starttime', authtime)
- endtime = ticket['endtime']
- renew_till = ticket.get('renew-till', None)
-
- starttime = self.get_EpochFromKerberosTime(starttime)
-
- if expected_life is not None:
- actual_end = self.get_EpochFromKerberosTime(
- endtime.decode('ascii'))
- actual_lifetime = actual_end - starttime
-
- self.assertEqual(expected_life, actual_lifetime)
-
- if renew_till is None:
- self.assertIsNone(expected_renew_life)
- else:
- if expected_renew_life is not None:
- actual_renew_till = self.get_EpochFromKerberosTime(
- renew_till.decode('ascii'))
- actual_renew_life = actual_renew_till - starttime
-
- self.assertEqual(expected_renew_life, actual_renew_life)
-
def _get_tgt(self, creds, *,
armor_tgt=None,
till=None,
diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py
index feb576b8458..eb3497c554e 100644
--- a/python/samba/tests/krb5/kdc_base_test.py
+++ b/python/samba/tests/krb5/kdc_base_test.py
@@ -894,7 +894,6 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest):
domain = samdb.domain_netbios_name().upper()
password = generate_random_password(32, 32)
- utf16pw = ('"%s"' % password).encode('utf-16-le')
try:
net_ctx.set_password(newpassword=password,
@@ -2167,7 +2166,7 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest):
#
# The NT hash is different, as it is returned to the client in
# the PAC so is visible in the network behaviour.
- if force_nt4_hash or smartcard_required:
+ if force_nt4_hash:
expected_etypes = {kcrypto.Enctype.RC4}
keys = self.get_keys(creds, expected_etypes=expected_etypes)
self.creds_set_keys(creds, keys)
@@ -3786,3 +3785,34 @@ class KDCBaseTest(TestCaseInTempDir, RawKerberosTest):
self.assertEqual(0, flags)
return validation
+
+ def check_ticket_times(self,
+ ticket_creds,
+ expected_life=None,
+ expected_renew_life=None,
+ delta=0):
+ ticket = ticket_creds.ticket_private
+
+ authtime = ticket['authtime']
+ starttime = ticket.get('starttime', authtime)
+ endtime = ticket['endtime']
+ renew_till = ticket.get('renew-till', None)
+
+ starttime = self.get_EpochFromKerberosTime(starttime)
+
+ if expected_life is not None:
+ actual_end = self.get_EpochFromKerberosTime(
+ endtime.decode('ascii'))
+ actual_lifetime = actual_end - starttime
+
+ self.assertAlmostEqual(expected_life, actual_lifetime, delta=delta)
+
+ if renew_till is None:
+ self.assertIsNone(expected_renew_life)
+ else:
+ if expected_renew_life is not None:
+ actual_renew_till = self.get_EpochFromKerberosTime(
+ renew_till.decode('ascii'))
+ actual_renew_life = actual_renew_till - starttime
+
+ self.assertAlmostEqual(expected_renew_life, actual_renew_life, delta=delta)
diff --git a/python/samba/tests/krb5/kpasswd_tests.py b/python/samba/tests/krb5/kpasswd_tests.py
index 0f1fe656f49..6f0b36a25f6 100755
--- a/python/samba/tests/krb5/kpasswd_tests.py
+++ b/python/samba/tests/krb5/kpasswd_tests.py
@@ -90,10 +90,6 @@ class KpasswdTests(KDCBaseTest):
return creds
- def get_kpasswd_sname(self):
- return self.PrincipalName_create(name_type=NT_PRINCIPAL,
- names=['kadmin', 'changepw'])
-
def get_ticket_lifetime(self, ticket):
enc_part = ticket.ticket_private
diff --git a/python/samba/tests/krb5/pkinit_tests.py b/python/samba/tests/krb5/pkinit_tests.py
index c1f85c6c9cd..0c92801cbce 100755
--- a/python/samba/tests/krb5/pkinit_tests.py
+++ b/python/samba/tests/krb5/pkinit_tests.py
@@ -24,6 +24,7 @@ sys.path.insert(0, 'bin/python')
os.environ['PYTHONUNBUFFERED'] = '1'
from datetime import datetime, timedelta
+import time
from pyasn1.type import univ
@@ -36,8 +37,12 @@ from cryptography.x509.oid import NameOID
import ldb
import samba.tests
-from samba import credentials, ntstatus
+from samba import credentials, generate_random_password, ntstatus
+from samba.nt_time import (nt_time_delta_from_timedelta,
+ nt_now, string_from_nt_time)
from samba.dcerpc import security, netlogon
+from samba.dsdb import UF_PASSWORD_EXPIRED, UF_DONT_EXPIRE_PASSWD
+from samba.tests.pso import PasswordSettings
from samba.tests.krb5 import kcrypto
from samba.tests.krb5.kdc_base_test import KDCBaseTest
from samba.tests.krb5.raw_testcase import PkInit, RawKerberosTest
@@ -51,6 +56,7 @@ from samba.tests.krb5.rfc4120_constants import (
KDC_ERR_PREAUTH_EXPIRED,
KDC_ERR_PREAUTH_FAILED,
KDC_ERR_PREAUTH_REQUIRED,
+ KPASSWD_SUCCESS,
KU_PA_ENC_TIMESTAMP,
NT_PRINCIPAL,
NT_SRV_INST,
@@ -66,6 +72,23 @@ SidType = RawKerberosTest.SidType
global_asn1_print = False
global_hexdump = False
+def set_ExpirePasswordsOnSmartCardOnlyAccounts(samdb, val):
+ msg = ldb.Message()
+ msg.dn = samdb.get_default_basedn()
+
+ # Allow val to be True, False, strings or message elements
+ if val is True:
+ val = "TRUE"
+ elif val is False:
+ val = "FALSE"
+ elif val is None:
+ val = []
+
+ msg["msDS-ExpirePasswordsOnSmartCardOnlyAccounts"] \
+ = ldb.MessageElement(val,
+ ldb.FLAG_MOD_REPLACE,
+ "msDS-ExpirePasswordsOnSmartCardOnlyAccounts")
+ samdb.modify(msg)
class PkInitTests(KDCBaseTest):
@classmethod
@@ -77,16 +100,23 @@ class PkInitTests(KDCBaseTest):
self.do_asn1_print = global_asn1_print
self.do_hexdump = global_hexdump
- def _get_creds(self, account_type=KDCBaseTest.AccountType.USER, use_cache=False, smartcard_required=False):
+ def _get_creds(self,
+ account_type=KDCBaseTest.AccountType.USER,
+ use_cache=False,
+ smartcard_required=False,
+ assigned_policy=None):
"""Return credentials with an account having a UPN for performing
PK-INIT."""
samdb = self.get_samdb()
realm = samdb.domain_dns_name().upper()
+ opts={'upn': f'{{account}}.{realm}@{realm}',
+ 'smartcard_required': smartcard_required}
+ if assigned_policy is not None:
+ opts['assigned_policy'] = str(assigned_policy.dn)
return self.get_cached_creds(
account_type=account_type,
- opts={'upn': f'{{account}}.{realm}@{realm}',
- 'smartcard_required': smartcard_required},
+ opts=opts,
use_cache=use_cache)
def test_pkinit_no_des3(self):
@@ -588,6 +618,59 @@ class PkInitTests(KDCBaseTest):
logon_type=netlogon.NetlogonNetworkInformation,
expect_error=ntstatus.NT_STATUS_WRONG_PASSWORD)
+ def _test_samlogon_smartcard_required_expired(self, smartcard_pw_expire):
+ """Test SamLogon with an account set to smartcard login required. No actual PK-INIT in this test."""
+ samdb = self.get_samdb()
+ msgs = samdb.search(base=samdb.get_default_basedn(),
+ scope=ldb.SCOPE_BASE,
+ attrs=["msDS-ExpirePasswordsOnSmartCardOnlyAccounts"])
+ msg = msgs[0]
+
+ try:
+ old_ExpirePasswordsOnSmartCardOnlyAccounts = msg["msDS-ExpirePasswordsOnSmartCardOnlyAccounts"]
+ except KeyError:
+ old_ExpirePasswordsOnSmartCardOnlyAccounts = None
+
+ self.addCleanup(set_ExpirePasswordsOnSmartCardOnlyAccounts,
+ samdb, old_ExpirePasswordsOnSmartCardOnlyAccounts)
+
+ # Enable auto-rotation for this test
+ set_ExpirePasswordsOnSmartCardOnlyAccounts(samdb, smartcard_pw_expire)
+
+ client_creds = self._get_creds(smartcard_required=True)
+
+ client_creds.set_kerberos_state(credentials.AUTO_USE_KERBEROS)
+
+ msg = ldb.Message()
+ msg.dn = client_creds.get_dn()
+
+ # Ideally we would set this to a time just long enough for the
+ # password to expire, but we are unable to do that.
+ #
+ # 0 means "must change on first login"
+ msg["pwdLastSet"] = \
+ ldb.MessageElement(str(0),
+ ldb.FLAG_MOD_REPLACE,
+ "pwdLastSet")
+ samdb.modify(msg)
+
+ # This shows that the magic rotation behaviour is not
+ # triggered in SamLogon
+ self._test_samlogon(
+ creds=client_creds,
+ logon_type=netlogon.NetlogonInteractiveInformation,
+ expect_error=ntstatus.NT_STATUS_SMARTCARD_LOGON_REQUIRED)
+
+ self._test_samlogon(creds=client_creds,
+ logon_type=netlogon.NetlogonNetworkInformation,
+ expect_error=ntstatus.NT_STATUS_WRONG_PASSWORD)
+
+ def test_samlogon_smartcard_required_expired(self):
+ self._test_samlogon_smartcard_required_expired(True)
+
+ def test_samlogon_smartcard_required_expired_disabled(self):
+ self._test_samlogon_smartcard_required_expired(False)
+
def test_pkinit_ntlm_from_pac(self):
"""Test public-key PK-INIT to get an NT hash and confirm NTLM
authentication is possible with it."""
@@ -629,8 +712,11 @@ class PkInitTests(KDCBaseTest):
freshness_token = self.create_freshness_token()
+ # The hash will not match as UF_SMARTCARD_REQUIRED at creation
+ # time make the password random
kdc_exchange_dict = self._pkinit_req(client_creds, krbtgt_creds,
- freshness_token=freshness_token)
+ freshness_token=freshness_token,
+ expect_matching_nt_hash_in_pac=False)
nt_hash_from_pac = kdc_exchange_dict['nt_hash_from_pac']
client_creds.set_nt_hash(nt_hash_from_pac,
@@ -655,34 +741,58 @@ class PkInitTests(KDCBaseTest):
self._test_samlogon(creds=client_creds,
logon_type=netlogon.NetlogonNetworkInformation)
- def test_pkinit_ntlm_from_pac_must_change_now(self):
- """Test public-key PK-INIT to get an NT hash and confirm NTLM
- authentication is possible with it."""
+ def _test_pkinit_ntlm_from_pac_must_change_now(self, smartcard_pw_expire):
+ """Test public-key PK-INIT on an account set to 'must change now'.
+ This shows that PKINIT is not available for these accounts and no
+ auto-rollover happens because UF_SMARTCARD_REQUIRED is not set"""
+ samdb = self.get_samdb()
+
+ msgs = samdb.search(base=samdb.get_default_basedn(),
+ scope=ldb.SCOPE_BASE,
+ attrs=["msDS-ExpirePasswordsOnSmartCardOnlyAccounts"])
+ msg = msgs[0]
+
+ try:
+ old_ExpirePasswordsOnSmartCardOnlyAccounts = msg["msDS-ExpirePasswordsOnSmartCardOnlyAccounts"]
+ except KeyError:
+ old_ExpirePasswordsOnSmartCardOnlyAccounts = None
+
+ self.addCleanup(set_ExpirePasswordsOnSmartCardOnlyAccounts,
+ samdb, old_ExpirePasswordsOnSmartCardOnlyAccounts)
+
+ # Enable auto-rotation for this test
+ set_ExpirePasswordsOnSmartCardOnlyAccounts(samdb, smartcard_pw_expire)
+
client_creds = self._get_creds()
client_creds.set_kerberos_state(credentials.AUTO_USE_KERBEROS)
- msg = ldb.Message()
- msg.dn = client_creds.get_dn()
+ mod_msg = ldb.Message()
+ mod_msg.dn = client_creds.get_dn()
# Ideally we would set this to a time just long enough for the
- # password to expire, but we are unable to do that.
+ # password to expire, but this is good enough
#
# 0 means "must change on first login"
- msg["pwdLastSet"] = \
+ mod_msg["pwdLastSet"] = \
ldb.MessageElement(str(0),
ldb.FLAG_MOD_REPLACE,
"pwdLastSet")
- samdb = self.get_samdb()
- samdb.modify(msg)
+ samdb.modify(mod_msg)
krbtgt_creds = self.get_krbtgt_creds()
freshness_token = self.create_freshness_token()
+ # Windows does not send an NTSTATUS in this case for an
+ # expired password against PKINIT, but will for ENC-TS,
+ # However Samba on Heimdal is consistent between both, so we
+ # must set expect_status=None to allow the test to pass
+ # against both.
self._pkinit_req(client_creds, krbtgt_creds,
freshness_token=freshness_token,
expect_error=KDC_ERR_KEY_EXPIRED,
- expect_edata=True
+ expect_edata=True,
+ expected_status=ntstatus.NT_STATUS_PASSWORD_MUST_CHANGE,
)
# AS-REQ will not succeed, password is still expired
@@ -706,9 +816,35 @@ class PkInitTests(KDCBaseTest):
logon_type=netlogon.NetlogonNetworkInformation,
expect_error=ntstatus.NT_STATUS_PASSWORD_MUST_CHANGE)
- def test_pkinit_ntlm_from_pac_smartcard_required_must_change_now(self):
+ def test_pkinit_ntlm_from_pac_must_change_now(self):
+ self._test_pkinit_ntlm_from_pac_must_change_now(smartcard_pw_expire=True)
+
+ def test_pkinit_ntlm_from_pac_must_change_now_rotate_disabled(self):
+ self._test_pkinit_ntlm_from_pac_must_change_now(smartcard_pw_expire=False)
+
+ def _test_pkinit_ntlm_from_pac_smartcard_required_must_change_now(self, smartcard_pw_expire):
--
Samba Shared Repository
More information about the samba-cvs
mailing list