The branch, master has been updated
       via  9ffcd38c16c s4:kdc:sdb_to_hdb strong/flexible certificate mappings
       via  14d9a1be895 s4:kdc:sdb Support Windows flexible cert mappings
       via  0245610b09f tests:s4:kdc Add tests for pkinit certificate mapping
       via  f9d9f559d99 python:domain:user Add altSecurityIdentities
       via  30ed2c92520 selftest: Add certificate binding configuration
       via  c45247815af config: add certificate backdating compensation
       via  470ccdb340e config: add strong certificate binding enforcement
       via  121598c6ad4 docs: smb.conf: add auth info audit logging
       via  f08d63f55ba WHATSNEW: auth info audit logging
       via  568740313ed s4:dsdb:audit_log clean up doc comments
       via  bd2d596446c s4:dsdb:audit_log change action for auth info
       via  9159e8080c9 s4:dsdb:audit_log log auth info changes
       via  00e12c2e2de tests:audit_log_pass_change add tests for auth info 
logging
       via  7577c5bc8f6 tests:audit_log_pass_change refactor the tests
      from  8cb97336ac3 third_party:heimdal: import 
lorikeet-heimdal-202509242121

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


- Log -----------------------------------------------------------------
commit 9ffcd38c16c0f44950a7ea547eb19a01590617f7
Author: Gary Lockyer <[email protected]>
Date:   Mon Sep 8 10:29:36 2025 +1200

    s4:kdc:sdb_to_hdb strong/flexible certificate mappings
    
    Map the content of sdb_certificate_mappings to the hdb extension
    HDB_Ext_CertificateMapping
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>
    
    Autobuild-User(master): Jennifer Sutton <[email protected]>
    Autobuild-Date(master): Fri Oct 10 02:30:06 UTC 2025 on atb-devel-224

commit 14d9a1be89557c3c7bca13be7410a47b7b6bf511
Author: Gary Lockyer <[email protected]>
Date:   Tue Sep 2 09:59:13 2025 +1200

    s4:kdc:sdb Support Windows flexible cert mappings
    
    Extract certificate mappings from the altSecurityIdentities attribute and
    populate the new sdb_certificate_mappings element of sdb
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 0245610b09f8ad4307fbed3143a581e603172fc4
Author: Gary Lockyer <[email protected]>
Date:   Mon Sep 22 15:40:58 2025 +1200

    tests:s4:kdc Add tests for pkinit certificate mapping
    
    Tests for pkinit with "strong certificate binding enforcement"
    See: https://support.microsoft.com/en-us/topic/
         kb5014754-certificate-based-authentication-changes-on-windows-domain
         -controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16
    
         KB5014754: Certificate-based authentication changes on Windows
         domain controllers
    
    Test environment configuration:
       ad_dc       none
       ad_dc_ntcfs compatibility
       ad_dc_smb1  full
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit f9d9f559d99457aaaf0902badb0b56a5749b95d8
Author: Gary Lockyer <[email protected]>
Date:   Mon Sep 22 15:42:31 2025 +1200

    python:domain:user Add altSecurityIdentities
    
    Add altSecurityIdentities to the User domain model so that it can be used by
    the key certificate binding enforcement tests.
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 30ed2c92520605980832b9c1c6a49cf670985a34
Author: Gary Lockyer <[email protected]>
Date:   Mon Sep 22 15:45:27 2025 +1200

    selftest: Add certificate binding configuration
    
    Configure the ad_dc and ad_dc_ntvfs test environments for pkinit certificate
    binding tests:
    
    ad_dc_ntvfs:
        strong certificate binding enforcement = compatibility
        certificate backdating compensation = 1500
    
    To allow testing of compatibility mode
    
    ad_dc:
        strong certificate binding enforcement = none
    
    To test no enforcement, and to avoid breaking existing kerberos tests
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit c45247815af1a5817f1d34255aeb75e75cec82bd
Author: Gary Lockyer <[email protected]>
Date:   Fri Aug 29 11:05:10 2025 +1200

    config: add certificate backdating compensation
    
    When preforming certificate based kerberos authentication (PKINIT) with
    "strong certificate binding enforcement = compatibility"", for WEAK mappings
    the certificate issue date must be after the date the user record was 
