From 0a4746a20085a21bd8f28faf13bc5168f3ad5afb Mon Sep 17 00:00:00 2001 From: Dave Craft Date: Sun, 4 Dec 2011 11:06:47 -0600 Subject: Invocation of samba_kcc from KCC task Modification to periodic and explicit invocation paths of the KCC topology generation code. Managed via samba_runcmd_send() API. The samba_kcc script is invoked if (kccsrv:samba_kcc = true) appears in smb.conf Signed-off-by: Andrew Tridgell --- source4/dsdb/kcc/kcc_periodic.c | 72 ++++++++++++++++++++++++++++++++++++++--- source4/dsdb/kcc/kcc_service.c | 36 ++++++++++++--------- source4/dsdb/wscript_build | 2 +- 3 files changed, 89 insertions(+), 21 deletions(-) diff --git a/source4/dsdb/kcc/kcc_periodic.c b/source4/dsdb/kcc/kcc_periodic.c index d9a716f61f..f4374d2722 100644 --- a/source4/dsdb/kcc/kcc_periodic.c +++ b/source4/dsdb/kcc/kcc_periodic.c @@ -588,12 +588,17 @@ static void kccsrv_periodic_run(struct kccsrv_service *service) TALLOC_CTX *mem_ctx; NTSTATUS status; - DEBUG(4,("kccsrv_periodic_run(): simple update\n")); + DEBUG(4,("kccsrv_periodic_run(): update\n")); mem_ctx = talloc_new(service); - status = kccsrv_simple_update(service, mem_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("kccsrv_simple_update failed - %s\n", nt_errstr(status))); + + if (service->samba_kcc_code) + status = kccsrv_samba_kcc(service, mem_ctx); + else { + status = kccsrv_simple_update(service, mem_ctx); + if (!NT_STATUS_IS_OK(status)) + DEBUG(0,("kccsrv_simple_update failed - %s\n", + nt_errstr(status))); } status = kccsrv_check_deleted(service, mem_ctx); @@ -602,3 +607,62 @@ static void kccsrv_periodic_run(struct kccsrv_service *service) } talloc_free(mem_ctx); } + +/* Called when samba_kcc script has finished + */ +static void samba_kcc_done(struct tevent_req *subreq) +{ + struct kccsrv_service *service = + tevent_req_callback_data(subreq, struct kccsrv_service); + int rc; + int sys_errno; + + service->periodic.subreq = NULL; + + rc = samba_runcmd_recv(subreq, &sys_errno); + TALLOC_FREE(subreq); + + if (rc != 0) + service->periodic.status = + map_nt_error_from_unix_common(sys_errno); + else + service->periodic.status = NT_STATUS_OK; + + if (!NT_STATUS_IS_OK(service->periodic.status)) + DEBUG(0,(__location__ ": Failed samba_kcc - %s\n", + nt_errstr(service->periodic.status))); + else + DEBUG(3,("Completed samba_kcc OK\n")); +} + +/* Invocation of the samba_kcc python script for replication + * topology generation. + */ +NTSTATUS kccsrv_samba_kcc(struct kccsrv_service *service, + TALLOC_CTX *ctxp) +{ + NTSTATUS status = NT_STATUS_OK; + const char * const *samba_kcc_command = + lpcfg_samba_kcc_command(service->task->lp_ctx); + + /* kill any existing child */ + TALLOC_FREE(service->periodic.subreq); + + DEBUG(0,("Calling samba_kcc script\n")); + service->periodic.subreq = samba_runcmd_send(service, + service->task->event_ctx, + timeval_current_ofs(40, 0), + 2, 0, samba_kcc_command, NULL); + + if (service->periodic.subreq == NULL) { + status = NT_STATUS_NO_MEMORY; + goto xerror; + } + tevent_req_set_callback(service->periodic.subreq, + samba_kcc_done, service); + +xerror: + if (!NT_STATUS_IS_OK(status)) + DEBUG(0,(__location__ ": failed - %s\n", nt_errstr(status))); + return status; +} diff --git a/source4/dsdb/kcc/kcc_service.c b/source4/dsdb/kcc/kcc_service.c index 5f7b537d14..ac19522698 100644 --- a/source4/dsdb/kcc/kcc_service.c +++ b/source4/dsdb/kcc/kcc_service.c @@ -144,16 +144,18 @@ static WERROR kccsrv_load_partitions(struct kccsrv_service *s) static NTSTATUS kccsrv_execute_kcc(struct irpc_message *msg, struct drsuapi_DsExecuteKCC *r) { TALLOC_CTX *mem_ctx; - NTSTATUS status; + NTSTATUS status = NT_STATUS_OK; struct kccsrv_service *service = talloc_get_type(msg->private_data, struct kccsrv_service); mem_ctx = talloc_new(service); - status = kccsrv_simple_update(service, mem_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("kccsrv_simple_update failed - %s\n", nt_errstr(status))); - talloc_free(mem_ctx); - return status; + if (service->samba_kcc_code) + status = kccsrv_samba_kcc(service, mem_ctx); + else { + status = kccsrv_simple_update(service, mem_ctx); + if (!NT_STATUS_IS_OK(status)) + DEBUG(0,("kccsrv_execute_kcc failed - %s\n", + nt_errstr(status))); } talloc_free(mem_ctx); @@ -222,10 +224,18 @@ static void kccsrv_task_init(struct task_server *task) return; } - periodic_startup_interval = lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv", - "periodic_startup_interval", 15); /* in seconds */ - service->periodic.interval = lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv", - "periodic_interval", 300); /* in seconds */ + periodic_startup_interval = + lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv", + "periodic_startup_interval", 15); /* in seconds */ + service->periodic.interval = + lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv", + "periodic_interval", 300); /* in seconds */ + + /* (kccsrv:samba_kcc=true) will run newer samba_kcc replication + * topology generation code. + */ + service->samba_kcc_code = lpcfg_parm_bool(task->lp_ctx, NULL, + "kccsrv", "samba_kcc", false); status = kccsrv_periodic_schedule(service, periodic_startup_interval); if (!W_ERROR_IS_OK(status)) { @@ -235,12 +245,6 @@ static void kccsrv_task_init(struct task_server *task) return; } - /* (kccsrv:intrasite=true) will run newer intrasite replication - * topology code. - */ - service->intrasite_code = lpcfg_parm_bool(task->lp_ctx, NULL, "kccsrv", - "intrasite", false); - irpc_add_name(task->msg_ctx, "kccsrv"); IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSEXECUTEKCC, kccsrv_execute_kcc, service); diff --git a/source4/dsdb/wscript_build b/source4/dsdb/wscript_build index 7645ae7700..0eb4eebe1f 100644 --- a/source4/dsdb/wscript_build +++ b/source4/dsdb/wscript_build @@ -43,7 +43,7 @@ bld.SAMBA_MODULE('service_kcc', autoproto='kcc/kcc_service_proto.h', subsystem='service', init_function='server_service_kcc_init', - deps='samdb process_model RPC_NDR_IRPC RPC_NDR_DRSUAPI', + deps='samdb process_model RPC_NDR_IRPC RPC_NDR_DRSUAPI UTIL_RUNCMD', internal_module=False, ) -- cgit