[SCM] Samba Shared Repository - branch v4-18-test updated

Jule Anger janger at samba.org
Tue Oct 10 15:28:01 UTC 2023


The branch, v4-18-test has been updated
       via  b9b0d8bc0f0 VERSION: Bump version up to Samba 4.18.9...
       via  d709251a392 Merge branch 'v4-18-stable' into v4-18-test
       via  3dc0412a79f Merge tag 'samba-4.18.8' into v4-18-stable
       via  f1c0d4f1feb VERSION: Disable GIT_SNAPSHOT for the 4.18.8 release.
       via  0bf0250e358 WHATSNEW: Add release notes for Samba 4.18.8.
       via  eb6f2d92e8a CVE-2023-42670 s3-rpc_server: Remove cross-check with "samba" EPM lookup
       via  4eba269b1ba CVE-2023-42670 s3-rpc_server: Strictly refuse to start RPC servers in conflict with AD DC
       via  2ef556473bd CVE-2023-42669 s3-rpc_server: Disable rpcecho for consistency with the AD DC
       via  e652fbe8525 CVE-2023-42669 s4-rpc_server: Disable rpcecho server by default
       via  4b3da3a97d1 CVE-2023-4154: Unimplement the original DirSync behaviour without LDAP_DIRSYNC_OBJECT_SECURITY
       via  e691257c618 CVE-2023-4154 dsdb/tests: Extend attribute read DirSync tests
       via  9d249db44c7 CVE-2023-4154 dsdb/tests: Add test for SEARCH_FLAG_RODC_ATTRIBUTE behaviour
       via  ebc2796a029 CVE-2023-4154 dsdb/tests: Speed up DirSync test by only checking positive matches once
       via  3e7bdcd0e48 CVE-2023-4154 dsdb/tests: Check that secret attributes are not visible with DirSync ever.
       via  23031057e86 CVE-2023-4154 dsdb/tests: Force the test attribute to be not-confidential at the start
       via  87ff4f57bf7 CVE-2023-4154 dsdb/tests: Use self.addCleanup() and delete_force()
       via  8ad21108f88 CVE-2023-4154 dsdb/tests: Do not run SimpleDirsyncTests twice
       via  570e892a0e8 CVE-2023-4154 libcli/security: add security_descriptor_[s|d]acl_insert() helpers
       via  7ebf51dd8b5 CVE-2023-4154 libcli/security: prepare security_descriptor_acl_add() to place the ace at a position
       via  da9bdf36c35 CVE-2023-4154 replace: add ARRAY_INSERT_ELEMENT() helper
       via  217b30b05e2 CVE-2023-4154 python/samba/ndr: add ndr_deepcopy() helper
       via  8a2b11fda30 CVE-2023-4154 py_security: allow idx argument to descriptor.[s|d]acl_add()
       via  8ebcfe5599c CVE-2023-4154 python:sd_utils: add dacl_{prepend,append,delete}_aces() helpers
       via  b65b141ed75 CVE-2023-4154 python:sd_utils: introduce update_aces_in_dacl() helper
       via  704fadfb60e CVE-2023-4154 s4-dsdb: Remove DSDB_ACL_CHECKS_DIRSYNC_FLAG
       via  e8df1a60866 CVE-2023-4154 s4:dsdb:tests: Fix code spelling
       via  5ca0ee6f111 CVE-2023-4154 s4:dsdb:tests: Refactor confidential attributes test
       via  582f4f2e844 CVE-2023-4154 dsdb: Remove remaining references to DC_MODE_RETURN_NONE and DC_MODE_RETURN_ALL
       via  3c432b14469 CVE-2023-4091: smbd: use open_access_mask for access check in open_file()
       via  bfe8e10bf3b CVE-2023-4091: smbtorture: test overwrite dispositions on read-only file
       via  3e64edae781 CVE-2023-3961:s3: smbd: Remove the SMB_ASSERT() that crashes on bad pipenames.
       via  d1a26b4f46b CVE-2023-3961:s3:torture: Add test SMB2-INVALID-PIPENAME to show we allow bad pipenames with unix separators through to the UNIX domain socket code.
       via  84b5d3640f7 CVE-2023-3961:s3:smbd: Catch any incoming pipe path that could exit socket_dir.
       via  2576c0275dc VERSION: Bump version up to Samba 4.18.8...
       via  85475a0cb20 CVE-2023-42670 s3-rpc_server: Remove cross-check with "samba" EPM lookup
       via  614d9c22357 CVE-2023-42670 s3-rpc_server: Strictly refuse to start RPC servers in conflict with AD DC
       via  2e2a9feecff CVE-2023-42669 s3-rpc_server: Disable rpcecho for consistency with the AD DC
       via  808a46b1877 CVE-2023-42669 s4-rpc_server: Disable rpcecho server by default
       via  23c5300d099 CVE-2023-4154: Unimplement the original DirSync behaviour without LDAP_DIRSYNC_OBJECT_SECURITY
       via  6925e6b6051 CVE-2023-4154 dsdb/tests: Extend attribute read DirSync tests
       via  84dcfc3b40f CVE-2023-4154 dsdb/tests: Add test for SEARCH_FLAG_RODC_ATTRIBUTE behaviour
       via  9499526ba8e CVE-2023-4154 dsdb/tests: Speed up DirSync test by only checking positive matches once
       via  5dc5062ba28 CVE-2023-4154 dsdb/tests: Check that secret attributes are not visible with DirSync ever.
       via  029c47f2a40 CVE-2023-4154 dsdb/tests: Force the test attribute to be not-confidential at the start
       via  ee3ac4fb9af CVE-2023-4154 dsdb/tests: Use self.addCleanup() and delete_force()
       via  2cff332edb5 CVE-2023-4154 dsdb/tests: Do not run SimpleDirsyncTests twice
       via  9dade2ab67f CVE-2023-4154 libcli/security: add security_descriptor_[s|d]acl_insert() helpers
       via  939f243222e CVE-2023-4154 libcli/security: prepare security_descriptor_acl_add() to place the ace at a position
       via  c896afcaf2f CVE-2023-4154 replace: add ARRAY_INSERT_ELEMENT() helper
       via  571d3bf48ee CVE-2023-4154 python/samba/ndr: add ndr_deepcopy() helper
       via  b56849aa64b CVE-2023-4154 py_security: allow idx argument to descriptor.[s|d]acl_add()
       via  f29255affdf CVE-2023-4154 python:sd_utils: add dacl_{prepend,append,delete}_aces() helpers
       via  39707a06cc5 CVE-2023-4154 python:sd_utils: introduce update_aces_in_dacl() helper
       via  563b7a56672 CVE-2023-4154 s4-dsdb: Remove DSDB_ACL_CHECKS_DIRSYNC_FLAG
       via  13eac83bc6e CVE-2023-4154 s4:dsdb:tests: Fix code spelling
       via  d1e0ee0ba7f CVE-2023-4154 s4:dsdb:tests: Refactor confidential attributes test
       via  fbc27662712 CVE-2023-4154 dsdb: Remove remaining references to DC_MODE_RETURN_NONE and DC_MODE_RETURN_ALL
       via  53c9e1c9d3b CVE-2023-4091: smbd: use open_access_mask for access check in open_file()
       via  ae5c0e1914a CVE-2023-4091: smbtorture: test overwrite dispositions on read-only file
       via  682a9a808b4 CVE-2023-3961:s3: smbd: Remove the SMB_ASSERT() that crashes on bad pipenames.
       via  fbb9cf8d118 CVE-2023-3961:s3:torture: Add test SMB2-INVALID-PIPENAME to show we allow bad pipenames with unix separators through to the UNIX domain socket code.
       via  1688b6d3dd4 CVE-2023-3961:s3:smbd: Catch any incoming pipe path that could exit socket_dir.
      from  ca1b7c185ed VERSION: Bump version up to Samba 4.18.8...

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-18-test


