The branch, master has been updated
       via  51b7bc61c6f samba-tool: Fix invalid escape sequences
       via  10a68f57086 python: Fix code spelling
       via  c7cfdcd299b python: Make use of OID comparator constants
       via  07b4266e5fa tests/krb5: Correct comment
       via  aef85083337 s4:dsdb: Check dsdb_module_search() return value
       via  78c8336fcb1 samba-tool: Fix code spelling
       via  726a93ff612 s4:torture:drs: Pass through unused parameters
       via  4d15d208848 python:join: Add missing word
       via  12cfa75da93 s4:dsdb: Remove trailing whitespace
       via  9214555cc47 s4:dsdb: Fix code spelling
       via  6d94e4d95e1 s3:smbd: Don’t free the caller’s buffer (CID 1610056)
       via  ad094f083f7 s3:winbindd: Allow ‘ptype’ to be NULL (CID 1615194)
       via  4157a3e0069 s3:winbindd: Fix NULL dereference (CID 1615195)
       via  460e65790ca lib:compression: Update my name
       via  3bbf00cd309 mailmap: Associate my identity with my old email 
addresses
       via  ff3be2892b1 python:tests: Permit expected_count to be zero
       via  fda6aef10f0 python:tests: Decode stdout for greater readability
       via  b7e7a070509 python:tests: Decode stdout and stderr for greater 
readability
       via  5e0b53542b7 python: Fix logging call
       via  260424a171a s4:dsdb: Remove unused code
       via  865e37b4a18 s4:dsdb: Remove trailing whitespace
       via  be22a49f5de samba-tool: Filter confidential attributes out of 
backups made with the ‘--no-secrets’ option
       via  b6fd9e22117 drs_utils: Split process_chunk() out into its own class
       via  50fb8fc795a python:tests: Test that secret keys and confidential 
attributes are not included in a --no-secrets backup
       via  cf848e35d1d drs_utils: Check for presence of more_flags attribute 
directly
       via  df719a28f17 s4:dsdb: Use PyLong_FromUnsignedLong() for unsigned 
values
       via  3eb65f1a6bd python:samdb: Add 
get_searchFlags_from_lDAPDisplayName() method
       via  4443abc74b7 python:samdb: Add 
get_must_contain_from_lDAPDisplayName() method
       via  3cc42b090ec python:samdb: Add get_lDAPDisplayName_by_governsID_id() 
method
       via  e40e7fc6bf0 python3: Remove Python 2–only call to decode()
       via  44548de57a3 python: Make set of seen GUIDs a local variable
       via  8fc5c78ff64 python: Correct comment
       via  6fa5aff8466 python: Simplify GetNCChanges call setup
       via  ef11923c6bd python: Remove unused ‘more_flags’ parameter
       via  51e14680b96 python: Tidy up formatting
       via  b9e9b5371b3 python:join: Remove unnecessary local variable
       via  25c4ee2337c drs_utils: Make loop exit condition explicit
       via  b0828fc3b06 drs_utils: Remove unnecessary qualification
      from  3ae8053f6bc s3:winbind: Delegate normalize_name_map to the idmap 
child

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


- Log -----------------------------------------------------------------
commit 51b7bc61c6fd04f6e3b33efe4ac300ba8a6658d5
Author: Jennifer Sutton <[email protected]>
Date:   Thu Jan 30 14:27:10 2025 +1300

    samba-tool: Fix invalid escape sequences
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>
    
    Autobuild-User(master): Jo Sutton <[email protected]>
    Autobuild-Date(master): Mon May 26 03:44:44 UTC 2025 on atb-devel-224

commit 10a68f570866f186a7610641267fdc98ad887d69
Author: Jennifer Sutton <[email protected]>
Date:   Fri Feb 14 16:21:45 2025 +1300

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

commit c7cfdcd299b13710e579e8b2ce7c62baca7623dc
Author: Jennifer Sutton <[email protected]>
Date:   Tue Jan 14 12:06:07 2025 +1300

    python: Make use of OID comparator constants
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 07b4266e5faa8029c51852f551e19a75b1b61c4a
Author: Jennifer Sutton <[email protected]>
Date:   Sat Nov 23 13:25:34 2024 +1300

    tests/krb5: Correct comment
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit aef850833377b910ba2a67446dbbb96a4d86ab46
Author: Jennifer Sutton <[email protected]>
Date:   Fri Jan 24 13:18:00 2025 +1300

    s4:dsdb: Check dsdb_module_search() return value
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 78c8336fcb15035d80d01911d712acda9c3966ac
Author: Jennifer Sutton <[email protected]>
Date:   Fri Aug 30 10:01:01 2024 +1200

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

