Skip to content

Commit

Permalink
source4 smdb: Add a post fork hook to the service API
Browse files Browse the repository at this point in the history
Add a post fork hook to the service API this will be called:

 - standard process model
   immediately after the task_init.

- single process model
  immediately after the task_init

- prefork process model, inhibit_pre_fork = true
  immediately after the task_init

- prefork process model, inhibit_pre_fork = false
  after each service worker has forked. It is not run on the service
  master process.

The post fork hook is not called in the standard model if a new process
is forked on a new connection. It is instead called immediately after
the task_init.

The task_init hook has been changed to return an error code. This ensures
the post_fork code is only run if the task_init code completed successfully.

Signed-off-by: Gary Lockyer <[email protected]>
  • Loading branch information
GaryWL committed Nov 1, 2018
1 parent d6777a6 commit 99aea42
Show file tree
Hide file tree
Showing 24 changed files with 317 additions and 182 deletions.
14 changes: 9 additions & 5 deletions file_server/file_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static void file_server_smbd_done(struct tevent_req *subreq)
/*
startup a copy of smbd as a child daemon
*/
static void s3fs_task_init(struct task_server *task)
static NTSTATUS s3fs_task_init(struct task_server *task)
{
struct tevent_req *subreq;
const char *smbd_path;
Expand All @@ -78,17 +78,19 @@ static void s3fs_task_init(struct task_server *task)
if (!winbind_off()) {
DEBUG(0,("Failed to re-disable recursive winbindd calls after forking smbd\n"));
task_server_terminate(task, "Failed to re-disable recursive winbindd calls", true);
return;
return NT_STATUS_UNSUCCESSFUL;
}
if (subreq == NULL) {
DEBUG(0, ("Failed to start smbd as child daemon\n"));
task_server_terminate(task, "Failed to startup s3fs smb task", true);
return;
return NT_STATUS_UNSUCCESSFUL;
}

tevent_req_set_callback(subreq, file_server_smbd_done, task);

DEBUG(5,("Started file server child smbd\n"));

return NT_STATUS_OK;
}

/* called at smbd startup - register ourselves as a server service */
Expand All @@ -98,7 +100,9 @@ NTSTATUS server_service_s3fs_init(TALLOC_CTX *ctx)
{
struct service_details details = {
.inhibit_fork_on_accept = true,
.inhibit_pre_fork = true
.inhibit_pre_fork = true,
.task_init = s3fs_task_init,
.post_fork = NULL
};
return register_server_service(ctx, "s3fs", s3fs_task_init, &details);
return register_server_service(ctx, "s3fs", &details);
}
23 changes: 13 additions & 10 deletions source4/cldap_server/cldap_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ static NTSTATUS cldapd_startup_interfaces(struct cldapd_server *cldapd, struct l
/*
startup the cldapd task
*/
static void cldapd_task_init(struct task_server *task)
static NTSTATUS cldapd_task_init(struct task_server *task)
{
struct cldapd_server *cldapd;
NTSTATUS status;
Expand All @@ -195,18 +195,18 @@ static void cldapd_task_init(struct task_server *task)

if (iface_list_count(ifaces) == 0) {
task_server_terminate(task, "cldapd: no network interfaces configured", false);
return;
return NT_STATUS_UNSUCCESSFUL;
}

switch (lpcfg_server_role(task->lp_ctx)) {
case ROLE_STANDALONE:
task_server_terminate(task, "cldap_server: no CLDAP server required in standalone configuration",
false);
return;
return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "cldap_server: no CLDAP server required in member server configuration",
false);
return;
return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want an CLDAP server */
break;
Expand All @@ -217,7 +217,7 @@ static void cldapd_task_init(struct task_server *task)
cldapd = talloc(task, struct cldapd_server);
if (cldapd == NULL) {
task_server_terminate(task, "cldapd: out of memory", true);
return;
return NT_STATUS_NO_MEMORY;
}

cldapd->task = task;
Expand All @@ -229,17 +229,19 @@ static void cldapd_task_init(struct task_server *task)
0);
if (cldapd->samctx == NULL) {
task_server_terminate(task, "cldapd failed to open samdb", true);
return;
return NT_STATUS_UNSUCCESSFUL;
}

/* start listening on the configured network interfaces */
status = cldapd_startup_interfaces(cldapd, task->lp_ctx, ifaces);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "cldapd failed to setup interfaces", true);
return;
return status;
}