- Log -----------------------------------------------------------------
commit b9b0d8bc0f013296f4ccd2962d537b88976eb9b7
Author: Jule Anger <janger at samba.org>
Date:   Tue Oct 10 17:25:29 2023 +0200

    VERSION: Bump version up to Samba 4.18.9...
    
    Signed-off-by: Jule Anger <janger at samba.org>

commit d709251a39245ee8c2c23d946ccac6bf411b10c5
Merge: ca1b7c185ed 3dc0412a79f
Author: Jule Anger <janger at samba.org>
Date:   Tue Oct 10 17:23:50 2023 +0200

    Merge branch 'v4-18-stable' into v4-18-test

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

Summary of changes:
 VERSION                                            |   2 +-
 WHATSNEW.txt                                       |  81 +++-
 .../smbdotconf/protocol/dcerpcendpointservers.xml  |   2 +-
 lib/param/loadparm.c                               |   2 +-
 lib/replace/replace.h                              |  15 +
 libcli/security/security_descriptor.c              |  55 ++-
 libcli/security/security_descriptor.h              |   6 +
 python/samba/ndr.py                                |  19 +
 python/samba/sd_utils.py                           | 153 ++++++-
 selftest/knownfail                                 |   2 +-
 selftest/knownfail.d/dirsync                       |  13 +
 selftest/target/Samba4.pm                          |   2 +-
 source3/param/loadparm.c                           |   2 +-
 source3/rpc_client/local_np.c                      |  13 +
 source3/rpc_server/rpc_host.c                      | 154 +------
 source3/rpc_server/rpcd_classic.c                  |  45 +-
 source3/rpc_server/rpcd_epmapper.c                 |  33 +-
 source3/rpc_server/rpcd_lsad.c                     |  21 +
 source3/rpc_server/rpcd_rpcecho.c                  |  33 +-
 source3/rpc_server/wscript_build                   |   1 +
 source3/selftest/tests.py                          |  14 +
 source3/smbd/open.c                                |   4 +-
 source3/torture/proto.h                            |   1 +
 source3/torture/test_smb2.c                        | 107 +++++
 source3/torture/torture.c                          |   4 +
 source4/dsdb/samdb/ldb_modules/dirsync.c           |  33 +-
 source4/dsdb/samdb/samdb.h                         |   1 -
 source4/dsdb/tests/python/acl.py                   |  12 +-
 .../dsdb/tests/python/ad_dc_search_performance.py  |   2 +-
 source4/dsdb/tests/python/confidential_attr.py     | 212 ++++-----
 source4/dsdb/tests/python/dirsync.py               | 473 ++++++++++++++++++---
 source4/dsdb/tests/python/ldap.py                  |  14 +-
 source4/dsdb/tests/python/ldap_modify_order.py     |   4 +-
 source4/dsdb/tests/python/ldap_syntaxes.py         |   4 +-
 source4/dsdb/tests/python/login_basics.py          |   2 +-
 source4/dsdb/tests/python/password_settings.py     |   4 +-
 source4/dsdb/tests/python/passwords.py             |   4 +-
 source4/dsdb/tests/python/sam.py                   |   2 +-
 source4/dsdb/tests/python/sec_descriptor.py        |  14 +-
 source4/dsdb/tests/python/token_group.py           |   4 +-
 source4/dsdb/tests/python/user_account_control.py  |   2 +-
 source4/librpc/ndr/py_security.c                   |  10 +-
 source4/rpc_server/wscript_build                   |   3 +-
 source4/torture/smb2/acls.c                        | 143 +++++++
 44 files changed, 1285 insertions(+), 442 deletions(-)
 create mode 100644 selftest/knownfail.d/dirsync


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index c3dd706bbb3..37824cd31dc 100644
--- a/VERSION
+++ b/VERSION
@@ -25,7 +25,7 @@
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=18
-SAMBA_VERSION_RELEASE=8
+SAMBA_VERSION_RELEASE=9
 
 ########################################################
 # If a official release has a serious bug              #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index fd11954058e..53fe4eafa72 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,81 @@