created.
    
    This parameter relaxes that constraint by allowing the certificate to have 
been
    issued up to the specified number of minutes before the user record was 
created.
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 470ccdb340e716b8baa69049997a0d8b2432dffa
Author: Gary Lockyer <[email protected]>
Date:   Thu Aug 28 13:07:01 2025 +1200

    config: add strong certificate binding enforcement
    
    This parameter controls the enforcement of Windows Certificate bindings as
    outlined in "KB5014754: Certificate-based authentication changes on Windows
    domain controllers",
    when preforming certificate based kerberos authentication (PKINIT)
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Jennifer Sutton <[email protected]>

commit 121598c6ad4430d98b3b9f5cf0ea24309969bcbc
Author: Douglas Bagnall <[email protected]>
Date:   Wed Oct 8 14:29:13 2025 +1300

    docs: smb.conf: add auth info audit logging
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit f08d63f55bae91f194295abc994ae058126df80f
Author: Douglas Bagnall <[email protected]>
Date:   Wed Oct 8 14:28:29 2025 +1300

    WHATSNEW: auth info audit logging
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Gary Lockyer <[email protected]>

commit 568740313ed162f083bc8254e967f59651a89bf3
Author: Gary Lockyer <[email protected]>
Date:   Mon Oct 6 16:04:41 2025 +1300

    s4:dsdb:audit_log clean up doc comments
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit bd2d596446c560f820d6deb3cca56ffc4e64bd10
Author: Gary Lockyer <[email protected]>
Date:   Mon Oct 6 14:28:19 2025 +1300

    s4:dsdb:audit_log change action for auth info
    
    Change the action logged for authentication information changes from
    "Public key change" to "Auth info change". To reflect that it's not just
    changes to public keys that get logged.
    
    This doesn't require a JSON log format version change, because the
    version was recently bumped in c9e752ab18f43758d704951f7f31e39dafa6fdb4
    and there hasn't been a Samba release in the meantime.
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 9159e8080c99d0cc5e55247d039a07cb7ef2ec03
Author: Gary Lockyer <[email protected]>
Date:   Mon Oct 6 13:06:12 2025 +1300

    s4:dsdb:audit_log log auth info changes
    
    Log changes to altSecurityIdentities, dNSHostName, 
msDS-additionalDnsHostNames
    and servicePrincipal name in the same way that changes to 
mdDS-keyCredentialLink
    changes are logged.
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 00e12c2e2def5fd180b210301d9d45df7fe565f5
Author: Gary Lockyer <[email protected]>
Date:   Mon Oct 6 12:46:44 2025 +1300

    tests:audit_log_pass_change add tests for auth info logging
    
    Add tests for the logging of changes to altSecurityIdentities, dnsHostName,
    servicePrincipalName and msDS-AdditionalDnsHostNames
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 7577c5bc8f6ee6ba008fa01622192b7b9f19f097
Author: Gary Lockyer <[email protected]>
Date:   Mon Oct 6 10:29:28 2025 +1300

    tests:audit_log_pass_change refactor the tests
    
    Refactor python/samba/tests/audit_log_pass_change.py to make it easier add 
tests
    for the logging of changes to alternateSecurityIdentities, dNSHostName,
    servicePrincipleName
    
    Signed-off-by: Gary Lockyer <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

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