commit 726a93ff612a14fb67725b64c00d105edd789e04
Author: Jennifer Sutton <[email protected]>
Date:   Tue Aug 13 12:00:05 2024 +1200

    s4:torture:drs: Pass through unused parameters
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 4d15d20884854b2f31d537ba4727c989a32abb1e
Author: Jennifer Sutton <[email protected]>
Date:   Thu Aug 15 14:57:11 2024 +1200

    python:join: Add missing word
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 12cfa75da9335439cea42fe28adb7063d0262e59
Author: Jennifer Sutton <[email protected]>
Date:   Tue Aug 6 13:53:13 2024 +1200

    s4:dsdb: Remove trailing whitespace
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 9214555cc47cb26430c329dab1b3b6e94fac3b1b
Author: Jennifer Sutton <[email protected]>
Date:   Tue Aug 6 11:51:21 2024 +1200

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

commit 6d94e4d95e153c9f692a0d044b00dfd8b45e3a7c
Author: Jennifer Sutton <[email protected]>
Date:   Fri Aug 2 14:42:10 2024 +1200

    s3:smbd: Don’t free the caller’s buffer (CID 1610056)
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit ad094f083f74eab9d394c14b86c0f83b0902d04e
Author: Jennifer Sutton <[email protected]>
Date:   Fri Aug 2 14:31:43 2024 +1200

    s3:winbindd: Allow ‘ptype’ to be NULL (CID 1615194)
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 4157a3e00696fc4d76c64208131d275d96324d81
Author: Jennifer Sutton <[email protected]>
Date:   Fri Aug 2 14:29:32 2024 +1200

    s3:winbindd: Fix NULL dereference (CID 1615195)
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 460e65790ca13fbd81f7bacad5db63f48876c9ab
Author: Jennifer Sutton <[email protected]>
Date:   Thu Aug 29 15:41:53 2024 +1200

    lib:compression: Update my name
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 3bbf00cd3095abc2801ac6105191d5794c054108
Author: Jennifer Sutton <[email protected]>
Date:   Mon Apr 15 15:10:37 2024 +1200

    mailmap: Associate my identity with my old email addresses
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit ff3be2892b152f2217337e88fd446404c2be87c2
Author: Jennifer Sutton <[email protected]>
Date:   Fri Aug 2 15:55:00 2024 +1200

    python:tests: Permit expected_count to be zero
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit fda6aef10f02e2bf4efde65af4259b864ceee095
Author: Jennifer Sutton <[email protected]>
Date:   Tue Aug 6 14:05:38 2024 +1200

    python:tests: Decode stdout for greater readability
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit b7e7a0705094bdd1fe6fb13a52b2a34169bb00f7
Author: Jennifer Sutton <[email protected]>
Date:   Tue Aug 6 13:51:00 2024 +1200

    python:tests: Decode stdout and stderr for greater readability
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 5e0b53542b7441214078389d5f9d5de553098988
Author: Jennifer Sutton <[email protected]>
Date:   Fri Apr 11 12:34:14 2025 +1200

    python: Fix logging call
    
    ERROR(<class AttributeError>): uncaught exception - RootLogger object has 
