1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

source4 smdb: Add a post fork hook to the service API

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 <gary@catalyst.net.nz>
This commit is contained in:
Gary Lockyer 2018-08-23 09:35:52 +12:00 committed by Gary Lockyer
parent d6777a66c0
commit 99aea42520
24 changed files with 317 additions and 182 deletions

View File

@ -53,7 +53,7 @@ static void file_server_smbd_done(struct tevent_req *subreq)
/* /*
startup a copy of smbd as a child daemon 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; struct tevent_req *subreq;
const char *smbd_path; const char *smbd_path;
@ -78,17 +78,19 @@ static void s3fs_task_init(struct task_server *task)
if (!winbind_off()) { if (!winbind_off()) {
DEBUG(0,("Failed to re-disable recursive winbindd calls after forking smbd\n")); 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); task_server_terminate(task, "Failed to re-disable recursive winbindd calls", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
if (subreq == NULL) { if (subreq == NULL) {
DEBUG(0, ("Failed to start smbd as child daemon\n")); DEBUG(0, ("Failed to start smbd as child daemon\n"));
task_server_terminate(task, "Failed to startup s3fs smb task", true); 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); tevent_req_set_callback(subreq, file_server_smbd_done, task);
DEBUG(5,("Started file server child smbd\n")); DEBUG(5,("Started file server child smbd\n"));
return NT_STATUS_OK;
} }
/* called at smbd startup - register ourselves as a server service */ /* called at smbd startup - register ourselves as a server service */
@ -98,7 +100,9 @@ NTSTATUS server_service_s3fs_init(TALLOC_CTX *ctx)
{ {
struct service_details details = { struct service_details details = {
.inhibit_fork_on_accept = true, .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);
} }

View File

@ -185,7 +185,7 @@ static NTSTATUS cldapd_startup_interfaces(struct cldapd_server *cldapd, struct l
/* /*
startup the cldapd task 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; struct cldapd_server *cldapd;
NTSTATUS status; NTSTATUS status;
@ -195,18 +195,18 @@ static void cldapd_task_init(struct task_server *task)
if (iface_list_count(ifaces) == 0) { if (iface_list_count(ifaces) == 0) {
task_server_terminate(task, "cldapd: no network interfaces configured", false); task_server_terminate(task, "cldapd: no network interfaces configured", false);
return; return NT_STATUS_UNSUCCESSFUL;
} }
switch (lpcfg_server_role(task->lp_ctx)) { switch (lpcfg_server_role(task->lp_ctx)) {
case ROLE_STANDALONE: case ROLE_STANDALONE:
task_server_terminate(task, "cldap_server: no CLDAP server required in standalone configuration", task_server_terminate(task, "cldap_server: no CLDAP server required in standalone configuration",
false); false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER: case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "cldap_server: no CLDAP server required in member server configuration", task_server_terminate(task, "cldap_server: no CLDAP server required in member server configuration",
false); false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC: case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want an CLDAP server */ /* Yes, we want an CLDAP server */
break; break;
@ -217,7 +217,7 @@ static void cldapd_task_init(struct task_server *task)
cldapd = talloc(task, struct cldapd_server); cldapd = talloc(task, struct cldapd_server);
if (cldapd == NULL) { if (cldapd == NULL) {
task_server_terminate(task, "cldapd: out of memory", true); task_server_terminate(task, "cldapd: out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
cldapd->task = task; cldapd->task = task;
@ -229,17 +229,19 @@ static void cldapd_task_init(struct task_server *task)
0); 0);
if (cldapd->samctx == NULL) { if (cldapd->samctx == NULL) {
task_server_terminate(task, "cldapd failed to open samdb", true); task_server_terminate(task, "cldapd failed to open samdb", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
/* start listening on the configured network interfaces */ /* start listening on the configured network interfaces */
status = cldapd_startup_interfaces(cldapd, task->lp_ctx, ifaces); status = cldapd_startup_interfaces(cldapd, task->lp_ctx, ifaces);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "cldapd failed to setup interfaces", true); task_server_terminate(task, "cldapd failed to setup interfaces", true);
return; return status;
} }
irpc_add_name(task->msg_ctx, "cldap_server"); irpc_add_name(task->msg_ctx, "cldap_server");
return NT_STATUS_OK;
} }
@ -250,8 +252,9 @@ NTSTATUS server_service_cldapd_init(TALLOC_CTX *ctx)
{ {
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .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, return register_server_service(ctx, "cldap", &details);
&details);
} }

View File

@ -790,7 +790,7 @@ static NTSTATUS dns_reload_zones(struct irpc_message *msg,
return NT_STATUS_OK; 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; struct dns_server *dns;
NTSTATUS status; NTSTATUS status;
@ -804,10 +804,10 @@ static void dns_task_init(struct task_server *task)
switch (lpcfg_server_role(task->lp_ctx)) { switch (lpcfg_server_role(task->lp_ctx)) {
case ROLE_STANDALONE: case ROLE_STANDALONE:
task_server_terminate(task, "dns: no DNS required in standalone configuration", false); task_server_terminate(task, "dns: no DNS required in standalone configuration", false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER: case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "dns: no DNS required in member server configuration", false); 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: case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want a DNS */ /* Yes, we want a DNS */
break; break;
@ -818,7 +818,7 @@ static void dns_task_init(struct task_server *task)
if (iface_list_count(ifaces) == 0) { if (iface_list_count(ifaces) == 0) {
task_server_terminate(task, "dns: no network interfaces configured", false); task_server_terminate(task, "dns: no network interfaces configured", false);
return; return NT_STATUS_UNSUCCESSFUL;
} }
} }
@ -827,7 +827,7 @@ static void dns_task_init(struct task_server *task)
dns = talloc_zero(task, struct dns_server); dns = talloc_zero(task, struct dns_server);
if (dns == NULL) { if (dns == NULL) {
task_server_terminate(task, "dns: out of memory", true); task_server_terminate(task, "dns: out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
dns->task = task; dns->task = task;
@ -835,7 +835,7 @@ static void dns_task_init(struct task_server *task)
dns->server_credentials = cli_credentials_init(dns); dns->server_credentials = cli_credentials_init(dns);
if (!dns->server_credentials) { if (!dns->server_credentials) {
task_server_terminate(task, "Failed to init server credentials\n", true); task_server_terminate(task, "Failed to init server credentials\n", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
dns->samdb = samdb_connect(dns, dns->samdb = samdb_connect(dns,
@ -846,7 +846,7 @@ static void dns_task_init(struct task_server *task)
0); 0);
if (!dns->samdb) { if (!dns->samdb) {
task_server_terminate(task, "dns: samdb_connect failed", true); task_server_terminate(task, "dns: samdb_connect failed", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
cli_credentials_set_conf(dns->server_credentials, task->lp_ctx); cli_credentials_set_conf(dns->server_credentials, task->lp_ctx);
@ -865,7 +865,7 @@ static void dns_task_init(struct task_server *task)
TALLOC_FREE(dns_acc); TALLOC_FREE(dns_acc);
if (!dns_spn) { if (!dns_spn) {
task_server_terminate(task, "dns: talloc_asprintf failed", true); 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); status = cli_credentials_set_stored_principal(dns->server_credentials, task->lp_ctx, dns_spn);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
@ -874,7 +874,7 @@ static void dns_task_init(struct task_server *task)
"despite finding it in the samdb! %s\n", "despite finding it in the samdb! %s\n",
nt_errstr(status)), nt_errstr(status)),
true); true);
return; return status;
} }
} else { } else {
TALLOC_FREE(dns_spn); TALLOC_FREE(dns_spn);
@ -884,41 +884,42 @@ static void dns_task_init(struct task_server *task)
talloc_asprintf(task, "Failed to obtain server credentials, perhaps a standalone server?: %s\n", talloc_asprintf(task, "Failed to obtain server credentials, perhaps a standalone server?: %s\n",
nt_errstr(status)), nt_errstr(status)),
true); true);
return; return status;
} }
} }
dns->tkeys = tkey_store_init(dns, TKEY_BUFFER_SIZE); dns->tkeys = tkey_store_init(dns, TKEY_BUFFER_SIZE);
if (!dns->tkeys) { if (!dns->tkeys) {
task_server_terminate(task, "Failed to allocate tkey storage\n", true); task_server_terminate(task, "Failed to allocate tkey storage\n", true);
return; return NT_STATUS_NO_MEMORY;
} }
status = dns_server_reload_zones(dns); status = dns_server_reload_zones(dns);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "dns: failed to load DNS zones", true); task_server_terminate(task, "dns: failed to load DNS zones", true);
return; return status;
} }
status = dns_startup_interfaces(dns, ifaces, task->model_ops); status = dns_startup_interfaces(dns, ifaces, task->model_ops);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "dns failed to setup interfaces", true); task_server_terminate(task, "dns failed to setup interfaces", true);
return; return status;
} }
/* Setup the IRPC interface and register handlers */ /* Setup the IRPC interface and register handlers */
status = irpc_add_name(task->msg_ctx, "dnssrv"); status = irpc_add_name(task->msg_ctx, "dnssrv");
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "dns: failed to register IRPC name", true); 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, status = IRPC_REGISTER(task->msg_ctx, irpc, DNSSRV_RELOAD_DNS_ZONES,
dns_reload_zones, dns); dns_reload_zones, dns);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "dns: failed to setup reload handler", true); 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) NTSTATUS server_service_dns_init(TALLOC_CTX *ctx)
@ -926,6 +927,8 @@ NTSTATUS server_service_dns_init(TALLOC_CTX *ctx)
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = 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);
} }

