dsdb-acls: Add documentation
[mat/samba.git] / source4 / dsdb / samdb / ldb_modules / acl_util.c
index aa7e1aa1d670e0ce839640fa9f14b04056d07b73..bc2a8f0704f535db619e8f4e22ade4c6475a16a0 100644 (file)
@@ -91,12 +91,45 @@ int dsdb_module_check_access_on_dn(struct ldb_module *module,
                                                guid);
 }
 
+/**
+ * @brief Checks the current as the requested access on 1 attribute
+ *
+ * This function checks if a given trustee has the requested access
+ * on the specified attribute given the current security descriptor.
+ * The attribute can be NULL in this case the check will skip the
+ * OBJECT_ACE entries.
+ *
+ * @param[in]  module      A struct ldb_module object, security token
+ *                         for the current user are stored within the
+ *                         module object.
+ *
+ * @param[in]  mem_ctx     A talloc context object for memory allocation
+ *
+ * @param[in]  sd          A security descriptor for attr
+ *
+ * @param[in]  rp_sid      The SID of the domain, used for expanding
+ *                         trustee in ACE that are just a RID.
+ *
+ * @param[in]  access_mask An integer that represents the desired access
+ *                         that the security descriptor should grant to
+ *                         the user on the given attribute
+ *
+ * @param[in]  attr        A dsdb_attribute for which the checks should be
+ *                         performed.
+ *
+ * @return                 Returns LDB_SUCCESS on success, on error another
+ *                         ldb error code.
+ *                         If the requested rights are not granted
+ *                         LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS will be returned.
+ *
+ */
 int acl_check_access_on_attribute(struct ldb_module *module,
                                  TALLOC_CTX *mem_ctx,
                                  struct security_descriptor *sd,
                                  struct dom_sid *rp_sid,
                                  uint32_t access_mask,
-                                 const struct dsdb_attribute *attr)
+                                 const struct dsdb_attribute *attr,
+                                 const struct dsdb_class *objectclass)
 {
        int ret;
        NTSTATUS status;
@@ -105,34 +138,34 @@ int acl_check_access_on_attribute(struct ldb_module *module,
        struct object_tree *new_node = NULL;
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
        struct security_token *token = acl_user_token(module);
-       if (attr) {
-               if (!GUID_all_zero(&attr->attributeSecurityGUID)) {
-                       if (!insert_in_object_tree(tmp_ctx,
-                                                  &attr->attributeSecurityGUID,
-                                                  access_mask, &root,
-                                                  &new_node)) {
-                               DEBUG(10, ("acl_search: cannot add to object tree securityGUID\n"));
-                               goto fail;
-                       }
-
-                       if (!insert_in_object_tree(tmp_ctx,
-                                                  &attr->schemaIDGUID,
-                                                  access_mask, &new_node,
-                                                  &new_node)) {
-                               DEBUG(10, ("acl_search: cannot add to object tree attributeGUID\n"));
-                               goto fail;
-                       }
-               }
-               else {
-                       if (!insert_in_object_tree(tmp_ctx,
-                                                  &attr->schemaIDGUID,
-                                                  access_mask, &root,
-                                                  &new_node)) {
-                               DEBUG(10, ("acl_search: cannot add to object tree attributeGUID\n"));
-                               goto fail;
-                       }
+
+       if (!insert_in_object_tree(tmp_ctx,
+                                  &objectclass->schemaIDGUID,
+                                  access_mask, NULL,
+                                  &root)) {
+               DEBUG(10, ("acl_search: cannot add to object tree class schemaIDGUID\n"));
+               goto fail;
+       }
+       new_node = root;
+
+       if (!GUID_all_zero(&attr->attributeSecurityGUID)) {
+               if (!insert_in_object_tree(tmp_ctx,
+                                          &attr->attributeSecurityGUID,
+                                          access_mask, new_node,
+                                          &new_node)) {
+                       DEBUG(10, ("acl_search: cannot add to object tree securityGUID\n"));
+                       goto fail;
                }
        }
+
+       if (!insert_in_object_tree(tmp_ctx,
+                                  &attr->schemaIDGUID,
+                                  access_mask, new_node,
+                                  &new_node)) {
+               DEBUG(10, ("acl_search: cannot add to object tree attributeGUID\n"));
+               goto fail;
+       }
+
        status = sec_access_check_ds(sd, token,
                                     access_mask,
                                     &access_granted,
@@ -151,8 +184,72 @@ fail:
        return ldb_operr(ldb_module_get_ctx(module));
 }
 
+int acl_check_access_on_objectclass(struct ldb_module *module,
+                                   TALLOC_CTX *mem_ctx,
+                                   struct security_descriptor *sd,
+                                   struct dom_sid *rp_sid,
+                                   uint32_t access_mask,
+                                   const struct dsdb_class *objectclass)
+{
+       int ret;
+       NTSTATUS status;
+       uint32_t access_granted;
+       struct object_tree *root = NULL;
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+       struct security_token *token = acl_user_token(module);
+
+       if (!insert_in_object_tree(tmp_ctx,
+                                  &objectclass->schemaIDGUID,
+                                  access_mask, NULL,
+                                  &root)) {
+               DEBUG(10, ("acl_search: cannot add to object tree class schemaIDGUID\n"));
+               goto fail;
+       }
+
+       status = sec_access_check_ds(sd, token,
+                                    access_mask,
+                                    &access_granted,
+                                    root,
+                                    rp_sid);
+       if (!NT_STATUS_IS_OK(status)) {
+               ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+       } else {
+               ret = LDB_SUCCESS;
+       }
+       talloc_free(tmp_ctx);
+       return ret;
+fail:
+       talloc_free(tmp_ctx);
+       return ldb_operr(ldb_module_get_ctx(module));
+}
 
-/* checks for validated writes */
+/**
+ * @brief Checks if a given extended right grants the desired access for a given user
+ *
+ * This function checks if a given user is granted the specified extended right
+ * with the requested access right.
+ *
+ * @param[in]  mem_ctx     A talloc context object for memory allocation
+ *
+ * @param[in]  sd          A security descriptor for attr
+ *
+ * @param[in]  token       The security token reprensenting the user
+ *
+ * @param[in]  ext_right   A string representation of the GUID of the extended
+ *                         right to test.
+ *
+ * @param[in]  right_typ   An integer that represents the desired access
+ *                         that the security descriptor should grant to
+ *                         the user for the specified extended access right
+ *
+ * @param[in]  dom_sid     The SID of the domain, used for expanding
+ *                         trustee in ACE that are just a RID.
+ *
+ * @return                 Returns LDB_SUCCESS on success, on error another
+ *                         ldb error code.
+ *                         If the requested rights are not granted
+ *                         LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS will be returned.
+ */
 int acl_check_extended_right(TALLOC_CTX *mem_ctx,
                             struct security_descriptor *sd,
                             struct security_token *token,
@@ -164,13 +261,12 @@ int acl_check_extended_right(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        uint32_t access_granted;
        struct object_tree *root = NULL;
-       struct object_tree *new_node = NULL;
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 
        GUID_from_string(ext_right, &right);
 
        if (!insert_in_object_tree(tmp_ctx, &right, right_type,
-                                  &root, &new_node)) {
+                                  NULL, &root)) {
                DEBUG(10, ("acl_ext_right: cannot add to object tree\n"));
                talloc_free(tmp_ctx);
                return LDB_ERR_OPERATIONS_ERROR;
@@ -234,8 +330,37 @@ uint32_t dsdb_request_sd_flags(struct ldb_request *req, bool *explicit)
         * equals all 4 bits
         */
        if (sd_flags == 0) {
-               sd_flags = 0xF;
+               sd_flags = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL | SECINFO_SACL;
        }
 
        return sd_flags;
 }
+
+int dsdb_module_schedule_sd_propagation(struct ldb_module *module,
+                                       struct ldb_dn *nc_root,
+                                       struct ldb_dn *dn,
+                                       bool include_self)
+{
+       struct ldb_context *ldb = ldb_module_get_ctx(module);
+       struct dsdb_extended_sec_desc_propagation_op *op;
+       int ret;
+
+       op = talloc_zero(module, struct dsdb_extended_sec_desc_propagation_op);
+       if (op == NULL) {
+               return ldb_oom(ldb);
+       }
+
+       op->nc_root = nc_root;
+       op->dn = dn;
+       op->include_self = include_self;
+
+       ret = dsdb_module_extended(module, op, NULL,
+                                  DSDB_EXTENDED_SEC_DESC_PROPAGATION_OID,
+                                  op,
+                                  DSDB_FLAG_TOP_MODULE |
+                                  DSDB_FLAG_AS_SYSTEM |
+                                  DSDB_FLAG_TRUSTED,
+                                  NULL);
+       TALLOC_FREE(op);
+       return ret;
+}