+                   ==============================
+                   Release Notes for Samba 4.18.8
+                          October 10, 2023
+                   ==============================
+
+
+This is a security release in order to address the following defects:
+
+
+o CVE-2023-3961:  Unsanitized pipe names allow SMB clients to connect as root to
+                  existing unix domain sockets on the file system.
+                  https://www.samba.org/samba/security/CVE-2023-3961.html
+
+o CVE-2023-4091:  SMB client can truncate files to 0 bytes by opening files with
+                  OVERWRITE disposition when using the acl_xattr Samba VFS
+                  module with the smb.conf setting
+                  "acl_xattr:ignore system acls = yes"
+                  https://www.samba.org/samba/security/CVE-2023-4091.html
+
+o CVE-2023-4154:  An RODC and a user with the GET_CHANGES right can view all
+                  attributes, including secrets and passwords.  Additionally,
+                  the access check fails open on error conditions.
+                  https://www.samba.org/samba/security/CVE-2023-4154.html
+
+o CVE-2023-42669: Calls to the rpcecho server on the AD DC can request that the
+                  server block for a user-defined amount of time, denying
+                  service.
+                  https://www.samba.org/samba/security/CVE-2023-42669.html
+
+o CVE-2023-42670: Samba can be made to start multiple incompatible RPC
+                  listeners, disrupting service on the AD DC.
+                  https://www.samba.org/samba/security/CVE-2023-42670.html
+
+
+Changes since 4.18.7
+--------------------
+
+o  Jeremy Allison <jra at samba.org>
+   * BUG 15422: CVE-2023-3961.
+
+o  Andrew Bartlett <abartlet at samba.org>
+   * BUG 15424: CVE-2023-4154.
+   * BUG 15473: CVE-2023-42670.
+   * BUG 15474: CVE-2023-42669.
+
+o  Ralph Boehme <slow at samba.org>
+   * BUG 15439: CVE-2023-4091.
+
+o  Stefan Metzmacher <metze at samba.org>
+   * BUG 15424: CVE-2023-4154.
+
+o  Joseph Sutton <josephsutton at catalyst.net.nz>
+   * BUG 15424: CVE-2023-4154.
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical:matrix.org matrix room, or
+#samba-technical IRC channel on irc.libera.chat.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored.  All bug reports should
+be filed under the Samba 4.1 and newer product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
                    ==============================
                    Release Notes for Samba 4.18.7
                          September 27, 2023