View File

@ -633,14 +633,14 @@ static NTSTATUS dnsupdate_dnsupdate_RODC(struct irpc_message *msg,
/* /*
startup the dns update task 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; NTSTATUS status;
struct dnsupdate_service *service; struct dnsupdate_service *service;
if (lpcfg_server_role(task->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) { if (lpcfg_server_role(task->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) {
/* not useful for non-DC */ /* not useful for non-DC */
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
} }
task_server_set_title(task, "task[dnsupdate]"); task_server_set_title(task, "task[dnsupdate]");
@ -648,7 +648,7 @@ static void dnsupdate_task_init(struct task_server *task)
service = talloc_zero(task, struct dnsupdate_service); service = talloc_zero(task, struct dnsupdate_service);
if (!service) { if (!service) {
task_server_terminate(task, "dnsupdate_task_init: out of memory", true); task_server_terminate(task, "dnsupdate_task_init: out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
service->task = task; service->task = task;
task->private_data = service; task->private_data = service;
@ -658,7 +658,7 @@ static void dnsupdate_task_init(struct task_server *task)
task_server_terminate(task, task_server_terminate(task,
"dnsupdate: Failed to obtain server credentials\n", "dnsupdate: Failed to obtain server credentials\n",
true); true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
service->samdb = samdb_connect(service, service->samdb = samdb_connect(service,
@ -670,7 +670,7 @@ static void dnsupdate_task_init(struct task_server *task)
if (!service->samdb) { if (!service->samdb) {
task_server_terminate(task, "dnsupdate: Failed to connect to local samdb\n", task_server_terminate(task, "dnsupdate: Failed to connect to local samdb\n",
true); true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
service->confupdate.interval = lpcfg_parm_int(task->lp_ctx, NULL, service->confupdate.interval = lpcfg_parm_int(task->lp_ctx, NULL,
@ -685,7 +685,7 @@ static void dnsupdate_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task, task_server_terminate(task, talloc_asprintf(task,
"dnsupdate: Failed to confupdate schedule: %s\n", "dnsupdate: Failed to confupdate schedule: %s\n",
nt_errstr(status)), true); nt_errstr(status)), true);
return; return status;
} }
dnsupdate_check_names(service); dnsupdate_check_names(service);
@ -694,7 +694,7 @@ static void dnsupdate_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task, task_server_terminate(task, talloc_asprintf(task,
"dnsupdate: Failed to nameupdate schedule: %s\n", "dnsupdate: Failed to nameupdate schedule: %s\n",
nt_errstr(status)), true); nt_errstr(status)), true);
return; return status;
} }
irpc_add_name(task->msg_ctx, "dnsupdate"); irpc_add_name(task->msg_ctx, "dnsupdate");
@ -704,6 +704,7 @@ static void dnsupdate_task_init(struct task_server *task)
/* create the intial file */ /* create the intial file */
dnsupdate_rebuild(service); dnsupdate_rebuild(service);
return NT_STATUS_OK;
} }
@ -715,7 +716,8 @@ NTSTATUS server_service_dnsupdate_init(TALLOC_CTX *ctx)
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = true, .inhibit_pre_fork = true,
.task_init = dnsupdate_task_init,
.post_fork = NULL
}; };
return register_server_service(ctx, "dnsupdate", dnsupdate_task_init, return register_server_service(ctx, "dnsupdate", &details);
&details);
} }

View File

