s4:dsdb Fix of double addition of SD-s
[ira/wip.git] / source4 / dsdb / samdb / ldb_modules / descriptor.c
index a22cce76a1cfa40f59cb98cd85c8620dd2736da4..544fb8c49c536934b588cd1f4eb395c2fc626ff7 100644 (file)
@@ -1,4 +1,4 @@
-   /*
+/*
    ldb database library
 
    Copyright (C) Simo Sorce  2006-2008
@@ -42,6 +42,9 @@
 #include "auth/auth.h"
 #include "param/param.h"
 
+struct descriptor_data {
+};
+
 struct descriptor_context {
                struct ldb_module *module;
                struct ldb_request *req;
@@ -49,15 +52,15 @@ struct descriptor_context {
                int (*step_fn)(struct descriptor_context *);
 };
 
-static struct dsdb_class * get_last_structural_class(const struct dsdb_schema *schema, struct ldb_message_element *element)
+static const struct dsdb_class * get_last_structural_class(const struct dsdb_schema *schema, struct ldb_message_element *element)
 {
-       struct dsdb_class *last_class = NULL;
+       const struct dsdb_class *last_class = NULL;
        int i;
        for (i = 0; i < element->num_values; i++){
-               if (!last_class)
+               if (!last_class) {
                        last_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &element->values[i]);
-               else {
-                       struct dsdb_class *tmp_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &element->values[i]);
+               else {
+                       const struct dsdb_class *tmp_class = dsdb_class_by_lDAPDisplayName_ldb_val(schema, &element->values[i]);
                        if (tmp_class->subClass_order > last_class->subClass_order)
                                last_class = tmp_class;
                }
@@ -136,9 +139,11 @@ static struct dom_sid *get_default_group(TALLOC_CTX *mem_ctx,
 {
        int *domainFunctionality;
 
-       domainFunctionality = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int);
+       domainFunctionality = talloc_get_type(
+               ldb_get_opaque(ldb, "domainFunctionality"), int);
 
-       if (*domainFunctionality && (*domainFunctionality >= DS_BEHAVIOR_WIN2008)){
+       if (*domainFunctionality
+                       && (*domainFunctionality >= DS_DOMAIN_FUNCTION_2008)) {
                return dag;
        }
 
@@ -149,7 +154,7 @@ static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
                                     struct ldb_dn *dn,
                                     TALLOC_CTX *mem_ctx,
                                     const struct dsdb_class *objectclass,
-                                    struct ldb_val *parent,
+                                    const struct ldb_val *parent,
                                     struct ldb_val *object)
 {
        struct security_descriptor *user_descriptor = NULL, *parent_descriptor = NULL;
@@ -164,7 +169,7 @@ static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
        struct dom_sid *default_owner;
        struct dom_sid *default_group;
 
-       if (object){
+       if (object) {
                user_descriptor = talloc(mem_ctx, struct security_descriptor);
                if(!user_descriptor)
                        return NULL;
@@ -176,9 +181,9 @@ static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
                        talloc_free(user_descriptor);
                        return NULL;
                }
-       }
-       else
+       } else {
                user_descriptor = get_sd_unpacked(module, mem_ctx, objectclass);
+       }
 
        if (parent){
                parent_descriptor = talloc(mem_ctx, struct security_descriptor);
@@ -262,6 +267,8 @@ static int get_search_callback(struct ldb_request *req, struct ldb_reply *ares)
                                        ares->response, ares->error);
        }
 
+       ldb_reset_err_string(ldb);
+
        switch (ares->type) {
        case LDB_REPLY_ENTRY:
                if (ac->search_res != NULL) {
@@ -324,9 +331,10 @@ static int descriptor_do_add(struct descriptor_context *ac)
        struct ldb_message *msg;
        TALLOC_CTX *mem_ctx;
        int ret;
-       struct ldb_val *sd_val = NULL, *parentsd_val = NULL;
+       struct ldb_val *sd_val = NULL;
+       const struct ldb_val *parentsd_val = NULL;
        DATA_BLOB *sd;
-       struct dsdb_class *objectclass;
+       const struct dsdb_class *objectclass;
 
        ldb = ldb_module_get_ctx(ac->module);
        schema = dsdb_get_schema(ldb);
@@ -343,32 +351,42 @@ static int descriptor_do_add(struct descriptor_context *ac)
        objectclass_element = ldb_msg_find_element(msg, "objectClass");
        objectclass = get_last_structural_class(schema, objectclass_element);
 
-       if (!objectclass)
+       if (!objectclass) {
+               ldb_asprintf_errstring(ldb, "No last structural objectclass found on %s", ldb_dn_get_linearized(msg->dn));
                return LDB_ERR_OPERATIONS_ERROR;
+       }
 
        if (sd_element)
                sd_val = &sd_element->values[0];
        /* NC's have no parent */
        if ((ldb_dn_compare(msg->dn, (ldb_get_schema_basedn(ldb))) == 0) ||
-                       (ldb_dn_compare(msg->dn, (ldb_get_config_basedn(ldb))) == 0) ||
-                       (ldb_dn_compare(msg->dn, (ldb_get_root_basedn(ldb))) == 0))
+           (ldb_dn_compare(msg->dn, (ldb_get_config_basedn(ldb))) == 0) ||
+           (ldb_dn_compare(msg->dn, (ldb_get_root_basedn(ldb))) == 0)) {
                parentsd_val = NULL;
-       else if (ac->search_res != NULL)
+       } else if (ac->search_res != NULL){
                parentsd_val = ldb_msg_find_ldb_val(ac->search_res->message, "nTSecurityDescriptor");
-
+       }
 
        /* get the parent descriptor and the one provided. If not provided, get the default.*/
        /* convert to security descriptor and calculate */
        sd = get_new_descriptor(ac->module, msg->dn, mem_ctx, objectclass,
                        parentsd_val, sd_val);
