dsdb: Move ldb_set_default_dns() into rootdse_get_private_data()
[metze/samba/wip.git] / source4 / dsdb / samdb / ldb_modules / rootdse.c
index 86ca89f1eb6d704b2d10549b1297682218a63bd4..751fe15d1a17b8de3789131de5a55e622efb737c 100644 (file)
@@ -217,7 +217,7 @@ static int dsdb_module_we_are_master(struct ldb_module *module, struct ldb_dn *d
                talloc_free(tmp_ctx);
                return ret;
        }
-       
+
        talloc_free(tmp_ctx);
        return LDB_SUCCESS;
 }
@@ -738,11 +738,11 @@ static int rootdse_filter_operations(struct ldb_module *module, struct ldb_reque
        if (session_info) {
                is_anonymous = security_token_is_anonymous(session_info->security_token);
        }
-       
+
        if (is_anonymous == false || (priv && priv->block_anonymous == false)) {
                return LDB_SUCCESS;
        }
-       
+
        if (req->operation == LDB_SEARCH) {
                if (req->op.search.scope == LDB_SCOPE_BASE && ldb_dn_is_null(req->op.search.base)) {
                        return LDB_SUCCESS;
@@ -863,11 +863,51 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
        return ldb_next_request(module, down_req);
 }
 
+static struct rootdse_private_data *rootdse_get_private_data(struct ldb_module *module)
+{
+       void *priv = ldb_module_get_private(module);
+       struct rootdse_private_data *data = NULL;
+       struct ldb_context *ldb
+               = ldb_module_get_ctx(module);
+
+       if (priv != NULL) {
+               data = talloc_get_type_abort(priv,
+                                            struct rootdse_private_data);
+       }
+
+       if (data != NULL) {
+               return data;
+       }
+
+       data = talloc_zero(module, struct rootdse_private_data);
+       if (data == NULL) {
+               return NULL;
+       }
+
+       data->num_controls = 0;
+       data->controls = NULL;
+       data->num_partitions = 0;
+       data->partitions = NULL;
+       data->block_anonymous = true;
+
+       ldb_module_set_private(module, data);
+
+       ldb_set_default_dns(ldb);
+
+       return data;
+}
+
+
 static int rootdse_register_control(struct ldb_module *module, struct ldb_request *req)
 {
-       struct rootdse_private_data *priv = talloc_get_type(ldb_module_get_private(module), struct rootdse_private_data);
+       struct rootdse_private_data *priv =
+               rootdse_get_private_data(module);
        char **list;
 
+       if (priv == NULL) {
+               return ldb_module_oom(module);
+       }
+
        list = talloc_realloc(priv, priv->controls, char *, priv->num_controls + 1);
        if (!list) {
                return ldb_oom(ldb_module_get_ctx(module));
@@ -886,9 +926,14 @@ static int rootdse_register_control(struct ldb_module *module, struct ldb_reques
 
 static int rootdse_register_partition(struct ldb_module *module, struct ldb_request *req)
 {
-       struct rootdse_private_data *priv = talloc_get_type(ldb_module_get_private(module), struct rootdse_private_data);
+       struct rootdse_private_data *priv =
+               rootdse_get_private_data(module);
        struct ldb_dn **list;
 
+       if (priv == NULL) {
+               return ldb_module_oom(module);
+       }
+
        list = talloc_realloc(priv, priv->partitions, struct ldb_dn *, priv->num_partitions + 1);
        if (!list) {
                return ldb_oom(ldb_module_get_ctx(module));
@@ -924,30 +969,21 @@ static int rootdse_request(struct ldb_module *module, struct ldb_request *req)
 static int rootdse_init(struct ldb_module *module)
 {
        int ret;
-       struct ldb_context *ldb;
        struct ldb_result *res;
-       struct rootdse_private_data *data;
        const char *attrs[] = { "msDS-Behavior-Version", NULL };
        const char *ds_attrs[] = { "dsServiceName", NULL };
        TALLOC_CTX *mem_ctx;
 
-       ldb = ldb_module_get_ctx(module);
+       struct ldb_context *ldb
+               = ldb_module_get_ctx(module);
+
+       struct rootdse_private_data *data
+               = rootdse_get_private_data(module);
 
-       data = talloc_zero(module, struct rootdse_private_data);
        if (data == NULL) {
-               return ldb_oom(ldb);
+               return ldb_module_oom(module);
        }
 
-       data->num_controls = 0;
-       data->controls = NULL;
-       data->num_partitions = 0;
-       data->partitions = NULL;
-       data->block_anonymous = true;
-
-       ldb_module_set_private(module, data);
-
-       ldb_set_default_dns(ldb);
-
        ret = ldb_next_init(module);
 
        if (ret != LDB_SUCCESS) {
@@ -1306,12 +1342,28 @@ static int rootdse_schemaupdatenow(struct ldb_module *module, struct ldb_request
                return ldb_next_request(module, req);
        }
 
+       /*
+        * schemaUpdateNow has been requested. Allow this to refresh the schema
+        * even if we're currently in the middle of a transaction
+        */
+       ret = ldb_set_opaque(ldb, "dsdb_schema_refresh_expected", (void *)1);
+       if (ret != LDB_SUCCESS) {
+               return ldb_operr(ldb);
+       }
+
        ret = ldb_extended(ldb, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID, schema_dn, &ext_res);
        if (ret != LDB_SUCCESS) {
+               ldb_set_opaque(ldb, "dsdb_schema_refresh_expected", (void *)0);
                return ldb_operr(ldb);
        }
 
        talloc_free(ext_res);
+
+       ret = ldb_set_opaque(ldb, "dsdb_schema_refresh_expected", (void *)0);
+       if (ret != LDB_SUCCESS) {
+               return ldb_operr(ldb);
+       }
+
        return ldb_module_done(req, NULL, NULL, ret);
 }
 
@@ -1520,6 +1572,12 @@ static int rootdse_become_master(struct ldb_module *module,
         */
        rootdse_del_trans(module);
 
+       /*
+        * We must use the global event loop to run this IRPC in
+        * single process mode
+        */
+       ldb_handle_use_global_event_context(req->handle);
+
        msg = imessaging_client_init(tmp_ctx, lp_ctx,
                                    ldb_get_event_context(ldb));
        if (!msg) {