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