revert ...
[metze/samba/wip.git] / libcli / security / access_check.c
index 70345f5a56089ab5b9c72858476e602e183a865d..936ffca242e6b6e7682f97dc3815e54715ee8fe9 100644 (file)
@@ -367,18 +367,32 @@ NTSTATUS se_file_access_check(const struct security_descriptor *sd,
 
 static const struct GUID *get_ace_object_type(struct security_ace *ace)
 {
-        struct GUID *type;
-
-        if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT)
-                type = &ace->object.object.type.type;
-        else
-                type = NULL;
-
-        return type;
+       if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
+               return &ace->object.object.type.type;
+       }
 
+       return NULL;
 }
 
-/* modified access check for the purposes of DS security
+/**
+ * @brief Perform directoryservice (DS) related access checks for a given user
+ *
+ * Perform DS access checks for the user represented by its security_token, on
+ * the provided security descriptor. If an tree associating GUID and access
+ * required is provided then object access (OA) are checked as well. *
+ * @param[in]   sd             The security descritor against which the required
+ *                             access are requested
+ *
+ * @param[in]   token          The security_token associated with the user to
+ *                             test
+ *
+ * @param[in]   access_desired A bitfield of rights that must be granted for the
+ *                             given user in the specified SD.
+ *
+ * If one
+ * of the entry in the tree grants all the requested rights for the given GUID
+ * FIXME
+ * tree can be null if not null it's the
  * Lots of code duplication, it will ve united in just one
  * function eventually */
 
@@ -389,31 +403,32 @@ NTSTATUS sec_access_check_ds(const struct security_descriptor *sd,
                             struct object_tree *tree,
                             struct dom_sid *replace_sid)
 {
-        uint32_t i;
-        uint32_t bits_remaining;
-        struct object_tree *node;
-        const struct GUID *type;
-        struct dom_sid *ps_sid = dom_sid_parse_talloc(NULL, SID_NT_SELF);
-
-        *access_granted = access_desired;
-        bits_remaining = access_desired;
-
-        /* handle the maximum allowed flag */
-        if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
-                access_desired |= access_check_max_allowed(sd, token);
-                access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
-                *access_granted = access_desired;
+       uint32_t i;
+       uint32_t bits_remaining;
+       struct object_tree *node;
+       const struct GUID *type;
+       struct dom_sid self_sid;
+
+       dom_sid_parse(SID_NT_SELF, &self_sid);
+
+       *access_granted = access_desired;
+       bits_remaining = access_desired;
+
+       /* handle the maximum allowed flag */
+       if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
+               access_desired |= access_check_max_allowed(sd, token);
+               access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
+               *access_granted = access_desired;
                bits_remaining = access_desired;
-        }
+       }
 
-        if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
-                if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
-                        bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
-                } else {
-                        talloc_free(ps_sid);
-                        return NT_STATUS_PRIVILEGE_NOT_HELD;
-                }
-        }
+       if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
+               if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
+                       bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
+               } else {
+                       return NT_STATUS_PRIVILEGE_NOT_HELD;
+               }
+       }
 
        /* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
        if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
@@ -431,88 +446,89 @@ NTSTATUS sec_access_check_ds(const struct security_descriptor *sd,
                bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
        }
 
-        /* a NULL dacl allows access */
-        if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
-                *access_granted = access_desired;
-                talloc_free(ps_sid);
-                return NT_STATUS_OK;
-        }
+       /* a NULL dacl allows access */
+       if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
+               *access_granted = access_desired;
+               return NT_STATUS_OK;
+       }
 
-        if (sd->dacl == NULL) {
-                goto done;
-        }
+       if (sd->dacl == NULL) {
+               goto done;
+       }
 
-        /* check each ace in turn. */
-        for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
+       /* check each ace in turn. */
+       for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
                struct dom_sid *trustee;
                struct security_ace *ace = &sd->dacl->aces[i];
 
-                if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
-                        continue;
-                }
-               if (dom_sid_equal(&ace->trustee, ps_sid) && replace_sid) {
-                       trustee = replace_sid;
+               if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
+                       continue;
                }
-               else
-               {
+
+               if (dom_sid_equal(&ace->trustee, &self_sid) && replace_sid) {
+                       trustee = replace_sid;
+               } else {
                        trustee = &ace->trustee;
                }
-                if (!security_token_has_sid(token, trustee)) {
-                        continue;
-                }
-
-                switch (ace->type) {
-                case SEC_ACE_TYPE_ACCESS_ALLOWED:
-                        if (tree)
-                                object_tree_modify_access(tree, ace->access_mask);
-
-                        bits_remaining &= ~ace->access_mask;
-                        break;
-                case SEC_ACE_TYPE_ACCESS_DENIED:
-                        if (bits_remaining & ace->access_mask) {
-                                talloc_free(ps_sid);
-                                return NT_STATUS_ACCESS_DENIED;
-                        }
-                        break;
-                case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
-                case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
-                        /* check only in case we have provided a tree,
-                         * the ACE has an object type and that type
-                         * is in the tree                           */
-                        type = get_ace_object_type(ace);
-
-                        if (!tree)
-                                continue;
-
-                        if (!type)
-                                node = tree;
-                        else
-                                if (!(node = get_object_tree_by_GUID(tree, type)))
-                                        continue;
-
-                        if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
-                                object_tree_modify_access(node, ace->access_mask);
-                                if (node->remaining_access == 0) {
-                                        talloc_free(ps_sid);
-                                        return NT_STATUS_OK;
-                                }
-                        } else {
-                                if (node->remaining_access & ace->access_mask){
-                                        talloc_free(ps_sid);
-                                        return NT_STATUS_ACCESS_DENIED;
-                                }
-                        }
-                        break;
-                default:        /* Other ACE types not handled/supported */
-                        break;
-                }
-        }
+
+               if (!security_token_has_sid(token, trustee)) {
+                       continue;
+               }
+
+               switch (ace->type) {
+               case SEC_ACE_TYPE_ACCESS_ALLOWED:
+                       if (tree) {
+                               object_tree_modify_access(tree, ace->access_mask);
+                       }
+
+                       bits_remaining &= ~ace->access_mask;
+                       break;
+               case SEC_ACE_TYPE_ACCESS_DENIED:
+                       if (bits_remaining & ace->access_mask) {
+                               return NT_STATUS_ACCESS_DENIED;
+                       }
+                       break;
+               case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
+               case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
+                       /*
+                        * check only in case we have provided a tree,
+                        * the ACE has an object type and that type
+                        * is in the tree
+                        */
+                       type = get_ace_object_type(ace);
+
+                       if (!tree) {
+                               continue;
+                       }
+
+                       if (!type) {
+                               node = tree;
+                       } else {
+                               if (!(node = get_object_tree_by_GUID(tree, type))) {
+                                       continue;
+                               }
+                       }
+
+                       if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
+                               object_tree_modify_access(node, ace->access_mask);
+                               if (node->remaining_access == 0) {
+                                       return NT_STATUS_OK;
+                               }
+                       } else {
+                               if (node->remaining_access & ace->access_mask){
+                                       return NT_STATUS_ACCESS_DENIED;
+                               }
+                       }
+                       break;
+               default:        /* Other ACE types not handled/supported */
+                       break;
+               }
+       }
 
 done:
-        talloc_free(ps_sid);
-        if (bits_remaining != 0) {
-                return NT_STATUS_ACCESS_DENIED;
-        }
+       if (bits_remaining != 0) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
 
-        return NT_STATUS_OK;
+       return NT_STATUS_OK;
 }