summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb
diff options
context:
space:
mode:
authorNadezhda Ivanova <nivanova@samba.org>2010-08-26 11:09:58 +0300
committerKamen Mazdrashki <kamenim@samba.org>2010-09-10 13:08:19 +0300
commit36e663ad712c062805f6b17c45c2ae7fa5141dd9 (patch)
tree47dec1a7c74d60697b5d432e57515987a7813938 /source4/dsdb/samdb
parent5ba2858b0271feecf3f7bc5bee7577d0e181563d (diff)
downloadsamba-36e663ad712c062805f6b17c45c2ae7fa5141dd9.tar.gz
samba-36e663ad712c062805f6b17c45c2ae7fa5141dd9.tar.bz2
samba-36e663ad712c062805f6b17c45c2ae7fa5141dd9.zip
s4-ldap: Added support for FSMO role transfer via LDAP by modify on rootDSE
GetNCChanges with the corresponding extended operation is initiated and added to the queue when a modify request is received on becomeSchemaMaster, becomeRidMaster, becomeNamingMaster, becomeInfrastructureMaster and becomePDC attributes in rootDSE.
Diffstat (limited to 'source4/dsdb/samdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/rootdse.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index 0949b83b43..f77fcbed23 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -30,6 +30,9 @@
#include "libcli/security/security.h"
#include "librpc/ndr/libndr.h"
#include "auth/auth.h"
+#include "param/param.h"
+#include "lib/messaging/irpc.h"
+#include "librpc/gen_ndr/ndr_irpc.h"
struct private_data {
unsigned int num_controls;
@@ -971,6 +974,34 @@ static int rootdse_add(struct ldb_module *module, struct ldb_request *req)
return LDB_ERR_NAMING_VIOLATION;
}
+static int rootdse_become_master(struct ldb_module *module,
+ struct ldb_request *req,
+ uint32_t role)
+{
+ struct drepl_takeFSMORole r;
+ struct server_id *sid;
+ struct messaging_context *msg;
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
+ TALLOC_CTX *tmp_ctx = talloc_new(req);
+ struct loadparm_context *lp_ctx = ldb_get_opaque(ldb, "loadparm");
+ NTSTATUS status_call, status_fn;
+
+ msg = messaging_client_init(tmp_ctx, lpcfg_messaging_path(tmp_ctx, lp_ctx),
+ ldb_get_event_context(ldb));
+
+ sid = irpc_servers_byname(msg, tmp_ctx, "dreplsrv");
+ r.in.role = role;
+ status_call = IRPC_CALL(msg, sid[0], irpc, DREPL_TAKEFSMOROLE, &r, NULL);
+ if (!NT_STATUS_IS_OK(status_call)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ status_fn = r.out.result;
+ if (!NT_STATUS_IS_OK(status_fn)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
+}
+
static int rootdse_modify(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
@@ -989,7 +1020,21 @@ static int rootdse_modify(struct ldb_module *module, struct ldb_request *req)
if (ldb_msg_find_element(req->op.mod.message, "schemaUpdateNow")) {
return rootdse_schemaupdatenow(module, req);
}
-
+ if (ldb_msg_find_element(req->op.mod.message, "becomeDomainMaster")) {
+ return rootdse_become_master(module, req, DREPL_NAMING_MASTER);
+ }
+ if (ldb_msg_find_element(req->op.mod.message, "becomeInfrastructureMaster")) {
+ return rootdse_become_master(module, req, DREPL_INFRASTRUCTURE_MASTER);
+ }
+ if (ldb_msg_find_element(req->op.mod.message, "becomeRidMaster")) {
+ return rootdse_become_master(module, req, DREPL_RID_MASTER);
+ }
+ if (ldb_msg_find_element(req->op.mod.message, "becomeSchemaMaster")) {
+ return rootdse_become_master(module, req, DREPL_SCHEMA_MASTER);
+ }
+ if (ldb_msg_find_element(req->op.mod.message, "becomePdc")) {
+ return rootdse_become_master(module, req, DREPL_PDC_MASTER);
+ }
if (ldb_msg_find_element(req->op.mod.message, "enableOptionalFeature")) {
return rootdse_enableoptionalfeature(module, req);
}