no attribute notice
      File "/samba/bin/python/samba/netcmd/__init__.py", line 387, in _run
        return self.run(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/samba/bin/python/samba/netcmd/domain/backup.py", line 698, in run
        logger.notice("back-up has no sysvol data")
        ^^^^^^^^^^^^^
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 260424a171a35403b578a5afce1d8826ebc5c476
Author: Jennifer Sutton <[email protected]>
Date:   Tue Feb 4 19:18:52 2025 +1300

    s4:dsdb: Remove unused code
    
    This code has not served a purpose since 2010, when commit
    6a2f7fe04c2c658e59fba01f7346303676b121b3 removed
    dsdb_class_from_drsuapi().
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 865e37b4a18d670e8287b1bf913ba1e21b3dc681
Author: Jennifer Sutton <[email protected]>
Date:   Tue Feb 4 19:18:28 2025 +1300

    s4:dsdb: Remove trailing whitespace
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit be22a49f5deb24c8e24ea60368d8a9cfdf827a1b
Author: Jennifer Sutton <[email protected]>
Date:   Tue Jan 28 14:15:02 2025 +1300

    samba-tool: Filter confidential attributes out of backups made with the 
‘--no-secrets’ option
    
    Without this change, ‘lab domains’ and backups intended not to contain
    secrets will still contain confidential information, such as BitLocker
    recovery data and KDS root keys. Add a new class that filters these
    attributes out.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit b6fd9e22117266aeff12797d09c18376f0cc55f9
Author: Jennifer Sutton <[email protected]>
Date:   Tue Jul 23 17:24:28 2024 +1200

    drs_utils: Split process_chunk() out into its own class
    
    This makes it easier to add classes with new functionality without
    having to figure out how to slot them into a linear class hierarchy.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 50fb8fc795a2824195fbf9c756ab2d07e927ae7d
Author: Jennifer Sutton <[email protected]>
Date:   Tue Jan 14 14:19:46 2025 +1300

    python:tests: Test that secret keys and confidential attributes are not 
included in a --no-secrets backup
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit cf848e35d1ddfbcc45325992459da059f968fe3a
Author: Jennifer Sutton <[email protected]>
Date:   Tue Jan 14 12:08:26 2025 +1300

    drs_utils: Check for presence of more_flags attribute directly
    
    This more directly indicates what we are trying to achieve.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit df719a28f179e4da6f9de58304bc6348e001632e
Author: Jennifer Sutton <[email protected]>
Date:   Wed May 21 13:08:56 2025 +1200

    s4:dsdb: Use PyLong_FromUnsignedLong() for unsigned values
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 3eb65f1a6bdd5c44f919882e6842b3872608aa5c
Author: Jennifer Sutton <[email protected]>
Date:   Tue Aug 6 13:54:56 2024 +1200

    python:samdb: Add get_searchFlags_from_lDAPDisplayName() method
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 4443abc74b7623dabc113b7f34ee7d4e2db3bedb
Author: Jennifer Sutton <[email protected]>
Date:   Wed Feb 5 16:07:49 2025 +1300

    python:samdb: Add get_must_contain_from_lDAPDisplayName() method
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 3cc42b090ec716c55335604193c1a5fa1b27750a
Author: Jennifer Sutton <[email protected]>
Date:   Tue Feb 4 18:50:32 2025 +1300

    python:samdb: Add get_lDAPDisplayName_by_governsID_id() method
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit e40e7fc6bf0f3dab9f4942741dac6ce188f8535c
Author: Jennifer Sutton <[email protected]>
Date:   Tue Sep 3 12:32:14 2024 +1200

    python3: Remove Python 2–only call to decode()
    
    AttributeError: 'str' object has no attribute 'decode'
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 44548de57a3f2932bb6546945cdb6f2212d3c4c2
Author: Jennifer Sutton <[email protected]>
Date:   Tue Sep 3 11:38:44 2024 +1200

    python: Make set of seen GUIDs a local variable
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 8fc5c78ff64ec1357b6d288e6069b0c9c78915df
Author: Jennifer Sutton <[email protected]>
Date:   Tue Sep 3 11:38:13 2024 +1200

    python: Correct comment
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 6fa5aff8466c227cd8a30de1b7ed034da2cf1dd7
Author: Jennifer Sutton <[email protected]>
Date:   Thu Aug 29 13:37:05 2024 +1200

    python: Simplify GetNCChanges call setup
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit ef11923c6bdad535af7268dcdb0efce563b9c6e1
Author: Jennifer Sutton <[email protected]>
Date:   Thu Aug 29 13:32:25 2024 +1200

    python: Remove unused ‘more_flags’ parameter
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 51e14680b96c4b6597717eea309bca3d53989436
Author: Jennifer Sutton <[email protected]>
Date:   Thu Aug 29 13:30:49 2024 +1200

    python: Tidy up formatting
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit b9e9b5371b3daeef6eb53932fc8d334483b9d4a9
Author: Jennifer Sutton <[email protected]>
Date:   Tue Aug 6 16:18:16 2024 +1200

    python:join: Remove unnecessary local variable
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit 25c4ee2337cfc0c5ccf72cb7e47ad3f190b48df5
Author: Jennifer Sutton <[email protected]>
Date:   Tue Aug 6 15:38:57 2024 +1200

    drs_utils: Make loop exit condition explicit
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

commit b0828fc3b06aae5649b9c3ea1d442cfd22ad6c33
Author: Jennifer Sutton <[email protected]>
Date:   Tue Aug 6 15:07:44 2024 +1200

    drs_utils: Remove unnecessary qualification
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15852
    
    Signed-off-by: Jennifer Sutton <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>

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

Summary of changes:
 .mailmap                                         |   3 +-
 lib/compression/lzxpress_huffman.c               |   2 +-
 python/samba/drs_utils.py                        | 235 ++++++++++++++++-------
 python/samba/join.py                             |  35 ++--
 python/samba/netcmd/domain/backup.py             |   2 +-
 python/samba/netcmd/domain/kds/root_key.py       |   2 +-
 python/samba/ntacls.py                           |   2 +-
 python/samba/samdb.py                            |  14 +-
 python/samba/schema.py                           |   4 +-
 python/samba/tests/__init__.py                   |  10 +-
 python/samba/tests/domain_backup.py              | 146 +++++++++++++-
 python/samba/tests/krb5/conditional_ace_tests.py |   2 +-
 python/samba/tests/samba_tool/join_member.py     |   2 +-
 source3/smbd/smb1_process.c                      |   4 +-
 source3/winbindd/winbindd_msrpc.c                |   2 +-
 source3/winbindd/winbindd_samr.c                 |   4 +-
 source4/dsdb/pydsdb.c                            | 186 ++++++++++++++++--
 source4/dsdb/samdb/ldb_modules/acl.c             |   4 +
 source4/dsdb/schema/schema.h                     |  10 -
 source4/dsdb/schema/schema_inferiors.c           | 100 +---------
 source4/dsdb/tests/python/confidential_attr.py   |   2 +-
 source4/torture/drs/python/drs_base.py           |   3 +-
 22 files changed, 552 insertions(+), 222 deletions(-)


Changeset truncated at 500 lines:

diff --git a/.mailmap b/.mailmap
index a797c26ff4f..4e7e1d11e89 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1 +1,2 @@
-Jo Sutton <[email protected]> <[email protected]>
+Jennifer Sutton <[email protected]> <[email protected]>
+Jennifer Sutton <[email protected]> <[email protected]>
diff --git a/lib/compression/lzxpress_huffman.c 
b/lib/compression/lzxpress_huffman.c
index 63b5ffae8ec..8a1421d42ad 100644
--- a/lib/compression/lzxpress_huffman.c
+++ b/lib/compression/lzxpress_huffman.c
@@ -4,7 +4,7 @@
  * Copyright © Catalyst IT 2022
  *
  * Written by Douglas Bagnall <[email protected]>
- *        and Jo Sutton       <[email protected]>
+ *        and Jennifer Sutton <[email protected]>
  *
  *  ** NOTE! The following LGPL license applies to this file.
  *  ** It does NOT imply that all of Samba is released under the LGPL
diff --git a/python/samba/drs_utils.py b/python/samba/drs_utils.py
index 06e6928e308..61c0576726f 100644
--- a/python/samba/drs_utils.py
+++ b/python/samba/drs_utils.py
@@ -23,12 +23,13 @@ from samba.ndr import ndr_unpack
 from samba import dsdb
 from samba import werror
 from samba import WERRORError
-import samba
+
 import ldb
 from samba.dcerpc.drsuapi import (DRSUAPI_ATTID_name,
                                   DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8,
                                   DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10)
 import re
+from abc import ABCMeta, abstractmethod
 
 
 class drsException(Exception):
@@ -158,12 +159,12 @@ def drs_get_rodc_partial_attribute_set(samdb):
         ldap_display_name = str(r["lDAPDisplayName"][0])
         if "systemFlags" in r:
             system_flags      = r["systemFlags"][0]
-            if (int(system_flags) & (samba.dsdb.DS_FLAG_ATTR_NOT_REPLICATED |
-                                     samba.dsdb.DS_FLAG_ATTR_IS_CONSTRUCTED)):
+            if (int(system_flags) & (dsdb.DS_FLAG_ATTR_NOT_REPLICATED |
+                                     dsdb.DS_FLAG_ATTR_IS_CONSTRUCTED)):
                 continue
         if "searchFlags" in r:
             search_flags = r["searchFlags"][0]
-            if (int(search_flags) & samba.dsdb.SEARCH_FLAG_RODC_ATTRIBUTE):
+            if int(search_flags) & dsdb.SEARCH_FLAG_RODC_ATTRIBUTE:
                 continue
         attid = samdb.get_attid_from_lDAPDisplayName(ldap_display_name)
         attids.append(int(attid))
@@ -171,7 +172,7 @@ def drs_get_rodc_partial_attribute_set(samdb):
     # the attids do need to be sorted, or windows doesn't return
     # all the attributes we need
     attids.sort()
-    partial_attribute_set.attids         = attids
+    partial_attribute_set.attids = attids
     partial_attribute_set.num_attids = len(attids)
     return partial_attribute_set
 
@@ -186,30 +187,60 @@ def drs_copy_highwater_mark(hwm, new_hwm):
     hwm.highest_usn = new_hwm.highest_usn
 
 
-class drs_Replicate(object):
-    """DRS replication calls"""
+class drs_ReplicatorImplBase(metaclass=ABCMeta):
+    @abstractmethod
+    def process_chunk(
+        self, samdb, level, ctr, schema, req_level, req, first_chunk,
+    ) -> None: ...
+
+    @abstractmethod
+    def supports_ext(self, ext) -> bool: ...
+
+    @abstractmethod
+    def get_nc_changes(self, req_level, req) -> bool: ...
 
+
+class drs_ReplicatorImpl(drs_ReplicatorImplBase):
     def __init__(self, binding_string, lp, creds, samdb, invocation_id):
         self.drs = drsuapi.drsuapi(binding_string, lp, creds)
-        (self.drs_handle, self.supports_ext) = drs_DsBind(self.drs)
+        (self.drs_handle, self._supports_ext) = drs_DsBind(self.drs)
         self.net = Net(creds=creds, lp=lp)
-        self.samdb = samdb
         if not isinstance(invocation_id, misc.GUID):
             raise RuntimeError("Must supply GUID for invocation_id")
         if invocation_id == misc.GUID("00000000-0000-0000-0000-000000000000"):
             raise RuntimeError("Must not set GUID 
00000000-0000-0000-0000-000000000000 as invocation_id")
-        self.replication_state = self.net.replicate_init(self.samdb, lp, 
self.drs, invocation_id)
+        self.replication_state = self.net.replicate_init(samdb, lp, self.drs, 
invocation_id)
+
+    def process_chunk(self, samdb, level, ctr, schema, req_level, req, 
first_chunk):
+        """Processes a single chunk of received replication data"""
+        # pass the replication into the py_net.c python bindings for processing
+        self.net.replicate_chunk(self.replication_state, level, ctr,
+                                 schema=schema, req_level=req_level, req=req)
+
+    def supports_ext(self, ext) -> bool:
+        return self._supports_ext & ext
+
+    def get_nc_changes(self, req_level, req) -> bool:
+        return self.drs.DsGetNCChanges(self.drs_handle, req_level, req)
+
+
+class drs_Replicator:
+    """DRS replication implementation"""
+
+    def __init__(self, repl, samdb):
+        self.samdb = samdb
+        self.repl = repl
         self.more_flags = 0
 
-    def _should_retry_with_get_tgt(self, error_code, req):
+    @staticmethod
+    def _should_retry_with_get_tgt(error_code, req):
 
         # If the error indicates we fail to resolve a target object for a
         # linked attribute, then we should retry the request with GET_TGT
         # (if we support it and haven't already tried that)
-        supports_ext = self.supports_ext
 
         return (error_code == werror.WERR_DS_DRA_RECYCLED_TARGET and
-                supports_ext & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10 and
+                hasattr(req, "more_flags") and
                 (req.more_flags & drsuapi.DRSUAPI_DRS_GET_TGT) == 0)
 
     @staticmethod
@@ -224,23 +255,20 @@ class drs_Replicate(object):
 
 
     def _calculate_missing_anc_locally(self, ctr):
-        self.guids_seen = set()
+        guids_seen = set()
 
-        # walk objects in ctr, add to guid_seen as we see them
+        # walk objects in ctr, add to guids_seen as we see them
         # note if an object doesn't have a parent
 
         object_to_check = ctr.first_object
 
-        while True:
-            if object_to_check is None:
-                break
-
-            self.guids_seen.add(str(object_to_check.object.identifier.guid))
+        while object_to_check is not None:
+            guids_seen.add(str(object_to_check.object.identifier.guid))
 
             if object_to_check.parent_object_guid is not None \
                and object_to_check.parent_object_guid \
                != misc.GUID("00000000-0000-0000-0000-000000000000") \
-               and str(object_to_check.parent_object_guid) not in 
self.guids_seen:
+               and str(object_to_check.parent_object_guid) not in guids_seen:
                 obj_dn = ldb.Dn(self.samdb, 
object_to_check.object.identifier.dn)
                 parent_dn = obj_dn.parent()
                 print(f"Object {parent_dn} with "
@@ -250,25 +278,22 @@ class drs_Replicate(object):
             object_to_check = object_to_check.next_object
 
 
-    def process_chunk(self, level, ctr, schema, req_level, req, first_chunk):
-        """Processes a single chunk of received replication data"""
-        # pass the replication into the py_net.c python bindings for processing
-        self.net.replicate_chunk(self.replication_state, level, ctr,
-                                 schema=schema, req_level=req_level, req=req)
-
     def replicate(self, dn, source_dsa_invocation_id, destination_dsa_guid,
                   schema=False, exop=drsuapi.DRSUAPI_EXOP_NONE, rodc=False,
-                  replica_flags=None, full_sync=True, sync_forced=False, 
more_flags=0):
+                  replica_flags=None, full_sync=True, sync_forced=False):
         """replicate a single DN"""
 
         # setup for a GetNCChanges call
-        if self.supports_ext & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10:
-            req = drsuapi.DsGetNCChangesRequest10()
-            req.more_flags = (more_flags | self.more_flags)
+        if self.repl.supports_ext(DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10):
             req_level = 10
-        else:
+            req = drsuapi.DsGetNCChangesRequest10()
+            req.more_flags = self.more_flags
+        elif self.repl.supports_ext(DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8):
             req_level = 8
             req = drsuapi.DsGetNCChangesRequest8()
+        else:
+            req_level = 5
+            req = drsuapi.DsGetNCChangesRequest5()
 
         req.destination_dsa_guid = destination_dsa_guid
         req.source_dsa_invocation_id = source_dsa_invocation_id
@@ -322,8 +347,7 @@ class drs_Replicate(object):
                                  drsuapi.DRSUAPI_DRS_NEVER_SYNCED |
                                  drsuapi.DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP)
             if rodc:
-                req.replica_flags |= (
-                     drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING)
+                req.replica_flags |= 
drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING
             else:
                 req.replica_flags |= drsuapi.DRSUAPI_DRS_WRIT_REP
 
@@ -334,37 +358,26 @@ class drs_Replicate(object):
         req.max_ndr_size = 402116
         req.extended_op = exop
         req.fsmo_info = 0
-        req.partial_attribute_set = None
-        req.partial_attribute_set_ex = None
-        req.mapping_ctr.num_mappings = 0
-        req.mapping_ctr.mappings = None
 
-        if not schema and rodc:
+        if hasattr(req, "partial_attribute_set") and not schema and rodc:
             req.partial_attribute_set = 
drs_get_rodc_partial_attribute_set(self.samdb)
 
-        if not self.supports_ext & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8:
-            req_level = 5
-            req5 = drsuapi.DsGetNCChangesRequest5()
-            for a in dir(req5):
-                if a[0] != '_':
-                    setattr(req5, a, getattr(req, a))
-            req = req5
-
         num_objects = 0
         num_links = 0
         first_chunk = True
 
         while True:
-            (level, ctr) = self.drs.DsGetNCChanges(self.drs_handle, req_level, 
req)
+            (level, ctr) = self.repl.get_nc_changes(req_level, req)
             if ctr.first_object is None and ctr.object_count != 0:
                 raise RuntimeError("DsGetNCChanges: NULL first_object with 
object_count=%u" % (ctr.object_count))
 
             try:
-                self.process_chunk(level, ctr, schema, req_level, req, 
first_chunk)
+                self.repl.process_chunk(
+                    self.samdb, level, ctr, schema, req_level, req, first_chunk
+                )
             except WERRORError as e:
                 # Check if retrying with the GET_TGT flag set might resolve 
this error
                 if self._should_retry_with_get_tgt(e.args[0], req):
-
                     print("Missing target object - retrying with DRS_GET_TGT")
                     req.more_flags |= drsuapi.DRSUAPI_DRS_GET_TGT
 
@@ -373,8 +386,7 @@ class drs_Replicate(object):
                     first_chunk = True
                     continue
 
-                if self._should_calculate_missing_anc_locally(e.args[0],
-                                                              req):
+                if self._should_calculate_missing_anc_locally(e.args[0], req):
                     print("Missing parent object - calculating missing objects 
locally")
 
                     self._calculate_missing_anc_locally(ctr)
@@ -398,14 +410,20 @@ class drs_Replicate(object):
         return (num_objects, num_links)
 
 
+class drs_Replicate(drs_Replicator):
+    """DRS replication calls"""
+
+    def __init__(self, binding_string, lp, creds, samdb, invocation_id):
+        repl = drs_ReplicatorImpl(binding_string, lp, creds, samdb, 
invocation_id)
+        super().__init__(repl, samdb)
+
 # Handles the special case of creating a new clone of a DB, while also renaming
 # the entire DB's objects on the way through
-class drs_ReplicateRenamer(drs_Replicate):
+class drs_ReplicateRenamer(drs_ReplicatorImplBase):
     """Uses DRS replication to rename the entire DB"""
 
-    def __init__(self, binding_string, lp, creds, samdb, invocation_id,
-                 old_base_dn, new_base_dn):
-        super().__init__(binding_string, lp, creds, samdb, invocation_id)
+    def __init__(self, repl, old_base_dn, new_base_dn):
+        self.repl = repl
         self.old_base_dn = old_base_dn
         self.new_base_dn = new_base_dn
 
@@ -419,27 +437,27 @@ class drs_ReplicateRenamer(drs_Replicate):
         """Uses string substitution to replace the base DN"""
         return re.sub('%s$' % self.old_base_dn, self.new_base_dn, dn_str)
 
-    def update_name_attr(self, base_obj):
+    @staticmethod
+    def update_name_attr(base_obj, samdb):
         """Updates the 'name' attribute for the base DN object"""
         for attr in base_obj.attribute_ctr.attributes:
             if attr.attid == DRSUAPI_ATTID_name:
-                base_dn = ldb.Dn(self.samdb, base_obj.identifier.dn)
+                base_dn = ldb.Dn(samdb, base_obj.identifier.dn)
                 new_name = base_dn.get_rdn_value()
-                attr.value_ctr.values[0].blob = new_name.encode('utf-16-le')
+                attr.value_ctr.values[0].blob = new_name.encode("utf-16-le")
 
-    def rename_top_level_object(self, first_obj):
+    def rename_top_level_object(self, first_obj, samdb):
         """Renames the first/top-level object in a partition"""
         old_dn = first_obj.identifier.dn
         first_obj.identifier.dn = self.rename_dn(first_obj.identifier.dn)
-        print("Renaming partition %s --> %s" % (old_dn,
-                                                first_obj.identifier.dn))
+        print("Renaming partition %s --> %s" % (old_dn, 
first_obj.identifier.dn))
 
         # we also need to fix up the 'name' attribute for the base DN,
         # otherwise the RDNs won't match
         if first_obj.identifier.dn == self.new_base_dn:
-            self.update_name_attr(first_obj)
+            self.update_name_attr(first_obj, samdb)
 
-    def process_chunk(self, level, ctr, schema, req_level, req, first_chunk):
+    def process_chunk(self, samdb, level, ctr, schema, req_level, req, 
first_chunk):
         """Processes a single chunk of received replication data"""
 
         # we need to rename the NC in every chunk - this gets used in searches
@@ -450,7 +468,92 @@ class drs_ReplicateRenamer(drs_Replicate):
         # rename the first object in each partition. This will cause every
         # subsequent object in the partition to be renamed as a side-effect
         if first_chunk and ctr.object_count != 0:
-            self.rename_top_level_object(ctr.first_object.object)
+            self.rename_top_level_object(ctr.first_object.object, samdb)
 
         # then do the normal repl processing to apply this chunk to our DB
-        super().process_chunk(level, ctr, schema, req_level, req, first_chunk)
+        self.repl.process_chunk(samdb, level, ctr, schema, req_level, req, 
first_chunk)
+
+    def supports_ext(self, ext) -> bool:
+        return self.repl.supports_ext(ext)
+
+    def get_nc_changes(self, req_level, req) -> bool:
+        return self.repl.get_nc_changes(req_level, req)
+
+
+class drs_SecretFilter(drs_ReplicatorImplBase):
+    # Objects of these types contain sensitive attributes that cannot simply be
+    # filtered out, because they are required attributes for their class
+    # (mustContain and systemMustContain). Instead of filtering out those
+    # sensitive attributes, we filter out the entire object.
+    object_classes_to_filter_out = {
+        "msKds-ProvRootKey",
+        "msFVE-RecoveryInformation",
+        "msTPM-InformationObject",
+    }
+
+    def __init__(self, repl):
+        self.repl = repl
+
+    def process_chunk(self, samdb, level, ctr, schema, req_level, req, 
first_chunk):
+        """Processes a single chunk of received replication data"""
+
+        def get_searchFlags(attr: drsuapi.DsReplicaAttribute) -> int:
+            attr_name = samdb.get_lDAPDisplayName_by_attid(attr.attid)
+            return samdb.get_searchFlags_from_lDAPDisplayName(attr_name)
+
+        def is_confidential(attr: drsuapi.DsReplicaAttribute) -> bool:
+            return get_searchFlags(attr) & dsdb.SEARCH_FLAG_CONFIDENTIAL
+
+        prev_obj = ctr
+        obj = ctr.first_object
+        first = True
+        while obj is not None:
+            object_class = None
+            must_contain = set()
+            for attr in obj.object.attribute_ctr.attributes:
+                if (
+                    attr.attid == drsuapi.DRSUAPI_ATTID_objectClass
+                    and attr.value_ctr.num_values
+                ):
+                    object_class = samdb.get_lDAPDisplayName_by_governsID_id(
+                        int.from_bytes(
+                            attr.value_ctr.values[0].blob, byteorder="little"
+                        )
+                    )
+                    must_contain = samdb.get_must_contain_from_lDAPDisplayName(
+                        object_class
+                    )
+                    break
+
+            if object_class in self.object_classes_to_filter_out:
+                obj = obj.next_object
+                if first:
+                    prev_obj.first_object = obj
+                else:
+                    prev_obj.next_object = obj
+
+                ctr.object_count -= 1
+                continue
+
+            for attr in filter(is_confidential, 
obj.object.attribute_ctr.attributes):
+                attr_name = samdb.get_lDAPDisplayName_by_attid(attr.attid)
+                if attr_name in must_contain:
+                    print(
+                        f"Warning: {attr_name} is a required attribute of 
{object_class} "
+                        f"— not filtering with --no-secrets"
+                    )
+                else:
+                    attr.value_ctr.num_values = 0
+
+            prev_obj = obj
+            obj = obj.next_object
+            first = False
+
+        # then do the normal repl processing to apply this chunk to our DB
+        self.repl.process_chunk(samdb, level, ctr, schema, req_level, req, 
first_chunk)
+
+    def supports_ext(self, ext) -> bool:
+        return self.repl.supports_ext(ext)
+
+    def get_nc_changes(self, req_level, req) -> bool:
+        return self.repl.get_nc_changes(req_level, req)
diff --git a/python/samba/join.py b/python/samba/join.py
index 3ea188682dc..717fbb35f52 100644
--- a/python/samba/join.py
+++ b/python/samba/join.py
@@ -66,7 +66,8 @@ class DCJoinContext(object):
                  promote_existing=False, plaintext_secrets=False,
                  backend_store=None,
                  backend_store_size=None,
-                 forced_local_samdb=None):
+                 forced_local_samdb=None,
+                 filter_secrets=False):
 
         ctx.logger = logger
         ctx.creds = creds
@@ -77,6 +78,7 @@ class DCJoinContext(object):
         ctx.plaintext_secrets = plaintext_secrets
         ctx.backend_store = backend_store
         ctx.backend_store_size = backend_store_size
+        ctx.filter_secrets = filter_secrets
 
         ctx.promote_existing = promote_existing
         ctx.promote_from_dn = None
@@ -954,9 +956,16 @@ class DCJoinContext(object):
 
     def create_replicator(ctx, repl_creds, binding_options):
         """Creates a new DRS object for managing replications"""
-        return drs_utils.drs_Replicate(
-                "ncacn_ip_tcp:%s[%s]" % (ctx.server, binding_options),
-                ctx.lp, repl_creds, ctx.local_samdb, ctx.invocation_id)
+        repl = drs_utils.drs_ReplicatorImpl(
+            f"ncacn_ip_tcp:{ctx.server}[{binding_options}]",
+            ctx.lp,
+            repl_creds,
+            ctx.local_samdb,
+            ctx.invocation_id,
+        )
+        if ctx.filter_secrets:
+            repl = drs_utils.drs_SecretFilter(repl)
+        return repl
 
     def join_replicate(ctx):
         """Replicate the SAM."""
@@ -989,6 +998,7 @@ class DCJoinContext(object):
                 binding_options += ",print"
 
             repl = ctx.create_replicator(repl_creds, binding_options)
+            repl = drs_utils.drs_Replicator(repl, ctx.local_samdb)
 
             repl.replicate(ctx.schema_dn, source_dsa_invocation_id,
                            destination_dsa_guid, schema=True, rodc=ctx.RODC,
@@ -1296,7 +1306,7 @@ class DCJoinContext(object):
                                                    | security.SECINFO_GROUP)])
 
         ctx.logger.info("All other DNS records (like _ldap SRV records) " +
-                        "will be created samba_dnsupdate on first startup")
+                        "will be created by samba_dnsupdate on first startup")
 
     def join_replicate_new_dns_records(ctx):
         for nc in (ctx.domaindns_zone, ctx.forestdns_zone):
