summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2013-01-15 09:56:46 +1100
committerStefan Metzmacher <metze@samba.org>2013-01-17 15:10:10 +0100
commit18d7e5df0eb8fb593e66daf25d142584f44b5b87 (patch)
tree96c899b64e46d1ceca99b4006c2946383e341f64 /source4/dsdb/samdb
parentb40d134bc1866dd7e5b5e7dfc5bf01f6d55b1c1f (diff)
downloadsamba-18d7e5df0eb8fb593e66daf25d142584f44b5b87.tar.gz
samba-18d7e5df0eb8fb593e66daf25d142584f44b5b87.tar.bz2
samba-18d7e5df0eb8fb593e66daf25d142584f44b5b87.zip
dsdb: Do not hold the transaction over the IRPC call to perform a role transfer
This avoids one samba process locking out another from the DB. Andrew Bartlett Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source4/dsdb/samdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/rootdse.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index add83d293a..eaf64517d9 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -1297,6 +1297,7 @@ static int rootdse_add(struct ldb_module *module, struct ldb_request *req)
struct fsmo_transfer_state {
struct ldb_context *ldb;
struct ldb_request *req;
+ struct ldb_module *module;
};
/*
@@ -1307,6 +1308,7 @@ static void rootdse_fsmo_transfer_callback(struct tevent_req *treq)
struct fsmo_transfer_state *fsmo = tevent_req_callback_data(treq, struct fsmo_transfer_state);
NTSTATUS status;
WERROR werr;
+ int ret;
struct ldb_request *req = fsmo->req;
struct ldb_context *ldb = fsmo->ldb;
@@ -1314,16 +1316,31 @@ static void rootdse_fsmo_transfer_callback(struct tevent_req *treq)
talloc_free(fsmo);
if (!NT_STATUS_IS_OK(status)) {
ldb_asprintf_errstring(ldb, "Failed FSMO transfer: %s", nt_errstr(status));
+ /*
+ * Now that it is failed, start the transaction up
+ * again so the wrappers can close it without additional error
+ */
+ ldb_next_start_trans(fsmo->module);
ldb_module_done(req, NULL, NULL, LDB_ERR_UNAVAILABLE);
return;
}
if (!W_ERROR_IS_OK(werr)) {
ldb_asprintf_errstring(ldb, "Failed FSMO transfer: %s", win_errstr(werr));
+ /*
+ * Now that it is failed, start the transaction up
+ * again so the wrappers can close it without additional error
+ */
+ ldb_next_start_trans(fsmo->module);
ldb_module_done(req, NULL, NULL, LDB_ERR_UNAVAILABLE);
return;
}
- ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
+ /*
+ * Now that it is done, start the transaction up again so the
+ * wrappers can close it without error
+ */
+ ret = ldb_next_start_trans(fsmo->module);
+ ldb_module_done(req, NULL, NULL, ret);
}
static int rootdse_become_master(struct ldb_module *module,
@@ -1358,6 +1375,13 @@ static int rootdse_become_master(struct ldb_module *module,
"RODC cannot become a role master.");
}
+ /*
+ * We always delete the transaction, not commit it, because
+ * this gives the least supprise to this supprising action (as
+ * we will never record anything done to this point
+ */
+ ldb_next_del_trans(module);
+
msg = imessaging_client_init(tmp_ctx, lp_ctx,
ldb_get_event_context(ldb));
if (!msg) {
@@ -1376,6 +1400,7 @@ static int rootdse_become_master(struct ldb_module *module,
}
fsmo->ldb = ldb;
fsmo->req = req;
+ fsmo->module = module;
/*
* we send the call asynchronously, as the ldap client is