dsdb: ensure we take out a read lock during the dsdb_init
authorAndrew Bartlett <abartlet@samba.org>
Mon, 9 Apr 2018 06:13:59 +0000 (18:13 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 12 Apr 2018 03:15:17 +0000 (05:15 +0200)
We have to also take it out in the partitions code when we load the
partition backends.

This ensures that the init handlers hold a whole-db lock just as the
search code does.

To ensure the locking count in schema_load is balanced, the
private data is now created in the first lock_read() call.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
source4/dsdb/samdb/ldb_modules/partition.c
source4/dsdb/samdb/ldb_modules/partition_init.c
source4/dsdb/samdb/ldb_modules/samba_dsdb.c
source4/dsdb/samdb/ldb_modules/schema_load.c

index 37e714d6e1be78e0c79695efdf28ffda84eb659b..9fb1b9dee12f3285f32186fb6813030c7e2891c0 100644 (file)
@@ -1236,6 +1236,30 @@ int partition_read_lock(struct ldb_module *module)
         *   ordering
         */
 
         *   ordering
         */
 
+       if (data == NULL) {
+               TALLOC_CTX *mem_ctx = talloc_new(module);
+
+               data = talloc_zero(mem_ctx, struct partition_private_data);
+               if (data == NULL) {
+                       talloc_free(mem_ctx);
+                       return ldb_operr(ldb);
+               }
+
+               /*
+                * When used from Samba4, this message is set by the
+                * samba4 module, as a fixed value not read from the
+                * DB.  This avoids listing modules in the DB
+                */
+               data->forced_module_msg = talloc_get_type(
+                       ldb_get_opaque(ldb,
+                                      DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME),
+                       struct ldb_message);
+
+               ldb_module_set_private(module, talloc_steal(module,
+                                                           data));
+               talloc_free(mem_ctx);
+       }
+
        /*
         * This will lock the metadata partition (sam.ldb) and
         * will also call event loops, so we do it before we
        /*
         * This will lock the metadata partition (sam.ldb) and
         * will also call event loops, so we do it before we
index 9a6ac0c05a9d1bbd0ab659c15be59d8faeb2a5d9..9a8bb7e211dc94d0d86a600df1aa5b13682774c8 100644 (file)
@@ -863,18 +863,9 @@ int partition_init(struct ldb_module *module)
                return ldb_operr(ldb);
        }
 
                return ldb_operr(ldb);
        }
 
-       data = talloc_zero(mem_ctx, struct partition_private_data);
-       if (data == NULL) {
-               return ldb_operr(ldb);
-       }
-
-       /* When used from Samba4, this message is set by the samba4
-        * module, as a fixed value not read from the DB.  This avoids
-        * listing modules in the DB */
-       data->forced_module_msg = talloc_get_type(
-               ldb_get_opaque(ldb,
-                              DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME),
-               struct ldb_message);
+       /* We actually got this during the read_lock call */
+       data = talloc_get_type_abort(ldb_module_get_private(module),
+                                    struct partition_private_data);
 
        /* This loads the partitions */
        ret = partition_reload_if_required(module, data, NULL);
 
        /* This loads the partitions */
        ret = partition_reload_if_required(module, data, NULL);
index 2605c1e511e12cc4d82a43a5bc21e72c07df9ae4..54ec6a26068f0dc8cebbb75714503e3af34806af 100644 (file)
@@ -249,7 +249,7 @@ static bool check_required_features(struct ldb_message_element *el)
 static int samba_dsdb_init(struct ldb_module *module)
 {
        struct ldb_context *ldb = ldb_module_get_ctx(module);
 static int samba_dsdb_init(struct ldb_module *module)
 {
        struct ldb_context *ldb = ldb_module_get_ctx(module);
-       int ret, len, i, j;
+       int ret, lock_ret, len, i, j;
        TALLOC_CTX *tmp_ctx = talloc_new(module);
        struct ldb_result *res;
        struct ldb_message *rootdse_msg = NULL, *partition_msg;
        TALLOC_CTX *tmp_ctx = talloc_new(module);
        struct ldb_result *res;
        struct ldb_message *rootdse_msg = NULL, *partition_msg;
@@ -627,7 +627,20 @@ static int samba_dsdb_init(struct ldb_module *module)
        /* Set this as the 'next' module, so that we effectivly append it to module chain */
        ldb_module_set_next(module, module_chain);
 
        /* Set this as the 'next' module, so that we effectivly append it to module chain */
        ldb_module_set_next(module, module_chain);
 
-       return ldb_next_init(module);
+       ret = ldb_next_read_lock(module);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
+       ret = ldb_next_init(module);
+
+       lock_ret = ldb_next_read_unlock(module);
+
+       if (lock_ret != LDB_SUCCESS) {
+               return lock_ret;
+       }
+
+       return ret;
 }
 
 static const struct ldb_module_ops ldb_samba_dsdb_module_ops = {
 }
 
 static const struct ldb_module_ops ldb_samba_dsdb_module_ops = {
index cfd88fec467f35df2253ac12be4177019a54544a..e977e8b0ad5ef285706a8b9766bc5dc9b68f7e99 100644 (file)
@@ -498,17 +498,11 @@ static int schema_load(struct ldb_context *ldb,
 static int schema_load_init(struct ldb_module *module)
 {
        struct ldb_context *ldb = ldb_module_get_ctx(module);
 static int schema_load_init(struct ldb_module *module)
 {
        struct ldb_context *ldb = ldb_module_get_ctx(module);
-       struct schema_load_private_data *private_data;
+       struct schema_load_private_data *private_data =
+               talloc_get_type_abort(ldb_module_get_private(module),
+                                     struct schema_load_private_data);
        int ret;
 
        int ret;
 
-       private_data = talloc_zero(module, struct schema_load_private_data);
-       if (private_data == NULL) {
-               return ldb_oom(ldb);
-       }
-       private_data->module = module;
-
-       ldb_module_set_private(module, private_data);
-
        ret = ldb_next_init(module);
        if (ret != LDB_SUCCESS) {
                return ret;
        ret = ldb_next_init(module);
        if (ret != LDB_SUCCESS) {
                return ret;
@@ -618,7 +612,14 @@ static int schema_read_lock(struct ldb_module *module)
        int ret;
 
        if (private_data == NULL) {
        int ret;
 
        if (private_data == NULL) {
-               return ldb_next_read_lock(module);
+               private_data = talloc_zero(module, struct schema_load_private_data);
+               if (private_data == NULL) {
+                       return ldb_module_oom(module);
+               }
+
+               private_data->module = module;
+
+               ldb_module_set_private(module, private_data);
        }
 
        ret = ldb_next_read_lock(module);
        }
 
        ret = ldb_next_read_lock(module);
@@ -640,11 +641,8 @@ static int schema_read_lock(struct ldb_module *module)
 static int schema_read_unlock(struct ldb_module *module)
 {
        struct schema_load_private_data *private_data =
 static int schema_read_unlock(struct ldb_module *module)
 {
        struct schema_load_private_data *private_data =
-               talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
-
-       if (private_data == NULL) {
-               return ldb_next_read_unlock(module);
-       }
+               talloc_get_type_abort(ldb_module_get_private(module),
+                                     struct schema_load_private_data);
 
        private_data->in_read_transaction--;
 
 
        private_data->in_read_transaction--;