+       if (sd_val) {
+               ldb_msg_remove_attr(msg, "nTSecurityDescriptor");
+       }
+
        if (sd) {
-               ldb_msg_add_steal_value(msg, "nTSecurityDescriptor", sd);
+               ret = ldb_msg_add_steal_value(msg, "nTSecurityDescriptor", sd);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
        }
 
        talloc_free(mem_ctx);
        ret = ldb_msg_sanity_check(ldb, msg);
 
        if (ret != LDB_SUCCESS) {
+               ldb_asprintf_errstring(ldb, "No last structural objectclass found on %s", ldb_dn_get_linearized(msg->dn));
                return ret;
        }
 
@@ -392,8 +410,10 @@ static int descriptor_add(struct ldb_module *module, struct ldb_request *req)
        struct descriptor_context *ac;
        struct ldb_dn *parent_dn;
        int ret;
+       struct descriptor_data *data;
        static const char * const descr_attrs[] = { "nTSecurityDescriptor", NULL };
 
+       data = talloc_get_type(ldb_module_get_private(module), struct descriptor_data);
        ldb = ldb_module_get_ctx(module);
 
        ldb_debug(ldb, LDB_DEBUG_TRACE, "descriptor_add\n");
@@ -449,11 +469,29 @@ static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
        return ldb_next_request(module, req);
 }
 
+static int descriptor_init(struct ldb_module *module)
+{
+       struct ldb_context *ldb;
+       struct descriptor_data *data;
+
+       ldb = ldb_module_get_ctx(module);
+       data = talloc(module, struct descriptor_data);
+       if (data == NULL) {
+               ldb_oom(ldb);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       ldb_module_set_private(module, data);
+       return ldb_next_init(module);
+}
+
+
 _PUBLIC_ const struct ldb_module_ops ldb_descriptor_module_ops = {
        .name              = "descriptor",
        .add           = descriptor_add,
        .modify        = descriptor_modify,
        .rename        = descriptor_rename,
+       .init_context  = descriptor_init
 };