idmap_autorid: Fix a race condition when acquiring ranges
authorVolker Lendecke <vl@samba.org>
Fri, 2 Dec 2016 15:37:49 +0000 (15:37 +0000)
committerVolker Lendecke <vl@samba.org>
Fri, 16 Dec 2016 16:38:20 +0000 (17:38 +0100)
Here we are in a transaction to create a range, but we already found
one to exist. We need to return the information about this range to the
caller, just as we do when actually allocating the range. This does not
hit us with current code, as we just have one idmap child. However, if
we parallelize that, two children might have found a domain to not exist
and call idmap_autorid_acquire_range simultaneously. One will create
the range, the other one will find it to already exist. The second child
will also have to pass the info up.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/winbindd/idmap_autorid_tdb.c

index 3386380cda4439905a32661c84c603e6b42ceb2b..702a2f6f36977d4edeb3fb4de7a79b563291fe65 100644 (file)
@@ -127,6 +127,26 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
                if (acquire) {
                        DEBUG(10, ("domain range already allocated - "
                                   "Not adding!\n"));
+
+                       mem_ctx = talloc_stackframe();
+
+                       ret = idmap_autorid_loadconfig(db, mem_ctx,
+                                                      &globalcfg);
+                       if (!NT_STATUS_IS_OK(ret)) {
+                               DEBUG(1, ("Fatal error while fetching "
+                                         "configuration: %s\n",
+                                         nt_errstr(ret)));
+                               goto error;
+                       }
+
+                       range->rangenum = stored_rangenum;
+                       range->low_id = globalcfg->minvalue
+                               + range->rangenum * globalcfg->rangesize;
+                       range->high_id =
+                               range->low_id  + globalcfg->rangesize - 1;
+
+                       TALLOC_FREE(mem_ctx);
+
                        return NT_STATUS_OK;
                }