@ -266,7 +266,7 @@ static NTSTATUS kccsrv_replica_get_info(struct irpc_message *msg, struct drsuapi
/* /*
startup the kcc service task startup the kcc service task
*/ */
static void kccsrv_task_init(struct task_server *task) static NTSTATUS kccsrv_task_init(struct task_server *task)
{ {
WERROR status; WERROR status;
struct kccsrv_service *service; struct kccsrv_service *service;
@ -275,10 +275,10 @@ static void kccsrv_task_init(struct task_server *task)
switch (lpcfg_server_role(task->lp_ctx)) { switch (lpcfg_server_role(task->lp_ctx)) {
case ROLE_STANDALONE: case ROLE_STANDALONE:
task_server_terminate(task, "kccsrv: no KCC required in standalone configuration", false); task_server_terminate(task, "kccsrv: no KCC required in standalone configuration", false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER: case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "kccsrv: no KCC required in domain member configuration", false); task_server_terminate(task, "kccsrv: no KCC required in domain member configuration", false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC: case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want a KCC */ /* Yes, we want a KCC */
break; break;
@ -289,7 +289,7 @@ static void kccsrv_task_init(struct task_server *task)
service = talloc_zero(task, struct kccsrv_service); service = talloc_zero(task, struct kccsrv_service);
if (!service) { if (!service) {
task_server_terminate(task, "kccsrv_task_init: out of memory", true); task_server_terminate(task, "kccsrv_task_init: out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
service->task = task; service->task = task;
service->startup_time = timeval_current(); service->startup_time = timeval_current();
@ -301,7 +301,7 @@ static void kccsrv_task_init(struct task_server *task)
talloc_asprintf(task, talloc_asprintf(task,
"kccsrv: Failed to obtain server credentials: %s\n", "kccsrv: Failed to obtain server credentials: %s\n",
win_errstr(status)), true); win_errstr(status)), true);
return; return werror_to_ntstatus(status);
} }
status = kccsrv_connect_samdb(service, task->lp_ctx); status = kccsrv_connect_samdb(service, task->lp_ctx);
@ -309,7 +309,7 @@ static void kccsrv_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task, task_server_terminate(task, talloc_asprintf(task,
"kccsrv: Failed to connect to local samdb: %s\n", "kccsrv: Failed to connect to local samdb: %s\n",
win_errstr(status)), true); win_errstr(status)), true);
return; return werror_to_ntstatus(status);
} }
status = kccsrv_load_partitions(service); status = kccsrv_load_partitions(service);
@ -317,7 +317,7 @@ static void kccsrv_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task, task_server_terminate(task, talloc_asprintf(task,
"kccsrv: Failed to load partitions: %s\n", "kccsrv: Failed to load partitions: %s\n",
win_errstr(status)), true); win_errstr(status)), true);
return; return werror_to_ntstatus(status);
} }
periodic_startup_interval = periodic_startup_interval =
@ -338,13 +338,14 @@ static void kccsrv_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task, task_server_terminate(task, talloc_asprintf(task,
"kccsrv: Failed to periodic schedule: %s\n", "kccsrv: Failed to periodic schedule: %s\n",
win_errstr(status)), true); win_errstr(status)), true);
return; return werror_to_ntstatus(status);
} }
irpc_add_name(task->msg_ctx, "kccsrv"); irpc_add_name(task->msg_ctx, "kccsrv");
IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSEXECUTEKCC, kccsrv_execute_kcc, service); IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSEXECUTEKCC, kccsrv_execute_kcc, service);
IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICAGETINFO, kccsrv_replica_get_info, service); IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICAGETINFO, kccsrv_replica_get_info, service);
return NT_STATUS_OK;
} }
/* /*
@ -354,7 +355,9 @@ NTSTATUS server_service_kcc_init(TALLOC_CTX *ctx)
{ {
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = true .inhibit_pre_fork = true,
.task_init = kccsrv_task_init,
.post_fork = NULL
}; };
return register_server_service(ctx, "kcc", kccsrv_task_init, &details); return register_server_service(ctx, "kcc", &details);
} }

View File

@ -428,7 +428,7 @@ static NTSTATUS dreplsrv_replica_mod(struct irpc_message *msg,
/* /*
startup the dsdb replicator service task startup the dsdb replicator service task
*/ */
static void dreplsrv_task_init(struct task_server *task) static NTSTATUS dreplsrv_task_init(struct task_server *task)
{ {
WERROR status; WERROR status;
struct dreplsrv_service *service; struct dreplsrv_service *service;
@ -438,11 +438,11 @@ static void dreplsrv_task_init(struct task_server *task)
case ROLE_STANDALONE: case ROLE_STANDALONE:
task_server_terminate(task, "dreplsrv: no DSDB replication required in standalone configuration", task_server_terminate(task, "dreplsrv: no DSDB replication required in standalone configuration",
false); false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER: case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "dreplsrv: no DSDB replication required in domain member configuration", task_server_terminate(task, "dreplsrv: no DSDB replication required in domain member configuration",
false); false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC: case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want DSDB replication */ /* Yes, we want DSDB replication */
break; break;
@ -453,7 +453,7 @@ static void dreplsrv_task_init(struct task_server *task)
service = talloc_zero(task, struct dreplsrv_service); service = talloc_zero(task, struct dreplsrv_service);
if (!service) { if (!service) {
task_server_terminate(task, "dreplsrv_task_init: out of memory", true); task_server_terminate(task, "dreplsrv_task_init: out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
service->task = task; service->task = task;
service->startup_time = timeval_current(); service->startup_time = timeval_current();
@ -464,7 +464,7 @@ static void dreplsrv_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task, task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to obtain server credentials: %s\n", "dreplsrv: Failed to obtain server credentials: %s\n",
win_errstr(status)), true); win_errstr(status)), true);
return; return werror_to_ntstatus(status);
} }
status = dreplsrv_connect_samdb(service, task->lp_ctx); status = dreplsrv_connect_samdb(service, task->lp_ctx);
@ -472,7 +472,7 @@ static void dreplsrv_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task, task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to connect to local samdb: %s\n", "dreplsrv: Failed to connect to local samdb: %s\n",
win_errstr(status)), true); win_errstr(status)), true);
return; return werror_to_ntstatus(status);
} }
status = dreplsrv_load_partitions(service); status = dreplsrv_load_partitions(service);
@ -480,7 +480,7 @@ static void dreplsrv_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task, task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to load partitions: %s\n", "dreplsrv: Failed to load partitions: %s\n",
win_errstr(status)), true); win_errstr(status)), true);
return; return werror_to_ntstatus(status);
} }
periodic_startup_interval = lpcfg_parm_int(task->lp_ctx, NULL, "dreplsrv", "periodic_startup_interval", 15); /* in seconds */ periodic_startup_interval = lpcfg_parm_int(task->lp_ctx, NULL, "dreplsrv", "periodic_startup_interval", 15); /* in seconds */
@ -491,7 +491,7 @@ static void dreplsrv_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task, task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to periodic schedule: %s\n", "dreplsrv: Failed to periodic schedule: %s\n",
win_errstr(status)), true); win_errstr(status)), true);
return; return werror_to_ntstatus(status);
} }
service->pending.im = tevent_create_immediate(service); service->pending.im = tevent_create_immediate(service);
@ -500,7 +500,7 @@ static void dreplsrv_task_init(struct task_server *task)
"dreplsrv: Failed to create immediate " "dreplsrv: Failed to create immediate "
"task for future DsReplicaSync\n", "task for future DsReplicaSync\n",
true); true);
return; return NT_STATUS_NO_MEMORY;
} }
/* if we are a RODC then we do not send DSReplicaSync*/ /* if we are a RODC then we do not send DSReplicaSync*/
@ -512,7 +512,7 @@ static void dreplsrv_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task, task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to setup notify schedule: %s\n", "dreplsrv: Failed to setup notify schedule: %s\n",
win_errstr(status)), true); win_errstr(status)), true);
return; return werror_to_ntstatus(status);
} }
} }
@ -526,6 +526,8 @@ static void dreplsrv_task_init(struct task_server *task)
IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TAKEFSMOROLE, drepl_take_FSMO_role, service); IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TAKEFSMOROLE, drepl_take_FSMO_role, service);
IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TRIGGER_REPL_SECRET, drepl_trigger_repl_secret, service); IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TRIGGER_REPL_SECRET, drepl_trigger_repl_secret, service);
imessaging_register(task->msg_ctx, service, MSG_DREPL_ALLOCATE_RID, dreplsrv_allocate_rid); imessaging_register(task->msg_ctx, service, MSG_DREPL_ALLOCATE_RID, dreplsrv_allocate_rid);
return NT_STATUS_OK;
} }
/* /*
@ -536,7 +538,8 @@ NTSTATUS server_service_drepl_init(TALLOC_CTX *ctx)
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = true, .inhibit_pre_fork = true,
.task_init = dreplsrv_task_init,
.post_fork = NULL,
}; };
return register_server_service(ctx, "drepl", dreplsrv_task_init, return register_server_service(ctx, "drepl", &details);
&details);
} }

View File

@ -265,7 +265,7 @@ static NTSTATUS echo_startup_interfaces(struct echo_server *echo,
/* Do the basic task initialization, check if the task should run */ /* Do the basic task initialization, check if the task should run */
static void echo_task_init(struct task_server *task) static NTSTATUS echo_task_init(struct task_server *task)
{ {
struct interface *ifaces; struct interface *ifaces;
struct echo_server *echo; struct echo_server *echo;
@ -282,7 +282,7 @@ static void echo_task_init(struct task_server *task)
case ROLE_DOMAIN_MEMBER: case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "echo: Not starting echo server " \ task_server_terminate(task, "echo: Not starting echo server " \
"for domain members", false); "for domain members", false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC: case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want to run the echo server */ /* Yes, we want to run the echo server */
break; break;
@ -294,7 +294,7 @@ static void echo_task_init(struct task_server *task)
task_server_terminate(task, task_server_terminate(task,
"echo: No network interfaces configured", "echo: No network interfaces configured",
false); false);
return; return NT_STATUS_UNSUCCESSFUL;
} }
task_server_set_title(task, "task[echo]"); task_server_set_title(task, "task[echo]");
@ -302,7 +302,7 @@ static void echo_task_init(struct task_server *task)
echo = talloc_zero(task, struct echo_server); echo = talloc_zero(task, struct echo_server);
if (echo == NULL) { if (echo == NULL) {
task_server_terminate(task, "echo: Out of memory", true); task_server_terminate(task, "echo: Out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
echo->task = task; echo->task = task;
@ -312,8 +312,9 @@ static void echo_task_init(struct task_server *task)
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "echo: Failed to set up interfaces", task_server_terminate(task, "echo: Failed to set up interfaces",
true); true);
return; return status;
} }
return NT_STATUS_OK;
} }
/* /*
@ -326,7 +327,10 @@ NTSTATUS server_service_echo_init(TALLOC_CTX *ctx)
{ {
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = true .inhibit_pre_fork = true,
.task_init = echo_task_init,
.post_fork = NULL
}; };
return register_server_service(ctx, "echo", echo_task_init, &details); return register_server_service(ctx, "echo", &details);
} }

View File

@ -261,7 +261,7 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
/* /*
startup the kdc task startup the kdc task
*/ */
static void kdc_task_init(struct task_server *task) static NTSTATUS kdc_task_init(struct task_server *task)
{ {
struct kdc_server *kdc; struct kdc_server *kdc;
krb5_kdc_configuration *kdc_config = NULL; krb5_kdc_configuration *kdc_config = NULL;
@ -273,14 +273,14 @@ static void kdc_task_init(struct task_server *task)
switch (lpcfg_server_role(task->lp_ctx)) { switch (lpcfg_server_role(task->lp_ctx)) {
case ROLE_STANDALONE: case ROLE_STANDALONE:
task_server_terminate(task, "kdc: no KDC required in standalone configuration", false); task_server_terminate(task, "kdc: no KDC required in standalone configuration", false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER: case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "kdc: no KDC required in member server configuration", false); task_server_terminate(task, "kdc: no KDC required in member server configuration", false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC: case ROLE_DOMAIN_BDC:
task_server_terminate(task, "Cannot start KDC as a 'classic Samba' DC", true); task_server_terminate(task, "Cannot start KDC as a 'classic Samba' DC", true);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC: case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want a KDC */ /* Yes, we want a KDC */
break; break;
@ -290,7 +290,7 @@ static void kdc_task_init(struct task_server *task)
if (iface_list_count(ifaces) == 0) { if (iface_list_count(ifaces) == 0) {
task_server_terminate(task, "kdc: no network interfaces configured", false); task_server_terminate(task, "kdc: no network interfaces configured", false);
return; return NT_STATUS_UNSUCCESSFUL;
} }
task_server_set_title(task, "task[kdc]"); task_server_set_title(task, "task[kdc]");
@ -298,7 +298,7 @@ static void kdc_task_init(struct task_server *task)
kdc = talloc_zero(task, struct kdc_server); kdc = talloc_zero(task, struct kdc_server);
if (kdc == NULL) { if (kdc == NULL) {
task_server_terminate(task, "kdc: out of memory", true); task_server_terminate(task, "kdc: out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
kdc->task = task; kdc->task = task;
@ -314,7 +314,7 @@ static void kdc_task_init(struct task_server *task)
if (!kdc->samdb) { if (!kdc->samdb) {
DEBUG(1,("kdc_task_init: unable to connect to samdb\n")); DEBUG(1,("kdc_task_init: unable to connect to samdb\n"));
task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true); task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc); ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc);
@ -322,7 +322,7 @@ static void kdc_task_init(struct task_server *task)
DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n", DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n",
ldb_errstring(kdc->samdb))); ldb_errstring(kdc->samdb)));
task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true); task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
kdc->proxy_timeout = lpcfg_parm_int(kdc->task->lp_ctx, NULL, "kdc", "proxy timeout", 5); kdc->proxy_timeout = lpcfg_parm_int(kdc->task->lp_ctx, NULL, "kdc", "proxy timeout", 5);
@ -334,7 +334,7 @@ static void kdc_task_init(struct task_server *task)
DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n", DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
error_message(ret))); error_message(ret)));
task_server_terminate(task, "kdc: krb5_init_context failed", true); task_server_terminate(task, "kdc: krb5_init_context failed", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r); krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r);
@ -343,14 +343,14 @@ static void kdc_task_init(struct task_server *task)
&kdc_config); &kdc_config);
if(ret) { if(ret) {
task_server_terminate(task, "kdc: failed to get KDC configuration", true); task_server_terminate(task, "kdc: failed to get KDC configuration", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
kdc_config->logf = (krb5_log_facility *)kdc->smb_krb5_context->pvt_log_data; kdc_config->logf = (krb5_log_facility *)kdc->smb_krb5_context->pvt_log_data;
kdc_config->db = talloc(kdc, struct HDB *); kdc_config->db = talloc(kdc, struct HDB *);
if (!kdc_config->db) { if (!kdc_config->db) {
task_server_terminate(task, "kdc: out of memory", true); task_server_terminate(task, "kdc: out of memory", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
kdc_config->num_db = 1; kdc_config->num_db = 1;
@ -382,7 +382,7 @@ static void kdc_task_init(struct task_server *task)
kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context); kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context);
if (!kdc->base_ctx) { if (!kdc->base_ctx) {
task_server_terminate(task, "kdc: out of memory", true); task_server_terminate(task, "kdc: out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
kdc->base_ctx->ev_ctx = task->event_ctx; kdc->base_ctx->ev_ctx = task->event_ctx;
@ -394,7 +394,7 @@ static void kdc_task_init(struct task_server *task)
&kdc_config->db[0]); &kdc_config->db[0]);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true); task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true);
return; return status;
} }
ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
@ -402,13 +402,13 @@ static void kdc_task_init(struct task_server *task)
&hdb_samba4_interface); &hdb_samba4_interface);
if(ret) { if(ret) {
task_server_terminate(task, "kdc: failed to register hdb plugin", true); task_server_terminate(task, "kdc: failed to register hdb plugin", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops); ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops);
if(ret) { if(ret) {
task_server_terminate(task, "kdc: failed to register keytab plugin", true); task_server_terminate(task, "kdc: failed to register keytab plugin", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
kdc->keytab_name = talloc_asprintf(kdc, "HDB:samba4&%p", kdc->base_ctx); kdc->keytab_name = talloc_asprintf(kdc, "HDB:samba4&%p", kdc->base_ctx);
@ -416,7 +416,7 @@ static void kdc_task_init(struct task_server *task)
task_server_terminate(task, task_server_terminate(task,
"kdc: Failed to set keytab name", "kdc: Failed to set keytab name",
true); true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
/* Register WinDC hooks */ /* Register WinDC hooks */
@ -425,21 +425,21 @@ static void kdc_task_init(struct task_server *task)
&windc_plugin_table); &windc_plugin_table);
if(ret) { if(ret) {
task_server_terminate(task, "kdc: failed to register windc plugin", true); task_server_terminate(task, "kdc: failed to register windc plugin", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
ret = krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context); ret = krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context);
if(ret) { if(ret) {
task_server_terminate(task, "kdc: failed to init windc plugin", true); task_server_terminate(task, "kdc: failed to init windc plugin", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
ret = krb5_kdc_pkinit_config(kdc->smb_krb5_context->krb5_context, kdc_config); ret = krb5_kdc_pkinit_config(kdc->smb_krb5_context->krb5_context, kdc_config);
if(ret) { if(ret) {
task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true); task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
kdc->private_data = kdc_config; kdc->private_data = kdc_config;
@ -448,17 +448,19 @@ static void kdc_task_init(struct task_server *task)
task->model_ops); task->model_ops);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "kdc failed to setup interfaces", true); task_server_terminate(task, "kdc failed to setup interfaces", true);
return; return status;
} }
status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS, status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS,
kdc_check_generic_kerberos, kdc); kdc_check_generic_kerberos, kdc);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "kdc failed to setup monitoring", true); task_server_terminate(task, "kdc failed to setup monitoring", true);
return; return status;
} }
irpc_add_name(task->msg_ctx, "kdc_server"); irpc_add_name(task->msg_ctx, "kdc_server");
return NT_STATUS_OK;
} }
@ -478,7 +480,9 @@ NTSTATUS server_service_kdc_init(TALLOC_CTX *ctx)
* the master process is responsible for managing the worker * the master process is responsible for managing the worker
* processes not performing work. * processes not performing work.
*/ */
.inhibit_pre_fork = true .inhibit_pre_fork = true,
.task_init = kdc_task_init,
.post_fork = NULL
}; };
return register_server_service(ctx, "kdc", kdc_task_init, &details); return register_server_service(ctx, "kdc", &details);
} }

