From: Christian Merten Date: Tue, 13 Sep 2022 23:29:34 +0000 (+0200) Subject: samba-tool dsacl: Add subcommand to delete ACEs X-Git-Tag: talloc-2.4.0~800 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1bd08133067c50b6125addb2f94d293261a192fa;p=thirdparty%2Fsamba.git 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 Reviewed-by: Douglas Bagnall Reviewed-by: Jeremy Allison --- diff --git a/python/samba/netcmd/dsacl.py b/python/samba/netcmd/dsacl.py index d3b8b5f554e..b4d3ddb2d3a 100644 --- a/python/samba/netcmd/dsacl.py +++ b/python/samba/netcmd/dsacl.py @@ -227,9 +227,89 @@ class cmd_dsacl_get(Command): self.print_acl(samdb, objectdn) +class cmd_dsacl_delete(Command): + """Delete an access list entry 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"), + 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 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") + + 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 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) + self.delete_ace(samdb, objectdn, sddl) + self.print_acl(samdb, objectdn, new=True) + + 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()