From: Christian Merten Date: Mon, 19 Sep 2022 20:47:10 +0000 (+0200) Subject: CVE-2023-4154 libcli security_descriptor: Add function to delete a given ace from... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=25585fda53fd2b6c2d7e21e7829945b51e984d07;p=thirdparty%2Fsamba.git CVE-2023-4154 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. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15424 Signed-off-by: Christian Merten Reviewed-by: Douglas Bagnall Reviewed-by: Jeremy Allison (cherry picked from commit 7efe673fbdcd27ddd23f36281c5f5338681a68fe) --- diff --git a/libcli/security/security_descriptor.c b/libcli/security/security_descriptor.c index ba142016389..64c2d027876 100644 --- a/libcli/security/security_descriptor.c +++ b/libcli/security/security_descriptor.c @@ -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;inum_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;inum_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 */ 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,