@@ -1389,7 +1399,7 @@ class DCJoinContext(object):
         objectAttr = lsa.ObjectAttribute()
         objectAttr.sec_qos = lsa.QosInfo()
 
-        pol_handle = lsaconn.OpenPolicy2(''.decode('utf-8'),
+        pol_handle = lsaconn.OpenPolicy2('',
                                          objectAttr, 
security.SEC_FLAG_MAXIMUM_ALLOWED)
 
         info = lsa.TrustDomainInfoInfoEx()
@@ -1658,7 +1668,8 @@ class DCCloneContext(DCJoinContext):
                          targetdir=targetdir, domain=domain,
                          dns_backend=dns_backend,
                          backend_store=backend_store,
-                         backend_store_size=backend_store_size)
+                         backend_store_size=backend_store_size,
+                         filter_secrets=not include_secrets)
 
         # As we don't want to create or delete these DNs, we set them to None
         ctx.server_dn = None
@@ -1726,11 +1737,8 @@ class DCCloneAndRenameContext(DCCloneContext):
         # We want to rename all the domain objects, and the simplest way to do
         # this is during replication. This is because the base DN of the top-
         # level replicated object will flow through to all the objects below it
-        binding_str = "ncacn_ip_tcp:%s[%s]" % (ctx.server, binding_options)
-        return drs_utils.drs_ReplicateRenamer(binding_str, ctx.lp, repl_creds,


-- 
Samba Shared Repository


Reply via email to