]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2020-25720: s4-acl: Move definition of acl_check_self_membership()
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Fri, 22 Apr 2022 03:01:00 +0000 (15:01 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 16 Sep 2022 02:32:36 +0000 (02:32 +0000)
This allows us to make use of it in acl_add().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14810

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/dsdb/samdb/ldb_modules/acl.c

index 4098ae2d671827962f3aaab11c3eb61d1de430d8..038eb1dad2fb10b17a9f43fe5cef74ef8a659c22 100644 (file)
@@ -1148,6 +1148,78 @@ fail:
        return LDB_ERR_CONSTRAINT_VIOLATION;
 }
 
+/* checks if modifications are allowed on "Member" attribute */
+static int acl_check_self_membership(TALLOC_CTX *mem_ctx,
+                                    struct ldb_module *module,
+                                    struct ldb_request *req,
+                                    struct security_descriptor *sd,
+                                    struct dom_sid *sid,
+                                    const struct dsdb_attribute *attr,
+                                    const struct dsdb_class *objectclass)
+{
+       int ret;
+       unsigned int i;
+       struct ldb_context *ldb = ldb_module_get_ctx(module);
+       struct ldb_dn *user_dn;
+       struct ldb_message_element *member_el;
+       const struct ldb_message *msg = NULL;
+
+       if (req->operation == LDB_MODIFY) {
+               msg = req->op.mod.message;
+       } else if (req->operation == LDB_ADD) {
+               msg = req->op.add.message;
+       } else {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       /* if we have wp, we can do whatever we like */
+       if (acl_check_access_on_attribute(module,
+                                         mem_ctx,
+                                         sd,
+                                         sid,
+                                         SEC_ADS_WRITE_PROP,
+                                         attr, objectclass) == LDB_SUCCESS) {
+               return LDB_SUCCESS;
+       }
+       /* if we are adding/deleting ourselves, check for self membership */
+       ret = dsdb_find_dn_by_sid(ldb, mem_ctx,
+                                 &acl_user_token(module)->sids[PRIMARY_USER_SID_INDEX],
+                                 &user_dn);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+       member_el = ldb_msg_find_element(msg, "member");
+       if (!member_el) {
+               return ldb_operr(ldb);
+       }
+       /* user can only remove oneself */
+       if (member_el->num_values == 0) {
+               return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+       }
+       for (i = 0; i < member_el->num_values; i++) {
+               if (strcasecmp((const char *)member_el->values[i].data,
+                              ldb_dn_get_extended_linearized(mem_ctx, user_dn, 1)) != 0) {
+                       return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+               }
+       }
+       ret = acl_check_extended_right(mem_ctx,
+                                      module,
+                                      req,
+                                      objectclass,
+                                      sd,
+                                      acl_user_token(module),
+                                      GUID_DRS_SELF_MEMBERSHIP,
+                                      SEC_ADS_SELF_WRITE,
+                                      sid);
+       if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
+               dsdb_acl_debug(sd, acl_user_token(module),
+                              msg->dn,
+                              true,
+                              10);
+       }
+       return ret;
+}
+
 static int acl_add(struct ldb_module *module, struct ldb_request *req)
 {
        int ret;
@@ -1280,78 +1352,6 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
        return ldb_next_request(module, req);
 }
 
-/* checks if modifications are allowed on "Member" attribute */
-static int acl_check_self_membership(TALLOC_CTX *mem_ctx,
-                                    struct ldb_module *module,
-                                    struct ldb_request *req,
-                                    struct security_descriptor *sd,
-                                    struct dom_sid *sid,
-                                    const struct dsdb_attribute *attr,
-                                    const struct dsdb_class *objectclass)
-{
-       int ret;
-       unsigned int i;
-       struct ldb_context *ldb = ldb_module_get_ctx(module);
-       struct ldb_dn *user_dn;
-       struct ldb_message_element *member_el;
-       const struct ldb_message *msg = NULL;
-
-       if (req->operation == LDB_MODIFY) {
-               msg = req->op.mod.message;
-       } else if (req->operation == LDB_ADD) {
-               msg = req->op.add.message;
-       } else {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       /* if we have wp, we can do whatever we like */
-       if (acl_check_access_on_attribute(module,
-                                         mem_ctx,
-                                         sd,
-                                         sid,
-                                         SEC_ADS_WRITE_PROP,
-                                         attr, objectclass) == LDB_SUCCESS) {
-               return LDB_SUCCESS;
-       }
-       /* if we are adding/deleting ourselves, check for self membership */
-       ret = dsdb_find_dn_by_sid(ldb, mem_ctx,
-                                 &acl_user_token(module)->sids[PRIMARY_USER_SID_INDEX],
-                                 &user_dn);
-       if (ret != LDB_SUCCESS) {
-               return ret;
-       }
-       member_el = ldb_msg_find_element(msg, "member");
-       if (!member_el) {
-               return ldb_operr(ldb);
-       }
-       /* user can only remove oneself */
-       if (member_el->num_values == 0) {
-               return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
-       }
-       for (i = 0; i < member_el->num_values; i++) {
-               if (strcasecmp((const char *)member_el->values[i].data,
-                              ldb_dn_get_extended_linearized(mem_ctx, user_dn, 1)) != 0) {
-                       return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
-               }
-       }
-       ret = acl_check_extended_right(mem_ctx,
-                                      module,
-                                      req,
-                                      objectclass,
-                                      sd,
-                                      acl_user_token(module),
-                                      GUID_DRS_SELF_MEMBERSHIP,
-                                      SEC_ADS_SELF_WRITE,
-                                      sid);
-       if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
-               dsdb_acl_debug(sd, acl_user_token(module),
-                              msg->dn,
-                              true,
-                              10);
-       }
-       return ret;
-}
-
 static int acl_check_password_rights(
        TALLOC_CTX *mem_ctx,
        struct ldb_module *module,