@@ -72,8 +150,7 @@ database (https://bugzilla.samba.org/).
 ======================================================================
 
 
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
                    ==============================
                    Release Notes for Samba 4.18.6
                           August 16, 2023
diff --git a/docs-xml/smbdotconf/protocol/dcerpcendpointservers.xml b/docs-xml/smbdotconf/protocol/dcerpcendpointservers.xml
index 8a217cc7f11..c6642b795fd 100644
--- a/docs-xml/smbdotconf/protocol/dcerpcendpointservers.xml
+++ b/docs-xml/smbdotconf/protocol/dcerpcendpointservers.xml
@@ -6,6 +6,6 @@
 	<para>Specifies which DCE/RPC endpoint servers should be run.</para>
 </description>
 
-<value type="default">epmapper, wkssvc, rpcecho, samr, netlogon, lsarpc, drsuapi, dssetup, unixinfo, browser, eventlog6, backupkey, dnsserver</value>
+<value type="default">epmapper, wkssvc, samr, netlogon, lsarpc, drsuapi, dssetup, unixinfo, browser, eventlog6, backupkey, dnsserver</value>
 <value type="example">rpcecho</value>
 </samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 16cb0d47f31..83b05260e09 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2730,7 +2730,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 	lpcfg_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
 	lpcfg_do_global_parameter(lp_ctx, "max connections", "0");
 
-	lpcfg_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper wkssvc rpcecho samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver");
+	lpcfg_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper wkssvc samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver");
 	lpcfg_do_global_parameter(lp_ctx, "server services", "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns");
 	lpcfg_do_global_parameter(lp_ctx, "kccsrv:samba_kcc", "true");
 	/* the winbind method for domain controllers is for both RODC
diff --git a/lib/replace/replace.h b/lib/replace/replace.h
index b15f3d14c8a..25e6e145eeb 100644
--- a/lib/replace/replace.h
+++ b/lib/replace/replace.h
@@ -885,6 +885,21 @@ typedef unsigned long long ptrdiff_t ;
 #define ARRAY_DEL_ELEMENT(a,i,n) \
 if((i)<((n)-1)){memmove(&((a)[(i)]),&((a)[(i)+1]),(sizeof(*(a))*((n)-(i)-1)));}
 
+/**
+ * Insert an array element by moving the rest one up
+ *
+ */
+#define ARRAY_INSERT_ELEMENT(__array,__old_last_idx,__new_elem,__new_idx) do { \
+	if ((__new_idx) < (__old_last_idx)) { \
+		const void *__src = &((__array)[(__new_idx)]); \
+		void *__dst = &((__array)[(__new_idx)+1]); \
+		size_t __num = (__old_last_idx)-(__new_idx); \
+		size_t __len = sizeof(*(__array)) * __num; \
+		memmove(__dst, __src, __len); \
+	} \
+	(__array)[(__new_idx)] = (__new_elem); \
+} while(0)
+
 /**
  * Pointer difference macro
  */