View File

@ -365,8 +365,9 @@ NTSTATUS server_service_mitkdc_init(TALLOC_CTX *mem_ctx)
* the master process is responsible for managing the worker * the master process is responsible for managing the worker
* processes not performing work. * processes not performing work.
*/ */
.inhibit_pre_fork = true .inhibit_pre_fork = true,
.task_init = mitkdc_task_init,
.post_fork = NULL
}; };
return register_server_service(mem_ctx, "kdc", mitkdc_task_init, return register_server_service(mem_ctx, "kdc", &details);
&details);
} }

View File

@ -1122,7 +1122,7 @@ static NTSTATUS add_socket(struct task_server *task,
/* /*
open the ldap server sockets open the ldap server sockets
*/ */
static void ldapsrv_task_init(struct task_server *task) static NTSTATUS ldapsrv_task_init(struct task_server *task)
{ {
char *ldapi_path; char *ldapi_path;
#ifdef WITH_LDAPI_PRIV_SOCKET #ifdef WITH_LDAPI_PRIV_SOCKET
@ -1136,11 +1136,11 @@ static void ldapsrv_task_init(struct task_server *task)
case ROLE_STANDALONE: case ROLE_STANDALONE:
task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration", task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration",
false); false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER: case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "ldap_server: no LDAP server required in member server configuration", task_server_terminate(task, "ldap_server: no LDAP server required in member server configuration",
false); false);
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC: case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want an LDAP server */ /* Yes, we want an LDAP server */
break; break;
@ -1149,14 +1149,20 @@ static void ldapsrv_task_init(struct task_server *task)
task_server_set_title(task, "task[ldapsrv]"); task_server_set_title(task, "task[ldapsrv]");
ldap_service = talloc_zero(task, struct ldapsrv_service); ldap_service = talloc_zero(task, struct ldapsrv_service);
if (ldap_service == NULL) goto failed; if (ldap_service == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
ldap_service->task = task; ldap_service->task = task;
dns_host_name = talloc_asprintf(ldap_service, "%s.%s", dns_host_name = talloc_asprintf(ldap_service, "%s.%s",
lpcfg_netbios_name(task->lp_ctx), lpcfg_netbios_name(task->lp_ctx),
lpcfg_dnsdomain(task->lp_ctx)); lpcfg_dnsdomain(task->lp_ctx));
if (dns_host_name == NULL) goto failed; if (dns_host_name == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
status = tstream_tls_params_server(ldap_service, status = tstream_tls_params_server(ldap_service,
dns_host_name, dns_host_name,
@ -1175,7 +1181,10 @@ static void ldapsrv_task_init(struct task_server *task)
} }
ldap_service->call_queue = tevent_queue_create(ldap_service, "ldapsrv_call_queue"); ldap_service->call_queue = tevent_queue_create(ldap_service, "ldapsrv_call_queue");
if (ldap_service->call_queue == NULL) goto failed; if (ldap_service->call_queue == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) { if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) {
struct interface *ifaces; struct interface *ifaces;
@ -1202,6 +1211,7 @@ static void ldapsrv_task_init(struct task_server *task)
wcard = iface_list_wildcard(task); wcard = iface_list_wildcard(task);
if (wcard == NULL) { if (wcard == NULL) {
DEBUG(0,("No wildcard addresses available\n")); DEBUG(0,("No wildcard addresses available\n"));
status = NT_STATUS_UNSUCCESSFUL;
goto failed; goto failed;
} }
for (i=0; wcard[i]; i++) { for (i=0; wcard[i]; i++) {
@ -1213,12 +1223,14 @@ static void ldapsrv_task_init(struct task_server *task)
} }
talloc_free(wcard); talloc_free(wcard);
if (num_binds == 0) { if (num_binds == 0) {
status = NT_STATUS_UNSUCCESSFUL;
goto failed; goto failed;
} }
} }
ldapi_path = lpcfg_private_path(ldap_service, task->lp_ctx, "ldapi"); ldapi_path = lpcfg_private_path(ldap_service, task->lp_ctx, "ldapi");
if (!ldapi_path) { if (!ldapi_path) {
status = NT_STATUS_UNSUCCESSFUL;
goto failed; goto failed;
} }
@ -1236,6 +1248,7 @@ static void ldapsrv_task_init(struct task_server *task)
#ifdef WITH_LDAPI_PRIV_SOCKET #ifdef WITH_LDAPI_PRIV_SOCKET
priv_dir = lpcfg_private_path(ldap_service, task->lp_ctx, "ldap_priv"); priv_dir = lpcfg_private_path(ldap_service, task->lp_ctx, "ldap_priv");
if (priv_dir == NULL) { if (priv_dir == NULL) {
status = NT_STATUS_UNSUCCESSFUL;
goto failed; goto failed;
} }
/* /*
@ -1245,11 +1258,12 @@ static void ldapsrv_task_init(struct task_server *task)
if (!directory_create_or_exist(priv_dir, 0750)) { if (!directory_create_or_exist(priv_dir, 0750)) {
task_server_terminate(task, "Cannot create ldap " task_server_terminate(task, "Cannot create ldap "
"privileged ldapi directory", true); "privileged ldapi directory", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
ldapi_path = talloc_asprintf(ldap_service, "%s/ldapi", priv_dir); ldapi_path = talloc_asprintf(ldap_service, "%s/ldapi", priv_dir);
talloc_free(priv_dir); talloc_free(priv_dir);
if (ldapi_path == NULL) { if (ldapi_path == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed; goto failed;
} }
@ -1269,10 +1283,11 @@ static void ldapsrv_task_init(struct task_server *task)
/* register the server */ /* register the server */
irpc_add_name(task->msg_ctx, "ldap_server"); irpc_add_name(task->msg_ctx, "ldap_server");
return; return NT_STATUS_OK;
failed: failed:
task_server_terminate(task, "Failed to startup ldap server task", true); task_server_terminate(task, "Failed to startup ldap server task", true);
return status;
} }
@ -1280,8 +1295,9 @@ NTSTATUS server_service_ldap_init(TALLOC_CTX *ctx)
{ {
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = false, .inhibit_fork_on_accept = false,
.inhibit_pre_fork = false .inhibit_pre_fork = false,
.task_init = ldapsrv_task_init,
.post_fork = NULL
}; };
return register_server_service(ctx, "ldap", ldapsrv_task_init, return register_server_service(ctx, "ldap", &details);
&details);
} }