irpc_add_name(task->msg_ctx, "cldap_server");

return NT_STATUS_OK;
}


Expand All @@ -250,8 +252,9 @@ NTSTATUS server_service_cldapd_init(TALLOC_CTX *ctx)
{
static const struct service_details details = {
.inhibit_fork_on_accept = true,
.inhibit_pre_fork = true
.inhibit_pre_fork = true,
.task_init = cldapd_task_init,
.post_fork = NULL
};
return register_server_service(ctx, "cldap", cldapd_task_init,
&details);
return register_server_service(ctx, "cldap", &details);
}
35 changes: 19 additions & 16 deletions source4/dns_server/dns_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ static NTSTATUS dns_reload_zones(struct irpc_message *msg,
return NT_STATUS_OK;
}

static void dns_task_init(struct task_server *task)
static NTSTATUS dns_task_init(struct task_server *task)
{
struct dns_server *dns;
NTSTATUS status;
Expand All @@ -804,10 +804,10 @@ static void dns_task_init(struct task_server *task)
switch (lpcfg_server_role(task->lp_ctx)) {
case ROLE_STANDALONE:
task_server_terminate(task, "dns: no DNS required in standalone configuration", false);
return;
return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "dns: no DNS required in member server configuration", false);
return;
return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want a DNS */
break;
Expand All @@ -818,7 +818,7 @@ static void dns_task_init(struct task_server *task)

if (iface_list_count(ifaces) == 0) {
task_server_terminate(task, "dns: no network interfaces configured", false);
return;
return NT_STATUS_UNSUCCESSFUL;
}
}

Expand All @@ -827,15 +827,15 @@ static void dns_task_init(struct task_server *task)
dns = talloc_zero(task, struct dns_server);
if (dns == NULL) {
task_server_terminate(task, "dns: out of memory", true);
return;
return NT_STATUS_NO_MEMORY;
}

dns->task = task;

dns->server_credentials = cli_credentials_init(dns);
if (!dns->server_credentials) {
task_server_terminate(task, "Failed to init server credentials\n", true);
return;
return NT_STATUS_UNSUCCESSFUL;
}

dns->samdb = samdb_connect(dns,
Expand All @@ -846,7 +846,7 @@ static void dns_task_init(struct task_server *task)
0);
if (!dns->samdb) {
task_server_terminate(task, "dns: samdb_connect failed", true);
return;
return NT_STATUS_UNSUCCESSFUL;
}

cli_credentials_set_conf(dns->server_credentials, task->lp_ctx);
Expand All @@ -865,7 +865,7 @@ static void dns_task_init(struct task_server *task)
TALLOC_FREE(dns_acc);
if (!dns_spn) {
task_server_terminate(task, "dns: talloc_asprintf failed", true);
return;
return NT_STATUS_UNSUCCESSFUL;
}
status = cli_credentials_set_stored_principal(dns->server_credentials, task->lp_ctx, dns_spn);
if (!NT_STATUS_IS_OK(status)) {
Expand All @@ -874,7 +874,7 @@ static void dns_task_init(struct task_server *task)
"despite finding it in the samdb! %s\n",
nt_errstr(status)),
true);
return;
return status;
}
} else {
TALLOC_FREE(dns_spn);
Expand All @@ -884,48 +884,51 @@ static void dns_task_init(struct task_server *task)
talloc_asprintf(task, "Failed to obtain server credentials, perhaps a standalone server?: %s\n",
nt_errstr(status)),
true);
return;
return status;
}
}

dns->tkeys = tkey_store_init(dns, TKEY_BUFFER_SIZE);
if (!dns->tkeys) {
task_server_terminate(task, "Failed to allocate tkey storage\n", true);
return;
return NT_STATUS_NO_MEMORY;
}

