[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Tue Sep 27 17:47:02 UTC 2022
The branch, master has been updated
via d89400b6201 samba-tool dsacl: Add additional unit test for delete subcommand
via 50eb747c14e python security: Add unit tests for comparing ACEs and exporting as SDDL
via 42b88992bd1 samba-tool dsacl: Add get and delete subcommand to samba-tool dsacl man section
via dff58819d02 samba-tool dsacl: Create common superclass for dsacl commands
via c9902b0574f samba-tool dsacl: Create helper functions to remove code duplication
via 492d3316d88 samba-tool dsacl: Add unit tests for delete subcommand
via 1bd08133067 samba-tool dsacl: Add subcommand to delete ACEs
via 80cf4c86594 librpc ndr/py_security: Export sddl_encode_ace to python
via b0f494c1086 librpc ndr/py_security: Export security_ace_equal as richcmp to python
via 84a54d2fa2b librpc ndr/py_security: Export ACE deletion functions to python
via 6501e4f00e5 libcli security/sddl: Make sddl_encode_ace visible
via 1a9aac53e8e libcli security_descriptor: Compare object type and inherited object type when comparing ACEs
via 7efe673fbdc libcli security_descriptor: Add function to delete a given ace from a security descriptor
from b600b0c8d96 s3: smbd: Fix memory leak in smbd_server_connection_terminate_done().
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit d89400b6201013ffdf06dc5480f59d9a41eb2f2a
Author: Christian Merten <christian at merten.dev>
Date: Mon Sep 19 23:28:07 2022 +0200
samba-tool dsacl: Add additional unit test for delete subcommand
Added one more unit test to the delete subcommand. This test adds
two ACEs, deletes one of them and checks if the right one was deleted
and the other one stayed the same.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Tue Sep 27 17:46:22 UTC 2022 on sn-devel-184
commit 50eb747c14ebf5cbcb3c80bd2a5e4e82580c0d5b
Author: Christian Merten <christian at merten.dev>
Date: Mon Sep 19 23:22:04 2022 +0200
python security: Add unit tests for comparing ACEs and exporting as SDDL
Added two unit tests for the python functions to compare ACEs and to
export an ACE as SDDL.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 42b88992bd1a1f5ed890c1f73a187bffad963388
Author: Christian Merten <christian at merten.dev>
Date: Thu Sep 15 10:38:22 2022 +0200
samba-tool dsacl: Add get and delete subcommand to samba-tool dsacl man section
Added get and delete subcommands to the man section of samba-tool dsacl.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit dff58819d02ef32c62292982ec6844ce634bebdd
Author: Christian Merten <christian at merten.dev>
Date: Thu Sep 15 10:20:04 2022 +0200
samba-tool dsacl: Create common superclass for dsacl commands
Created a base class for dsacl commands providing print_acl and some fixed command line options to
reduce code duplication.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit c9902b0574fab9b3e10f440898d4980383dfe3c7
Author: Christian Merten <christian at merten.dev>
Date: Thu Sep 15 10:08:47 2022 +0200
samba-tool dsacl: Create helper functions to remove code duplication
Make multiple methods of dsacl command classes separate helper functions to avoid code duplication.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 492d3316d888b2ded61d949adc405d9a13fa7d10
Author: Christian Merten <christian at merten.dev>
Date: Wed Sep 14 01:33:18 2022 +0200
samba-tool dsacl: Add unit tests for delete subcommand
Two unit tests for the new samba-tool dsacl delete command have been added.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 1bd08133067c50b6125addb2f94d293261a192fa
Author: Christian Merten <christian at merten.dev>
Date: Wed Sep 14 01:29:34 2022 +0200
samba-tool dsacl: Add subcommand to delete ACEs
A new subcommand has been added to samba-tool dsacl to delete one or multiple ACEs from the security
descriptor of an object.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 80cf4c86594ca1210d23712daadecb6deb829066
Author: Christian Merten <christian at merten.dev>
Date: Mon Sep 19 23:12:59 2022 +0200
librpc ndr/py_security: Export sddl_encode_ace to python
Added sddl_encode_ace as new method as_sddl to security_ace class in python.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit b0f494c10860535c907376432a9b1678f4038d7f
Author: Christian Merten <christian at merten.dev>
Date: Mon Sep 19 23:11:37 2022 +0200
librpc ndr/py_security: Export security_ace_equal as richcmp to python
Patched security_ace with a richcmp function given by
security_ace_equal.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 84a54d2fa2b1590fdb4e2ea986ded9c39a82cf78
Author: Christian Merten <christian at merten.dev>
Date: Mon Sep 19 23:01:34 2022 +0200
librpc ndr/py_security: Export ACE deletion functions to python
Exported security_descriptor_sacl_del and security_descriptor_dacl_del as new methods of the
security descriptor class to python.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 6501e4f00e5a36debdf44add1335818a791552f0
Author: Christian Merten <christian at merten.dev>
Date: Mon Sep 19 22:53:45 2022 +0200
libcli security/sddl: Make sddl_encode_ace visible
Removed static flag from sddl_encode_ace and added to headers.
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
Signed-off-by: Christian Merten <christian at merten.dev>
commit 1a9aac53e8ee081cf6d2028de759563120619554
Author: Christian Merten <christian at merten.dev>
Date: Mon Sep 19 22:50:58 2022 +0200
libcli security_descriptor: Compare object type and inherited object type when comparing ACEs
Fixed security_ace_equal returning true, despite differing object type, by checking (inherited) object type
of both ACEs is equal.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 7efe673fbdcd27ddd23f36281c5f5338681a68fe
Author: Christian Merten <christian at merten.dev>
Date: Mon Sep 19 22:47:10 2022 +0200
libcli security_descriptor: Add function to delete a given ace from a security descriptor
Two functions have been added to delete a given ace from the SACL or the DACL of a security descriptor.
Signed-off-by: Christian Merten <christian at merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra at samba.org>
-----------------------------------------------------------------------
Summary of changes:
docs-xml/manpages/samba-tool.8.xml | 10 ++
libcli/security/sddl.c | 4 +-
libcli/security/sddl.h | 3 +-
libcli/security/security_descriptor.c | 101 +++++++++++++++++++
libcli/security/security_descriptor.h | 4 +
python/samba/netcmd/dsacl.py | 171 ++++++++++++++++++---------------
python/samba/tests/samba_tool/dsacl.py | 88 +++++++++++++++++
python/samba/tests/security.py | 35 +++++++
source4/librpc/ndr/py_security.c | 131 ++++++++++++++++++++++++-
9 files changed, 467 insertions(+), 80 deletions(-)
Changeset truncated at 500 lines:
diff --git a/docs-xml/manpages/samba-tool.8.xml b/docs-xml/manpages/samba-tool.8.xml
index 10ffa8a4d5f..60f3a5f06ed 100644
--- a/docs-xml/manpages/samba-tool.8.xml
+++ b/docs-xml/manpages/samba-tool.8.xml
@@ -764,6 +764,16 @@
<para>Administer DS ACLs</para>
</refsect2>
+<refsect3>
+ <title>dsacl delete</title>
+ <para>Delete an access list entry on a directory object.</para>
+</refsect3>
+
+<refsect3>
+ <title>dsacl get</title>
+ <para>Print access list on a directory object.</para>
+</refsect3>
+
<refsect3>
<title>dsacl set</title>
<para>Modify access list on a directory object.</para>
diff --git a/libcli/security/sddl.c b/libcli/security/sddl.c
index 5bb65ddfd6b..e6c3c94f215 100644
--- a/libcli/security/sddl.c
+++ b/libcli/security/sddl.c
@@ -583,8 +583,8 @@ static char *sddl_encode_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
/*
encode an ACE in SDDL format
*/
-static char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace,
- const struct dom_sid *domain_sid)
+char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace,
+ const struct dom_sid *domain_sid)
{
char *sddl = NULL;
TALLOC_CTX *tmp_ctx;
diff --git a/libcli/security/sddl.h b/libcli/security/sddl.h
index e8bc25a619c..6720ec6453e 100644
--- a/libcli/security/sddl.h
+++ b/libcli/security/sddl.h
@@ -27,6 +27,7 @@ struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl,
const struct dom_sid *domain_sid);
char *sddl_encode(TALLOC_CTX *mem_ctx, const struct security_descriptor *sd,
const struct dom_sid *domain_sid);
-
+char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace,
+ const struct dom_sid *domain_sid);
#endif /* __SDDL_H__ */
diff --git a/libcli/security/security_descriptor.c b/libcli/security/security_descriptor.c
index ba142016389..23d436dbaeb 100644
--- a/libcli/security/security_descriptor.c
+++ b/libcli/security/security_descriptor.c
@@ -21,6 +21,7 @@
#include "includes.h"
#include "libcli/security/security.h"
+#include "librpc/ndr/libndr.h"
/*
return a blank security descriptor (no owners, dacl or sacl)
@@ -419,6 +420,98 @@ NTSTATUS security_descriptor_sacl_del(struct security_descriptor *sd,
return security_descriptor_acl_del(sd, true, trustee);
}
+/*
+ delete the given ACE in the SACL or DACL of a security_descriptor
+*/
+static NTSTATUS security_descriptor_acl_del_ace(struct security_descriptor *sd,
+ bool sacl_del,
+ const struct security_ace *ace)
+{
+ uint32_t i;
+ bool found = false;
+ struct security_acl *acl = NULL;
+
+ if (sacl_del) {
+ acl = sd->sacl;
+ } else {
+ acl = sd->dacl;
+ }
+
+ if (acl == NULL) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ for (i=0;i<acl->num_aces;i++) {
+ if (security_ace_equal(ace, &acl->aces[i])) {
+ ARRAY_DEL_ELEMENT(acl->aces, i, acl->num_aces);
+ acl->num_aces--;
+ if (acl->num_aces == 0) {
+ acl->aces = NULL;
+ }
+ found = true;
+ i--;
+ }
+ }
+
+ if (!found) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ acl->revision = SECURITY_ACL_REVISION_NT4;
+
+ for (i=0;i<acl->num_aces;i++) {
+ switch (acl->aces[i].type) {
+ case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
+ case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
+ case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
+ case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
+ acl->revision = SECURITY_ACL_REVISION_ADS;
+ return NT_STATUS_OK;
+ default:
+ break; /* only for the switch statement */
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS security_descriptor_dacl_del_ace(struct security_descriptor *sd,
+ const struct security_ace *ace)
+{
+ return security_descriptor_acl_del_ace(sd, false, ace);
+}
+
+NTSTATUS security_descriptor_sacl_del_ace(struct security_descriptor *sd,
+ const struct security_ace *ace)
+{
+ return security_descriptor_acl_del_ace(sd, true, ace);
+}
+
+static bool security_ace_object_equal(const struct security_ace_object *object1,
+ const struct security_ace_object *object2)
+{
+ if (object1 == object2) {
+ return true;
+ }
+ if ((object1 == NULL) || (object2 == NULL)) {
+ return false;
+ }
+ if (object1->flags != object2->flags) {
+ return false;
+ }
+ if (object1->flags & SEC_ACE_OBJECT_TYPE_PRESENT
+ && !GUID_equal(&object1->type.type, &object2->type.type)) {
+ return false;
+ }
+ if (object1->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT
+ && !GUID_equal(&object1->inherited_type.inherited_type,
+ &object2->inherited_type.inherited_type)) {
+ return false;
+ }
+
+ return true;
+}
+
/*
compare two security ace structures
*/
@@ -440,6 +533,14 @@ bool security_ace_equal(const struct security_ace *ace1,
if (ace1->access_mask != ace2->access_mask) {
return false;
}
+ if ((ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT
+ || ace1->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT
+ || ace1->type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT
+ || ace1->type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT)
+ && !security_ace_object_equal(&ace1->object.object,
+ &ace2->object.object)) {
+ return false;
+ }
if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) {
return false;
}
diff --git a/libcli/security/security_descriptor.h b/libcli/security/security_descriptor.h
index 7e6df87fefa..46545321d15 100644
--- a/libcli/security/security_descriptor.h
+++ b/libcli/security/security_descriptor.h
@@ -39,6 +39,10 @@ NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd,
const struct dom_sid *trustee);
NTSTATUS security_descriptor_sacl_del(struct security_descriptor *sd,
const struct dom_sid *trustee);
+NTSTATUS security_descriptor_dacl_del_ace(struct security_descriptor *sd,
+ const struct security_ace *ace);
+NTSTATUS security_descriptor_sacl_del_ace(struct security_descriptor *sd,
+ const struct security_ace *ace);
bool security_ace_equal(const struct security_ace *ace1,
const struct security_ace *ace2);
bool security_acl_equal(const struct security_acl *acl1,
diff --git a/python/samba/netcmd/dsacl.py b/python/samba/netcmd/dsacl.py
index d3b8b5f554e..02be8fd982b 100644
--- a/python/samba/netcmd/dsacl.py
+++ b/python/samba/netcmd/dsacl.py
@@ -42,12 +42,42 @@ from samba.netcmd import (
Option,
)
+def find_trustee_sid(samdb, trusteedn):
+ res = samdb.search(base=trusteedn, expression="(objectClass=*)",
+ scope=SCOPE_BASE)
+ assert(len(res) == 1)
+ return ndr_unpack(security.dom_sid, res[0]["objectSid"][0])
+
+
+def modify_descriptor(samdb, object_dn, desc, controls=None):
+ assert(isinstance(desc, security.descriptor))
+ m = ldb.Message()
+ m.dn = ldb.Dn(samdb, object_dn)
+ m["nTSecurityDescriptor"] = ldb.MessageElement(
+ (ndr_pack(desc)), ldb.FLAG_MOD_REPLACE,
+ "nTSecurityDescriptor")
+ samdb.modify(m)
+
+
+def read_descriptor(samdb, object_dn):
+ res = samdb.search(base=object_dn, scope=SCOPE_BASE,
+ attrs=["nTSecurityDescriptor"])
+ # we should theoretically always have an SD
+ assert(len(res) == 1)
+ desc = res[0]["nTSecurityDescriptor"][0]
+ return ndr_unpack(security.descriptor, desc)
+
+
+def get_domain_sid(samdb):
+ res = samdb.search(base=samdb.domain_dn(),
+ expression="(objectClass=*)", scope=SCOPE_BASE)
+ return ndr_unpack(security.dom_sid, res[0]["objectSid"][0])
-class cmd_dsacl_set(Command):
- """Modify access list on a directory object."""
+
+class cmd_dsacl_base(Command):
+ """Base class for DSACL commands."""
synopsis = "%prog [options]"
- car_help = """ The access control right to allow or deny """
takes_optiongroups = {
"sambaopts": options.SambaOptions,
@@ -55,6 +85,18 @@ class cmd_dsacl_set(Command):
"versionopts": options.VersionOptions,
}
+ def print_acl(self, samdb, object_dn, prefix=''):
+ desc = read_descriptor(samdb, object_dn)
+ desc_sddl = desc.as_sddl(get_domain_sid(samdb))
+ self.outf.write("%sdescriptor for %s:\n" % (prefix, object_dn))
+ self.outf.write(desc_sddl + "\n")
+
+
+class cmd_dsacl_set(cmd_dsacl_base):
+ """Modify access list on a directory object."""
+
+ car_help = """ The access control right to allow or deny """
+
takes_options = [
Option("-H", "--URL", help="LDB URL for database or target server",
type=str, metavar="URL", dest="H"),
@@ -82,41 +124,13 @@ class cmd_dsacl_set(Command):
type="string"),
]
- def find_trustee_sid(self, samdb, trusteedn):
- res = samdb.search(base=trusteedn, expression="(objectClass=*)",
- scope=SCOPE_BASE)
- assert(len(res) == 1)
- return ndr_unpack(security.dom_sid, res[0]["objectSid"][0])
-
- def modify_descriptor(self, samdb, object_dn, desc, controls=None):
- assert(isinstance(desc, security.descriptor))
- m = ldb.Message()
- m.dn = ldb.Dn(samdb, object_dn)
- m["nTSecurityDescriptor"] = ldb.MessageElement(
- (ndr_pack(desc)), ldb.FLAG_MOD_REPLACE,
- "nTSecurityDescriptor")
- samdb.modify(m)
-
- def read_descriptor(self, samdb, object_dn):
- res = samdb.search(base=object_dn, scope=SCOPE_BASE,
- attrs=["nTSecurityDescriptor"])
- # we should theoretically always have an SD
- assert(len(res) == 1)
- desc = res[0]["nTSecurityDescriptor"][0]
- return ndr_unpack(security.descriptor, desc)
-
- def get_domain_sid(self, samdb):
- res = samdb.search(base=samdb.domain_dn(),
- expression="(objectClass=*)", scope=SCOPE_BASE)
- return ndr_unpack(security.dom_sid, res[0]["objectSid"][0])
-
def add_ace(self, samdb, object_dn, new_ace):
"""Add new ace explicitly."""
- desc = self.read_descriptor(samdb, object_dn)
- new_ace = security.descriptor.from_sddl("D:" + new_ace,self.get_domain_sid(samdb))
+ desc = read_descriptor(samdb, object_dn)
+ new_ace = security.descriptor.from_sddl("D:" + new_ace, get_domain_sid(samdb))
new_ace_list = re.findall(r"\(.*?\)",new_ace.as_sddl())
for new_ace in new_ace_list:
- desc_sddl = desc.as_sddl(self.get_domain_sid(samdb))
+ desc_sddl = desc.as_sddl(get_domain_sid(samdb))
# TODO add bindings for descriptor manipulation and get rid of this
desc_aces = re.findall(r"\(.*?\)", desc_sddl)
for ace in desc_aces:
@@ -128,17 +142,8 @@ class cmd_dsacl_set(Command):
desc_sddl = desc_sddl[:desc_sddl.index("(")] + new_ace + desc_sddl[desc_sddl.index("("):]
else:
desc_sddl = desc_sddl + new_ace
- desc = security.descriptor.from_sddl(desc_sddl, self.get_domain_sid(samdb))
- self.modify_descriptor(samdb, object_dn, desc)
-
- def print_acl(self, samdb, object_dn, new=False):
- desc = self.read_descriptor(samdb, object_dn)
- desc_sddl = desc.as_sddl(self.get_domain_sid(samdb))
- if new:
- self.outf.write("new descriptor for %s:\n" % object_dn)
- else:
- self.outf.write("old descriptor for %s:\n" % object_dn)
- self.outf.write(desc_sddl + "\n")
+ desc = security.descriptor.from_sddl(desc_sddl, get_domain_sid(samdb))
+ modify_descriptor(samdb, object_dn, desc)
def run(self, car, action, objectdn, trusteedn, sddl,
H=None, credopts=None, sambaopts=None, versionopts=None):
@@ -165,7 +170,7 @@ class cmd_dsacl_set(Command):
'repl-sync': GUID_DRS_REPL_SYNCRONIZE,
'ro-repl-secret-sync': GUID_DRS_RO_REPL_SECRET_SYNC,
}
- sid = self.find_trustee_sid(samdb, trusteedn)
+ sid = find_trustee_sid(samdb, trusteedn)
if sddl:
new_ace = sddl
elif action == "allow":
@@ -175,22 +180,14 @@ class cmd_dsacl_set(Command):
else:
raise CommandError("Wrong argument '%s'!" % action)
- self.print_acl(samdb, objectdn)
+ self.print_acl(samdb, objectdn, prefix='old ')
self.add_ace(samdb, objectdn, new_ace)
- self.print_acl(samdb, objectdn, new=True)
+ self.print_acl(samdb, objectdn, prefix='new ')
-class cmd_dsacl_get(Command):
+class cmd_dsacl_get(cmd_dsacl_base):
"""Print access list on a directory object."""
- synopsis = "%prog [options]"
-
- takes_optiongroups = {
- "sambaopts": options.SambaOptions,
- "credopts": options.CredentialsOptions,
- "versionopts": options.VersionOptions,
- }
-
takes_options = [
Option("-H", "--URL", help="LDB URL for database or target server",
type=str, metavar="URL", dest="H"),
@@ -198,25 +195,6 @@ class cmd_dsacl_get(Command):
type="string"),
]
- def read_descriptor(self, samdb, object_dn):
- res = samdb.search(base=object_dn, scope=SCOPE_BASE,
- attrs=["nTSecurityDescriptor"])
- # we should theoretically always have an SD
- assert(len(res) == 1)
- desc = res[0]["nTSecurityDescriptor"][0]
- return ndr_unpack(security.descriptor, desc)
-
- def get_domain_sid(self, samdb):
- res = samdb.search(base=samdb.domain_dn(),
- expression="(objectClass=*)", scope=SCOPE_BASE)
- return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
-
- def print_acl(self, samdb, object_dn):
- desc = self.read_descriptor(samdb, object_dn)
- desc_sddl = desc.as_sddl(self.get_domain_sid(samdb))
- self.outf.write("descriptor for %s:\n" % object_dn)
- self.outf.write(desc_sddl + "\n")
-
def run(self, objectdn,
H=None, credopts=None, sambaopts=None, versionopts=None):
lp = sambaopts.get_loadparm()
@@ -227,9 +205,50 @@ class cmd_dsacl_get(Command):
self.print_acl(samdb, objectdn)
+class cmd_dsacl_delete(cmd_dsacl_base):
+ """Delete an access list entry on a directory object."""
+
+ takes_options = [
+ Option("-H", "--URL", help="LDB URL for database or target server",
+ type=str, metavar="URL", dest="H"),
+ Option("--objectdn", help="DN of the object whose SD to modify",
+ type="string"),
+ Option("--sddl", help="An ACE or group of ACEs to be deleted from the object",
+ type="string"),
+ ]
+
+ def run(self, objectdn, sddl, H=None, credopts=None, sambaopts=None, versionopts=None):
+ lp = sambaopts.get_loadparm()
+ creds = credopts.get_credentials(lp)
+
+ if sddl is None or objectdn is None:
+ return self.usage()
+
+ samdb = SamDB(url=H, session_info=system_session(),
+ credentials=creds, lp=lp)
+
+ self.print_acl(samdb, objectdn, prefix='old ')
+ self.delete_ace(samdb, objectdn, sddl)
+ self.print_acl(samdb, objectdn, prefix='new ')
+
+ def delete_ace(self, samdb, object_dn, delete_aces):
+ """Delete ace explicitly."""
+ desc = read_descriptor(samdb, object_dn)
+ domsid = get_domain_sid(samdb)
+ delete_aces = security.descriptor.from_sddl("D:" + delete_aces, domsid).dacl.aces
+ for ace in delete_aces:
+ if ace in desc.dacl.aces:
+ desc.dacl_del_ace(ace)
+ else:
+ sddl = ace.as_sddl(domsid)
+ self.outf.write("WARNING: (%s) was not found in the current security descriptor.\n" % sddl)
+ modify_descriptor(samdb, object_dn, desc)
+
+
class cmd_dsacl(SuperCommand):
"""DS ACLs manipulation."""
subcommands = {}
subcommands["set"] = cmd_dsacl_set()
subcommands["get"] = cmd_dsacl_get()
+ subcommands["delete"] = cmd_dsacl_delete()
diff --git a/python/samba/tests/samba_tool/dsacl.py b/python/samba/tests/samba_tool/dsacl.py
index 66c662f7a3b..54aef5bd39a 100644
--- a/python/samba/tests/samba_tool/dsacl.py
+++ b/python/samba/tests/samba_tool/dsacl.py
@@ -122,3 +122,91 @@ class DSaclSetSddlTestCase(SambaToolCmdTest):
self.assertEqual(err, "", "Shouldn't be any error messages")
acl_list = re.findall('.*descriptor for.*:\n(.*?)\n',out)
return acl_list
+
+ def test_add_delete_sddl(self):
+ """Tests if a sddl string can be added 'the normal way', deleted and
+ final state is the same as initial.
+ """
+ (result, out, err) = self.runsubcmd("dsacl", "get",
+ "--objectdn=%s" % self.dn)
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ # extract only the two sddl strings from samba-tool output
+ acl_list_orig = re.findall('^descriptor for.*:\n(.*?)\n', out)[0]
+
+ (result, out, err) = self.runsubcmd("dsacl", "set",
+ "--objectdn=%s" % self.dn,
+ "--sddl=%s" % self.sddl)
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ acl_list_added = re.findall('new descriptor for.*:\n(.*?)\n', out)[0]
+ self.assertNotEqual(acl_list_added, acl_list_orig, "After adding the SD should be different.")
+ self.assertMatch(acl_list_added, self.sddl, "The added ACE should be part of the new SD.")
+
+ (result, out, err) = self.runsubcmd("dsacl", "delete",
+ "--objectdn=%s" % self.dn,
+ "--sddl=%s" % self.sddl)
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ acl_list_final = re.findall('new descriptor for.*:\n(.*?)\n', out)[0]
+ self.assertEqual(acl_list_orig, acl_list_final,
+ "output of dsacl delete should be the same as before adding")
+
+ (result, out, err) = self.runsubcmd("dsacl", "get",
+ "--objectdn=%s" % self.dn)
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ # extract only the two sddl strings from samba-tool output
+ acl_list_final_get = re.findall('^descriptor for.*:\n(.*?)\n', out)[0]
+ self.assertEqual(acl_list_orig, acl_list_final_get,
+ "output of dsacl get should be the same as after adding and deleting again")
+
+ def test_delete(self):
+ # add sddl_multi first
+ (result, out, err) = self.runsubcmd("dsacl", "set",
+ "--objectdn=%s" % self.dn,
+ "--sddl=%s" % self.sddl_multi)
+
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ # delete sddl
+ (result, out, err) = self.runsubcmd("dsacl", "delete",
+ "--objectdn=%s" % self.dn,
+ "--sddl=%s" % self.sddl)
+ self.assertCmdSuccess(result, out, err)
+ self.assertEqual(err, "", "Shouldn't be any error messages")
+ acl_list_deleted = re.findall('new descriptor for.*:\n(.*?)\n', out)[0]
+
+ self.assertNotRegex(acl_list_deleted, re.escape(self.sddl))
--
Samba Shared Repository
More information about the samba-cvs
mailing list