diff --git a/libcli/security/security_descriptor.c b/libcli/security/security_descriptor.c
index 23d436dbaeb..db998bbf816 100644
--- a/libcli/security/security_descriptor.c
+++ b/libcli/security/security_descriptor.c
@@ -268,9 +268,11 @@ NTSTATUS security_descriptor_for_client(TALLOC_CTX *mem_ctx,
 
 static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
 					    bool add_to_sacl,
-					    const struct security_ace *ace)
+					    const struct security_ace *ace,
+					    ssize_t _idx)
 {
 	struct security_acl *acl = NULL;
+	ssize_t idx;
 
 	if (add_to_sacl) {
 		acl = sd->sacl;
@@ -289,15 +291,28 @@ static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
 		acl->aces     = NULL;
 	}
 
+	if (_idx < 0) {
+		idx = (acl->num_aces + 1) + _idx;
+	} else {
+		idx = _idx;
+	}
+
+	if (idx < 0) {
+		return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
+	} else if (idx > acl->num_aces) {
+		return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
+	}
+
 	acl->aces = talloc_realloc(acl, acl->aces,
 				   struct security_ace, acl->num_aces+1);
 	if (acl->aces == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	acl->aces[acl->num_aces] = *ace;
+	ARRAY_INSERT_ELEMENT(acl->aces, acl->num_aces, *ace, idx);
+	acl->num_aces++;
 
-	switch (acl->aces[acl->num_aces].type) {
+	switch (acl->aces[idx].type) {
 	case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
 	case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
 	case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
@@ -308,8 +323,6 @@ static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
 		break;
 	}
 
-	acl->num_aces++;
-
 	if (add_to_sacl) {
 		sd->sacl = acl;
 		sd->type |= SEC_DESC_SACL_PRESENT;
@@ -328,7 +341,21 @@ static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
 NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd,
 				      const struct security_ace *ace)
 {
-	return security_descriptor_acl_add(sd, true, ace);
+	return security_descriptor_acl_add(sd, true, ace, -1);
+}
+
+/*
+  insert an ACE at a given index to the SACL of a security_descriptor
+
+  idx can be negative, which means it's related to the new size from the
+  end, so -1 means the ace is appended at the end.
+*/
+
+NTSTATUS security_descriptor_sacl_insert(struct security_descriptor *sd,
+					 const struct security_ace *ace,
+					 ssize_t idx)
+{
+	return security_descriptor_acl_add(sd, true, ace, idx);
 }
 
 /*
@@ -338,7 +365,21 @@ NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd,
 NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd,
 				      const struct security_ace *ace)
 {
-	return security_descriptor_acl_add(sd, false, ace);
+	return security_descriptor_acl_add(sd, false, ace, -1);
+}
+
+/*
+  insert an ACE at a given index to the DACL of a security_descriptor
+
+  idx can be negative, which means it's related to the new size from the
+  end, so -1 means the ace is appended at the end.
+*/
+
+NTSTATUS security_descriptor_dacl_insert(struct security_descriptor *sd,
+					 const struct security_ace *ace,
+					 ssize_t idx)
+{
+	return security_descriptor_acl_add(sd, false, ace, idx);
 }
 
 /*
diff --git a/libcli/security/security_descriptor.h b/libcli/security/security_descriptor.h
index 46545321d15..354bc17e925 100644
--- a/libcli/security/security_descriptor.h
+++ b/libcli/security/security_descriptor.h
@@ -33,8 +33,14 @@ NTSTATUS security_descriptor_for_client(TALLOC_CTX *mem_ctx,
 					struct security_descriptor **_csd);
 NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd,
 				      const struct security_ace *ace);
+NTSTATUS security_descriptor_sacl_insert(struct security_descriptor *sd,
+					 const struct security_ace *ace,
+					 ssize_t idx);
 NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd,
 				      const struct security_ace *ace);
+NTSTATUS security_descriptor_dacl_insert(struct security_descriptor *sd,
+					 const struct security_ace *ace,
+					 ssize_t idx);
 NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd,
 				      const struct dom_sid *trustee);
 NTSTATUS security_descriptor_sacl_del(struct security_descriptor *sd,
diff --git a/python/samba/ndr.py b/python/samba/ndr.py
index 35b2414e8ae..8369abfb2d0 100644
--- a/python/samba/ndr.py
+++ b/python/samba/ndr.py
@@ -56,6 +56,25 @@ def ndr_print(object):
     return ndr_print()
 
 
+def ndr_deepcopy(object):
+    """Create a deep copy of a NDR object, using pack/unpack
+
+    :param object: Object to copy
+    :return: The object copy
+    """
+    ndr_pack = getattr(object, "__ndr_pack__", None)
+    if ndr_pack is None:
+        raise TypeError("%r is not a NDR object" % object)
+    data = ndr_pack()
+    cls = type(object)
+    copy = cls()
+    ndr_unpack = getattr(copy, "__ndr_unpack__", None)
+    if ndr_unpack is None:
+        raise TypeError("%r is not a NDR object" % copy)
+    ndr_unpack(data, allow_remaining=False)
+    return copy
+
+
 def ndr_pack_in(object, bigendian=False, ndr64=False):
     """Pack the input of an NDR function object.
 
diff --git a/python/samba/sd_utils.py b/python/samba/sd_utils.py
index 26e80ee2f4a..462bbfbaf18 100644
--- a/python/samba/sd_utils.py
+++ b/python/samba/sd_utils.py
@@ -21,8 +21,11 @@
 import samba
 from ldb import Message, MessageElement, Dn
 from ldb import FLAG_MOD_REPLACE, SCOPE_BASE
-from samba.ndr import ndr_pack, ndr_unpack
+from samba.ndr import ndr_pack, ndr_unpack, ndr_deepcopy
 from samba.dcerpc import security
+from samba.ntstatus import (
+    NT_STATUS_OBJECT_NAME_NOT_FOUND,
+)
 
 
 class SDUtils(object):
@@ -63,19 +66,145 @@ class SDUtils(object):
         res = self.ldb.search(object_dn)
         return ndr_unpack(security.dom_sid, res[0]["objectSid"][0])
 
+    def update_aces_in_dacl(self, dn, del_aces=None, add_aces=None,
+                            sddl_attr=None, controls=None):
+        if del_aces is None:
+            del_aces=[]
+        if add_aces is None:
+            add_aces=[]
+
+        def ace_from_sddl(ace_sddl):
+            ace_sd = security.descriptor.from_sddl("D:" + ace_sddl, self.domain_sid)
+            assert(len(ace_sd.dacl.aces)==1)
+            return ace_sd.dacl.aces[0]
+
+        if sddl_attr is None:
+            if controls is None:
+                controls=["sd_flags:1:%d" % security.SECINFO_DACL]
+            sd = self.read_sd_on_dn(dn, controls=controls)
+            if not sd.type & security.SEC_DESC_DACL_PROTECTED:
+                # if the DACL is not protected remove all
+                # inherited aces, as they will be re-inherited
+                # on the server, we need a ndr_deepcopy in order
+                # to avoid reference problems while deleting
+                # the aces while looping over them
+                dacl_copy = ndr_deepcopy(sd.dacl)
+                for ace in dacl_copy.aces:
+                    if ace.flags & security.SEC_ACE_FLAG_INHERITED_ACE:
+                        try:
+                            sd.dacl_del_ace(ace)
+                        except samba.NTSTATUSError as err:
+                            if err.args[0] != NT_STATUS_OBJECT_NAME_NOT_FOUND:
+                                raise err
+                            # dacl_del_ace may remove more than
+                            # one ace, so we may not find it anymore
+                            pass
+        else:
+            if controls is None:
+                controls=[]
+            res = self.ldb.search(dn, SCOPE_BASE, None,
+                                  [sddl_attr], controls=controls)
+            old_sddl = str(res[0][sddl_attr][0])
+            sd = security.descriptor.from_sddl(old_sddl, self.domain_sid)
+
+        num_changes = 0
+        del_ignored = []
+        add_ignored = []
+        inherited_ignored = []
+
+        for ace in del_aces:
+            if isinstance(ace, str):
+                ace = ace_from_sddl(ace)
+            assert(isinstance(ace, security.ace))
+
+            if ace.flags & security.SEC_ACE_FLAG_INHERITED_ACE:
+                inherited_ignored.append(ace)
+                continue
+
+            if ace not in sd.dacl.aces:
+                del_ignored.append(ace)
+                continue
+
+            sd.dacl_del_ace(ace)
+            num_changes += 1
+
+        for ace in add_aces:
+            add_idx = -1
+            if isinstance(ace, dict):
+                if "idx" in ace:
+                    add_idx = ace["idx"]
+                ace = ace["ace"]
+            if isinstance(ace, str):
+                ace = ace_from_sddl(ace)
+            assert(isinstance(ace, security.ace))
+
+            if ace.flags & security.SEC_ACE_FLAG_INHERITED_ACE:
+                inherited_ignored.append(ace)
+                continue
+
+            if ace in sd.dacl.aces:
+                add_ignored.append(ace)
+                continue
+
+            sd.dacl_add(ace, add_idx)
+            num_changes += 1
+
+        if num_changes == 0:
+            return del_ignored, add_ignored, inherited_ignored
+
+        if sddl_attr is None:
+            self.modify_sd_on_dn(dn, sd, controls=controls)
+        else:
+            new_sddl = sd.as_sddl(self.domain_sid)
+            m = Message()
+            m.dn = dn
+            m[sddl_attr] = MessageElement(new_sddl.encode('ascii'),
+                                          FLAG_MOD_REPLACE,
+                                          sddl_attr)
+            self.ldb.modify(m, controls=controls)
+
+        return del_ignored, add_ignored, inherited_ignored
+
+    def dacl_prepend_aces(self, object_dn, aces, controls=None):
+        """Prepend an ACE (or more) to an objects security descriptor
+        """
+        ace_sd = security.descriptor.from_sddl("D:" + aces, self.domain_sid)
+        add_aces = []
+        add_idx = 0
+        for ace in ace_sd.dacl.aces:
+            add_aces.append({"idx": add_idx, "ace": ace})
+            add_idx += 1
+        _,ai,ii = self.update_aces_in_dacl(object_dn, add_aces=add_aces,
+                                           controls=controls)
+        return ai, ii
+
     def dacl_add_ace(self, object_dn, ace):
-        """Add an ACE to an objects security descriptor
+        """Add an ACE (or more) to an objects security descriptor
         """
-        desc = self.read_sd_on_dn(object_dn, ["show_deleted:1"])
-        desc_sddl = desc.as_sddl(self.domain_sid)
-        if ace in desc_sddl:
-            return
-        if desc_sddl.find("(") >= 0:
-            desc_sddl = (desc_sddl[:desc_sddl.index("(")] + ace +
-                         desc_sddl[desc_sddl.index("("):])
-        else:
-            desc_sddl = desc_sddl + ace
-        self.modify_sd_on_dn(object_dn, desc_sddl, ["show_deleted:1"])
+        _,_ = self.dacl_prepend_aces(object_dn, ace,
+                                     controls=["show_deleted:1"])
+
+    def dacl_append_aces(self, object_dn, aces, controls=None):
+        """Append an ACE (or more) to an objects security descriptor
+        """
+        ace_sd = security.descriptor.from_sddl("D:" + aces, self.domain_sid)
+        add_aces = []
+        for ace in ace_sd.dacl.aces:
+            add_aces.append(ace)
+        _,ai,ii = self.update_aces_in_dacl(object_dn, add_aces=add_aces,
+                                           controls=controls)
+        return ai, ii
+
+    def dacl_delete_aces(self, object_dn, aces, controls=None):
+        """Delete an ACE (or more) to an objects security descriptor
+        """
+        del_sd = security.descriptor.from_sddl("D:" + aces, self.domain_sid)
+        del_aces = []
+        for ace in del_sd.dacl.aces:
+            del_aces.append(ace)
+        di,_,ii = self.update_aces_in_dacl(object_dn, del_aces=del_aces,
+                                           controls=controls)
+        return di, ii
 
     def get_sd_as_sddl(self, object_dn, controls=[]):
         """Return object nTSecutiryDescriptor in SDDL format
diff --git a/selftest/knownfail b/selftest/knownfail
index c6e0a242ecb..f1768a270b5 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -151,7 +151,7 @@
 ^samba4.smb2.acls.*.inheritflags
 ^samba4.smb2.acls.*.owner
 ^samba4.smb2.acls.*.ACCESSBASED
-^samba4.ldap.dirsync.python.ad_dc_ntvfs..__main__.ExtendedDirsyncTests.test_dirsync_deleted_items
+^samba4.ldap.dirsync.python.ad_dc_ntvfs..__main__.SimpleDirsyncTests.test_dirsync_deleted_items_OBJECT_SECURITY
 #^samba4.ldap.dirsync.python.ad_dc_ntvfs..__main__.ExtendedDirsyncTests.*
 ^samba4.libsmbclient.opendir.(NT1|SMB3).opendir # This requires netbios browsing
 ^samba4.rpc.drsuapi.*.drsuapi.DsGetDomainControllerInfo\(.*\)$
diff --git a/selftest/knownfail.d/dirsync b/selftest/knownfail.d/dirsync


-- 
Samba Shared Repository



More information about the samba-cvs mailing list