Summary of changes:
 WHATSNEW.txt                                       |   17 +
 docs-xml/smbdotconf/logging/loglevel.xml           |   24 +-
 docs-xml/smbdotconf/security/kdccertbackdating.xml |   28 +
 .../security/kdccertbindingenforcement.xml         |  109 ++
 lib/param/loadparm.c                               |    2 +
 lib/param/loadparm.h                               |    4 +
 lib/param/param_table.c                            |    9 +
 python/samba/domain/models/user.py                 |    1 +
 python/samba/tests/audit_log_pass_change.py        |  242 ++--
 python/samba/tests/krb5/key_trust_tests.py         |    2 +-
 .../tests/krb5/pkinit_certificate_mapping_tests.py | 1170 ++++++++++++++++++++
 python/samba/tests/krb5/rfc4120_constants.py       |    1 +
 selftest/knownfail_mit_kdc                         |    3 +
 selftest/target/Samba4.pm                          |    9 +-
 source3/param/loadparm.c                           |    3 +
 source4/auth/sam.c                                 |    4 +-
 source4/dsdb/common/util.h                         |   12 +
 source4/dsdb/samdb/ldb_modules/audit_log.c         |  234 ++--
 source4/dsdb/samdb/ldb_modules/audit_util.c        |   24 +
 .../dsdb/samdb/ldb_modules/tests/test_audit_log.c  |    2 +-
 source4/kdc/db-glue.c                              |  469 +++++++-
 source4/kdc/sdb.c                                  |   43 +
 source4/kdc/sdb.h                                  |   22 +
 source4/kdc/sdb_to_hdb.c                           |  187 ++++
 source4/kdc/tests/db-glue-test.c                   |  947 +++++++++++++++-
 source4/kdc/tests/sdb_to_hdb_test.c                |  409 +++++++
 source4/selftest/tests.py                          |   18 +
 27 files changed, 3774 insertions(+), 221 deletions(-)
 create mode 100644 docs-xml/smbdotconf/security/kdccertbackdating.xml
 create mode 100644 docs-xml/smbdotconf/security/kdccertbindingenforcement.xml
 create mode 100755 python/samba/tests/krb5/pkinit_certificate_mapping_tests.py


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 968ebd08de2..5447e383b27 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -16,6 +16,23 @@ UPGRADING
 NEW FEATURES/CHANGES
 ====================
 
+Authentication information audit support
+----------------------------------------
+
+There are some Active Directory attributes that are not secret, but
+are relied on in some forms of authentication. Changes to these
+attributes could indicate surreptitious activity. The
+"dsdb_password_audit" and "dsdb_password_json_audit" debug classes now
+log changes to the following attributes:
+
+ * altSecurityIdentities
+ * dNSHostName
+ * msDS-AdditionalDnsHostName
+ * msDS-KeyCredentialLink
+ * servicePrincipalName
+
+For the JSON logs, changes to these will be logged with the "action"
+field set to "Auth info change".
 
 REMOVED FEATURES
 ================
diff --git a/docs-xml/smbdotconf/logging/loglevel.xml 
b/docs-xml/smbdotconf/logging/loglevel.xml
index 19ab2b77571..cd96786952e 100644
--- a/docs-xml/smbdotconf/logging/loglevel.xml
+++ b/docs-xml/smbdotconf/logging/loglevel.xml
@@ -123,10 +123,11 @@
        <listitem><para>5: Replicated updates from another DC</para></listitem>
     </itemizedlist>
 
-    <para>Password changes and Password resets in the AD DC are logged
-    under <parameter>dsdb_password_audit</parameter> and a JSON
+    <para>In the AD DC, password changes, password resets, and certain
+    authentication related attribute changes are logged under
+    <parameter>dsdb_password_audit</parameter> and a JSON
     representation is logged under the
-    <parameter>dsdb_password_json_audit</parameter>.  Password changes
+    <parameter>dsdb_password_json_audit</parameter>. Password changes
     will also appears as authentication events via
     <parameter>auth_audit</parameter> and
     <parameter>auth_audit_json</parameter>.</para>