status = dns_server_reload_zones(dns);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "dns: failed to load DNS zones", true);
return;
return status;
}

status = dns_startup_interfaces(dns, ifaces, task->model_ops);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "dns failed to setup interfaces", true);
return;
return status;
}

/* Setup the IRPC interface and register handlers */
status = irpc_add_name(task->msg_ctx, "dnssrv");
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "dns: failed to register IRPC name", true);
return;
return status;
}

status = IRPC_REGISTER(task->msg_ctx, irpc, DNSSRV_RELOAD_DNS_ZONES,
dns_reload_zones, dns);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "dns: failed to setup reload handler", true);
return;
return status;
}
return NT_STATUS_OK;
}

NTSTATUS server_service_dns_init(TALLOC_CTX *ctx)
{
static const struct service_details details = {
.inhibit_fork_on_accept = true,
.inhibit_pre_fork = true,
.task_init = dns_task_init,
.post_fork = NULL
};
return register_server_service(ctx, "dns", dns_task_init, &details);
return register_server_service(ctx, "dns", &details);
}
20 changes: 11 additions & 9 deletions source4/dsdb/dns/dns_update.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,22 +633,22 @@ static NTSTATUS dnsupdate_dnsupdate_RODC(struct irpc_message *msg,
/*
startup the dns update task
*/
static void dnsupdate_task_init(struct task_server *task)
static NTSTATUS dnsupdate_task_init(struct task_server *task)
{
NTSTATUS status;
struct dnsupdate_service *service;

if (lpcfg_server_role(task->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) {
/* not useful for non-DC */
return;
return NT_STATUS_INVALID_DOMAIN_ROLE;
}

task_server_set_title(task, "task[dnsupdate]");

service = talloc_zero(task, struct dnsupdate_service);
if (!service) {
task_server_terminate(task, "dnsupdate_task_init: out of memory", true);
return;
return NT_STATUS_NO_MEMORY;
}
service->task = task;
task->private_data = service;
Expand All @@ -658,7 +658,7 @@ static void dnsupdate_task_init(struct task_server *task)
task_server_terminate(task,
"dnsupdate: Failed to obtain server credentials\n",
true);
return;
return NT_STATUS_UNSUCCESSFUL;
}

service->samdb = samdb_connect(service,
Expand All @@ -670,7 +670,7 @@ static void dnsupdate_task_init(struct task_server *task)
if (!service->samdb) {
task_server_terminate(task, "dnsupdate: Failed to connect to local samdb\n",
true);
return;
return NT_STATUS_UNSUCCESSFUL;
}

service->confupdate.interval = lpcfg_parm_int(task->lp_ctx, NULL,
Expand All @@ -685,7 +685,7 @@ static void dnsupdate_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task,
"dnsupdate: Failed to confupdate schedule: %s\n",
nt_errstr(status)), true);
return;
return status;
}

dnsupdate_check_names(service);
Expand All @@ -694,7 +694,7 @@ static void dnsupdate_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task,
"dnsupdate: Failed to nameupdate schedule: %s\n",
nt_errstr(status)), true);
return;
return status;
}

irpc_add_name(task->msg_ctx, "dnsupdate");
Expand All @@ -704,6 +704,7 @@ static void dnsupdate_task_init(struct task_server *task)

/* create the intial file */
dnsupdate_rebuild(service);
return NT_STATUS_OK;

}

Expand All @@ -715,7 +716,8 @@ NTSTATUS server_service_dnsupdate_init(TALLOC_CTX *ctx)
static const struct service_details details = {
.inhibit_fork_on_accept = true,
.inhibit_pre_fork = true,
.task_init = dnsupdate_task_init,
.post_fork = NULL
};
return register_server_service(ctx, "dnsupdate", dnsupdate_task_init,
&details);
return register_server_service(ctx, "dnsupdate", &details);
}
Loading

0 comments on commit 99aea42

Please sign in to comment.