View File

@ -35,7 +35,7 @@ NTSTATUS server_service_nbtd_init(TALLOC_CTX *);
/* /*
startup the nbtd task startup the nbtd task
*/ */
static void nbtd_task_init(struct task_server *task) static NTSTATUS nbtd_task_init(struct task_server *task)
{ {
struct nbtd_server *nbtsrv; struct nbtd_server *nbtsrv;
NTSTATUS status; NTSTATUS status;
@ -45,12 +45,12 @@ static void nbtd_task_init(struct task_server *task)
if (iface_list_count(ifaces) == 0) { if (iface_list_count(ifaces) == 0) {
task_server_terminate(task, "nbtd: no network interfaces configured", false); task_server_terminate(task, "nbtd: no network interfaces configured", false);
return; return NT_STATUS_UNSUCCESSFUL;
} }
if (lpcfg_disable_netbios(task->lp_ctx)) { if (lpcfg_disable_netbios(task->lp_ctx)) {
task_server_terminate(task, "nbtd: 'disable netbios = yes' set in smb.conf, shutting down nbt server", false); task_server_terminate(task, "nbtd: 'disable netbios = yes' set in smb.conf, shutting down nbt server", false);
return; return NT_STATUS_UNSUCCESSFUL;
} }
task_server_set_title(task, "task[nbtd]"); task_server_set_title(task, "task[nbtd]");
@ -58,7 +58,7 @@ static void nbtd_task_init(struct task_server *task)
nbtsrv = talloc(task, struct nbtd_server); nbtsrv = talloc(task, struct nbtd_server);
if (nbtsrv == NULL) { if (nbtsrv == NULL) {
task_server_terminate(task, "nbtd: out of memory", true); task_server_terminate(task, "nbtd: out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
nbtsrv->task = task; nbtsrv->task = task;
@ -70,7 +70,7 @@ static void nbtd_task_init(struct task_server *task)
status = nbtd_startup_interfaces(nbtsrv, task->lp_ctx, ifaces); status = nbtd_startup_interfaces(nbtsrv, task->lp_ctx, ifaces);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "nbtd failed to setup interfaces", true); task_server_terminate(task, "nbtd failed to setup interfaces", true);
return; return status;
} }
nbtsrv->sam_ctx = samdb_connect(nbtsrv, nbtsrv->sam_ctx = samdb_connect(nbtsrv,
@ -81,14 +81,14 @@ static void nbtd_task_init(struct task_server *task)
0); 0);
if (nbtsrv->sam_ctx == NULL) { if (nbtsrv->sam_ctx == NULL) {
task_server_terminate(task, "nbtd failed to open samdb", true); task_server_terminate(task, "nbtd failed to open samdb", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
/* start the WINS server, if appropriate */ /* start the WINS server, if appropriate */
status = nbtd_winsserver_init(nbtsrv); status = nbtd_winsserver_init(nbtsrv);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "nbtd failed to start WINS server", true); task_server_terminate(task, "nbtd failed to start WINS server", true);
return; return status;
} }
nbtd_register_irpc(nbtsrv); nbtd_register_irpc(nbtsrv);
@ -97,6 +97,8 @@ static void nbtd_task_init(struct task_server *task)
nbtd_register_names(nbtsrv); nbtd_register_names(nbtsrv);
irpc_add_name(task->msg_ctx, "nbt_server"); irpc_add_name(task->msg_ctx, "nbt_server");
return NT_STATUS_OK;
} }
@ -107,7 +109,9 @@ NTSTATUS server_service_nbtd_init(TALLOC_CTX *ctx)
{ {
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = true .inhibit_pre_fork = true,
.task_init = nbtd_task_init,
.post_fork = NULL
}; };
return register_server_service(ctx, "nbt", nbtd_task_init, &details); return register_server_service(ctx, "nbt", &details);
} }

View File