@@ -134,9 +135,24 @@
     <para>Log levels for <parameter>dsdb_password_audit</parameter> and
     <parameter>dsdb_password_json_audit</parameter> are:</para>
     <itemizedlist>
-       <listitem><para>5: Successful password changes and 
resets</para></listitem>
+       <listitem><para>5: Successful password changes and resets, and
+       authentication related attribute changes.</para></listitem>
     </itemizedlist>
 
+    <para>Changes to the following attributes are logged:</para>
+    <itemizedlist>
+       <listitem><para>altSecurityIdentities</para></listitem>
+       <listitem><para>dNSHostName</para></listitem>
+       <listitem><para>msDS-AdditionalDnsHostName</para></listitem>
+       <listitem><para>msDS-KeyCredentialLink</para></listitem>
+       <listitem><para>servicePrincipalName</para></listitem>
+    </itemizedlist>
+    <para>In the <parameter>dsdb_password_json_audit</parameter> log
+    these are given the value "Auth info change" in the "action"
+    field. Password changes and resets have the value "change" and
+    "reset" in this field, respectively.</para>
+
+
     <para>Transaction rollbacks and prepare commit failures are logged under
     the <parameter>dsdb_transaction_audit</parameter> and a JSON 
representation is logged under the
     <parameter>dsdb_transaction_json_audit</parameter>. </para>
