From 36e663ad712c062805f6b17c45c2ae7fa5141dd9 Mon Sep 17 00:00:00 2001 From: Nadezhda Ivanova Date: Thu, 26 Aug 2010 11:09:58 +0300 Subject: 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. --- source4/dsdb/samdb/ldb_modules/rootdse.c | 47 +++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'source4/dsdb/samdb/ldb_modules') 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); } -- cgit