libcli security_descriptor: Add function to delete a given ace from a security descriptor
authorChristian Merten <christian@merten.dev>
Mon, 19 Sep 2022 20:47:10 +0000 (22:47 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 27 Sep 2022 16:46:35 +0000 (16:46 +0000)
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@merten.dev>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra@samba.org>
libcli/security/security_descriptor.c
libcli/security/security_descriptor.h

index ba142016389f75b1bf9eecb35b38a3c864c1e5c3..64c2d027876a21a31095f59920f669d76218ac8e 100644 (file)
@@ -419,6 +419,72 @@ 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);
+}
 /*
   compare two security ace structures
 */
index 7e6df87fefabde1df1f2a0cc9b1ad18d66729700..46545321d15a2cd6c05df45bd4dcaeda99a72134 100644 (file)
@@ -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,