diff --git a/docs-xml/smbdotconf/security/kdccertbackdating.xml 
b/docs-xml/smbdotconf/security/kdccertbackdating.xml
new file mode 100644
index 00000000000..11926a164bb
--- /dev/null
+++ b/docs-xml/smbdotconf/security/kdccertbackdating.xml
@@ -0,0 +1,28 @@
+<samba:parameter name="certificate backdating compensation"
+                 context="G"
+                 type="integer"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc";>
+<description>
+    <para>
+        When performing certificate based kerberos authentication
+        (PKINIT) with
+        <smbconfoption name="strong certificate binding enforcement">
+            compatibility
+        </smbconfoption>
+    </para>
+    <para>
+        This parameter specifies number of minutes that a certificate's issue
+        date may precede the creation of a users account.
+    </para>
+
+    <para>More details can be found at
+        <ulink 
url="https://support.microsoft.com/en-us/topic/kb5014754-certificate-based-authentication-changes-on-windows-domain-controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16";>
+            KB5014754: Certificate-based authentication changes on Windows
+            domain controllers
+        </ulink>
+    </para>
+
+</description>
+
+<value type="default">0</value>
+</samba:parameter>
diff --git a/docs-xml/smbdotconf/security/kdccertbindingenforcement.xml 
b/docs-xml/smbdotconf/security/kdccertbindingenforcement.xml
new file mode 100644
index 00000000000..fa1fab40ee8
--- /dev/null
+++ b/docs-xml/smbdotconf/security/kdccertbindingenforcement.xml
@@ -0,0 +1,109 @@
+<samba:parameter name="strong certificate binding enforcement"
+                 context="G"
+                 type="enum"
+                 enumlist="enum_strong_cert_binding_enforcement_vals"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc";>
+<description>
+    <para>This parameter controls the enforcement of Windows Certificate
+        bindings as outlined in
+            <ulink 
url="https://support.microsoft.com/en-us/topic/kb5014754-certificate-based-authentication-changes-on-windows-domain-controllers-ad2c23b0-15d8-4340-a468-4d4f3b188f16";>
+                KB5014754: Certificate-based authentication changes on
+                Windows domain controllers
+            </ulink>, when performing certificate based kerberos authentication
+            (PKINIT)
+    </para>
+
+    <para>The possible values are:
+        <itemizedlist>
+            <listitem>
+                <para><constant>none</constant></para>
+                <para>
+                    No validation of the certificate mappings is performed
+                </para>
+            </listitem>
+            <listitem>
+                <para><constant>compatibility</constant></para>
+                <para>
+                        Weak certificate mappings are permitted.
+                </para>
+                <para>
+                    In compatibility mode for WEAK mappings the date the
+                    certificate was issued must be after the date that the user
+                    was created.
+                </para>
+                <para>
+                    <constant>Unless</constant>
+                    <smbconfoption name="certificate backdating compensation"/>
+                    has a value.  In that case the certificate may have been
+                    issued no more that number of minutes before the user
+                    was created.
+                </para>
+            </listitem>
+            <listitem>
+                <para><constant>full</constant></para>
+                <para>
+                    Only <constant>strong</constant> certificate mappings are
+                    permitted. This is the default.
+                </para>
+            </listitem>
+        </itemizedlist>
+    </para>
+
+    <para>
+        Certificate mappings are configured in the users
+        <constant>altSecurityIdentities</constant>
+            attribute and may be any of:
+            <itemizedlist>
+            <listitem>
+                <para>X509 Issuer and subject</para>
+                <para>Example: 
"X509:&lt;I&gt;IssuerName&lt;S&gt;SubjectName"</para>
+                <para>
+                    The values provided for the issuer name and subject name
+                    must match those in the users certificate exactly.
+                </para>
+                <para><emphasis>WEAK</emphasis></para>
+            </listitem>
+            <listitem>
+                <para>X509 Subject only</para>
+                <para>Example: "X509:&lt;S&gt;SubjectName"</para>
+                <para>
+                    The value provided for the issuer subject name
+                    must match that in the users certificate exactly.
+                </para>
+                <para><emphasis>WEAK</emphasis></para>
+            </listitem>
+            <listitem>
+                <para>X509 RFC822</para>
+                <para>Example: "X509:&lt;RFC822&gt;[email protected]"</para>
+                <para>
+                    Email address
+                </para>
+                <para><emphasis>WEAK</emphasis></para>
+            </listitem>
+            <listitem>
+                <para>X509 Issuer and serial number</para>
+                <para>Example: 
"X509:&lt;I&gt;IssuerName&lt;SR&gt;123456789"</para>
+                <para>
+                    Certificate issuer and serial number
+                </para>
+                <para><emphasis>STRONG</emphasis></para>
+            </listitem>
+            <listitem>
+                <para>X509 Subject Key Identifier</para>
+                <para>Example: "&lt;SKI&gt;01234xxxxx"</para>
+                <para><emphasis>STRONG</emphasis></para>
+            </listitem>
+            <listitem>
+                <para>X509 public key SHA1 </para>
+                <para>Example: "X509:&lt;SHA1-PUKEY&gt;1234567890abcdef"</para>
+                <para>
+                    The SHA1 hash of the certificates public key
+                </para>
+                <para><emphasis>STRONG</emphasis></para>
+            </listitem>
+            </itemizedlist>
+    </para>
+</description>
+
+<value type="default">full</value>
+</samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 4af9638ffd7..8aea8f8499b 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2957,6 +2957,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX 
*mem_ctx)
        lpcfg_do_global_parameter_var(lp_ctx, "dns port", "%d", 
DNS_SERVICE_PORT);
 
        lpcfg_do_global_parameter(lp_ctx, "kdc enable fast", "True");
