diff options
author | Andrew Bartlett <abartlet@samba.org> | 2013-01-15 09:56:46 +1100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2013-01-17 15:10:10 +0100 |
commit | 18d7e5df0eb8fb593e66daf25d142584f44b5b87 (patch) | |
tree | 96c899b64e46d1ceca99b4006c2946383e341f64 /source4/dsdb/samdb | |
parent | b40d134bc1866dd7e5b5e7dfc5bf01f6d55b1c1f (diff) | |
download | samba-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.c | 27 |
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 |