@ -489,7 +489,7 @@ static const struct stream_server_ops ntp_signd_stream_ops = {
/* /*
startup the ntp_signd task startup the ntp_signd task
*/ */
static void ntp_signd_task_init(struct task_server *task) static NTSTATUS ntp_signd_task_init(struct task_server *task)
{ {
struct ntp_signd_server *ntp_signd; struct ntp_signd_server *ntp_signd;
NTSTATUS status; NTSTATUS status;
@ -501,7 +501,7 @@ static void ntp_signd_task_init(struct task_server *task)
lpcfg_ntp_signd_socket_directory(task->lp_ctx)); lpcfg_ntp_signd_socket_directory(task->lp_ctx));
task_server_terminate(task, task_server_terminate(task,
error, true); error, true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
task_server_set_title(task, "task[ntp_signd]"); task_server_set_title(task, "task[ntp_signd]");
@ -509,7 +509,7 @@ static void ntp_signd_task_init(struct task_server *task)
ntp_signd = talloc(task, struct ntp_signd_server); ntp_signd = talloc(task, struct ntp_signd_server);
if (ntp_signd == NULL) { if (ntp_signd == NULL) {
task_server_terminate(task, "ntp_signd: out of memory", true); task_server_terminate(task, "ntp_signd: out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
ntp_signd->task = task; ntp_signd->task = task;
@ -523,10 +523,15 @@ static void ntp_signd_task_init(struct task_server *task)
0); 0);
if (ntp_signd->samdb == NULL) { if (ntp_signd->samdb == NULL) {
task_server_terminate(task, "ntp_signd failed to open samdb", true); task_server_terminate(task, "ntp_signd failed to open samdb", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
address = talloc_asprintf(ntp_signd, "%s/socket", lpcfg_ntp_signd_socket_directory(task->lp_ctx)); address = talloc_asprintf(ntp_signd, "%s/socket", lpcfg_ntp_signd_socket_directory(task->lp_ctx));
if (address == NULL) {
task_server_terminate(
task, "ntp_signd out of memory in talloc_asprintf()", true);
return NT_STATUS_NO_MEMORY;
}
status = stream_setup_socket(ntp_signd->task, status = stream_setup_socket(ntp_signd->task,
ntp_signd->task->event_ctx, ntp_signd->task->event_ctx,
@ -540,9 +545,11 @@ static void ntp_signd_task_init(struct task_server *task)
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to bind to %s - %s\n", DEBUG(0,("Failed to bind to %s - %s\n",
address, nt_errstr(status))); address, nt_errstr(status)));
return; return status;
} }
return NT_STATUS_OK;
} }
@ -551,8 +558,9 @@ NTSTATUS server_service_ntp_signd_init(TALLOC_CTX *ctx)
{ {
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = true .inhibit_pre_fork = true,
.task_init = ntp_signd_task_init,
.post_fork = NULL
}; };
return register_server_service(ctx, "ntp_signd", ntp_signd_task_init, return register_server_service(ctx, "ntp_signd", &details);
&details);
} }

View File

@ -44,9 +44,9 @@ NTSTATUS server_service_rpc_init(TALLOC_CTX *);
/* /*
open the dcerpc server sockets open the dcerpc server sockets
*/ */
static void dcesrv_task_init(struct task_server *task) static NTSTATUS dcesrv_task_init(struct task_server *task)
{ {
NTSTATUS status; NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
struct dcesrv_context *dce_ctx; struct dcesrv_context *dce_ctx;
struct dcesrv_endpoint *e; struct dcesrv_endpoint *e;
const struct model_ops *single_model_ops; const struct model_ops *single_model_ops;
@ -135,9 +135,10 @@ static void dcesrv_task_init(struct task_server *task)
} }
irpc_add_name(task->msg_ctx, "rpc_server"); irpc_add_name(task->msg_ctx, "rpc_server");
return; return NT_STATUS_OK;
failed: failed:
task_server_terminate(task, "Failed to startup dcerpc server task", true); task_server_terminate(task, "Failed to startup dcerpc server task", true);
return status;
} }
NTSTATUS server_service_rpc_init(TALLOC_CTX *ctx) NTSTATUS server_service_rpc_init(TALLOC_CTX *ctx)
@ -151,7 +152,9 @@ NTSTATUS server_service_rpc_init(TALLOC_CTX *ctx)
* mode by defult to get a forking NETLOGON server * mode by defult to get a forking NETLOGON server
*/ */
.inhibit_fork_on_accept = false, .inhibit_fork_on_accept = false,
.inhibit_pre_fork = true .inhibit_pre_fork = true,
.task_init = dcesrv_task_init,
.post_fork = NULL
}; };
return register_server_service(ctx, "rpc", dcesrv_task_init, &details); return register_server_service(ctx, "rpc", &details);
} }

View File

@ -38,9 +38,9 @@
/* /*
open the smb server sockets open the smb server sockets
*/ */
static void smbsrv_task_init(struct task_server *task) static NTSTATUS smbsrv_task_init(struct task_server *task)
{ {
NTSTATUS status; NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
task_server_set_title(task, "task[smbsrv]"); task_server_set_title(task, "task[smbsrv]");
@ -72,6 +72,7 @@ static void smbsrv_task_init(struct task_server *task)
wcard = iface_list_wildcard(task); wcard = iface_list_wildcard(task);
if (wcard == NULL) { if (wcard == NULL) {
DEBUG(0,("No wildcard addresses available\n")); DEBUG(0,("No wildcard addresses available\n"));
status = NT_STATUS_UNSUCCESSFUL;
goto failed; goto failed;
} }
for (i=0; wcard[i]; i++) { for (i=0; wcard[i]; i++) {
@ -86,9 +87,10 @@ static void smbsrv_task_init(struct task_server *task)
} }
irpc_add_name(task->msg_ctx, "smb_server"); irpc_add_name(task->msg_ctx, "smb_server");
return; return NT_STATUS_OK;
failed: failed:
task_server_terminate(task, "Failed to startup smb server task", true); task_server_terminate(task, "Failed to startup smb server task", true);
return status;
} }
/* called at smbd startup - register ourselves as a server service */ /* called at smbd startup - register ourselves as a server service */
@ -96,9 +98,11 @@ NTSTATUS server_service_smb_init(TALLOC_CTX *ctx)
{ {
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = true .inhibit_pre_fork = true,
.task_init = smbsrv_task_init,
.post_fork = NULL
}; };
ntvfs_init(cmdline_lp_ctx); ntvfs_init(cmdline_lp_ctx);
share_init(); share_init();
return register_server_service(ctx, "smb", smbsrv_task_init, &details); return register_server_service(ctx, "smb", &details);
} }

View File

