Split the dsdb_access_check_on_dn.
authorNadezhda Ivanova <nadezhda.ivanova@postpath.com>
Fri, 12 Mar 2010 01:13:51 +0000 (03:13 +0200)
committerNadezhda Ivanova <nadezhda.ivanova@postpath.com>
Fri, 12 Mar 2010 01:13:51 +0000 (03:13 +0200)
Split the dsdb_access_check_on_dn so it can be reused for checks
from both within the module stack and outside it.

source4/dsdb/common/dsdb_access.c
source4/dsdb/samdb/ldb_modules/acl.c

index 1f8b795a7bd63ef45339b962e49ee6a5935a1513..40233f9379d8c1bb6239f8d0a6aa63a4e7e3de5e 100644 (file)
  */
 
 #include "includes.h"
-#include "events/events.h"
 #include "ldb.h"
 #include "ldb_errors.h"
-#include "../lib/util/util_ldb.h"
-#include "../lib/crypto/crypto.h"
 #include "libcli/security/security.h"
 #include "librpc/gen_ndr/ndr_security.h"
-#include "librpc/gen_ndr/ndr_misc.h"
-#include "../libds/common/flags.h"
 #include "libcli/ldap/ldap_ndr.h"
 #include "param/param.h"
-#include "libcli/auth/libcli_auth.h"
-#include "librpc/gen_ndr/ndr_drsblobs.h"
-#include "system/locale.h"
 #include "auth/auth.h"
-#include "lib/util/tsort.h"
 
 void dsdb_acl_debug(struct security_descriptor *sd,
                      struct security_token *token,
@@ -113,38 +104,20 @@ int dsdb_get_dom_sid_from_ldb_message(TALLOC_CTX *mem_ctx,
        return LDB_SUCCESS;
 }
 
-int dsdb_check_access_on_dn(struct ldb_context *ldb,
-                             TALLOC_CTX *mem_ctx,
-                             struct ldb_dn *dn,
-                             uint32_t access,
-                             const struct GUID *guid)
+int dsdb_check_access_on_dn_internal(struct ldb_result *acl_res,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct security_token *token,
+                                    struct ldb_dn *dn,
+                                    uint32_t access,
+                                    const struct GUID *guid)
 {
-       int ret;
-       struct ldb_result *acl_res;
        struct security_descriptor *sd = NULL;
        struct dom_sid *sid = NULL;
        struct object_tree *root = NULL;
        struct object_tree *new_node = NULL;
        NTSTATUS status;
        uint32_t access_granted;
-       static const char *acl_attrs[] = {
-               "nTSecurityDescriptor",
-               "objectSid",
-               NULL
-       };
-
-       struct auth_session_info *session_info
-               = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
-       if(!session_info) {
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       ret = ldb_search(ldb, mem_ctx, &acl_res, dn, LDB_SCOPE_BASE, acl_attrs, NULL);
-       /* we sould be able to find the parent */
-       if (ret != LDB_SUCCESS) {
-               DEBUG(10,("acl: failed to find object %s\n", ldb_dn_get_linearized(dn)));
-               return ret;
-       }
+       int ret;
 
        ret = dsdb_get_sd_from_ldb_message(mem_ctx, acl_res->msgs[0], &sd);
        if (ret != LDB_SUCCESS) {
@@ -164,14 +137,14 @@ int dsdb_check_access_on_dn(struct ldb_context *ldb,
                        return LDB_ERR_OPERATIONS_ERROR;
                }
        }
-       status = sec_access_check_ds(sd, session_info->security_token,
+       status = sec_access_check_ds(sd, token,
                                     access,
                                     &access_granted,
                                     root,
                                     sid);
        if (!NT_STATUS_IS_OK(status)) {
                dsdb_acl_debug(sd,
-                              session_info->security_token,
+                              token,
                               dn,
                               true,
                               10);
@@ -179,3 +152,43 @@ int dsdb_check_access_on_dn(struct ldb_context *ldb,
        }
        return LDB_SUCCESS;
 }
+
+/* performs an access check from outside the module stack
+ * given the dn of the object to be checked, the required access
+ * guid is either the guid of the extended right, or NULL
+ */
+
+int dsdb_check_access_on_dn(struct ldb_context *ldb,
+                           TALLOC_CTX *mem_ctx,
+                           struct ldb_dn *dn,
+                           uint32_t access,
+                           const struct GUID *guid)
+{
+       int ret;
+       struct ldb_result *acl_res;
+       static const char *acl_attrs[] = {
+               "nTSecurityDescriptor",
+               "objectSid",
+               NULL
+       };
+
+       struct auth_session_info *session_info
+               = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
+       if(!session_info) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       ret = ldb_search(ldb, mem_ctx, &acl_res, dn, LDB_SCOPE_BASE, acl_attrs, NULL);
+       if (ret != LDB_SUCCESS) {
+               DEBUG(10,("access_check: failed to find object %s\n", ldb_dn_get_linearized(dn)));
+               return ret;
+       }
+
+       return dsdb_check_access_on_dn_internal(acl_res,
+                                               mem_ctx,
+                                               session_info->security_token,
+                                               dn,
+                                               access,
+                                               guid);
+}
+
index 9280de1b97c0d8234efd3c914e4ca2f1ce6efc4f..b0c1e2fa9e255c464ff903afbcc67763c24ebf10 100644 (file)
@@ -82,6 +82,45 @@ static struct security_token *acl_user_token(struct ldb_module *module)
        return session_info->security_token;
 }
 
+/* performs an access check from inside the module stack
+ * given the dn of the object to be checked, the required access
+ * guid is either the guid of the extended right, or NULL
+ */
+
+int dsdb_module_check_access_on_dn(struct ldb_module *module,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct ldb_dn *dn,
+                                  uint32_t access,
+                                  const struct GUID *guid)
+{
+       int ret;
+       struct ldb_result *acl_res;
+       static const char *acl_attrs[] = {
+               "nTSecurityDescriptor",
+               "objectSid",
+               NULL
+       };
+       struct ldb_context *ldb = ldb_module_get_ctx(module);
+       struct auth_session_info *session_info
+               = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
+       if(!session_info) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       ret = dsdb_module_search_dn(module, mem_ctx, &acl_res, dn,
+                                   acl_attrs, DSDB_SEARCH_SHOW_DELETED);
+       if (ret != LDB_SUCCESS) {
+               DEBUG(10,("access_check: failed to find object %s\n", ldb_dn_get_linearized(dn)));
+               return ret;
+       }
+       return dsdb_check_access_on_dn_internal(acl_res,
+                                               mem_ctx,
+                                               session_info->security_token,
+                                               dn,
+                                               access,
+                                               guid);
+}
+
+
 static int acl_module_init(struct ldb_module *module)
 {
        struct ldb_context *ldb;
@@ -606,7 +645,7 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
 
        guid = class_schemaid_guid_by_lDAPDisplayName(dsdb_get_schema(ldb),
                                                      (char *)oc_el->values[oc_el->num_values-1].data);
-       ret = dsdb_check_access_on_dn(ldb, req, parent, SEC_ADS_CREATE_CHILD, guid);
+       ret = dsdb_module_check_access_on_dn(module, req, parent, SEC_ADS_CREATE_CHILD, guid);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
@@ -787,7 +826,7 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req)
        }
        ldb = ldb_module_get_ctx(module);
        /* first check if we have delete object right */
-       ret = dsdb_check_access_on_dn(ldb, req, req->op.del.dn, SEC_STD_DELETE, NULL);
+       ret = dsdb_module_check_access_on_dn(module, req, req->op.del.dn, SEC_STD_DELETE, NULL);
        if (ret == LDB_SUCCESS) {
                return ldb_next_request(module, req);
        }
@@ -801,7 +840,7 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req)
                return ldb_module_done(req, NULL, NULL, LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS);
        }
 