+       lpcfg_do_global_parameter(lp_ctx, "strong certificate binding 
enforcement", "full");
+       lpcfg_do_global_parameter(lp_ctx, "certificate backdating 
compensation", "0");
 
        lpcfg_do_global_parameter(lp_ctx, "nt status support", "True");
 
diff --git a/lib/param/loadparm.h b/lib/param/loadparm.h
index 32788e37391..a979a8ac8f6 100644
--- a/lib/param/loadparm.h
+++ b/lib/param/loadparm.h
@@ -183,6 +183,10 @@ struct file_lists {
 #define KERBEROS_ETYPES_STRONG 1
 #define KERBEROS_ETYPES_LEGACY 2
 
+#define KDC_CERT_BINDING_NONE 0
+#define KDC_CERT_BINDING_COMPAT 1
+#define KDC_CERT_BINDING_FULL 2
+
 /* ACL compatibility */
 enum acl_compatibility {ACL_COMPAT_AUTO, ACL_COMPAT_WINNT, ACL_COMPAT_WIN2K};
 
diff --git a/lib/param/param_table.c b/lib/param/param_table.c
index 0283569882a..04d4d1dac84 100644
--- a/lib/param/param_table.c
+++ b/lib/param/param_table.c
@@ -294,6 +294,15 @@ static const struct enum_list 
enum_kerberos_encryption_types_vals[] = {
        {-1, NULL}
 };
 
+/* KDC Windows KB5014754 certificate binding enforcement modes */
+
+static const struct enum_list enum_strong_cert_binding_enforcement_vals[] = {
+       {KDC_CERT_BINDING_NONE, "none"},
+       {KDC_CERT_BINDING_COMPAT, "compatibility"},
+       {KDC_CERT_BINDING_FULL, "full"},
+       {-1, NULL}
+};
+
 static const struct enum_list enum_printing[] = {
        {PRINT_SYSV, "sysv"},
        {PRINT_AIX, "aix"},
diff --git a/python/samba/domain/models/user.py 
b/python/samba/domain/models/user.py
index 14581809454..dd169398967 100644
--- a/python/samba/domain/models/user.py
+++ b/python/samba/domain/models/user.py
@@ -44,6 +44,7 @@ class User(OrganizationalPerson):
     display_name = StringField("displayName")
     key_credential_link = KeyCredentialLinkDnField("msDS-KeyCredentialLink",
                                                    many=True)
+    alt_security_identities = StringField("altSecurityIdentities", many=True)
     last_logoff = NtTimeField("lastLogoff", readonly=True)
     last_logon = NtTimeField("lastLogon", readonly=True)
     logon_count = IntegerField("logonCount", readonly=True)
diff --git a/python/samba/tests/audit_log_pass_change.py 
b/python/samba/tests/audit_log_pass_change.py
index 2aa4be48ce0..203e3a0f941 100644
--- a/python/samba/tests/audit_log_pass_change.py
+++ b/python/samba/tests/audit_log_pass_change.py
@@ -43,6 +43,9 @@ USER_PASS = samba.generate_random_password(32, 32)
 SECOND_USER_NAME = "auditlogtestuser02"
 SECOND_USER_PASS = samba.generate_random_password(32, 32)
 
+MACHINE_NAME = "auditlogtestmachineuser"
+MACHINE_PASS = samba.generate_random_password(32, 32)
+
 
 class AuditLogPassChangeTests(AuditLogTestBase):
 
@@ -95,6 +98,17 @@ class AuditLogPassChangeTests(AuditLogTestBase):
             "userPassword": USER_PASS
         })
 
+        # (Re)adds the test user MACHINE_NAME with password MACHINE_PASS
+        delete_force(
+            self.ldb,
+            "cn=" + MACHINE_NAME + ",cn=users," + self.base_dn)
+        self.ldb.add({
+            "dn": "cn=" + MACHINE_NAME + ",cn=users," + self.base_dn,
+            "objectclass": "computer",
+            "sAMAccountName": MACHINE_NAME,
+            "userPassword": MACHINE_PASS
+        })
+
     #
     # Discard the messages from the setup code
     #
@@ -403,20 +417,146 @@ class AuditLogPassChangeTests(AuditLogTestBase):
         session_id = self.get_session()
         service_description = self.get_service_description()
         self.assertEqual(service_description, "LDAP")
+
+        self._test_ldap_authentication_information(
+            "msDS-keyCredentialLink", kcls)
+
         transactions_seen = set()
 
-        with self.subTest("initial setup"):
+        with self.subTest("add bad KCL DN value"):
+            self.ldb.modify_ldif(
+                f"dn: {dn}\n"
+                "changetype: modify\n"
+                "replace: msDS-keyCredentialLink\n"
+                f"msDS-keyCredentialLink: B:4:f1ea:{dn}\n")
+            messages = self.waitForMessages(1, dn=dn)
+            self.discardMessages()
+            audit = messages[0]["passwordChange"]
+            self.assertEqual(EVT_ID_DIRECTORY_OBJECT_CHANGE, audit["eventId"])
+            self.assertEqual("Auth info change", audit["action"])
+            self.assertEqual(dn, audit["dn"])
+            self.assertIn(self.remoteAddress, audit["remoteAddress"])
+            self.assertEqual(session_id, audit["sessionId"])
+            self.assertEqual(0, audit["statusCode"])
+            transactions_seen.add(audit["transactionId"])
+
+        with self.subTest("add a second DN value"):
+            # should this fail?
             self.ldb.modify_ldif(
                 f"dn: {dn}\n"
                 "changetype: modify\n"
                 "add: msDS-keyCredentialLink\n"
-                f"msDS-keyCredentialLink: {kcls[0]}\n")
+                f"msDS-keyCredentialLink: B:4:f1ee:{dn}\n")
+            messages = self.waitForMessages(1, dn=dn)
+            self.discardMessages()
+            audit = messages[0]["passwordChange"]
+            self.assertEqual(EVT_ID_DIRECTORY_OBJECT_CHANGE, audit["eventId"])
+            self.assertEqual("Auth info change", audit["action"])
+            self.assertEqual(dn, audit["dn"])
+            self.assertIn(self.remoteAddress, audit["remoteAddress"])
+            self.assertEqual(session_id, audit["sessionId"])
+            self.assertEqual(0, audit["statusCode"])
+            transactions_seen.add(audit["transactionId"])
+
+        # these should all have been separate transactions
+        with self.subTest("check transactions"):
+            self.assertEqual(len(transactions_seen), 2)
+            for t in transactions_seen:
+                self.assertTrue(self.is_guid(t))
+
+        with self.subTest("add bad Binary DN value"):
+            for bad_dn in ('B:6:f1ea:{dn}', 'flea', dn):
+                with self.assertRaises(LdbError) as e:
+                    self.ldb.modify_ldif(
+                        f"dn: {dn}\n"
+                        "changetype: modify\n"
+                        "replace: msDS-keyCredentialLink\n"
+                        f"msDS-keyCredentialLink: {bad_dn}\n")
+                self.assertEqual(e.exception.args[0], ERR_INVALID_DN_SYNTAX)
+            # no messages from those the 3 bad DNs
+            # because DN syntax check comes first
+            messages = self.waitForMessages(1, dn=dn)
+            self.assertEqual(0, len(messages))
+
+
+    def test_ldap_altSecurityIdentities(self):
+        """Test logging of altSecurityIdentities changes.
+        """
+        values = [
+            "X509:<SKI>123456789123",
+            "X509:<S>SubjectName<I>IssuerName",
+            "X509:<I>IssuerName<SR>123456789123"
+        ]
+        self._test_ldap_authentication_information(
+            "altSecurityIdentities", values)
+
+
+    def test_ldap_service_principal_name(self):
+        """Test logging of servicePrincipalName changes.
+        """
+        values = [
+            "HOST/principal1",
+            "HOST/principal2",
+            "HOST/Principla3"
+        ]
+        self._test_ldap_authentication_information(
+            "servicePrincipalName", values)
+
+
+    def test_ldap_dns_host_name(self):
+        """Test logging of dNSHostName changes.
+        """
+        values = [
+            "host1.test.samba.org",
+            "host2.test.samba.org",
+            "host3.test.samba.org"
+        ]
+        self._test_ldap_authentication_information(
+            "dNSHostName", values, user=MACHINE_NAME)
+
+    def test_ldap_msDS_AdditionalDnsHostName(self):
+        """Test logging of msDS-AdditionalDnsHostName changes.
+        """
+        values = [
+            "host1.test.samba.org",
+            "host2.test.samba.org",
+            "host3.test.samba.org"
+        ]
+        self._test_ldap_authentication_information(
+            "msDS-AdditionalDnsHostName", values, user=MACHINE_NAME)
+
+    def _test_ldap_authentication_information(
+            self,
+            attribute,
+            values,
+            user=USER_NAME ):
+        """Test logging of authentication information changes.
+        """
+        #
+        # To avoid all the set-up cost of making a fresh DB and user,
+        # we use sub-tests in this test.
+        #
+
+        dn = f"cn={user},cn=users,{self.base_dn}"
+        self.discardSetupMessages(dn)
+
+        session_id = self.get_session()
+        service_description = self.get_service_description()
+        self.assertEqual(service_description, "LDAP")
+        transactions_seen = set()
+
+        with self.subTest("initial setup"):
+            self.ldb.modify_ldif(
+                f"dn: {dn}\n"
+                "changetype: modify\n"
+                f"add: {attribute}\n"
+                f"{attribute}: {values[0]}\n")
             messages = self.waitForMessages(1, dn=dn)
             print("Received %d messages" % len(messages))
             self.assertEqual(1, len(messages))
             audit = messages[0]["passwordChange"]
             self.assertEqual(EVT_ID_DIRECTORY_OBJECT_CHANGE, audit["eventId"])
-            self.assertEqual("Public key change", audit["action"])
+            self.assertEqual("Auth info change", audit["action"])
             self.assertEqual(dn, audit["dn"])
             self.assertIn(self.remoteAddress, audit["remoteAddress"])
             self.assertEqual(session_id, audit["sessionId"])
@@ -428,14 +568,14 @@ class AuditLogPassChangeTests(AuditLogTestBase):
             self.ldb.modify_ldif(
                 f"dn: {dn}\n"
                 "changetype: modify\n"
-                "replace: msDS-keyCredentialLink\n"
-                f"msDS-keyCredentialLink: {kcls[1]}\n")
+                f"replace: {attribute}\n"
+                f"{attribute}: {values[1]}\n")
             messages = self.waitForMessages(1, dn=dn)
             print("Received %d messages" % len(messages))
             self.assertEqual(1, len(messages))
             audit = messages[0]["passwordChange"]
             self.assertEqual(EVT_ID_DIRECTORY_OBJECT_CHANGE, audit["eventId"])