@ -58,7 +58,7 @@ struct model_ops {
void (*new_task)(struct tevent_context *, void (*new_task)(struct tevent_context *,
struct loadparm_context *lp_ctx, struct loadparm_context *lp_ctx,
const char *service_name, const char *service_name,
void (*)(struct tevent_context *, struct task_server * (*)(struct tevent_context *,
struct loadparm_context *, struct server_id, struct loadparm_context *, struct server_id,
void *, void *), void *, void *),
void *, void *,

View File

@ -227,7 +227,7 @@ static void prefork_new_task(
struct tevent_context *ev, struct tevent_context *ev,
struct loadparm_context *lp_ctx, struct loadparm_context *lp_ctx,
const char *service_name, const char *service_name,
void (*new_task_fn)(struct tevent_context *, struct task_server *(*new_task_fn)(struct tevent_context *,
struct loadparm_context *lp_ctx, struct loadparm_context *lp_ctx,
struct server_id , void *, void *), struct server_id , void *, void *),
void *private_data, void *private_data,
@ -239,6 +239,7 @@ static void prefork_new_task(
int i, num_children; int i, num_children;
struct tevent_context *ev2; struct tevent_context *ev2;
struct task_server *task = NULL;
t = tfork_create(); t = tfork_create();
if (t == NULL) { if (t == NULL) {
@ -277,8 +278,14 @@ static void prefork_new_task(
setup_handlers(ev, from_parent_fd); setup_handlers(ev, from_parent_fd);
if (service_details->inhibit_pre_fork) { if (service_details->inhibit_pre_fork) {
new_task_fn(ev, lp_ctx, cluster_id(pid, 0), private_data, NULL); task = new_task_fn(
/* The task does not support pre-fork */ ev, lp_ctx, cluster_id(pid, 0), private_data, NULL);
/*
* The task does not support pre-fork
*/
if (task != NULL && service_details->post_fork != NULL) {
service_details->post_fork(task);
}
tevent_loop_wait(ev); tevent_loop_wait(ev);
TALLOC_FREE(ev); TALLOC_FREE(ev);
exit(0); exit(0);
@ -298,7 +305,12 @@ static void prefork_new_task(
* process accepting and handling requests, it's responsible for * process accepting and handling requests, it's responsible for
* monitoring and controlling the child work processes. * monitoring and controlling the child work processes.
*/ */
new_task_fn(ev2, lp_ctx, cluster_id(pid, 0), private_data, NULL); task = new_task_fn(ev2, lp_ctx, cluster_id(pid, 0), private_data, NULL);
if (task == NULL) {
TALLOC_FREE(ev);
TALLOC_FREE(ev2);
exit(0);
}
{ {
int default_children; int default_children;
@ -313,7 +325,9 @@ static void prefork_new_task(
} }
DBG_NOTICE("Forking %d %s worker processes\n", DBG_NOTICE("Forking %d %s worker processes\n",
num_children, service_name); num_children, service_name);
/* We are now free to spawn some worker processes */ /*
* We are now free to spawn some worker processes
*/
for (i=0; i < num_children; i++) { for (i=0; i < num_children; i++) {
struct tfork* w = NULL; struct tfork* w = NULL;
@ -335,7 +349,9 @@ static void prefork_new_task(
} }
tevent_fd_set_auto_close(fde); tevent_fd_set_auto_close(fde);
} else { } else {
/* tfork uses malloc */ /*
* tfork uses malloc
*/
free(w); free(w);
TALLOC_FREE(ev); TALLOC_FREE(ev);
@ -343,6 +359,9 @@ static void prefork_new_task(
service_name); service_name);
prefork_reload_after_fork(); prefork_reload_after_fork();
setup_handlers(ev2, from_parent_fd); setup_handlers(ev2, from_parent_fd);
if (service_details->post_fork != NULL) {
service_details->post_fork(task);
}
tevent_loop_wait(ev2); tevent_loop_wait(ev2);
talloc_free(ev2); talloc_free(ev2);
exit(0); exit(0);

View File

@ -92,7 +92,7 @@ static void single_accept_connection(struct tevent_context *ev,
static void single_new_task(struct tevent_context *ev, static void single_new_task(struct tevent_context *ev,
struct loadparm_context *lp_ctx, struct loadparm_context *lp_ctx,
const char *service_name, const char *service_name,
void (*new_task)(struct tevent_context *, struct task_server *(*new_task)(struct tevent_context *,
struct loadparm_context *, struct loadparm_context *,
struct server_id, void *, void *), struct server_id, void *, void *),
void *private_data, void *private_data,
@ -102,7 +102,7 @@ static void single_new_task(struct tevent_context *ev,
pid_t pid = getpid(); pid_t pid = getpid();
/* start our taskids at MAX_INT32, the first 2^31 tasks are is reserved for fd numbers */ /* start our taskids at MAX_INT32, the first 2^31 tasks are is reserved for fd numbers */
static uint32_t taskid = INT32_MAX; static uint32_t taskid = INT32_MAX;
struct task_server *task = NULL;
/* /*
* We use the PID so we cannot collide in with cluster ids * We use the PID so we cannot collide in with cluster ids
* generated in other single mode tasks, and, and won't * generated in other single mode tasks, and, and won't
@ -112,7 +112,10 @@ static void single_new_task(struct tevent_context *ev,
* Using the pid unaltered makes debugging of which process * Using the pid unaltered makes debugging of which process
* owns the messaging socket easier. * owns the messaging socket easier.
*/ */
new_task(ev, lp_ctx, cluster_id(pid, taskid++), private_data, NULL); task = new_task(ev, lp_ctx, cluster_id(pid, taskid++), private_data, NULL);
if (task != NULL && service_details->post_fork != NULL) {
service_details->post_fork(task);
}
} }

View File

@ -393,7 +393,7 @@ static void standard_accept_connection(
static void standard_new_task(struct tevent_context *ev, static void standard_new_task(struct tevent_context *ev,
struct loadparm_context *lp_ctx, struct loadparm_context *lp_ctx,
const char *service_name, const char *service_name,
void (*new_task)(struct tevent_context *, struct loadparm_context *lp_ctx, struct server_id , void *, void *), struct task_server *(*new_task)(struct tevent_context *, struct loadparm_context *lp_ctx, struct server_id , void *, void *),
void *private_data, void *private_data,
const struct service_details *service_details, const struct service_details *service_details,
int from_parent_fd) int from_parent_fd)
@ -404,6 +404,7 @@ static void standard_new_task(struct tevent_context *ev,
struct tevent_fd *fde = NULL; struct tevent_fd *fde = NULL;
struct tevent_signal *se = NULL; struct tevent_signal *se = NULL;
struct process_context *proc_ctx = NULL; struct process_context *proc_ctx = NULL;
struct task_server* task = NULL;
state = setup_standard_child_pipe(ev, service_name); state = setup_standard_child_pipe(ev, service_name);
if (state == NULL) { if (state == NULL) {
@ -486,7 +487,16 @@ static void standard_new_task(struct tevent_context *ev,
proc_ctx->forked_on_accept = false; proc_ctx->forked_on_accept = false;
/* setup this new task. Cluster ID is PID based for this process model */ /* setup this new task. Cluster ID is PID based for this process model */
new_task(ev, lp_ctx, cluster_id(pid, 0), private_data, proc_ctx); task = new_task(ev, lp_ctx, cluster_id(pid, 0), private_data, proc_ctx);
/*
* Currently we don't support the post_fork functionality in the
* standard model, i.e. it is only called here not after a new process
* is forked in standard_accept_connection.
*/
if (task != NULL && service_details->post_fork != NULL) {
service_details->post_fork(task);
}
/* we can't return to the top level here, as that event context is gone, /* we can't return to the top level here, as that event context is gone,
so we now process events in the new event context until there are no so we now process events in the new event context until there are no

View File

@ -30,8 +30,7 @@
static struct registered_server { static struct registered_server {
struct registered_server *next, *prev; struct registered_server *next, *prev;
const char *service_name; const char *service_name;
struct service_details *service_details; const struct service_details *service_details;
void (*task_init)(struct task_server *);
} *registered_servers; } *registered_servers;
/* /*
@ -39,14 +38,12 @@ static struct registered_server {
*/ */
NTSTATUS register_server_service(TALLOC_CTX *ctx, NTSTATUS register_server_service(TALLOC_CTX *ctx,
const char *name, const char *name,
void (*task_init) (struct task_server *),
const struct service_details *details) const struct service_details *details)
{ {
struct registered_server *srv; struct registered_server *srv;
srv = talloc(ctx, struct registered_server); srv = talloc(ctx, struct registered_server);
NT_STATUS_HAVE_NO_MEMORY(srv); NT_STATUS_HAVE_NO_MEMORY(srv);
srv->service_name = name; srv->service_name = name;
srv->task_init = task_init;
srv->service_details = srv->service_details =
talloc_memdup(ctx, details, sizeof(struct service_details)); talloc_memdup(ctx, details, sizeof(struct service_details));
NT_STATUS_HAVE_NO_MEMORY(srv->service_details); NT_STATUS_HAVE_NO_MEMORY(srv->service_details);
@ -70,7 +67,6 @@ static NTSTATUS server_service_init(const char *name,
return task_server_startup(event_context, lp_ctx, return task_server_startup(event_context, lp_ctx,
srv->service_name, srv->service_name,
model_ops, model_ops,
srv->task_init,
srv->service_details, srv->service_details,
from_parent_fd); from_parent_fd);
} }

View File

@ -40,7 +40,31 @@ struct service_details {
* processes. In this mode pre-fork is equivalent to standard with * processes. In this mode pre-fork is equivalent to standard with
* inhibit_fork_on_accept set. * inhibit_fork_on_accept set.
*/ */
bool inhibit_pre_fork; bool inhibit_pre_fork;
/*
* Initialise the server task.
*/
NTSTATUS (*task_init) (struct task_server *);
/*
* post fork processing this is 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.
*/
void (*post_fork) (struct task_server *);
}; };
#include "smbd/service_proto.h" #include "smbd/service_proto.h"

View File

@ -62,7 +62,7 @@ void task_server_terminate(struct task_server *task, const char *reason, bool fa
/* used for the callback from the process model code */ /* used for the callback from the process model code */
struct task_state { struct task_state {
void (*task_init)(struct task_server *); const struct service_details *service_details;
const struct model_ops *model_ops; const struct model_ops *model_ops;
}; };
@ -71,17 +71,18 @@ struct task_state {
called by the process model code when the new task starts up. This then calls called by the process model code when the new task starts up. This then calls
the server specific startup code the server specific startup code
*/ */
static void task_server_callback(struct tevent_context *event_ctx, static struct task_server *task_server_callback(struct tevent_context *event_ctx,
struct loadparm_context *lp_ctx, struct loadparm_context *lp_ctx,
struct server_id server_id, struct server_id server_id,
void *private_data, void *private_data,
void *context) void *context)
{ {
struct task_state *state = talloc_get_type(private_data, struct task_state);
struct task_server *task; struct task_server *task;
NTSTATUS status = NT_STATUS_OK;
struct task_state *state = talloc_get_type(private_data, struct task_state);
task = talloc(event_ctx, struct task_server); task = talloc(event_ctx, struct task_server);
if (task == NULL) return; if (task == NULL) return NULL;
task->event_ctx = event_ctx; task->event_ctx = event_ctx;
task->model_ops = state->model_ops; task->model_ops = state->model_ops;
@ -95,10 +96,14 @@ static void task_server_callback(struct tevent_context *event_ctx,
task->event_ctx); task->event_ctx);
if (!task->msg_ctx) { if (!task->msg_ctx) {
task_server_terminate(task, "imessaging_init() failed", true); task_server_terminate(task, "imessaging_init() failed", true);
return; return NULL;
} }
state->task_init(task); status = state->service_details->task_init(task);
if (!NT_STATUS_IS_OK(status)) {
return NULL;
}
return task;
} }
/* /*
@ -108,7 +113,6 @@ NTSTATUS task_server_startup(struct tevent_context *event_ctx,
struct loadparm_context *lp_ctx, struct loadparm_context *lp_ctx,
const char *service_name, const char *service_name,
const struct model_ops *model_ops, const struct model_ops *model_ops,
void (*task_init)(struct task_server *),
const struct service_details *service_details, const struct service_details *service_details,
int from_parent_fd) int from_parent_fd)
{ {
@ -117,7 +121,7 @@ NTSTATUS task_server_startup(struct tevent_context *event_ctx,
state = talloc(event_ctx, struct task_state); state = talloc(event_ctx, struct task_state);
NT_STATUS_HAVE_NO_MEMORY(state); NT_STATUS_HAVE_NO_MEMORY(state);
state->task_init = task_init; state->service_details = service_details;
state->model_ops = model_ops; state->model_ops = model_ops;
state->model_ops->new_task(event_ctx, lp_ctx, service_name, state->model_ops->new_task(event_ctx, lp_ctx, service_name,

View File

@ -293,7 +293,7 @@ static const struct stream_server_ops web_stream_ops = {
/* /*
startup the web server task startup the web server task
*/ */
static void websrv_task_init(struct task_server *task) static NTSTATUS websrv_task_init(struct task_server *task)
{ {
NTSTATUS status; NTSTATUS status;
uint16_t port = lpcfg_web_port(task->lp_ctx); uint16_t port = lpcfg_web_port(task->lp_ctx);
@ -304,7 +304,10 @@ static void websrv_task_init(struct task_server *task)
/* startup the Python processor - unfortunately we can't do this /* startup the Python processor - unfortunately we can't do this
per connection as that wouldn't allow for session variables */ per connection as that wouldn't allow for session variables */
wdata = talloc_zero(task, struct web_server_data); wdata = talloc_zero(task, struct web_server_data);
if (wdata == NULL) goto failed; if (wdata == NULL) {
status = NT_STATUS_NO_MEMORY;
goto failed;
}
wdata->task = task; wdata->task = task;
task->private_data = wdata; task->private_data = wdata;
@ -339,6 +342,7 @@ static void websrv_task_init(struct task_server *task)
wcard = iface_list_wildcard(task); wcard = iface_list_wildcard(task);
if (wcard == NULL) { if (wcard == NULL) {
DEBUG(0,("No wildcard addresses available\n")); DEBUG(0,("No wildcard addresses available\n"));
status = NT_STATUS_UNSUCCESSFUL;
goto failed; goto failed;
} }
for (i=0; wcard[i]; i++) { for (i=0; wcard[i]; i++) {
@ -356,15 +360,22 @@ static void websrv_task_init(struct task_server *task)
} }
wdata->tls_params = tls_initialise(wdata, task->lp_ctx); wdata->tls_params = tls_initialise(wdata, task->lp_ctx);
if (wdata->tls_params == NULL) goto failed; if (wdata->tls_params == NULL) {
status = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
if (!wsgi_initialize(wdata)) goto failed; if (!wsgi_initialize(wdata)) {
status = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
return; return NT_STATUS_OK;
failed: failed:
task_server_terminate(task, "websrv_task_init: failed to startup web server task", true); task_server_terminate(task, "websrv_task_init: failed to startup web server task", true);
return status;
} }
@ -373,7 +384,9 @@ NTSTATUS server_service_web_init(TALLOC_CTX *ctx)
{ {
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = true .inhibit_pre_fork = true,
.task_init = websrv_task_init,
.post_fork = NULL
}; };
return register_server_service(ctx, "web", websrv_task_init, &details); return register_server_service(ctx, "web", &details);
} }

View File

@ -54,7 +54,7 @@ static void winbindd_done(struct tevent_req *subreq)
/* /*
startup a copy of winbindd as a child daemon startup a copy of winbindd as a child daemon
*/ */
static void winbindd_task_init(struct task_server *task) static NTSTATUS winbindd_task_init(struct task_server *task)
{ {
struct tevent_req *subreq; struct tevent_req *subreq;
const char *winbindd_path; const char *winbindd_path;
@ -76,12 +76,13 @@ static void winbindd_task_init(struct task_server *task)
if (subreq == NULL) { if (subreq == NULL) {
DEBUG(0, ("Failed to start winbindd as child daemon\n")); DEBUG(0, ("Failed to start winbindd as child daemon\n"));
task_server_terminate(task, "Failed to startup winbindd task", true); task_server_terminate(task, "Failed to startup winbindd task", true);
return; return NT_STATUS_UNSUCCESSFUL;
} }
tevent_req_set_callback(subreq, winbindd_done, task); tevent_req_set_callback(subreq, winbindd_done, task);
DEBUG(5,("Started winbindd as a child daemon\n")); DEBUG(5,("Started winbindd as a child daemon\n"));
return NT_STATUS_OK;
} }
/* called at winbindd startup - register ourselves as a server service */ /* called at winbindd startup - register ourselves as a server service */
@ -92,13 +93,13 @@ NTSTATUS server_service_winbindd_init(TALLOC_CTX *ctx)
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = true, .inhibit_pre_fork = true,
.task_init = winbindd_task_init,
.post_fork = NULL
}; };
NTSTATUS status = register_server_service(ctx, "winbindd", NTSTATUS status = register_server_service(ctx, "winbindd", &details);
winbindd_task_init, &details);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
return status; return status;
} }
return register_server_service(ctx, "winbind", winbindd_task_init, return register_server_service(ctx, "winbind", &details);
&details);
} }

View File

@ -446,13 +446,13 @@ static NTSTATUS wreplsrv_setup_partners(struct wreplsrv_service *service)
/* /*
startup the wrepl task startup the wrepl task
*/ */
static void wreplsrv_task_init(struct task_server *task) static NTSTATUS wreplsrv_task_init(struct task_server *task)
{ {
NTSTATUS status; NTSTATUS status;
struct wreplsrv_service *service; struct wreplsrv_service *service;
if (!lpcfg_we_are_a_wins_server(task->lp_ctx)) { if (!lpcfg_we_are_a_wins_server(task->lp_ctx)) {
return; return NT_STATUS_INVALID_DOMAIN_ROLE;
} }
task_server_set_title(task, "task[wreplsrv]"); task_server_set_title(task, "task[wreplsrv]");
@ -460,7 +460,7 @@ static void wreplsrv_task_init(struct task_server *task)
service = talloc_zero(task, struct wreplsrv_service); service = talloc_zero(task, struct wreplsrv_service);
if (!service) { if (!service) {
task_server_terminate(task, "wreplsrv_task_init: out of memory", true); task_server_terminate(task, "wreplsrv_task_init: out of memory", true);
return; return NT_STATUS_NO_MEMORY;
} }
service->task = task; service->task = task;
service->startup_time = timeval_current(); service->startup_time = timeval_current();
@ -472,7 +472,7 @@ static void wreplsrv_task_init(struct task_server *task)
status = wreplsrv_open_winsdb(service, task->lp_ctx); status = wreplsrv_open_winsdb(service, task->lp_ctx);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "wreplsrv_task_init: wreplsrv_open_winsdb() failed", true); task_server_terminate(task, "wreplsrv_task_init: wreplsrv_open_winsdb() failed", true);
return; return status;
} }
/* /*
@ -481,7 +481,7 @@ static void wreplsrv_task_init(struct task_server *task)
status = wreplsrv_setup_partners(service); status = wreplsrv_setup_partners(service);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_partners() failed", true); task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_partners() failed", true);
return; return status;
} }
/* /*
@ -491,16 +491,18 @@ static void wreplsrv_task_init(struct task_server *task)
status = wreplsrv_setup_sockets(service, task->lp_ctx); status = wreplsrv_setup_sockets(service, task->lp_ctx);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_sockets() failed", true); task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_sockets() failed", true);
return; return status;
} }
status = wreplsrv_setup_periodic(service); status = wreplsrv_setup_periodic(service);
if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_periodic() failed", true); task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_periodic() failed", true);
return; return status;
} }
irpc_add_name(task->msg_ctx, "wrepl_server"); irpc_add_name(task->msg_ctx, "wrepl_server");
return NT_STATUS_OK;
} }
/* /*
@ -510,8 +512,9 @@ NTSTATUS server_service_wrepl_init(TALLOC_CTX *ctx)
{ {
static const struct service_details details = { static const struct service_details details = {
.inhibit_fork_on_accept = true, .inhibit_fork_on_accept = true,
.inhibit_pre_fork = true .inhibit_pre_fork = true,
.task_init = wreplsrv_task_init,
.post_fork = NULL
}; };
return register_server_service(ctx, "wrepl", wreplsrv_task_init, return register_server_service(ctx, "wrepl", &details);
&details);
} }