-       ret = dsdb_check_access_on_dn(ldb, req, parent, SEC_ADS_DELETE_CHILD, NULL);
+       ret = dsdb_module_check_access_on_dn(module, req, parent, SEC_ADS_DELETE_CHILD, NULL);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
@@ -932,7 +971,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
                return ldb_module_done(req, NULL, NULL,  LDB_ERR_OPERATIONS_ERROR);
        }
 
-       ret = dsdb_check_access_on_dn(ldb, req, newparent, SEC_ADS_CREATE_CHILD, guid);
+       ret = dsdb_module_check_access_on_dn(module, req, newparent, SEC_ADS_CREATE_CHILD, guid);
        if (ret != LDB_SUCCESS) {
                DEBUG(10,("acl:access_denied renaming %s", ldb_dn_get_linearized(req->op.rename.olddn)));
                return ret;
@@ -949,7 +988,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
                return ldb_next_request(module, req);
        }
        /* what about delete child on the current parent */
-       ret = dsdb_check_access_on_dn(ldb, req, oldparent, SEC_ADS_DELETE_CHILD, NULL);
+       ret = dsdb_module_check_access_on_dn(module, req, oldparent, SEC_ADS_DELETE_CHILD, NULL);
        if (ret != LDB_SUCCESS) {
                DEBUG(10,("acl:access_denied renaming %s", ldb_dn_get_linearized(req->op.rename.olddn)));
                return ldb_module_done(req, NULL, NULL, ret);