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()