-            self.assertEqual("Public key change", audit["action"])
+            self.assertEqual("Auth info change", audit["action"])
             self.assertEqual(dn, audit["dn"])
             self.assertIn(self.remoteAddress, audit["remoteAddress"])
             self.assertTrue(self.is_guid(audit["sessionId"]))
@@ -446,16 +586,16 @@ class AuditLogPassChangeTests(AuditLogTestBase):
             self.ldb.modify_ldif(
                 f"dn: {dn}\n"
                 "changetype: modify\n"
-                "delete: msDS-keyCredentialLink\n"
-                f"msDS-keyCredentialLink: {kcls[1]}\n"
-                "add: msDS-keyCredentialLink\n"
-                f"msDS-keyCredentialLink: {kcls[2]}\n")
+                f"delete: {attribute}\n"
+                f"{attribute}: {values[1]}\n"
+                f"add: {attribute}\n"
+                f"{attribute}: {values[2]}\n")
             messages = self.waitForMessages(1, dn=dn)
             print("Received %d messages" % len(messages))
             self.assertEqual(1, len(messages))
             audit = messages[0]["passwordChange"]
             self.assertEqual(EVT_ID_DIRECTORY_OBJECT_CHANGE, audit["eventId"])
-            self.assertEqual("Public key change", audit["action"])


-- 
Samba Shared Repository

Reply via email to