summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--file_server/file_server.c14
-rw-r--r--source4/cldap_server/cldap_server.c23
-rw-r--r--source4/dns_server/dns_server.c35
-rw-r--r--source4/dsdb/dns/dns_update.c20
-rw-r--r--source4/dsdb/kcc/kcc_service.c23
-rw-r--r--source4/dsdb/repl/drepl_service.c27
-rw-r--r--source4/echo_server/echo_server.c18
-rw-r--r--source4/kdc/kdc-heimdal.c50
-rw-r--r--source4/kdc/kdc-service-mit.c7
-rw-r--r--source4/ldap_server/ldap_server.c38
-rw-r--r--source4/nbt_server/nbt_server.c22
-rw-r--r--source4/ntp_signd/ntp_signd.c24
-rw-r--r--source4/rpc_server/service_rpc.c13
-rw-r--r--source4/smb_server/service_smb.c14
-rw-r--r--source4/smbd/process_model.h2
-rw-r--r--source4/smbd/process_prefork.c31
-rw-r--r--source4/smbd/process_single.c9
-rw-r--r--source4/smbd/process_standard.c14
-rw-r--r--source4/smbd/service.c6
-rw-r--r--source4/smbd/service.h26
-rw-r--r--source4/smbd/service_task.c20
-rw-r--r--source4/web_server/web_server.c27
-rw-r--r--source4/winbind/winbindd.c13
-rw-r--r--source4/wrepl_server/wrepl_server.c23
24 files changed, 317 insertions, 182 deletions
diff --git a/file_server/file_server.c b/file_server/file_server.c
index 1b6a01b0b56..4c216695a1f 100644
--- a/file_server/file_server.c
+++ b/file_server/file_server.c
@@ -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;
@@ -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 */
@@ -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);
}
diff --git a/source4/cldap_server/cldap_server.c b/source4/cldap_server/cldap_server.c
index 65d983f7295..51183260833 100644
--- a/source4/cldap_server/cldap_server.c
+++ b/source4/cldap_server/cldap_server.c
@@ -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;
@@ -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;
@@ -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;
@@ -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;
}
@@ -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);
}
diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c
index c7c1cdde038..43ea88158ce 100644
--- a/source4/dns_server/dns_server.c
+++ b/source4/dns_server/dns_server.c
@@ -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;
@@ -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;
@@ -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;
}
}
@@ -827,7 +827,7 @@ 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;
@@ -835,7 +835,7 @@ static void dns_task_init(struct task_server *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,
@@ -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);
@@ -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)) {
@@ -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);
@@ -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",
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)
@@ -926,6 +927,8 @@ 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);
}
diff --git a/source4/dsdb/dns/dns_update.c b/source4/dsdb/dns/dns_update.c
index 08e7eb2224a..20052f4e47f 100644
--- a/source4/dsdb/dns/dns_update.c
+++ b/source4/dsdb/dns/dns_update.c
@@ -633,14 +633,14 @@ 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]");
@@ -648,7 +648,7 @@ static void dnsupdate_task_init(struct task_server *task)
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;
@@ -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,
@@ -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,
@@ -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);
@@ -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");
@@ -704,6 +704,7 @@ static void dnsupdate_task_init(struct task_server *task)
/* create the intial file */
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 = {
.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);
}
diff --git a/source4/dsdb/kcc/kcc_service.c b/source4/dsdb/kcc/kcc_service.c
index e1bbae2abc1..4710d5bcdf5 100644
--- a/source4/dsdb/kcc/kcc_service.c
+++ b/source4/dsdb/kcc/kcc_service.c
@@ -266,7 +266,7 @@ static NTSTATUS kccsrv_replica_get_info(struct irpc_message *msg, struct drsuapi
/*
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;
struct kccsrv_service *service;
@@ -275,10 +275,10 @@ static void kccsrv_task_init(struct task_server *task)
switch (lpcfg_server_role(task->lp_ctx)) {
case ROLE_STANDALONE:
task_server_terminate(task, "kccsrv: no KCC required in standalone configuration", false);
- return;
+ return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER:
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:
/* Yes, we want a KCC */
break;
@@ -289,7 +289,7 @@ static void kccsrv_task_init(struct task_server *task)
service = talloc_zero(task, struct kccsrv_service);
if (!service) {
task_server_terminate(task, "kccsrv_task_init: out of memory", true);
- return;
+ return NT_STATUS_NO_MEMORY;
}
service->task = task;
service->startup_time = timeval_current();
@@ -301,7 +301,7 @@ static void kccsrv_task_init(struct task_server *task)
talloc_asprintf(task,
"kccsrv: Failed to obtain server credentials: %s\n",
win_errstr(status)), true);
- return;
+ return werror_to_ntstatus(status);
}
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,
"kccsrv: Failed to connect to local samdb: %s\n",
win_errstr(status)), true);
- return;
+ return werror_to_ntstatus(status);
}
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,
"kccsrv: Failed to load partitions: %s\n",
win_errstr(status)), true);
- return;
+ return werror_to_ntstatus(status);
}
periodic_startup_interval =
@@ -338,13 +338,14 @@ static void kccsrv_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task,
"kccsrv: Failed to periodic schedule: %s\n",
win_errstr(status)), true);
- return;
+ return werror_to_ntstatus(status);
}
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_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 = {
.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);
}
diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c
index 9789e784a13..350ed611aea 100644
--- a/source4/dsdb/repl/drepl_service.c
+++ b/source4/dsdb/repl/drepl_service.c
@@ -428,7 +428,7 @@ static NTSTATUS dreplsrv_replica_mod(struct irpc_message *msg,
/*
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;
struct dreplsrv_service *service;
@@ -438,11 +438,11 @@ static void dreplsrv_task_init(struct task_server *task)
case ROLE_STANDALONE:
task_server_terminate(task, "dreplsrv: no DSDB replication required in standalone configuration",
false);
- return;
+ return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "dreplsrv: no DSDB replication required in domain member configuration",
false);
- return;
+ return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want DSDB replication */
break;
@@ -453,7 +453,7 @@ static void dreplsrv_task_init(struct task_server *task)
service = talloc_zero(task, struct dreplsrv_service);
if (!service) {
task_server_terminate(task, "dreplsrv_task_init: out of memory", true);
- return;
+ return NT_STATUS_NO_MEMORY;
}
service->task = task;
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,
"dreplsrv: Failed to obtain server credentials: %s\n",
win_errstr(status)), true);
- return;
+ return werror_to_ntstatus(status);
}
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,
"dreplsrv: Failed to connect to local samdb: %s\n",
win_errstr(status)), true);
- return;
+ return werror_to_ntstatus(status);
}
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,
"dreplsrv: Failed to load partitions: %s\n",
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 */
@@ -491,7 +491,7 @@ static void dreplsrv_task_init(struct task_server *task)
task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to periodic schedule: %s\n",
win_errstr(status)), true);
- return;
+ return werror_to_ntstatus(status);
}
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 "
"task for future DsReplicaSync\n",
true);
- return;
+ return NT_STATUS_NO_MEMORY;
}
/* 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,
"dreplsrv: Failed to setup notify schedule: %s\n",
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_TRIGGER_REPL_SECRET, drepl_trigger_repl_secret, service);
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 = {
.inhibit_fork_on_accept = true,
.inhibit_pre_fork = true,
+ .task_init = dreplsrv_task_init,
+ .post_fork = NULL,
};
- return register_server_service(ctx, "drepl", dreplsrv_task_init,
- &details);
+ return register_server_service(ctx, "drepl", &details);
}
diff --git a/source4/echo_server/echo_server.c b/source4/echo_server/echo_server.c
index 657180f760c..f38999ae139 100644
--- a/source4/echo_server/echo_server.c
+++ b/source4/echo_server/echo_server.c
@@ -265,7 +265,7 @@ static NTSTATUS echo_startup_interfaces(struct echo_server *echo,
/* 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 echo_server *echo;
@@ -282,7 +282,7 @@ static void echo_task_init(struct task_server *task)
case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "echo: Not starting echo server " \
"for domain members", false);
- return;
+ return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want to run the echo server */
break;
@@ -294,7 +294,7 @@ static void echo_task_init(struct task_server *task)
task_server_terminate(task,
"echo: No network interfaces configured",
false);
- return;
+ return NT_STATUS_UNSUCCESSFUL;
}
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);
if (echo == NULL) {
task_server_terminate(task, "echo: Out of memory", true);
- return;
+ return NT_STATUS_NO_MEMORY;
}
echo->task = task;
@@ -312,8 +312,9 @@ static void echo_task_init(struct task_server *task)
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "echo: Failed to set up interfaces",
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 = {
.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);
}
diff --git a/source4/kdc/kdc-heimdal.c b/source4/kdc/kdc-heimdal.c
index 8f09c41d74d..3beff5d95da 100644
--- a/source4/kdc/kdc-heimdal.c
+++ b/source4/kdc/kdc-heimdal.c
@@ -261,7 +261,7 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
/*
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;
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)) {
case ROLE_STANDALONE:
task_server_terminate(task, "kdc: no KDC required in standalone configuration", false);
- return;
+ return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER:
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_BDC:
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:
/* Yes, we want a KDC */
break;
@@ -290,7 +290,7 @@ static void kdc_task_init(struct task_server *task)
if (iface_list_count(ifaces) == 0) {
task_server_terminate(task, "kdc: no network interfaces configured", false);
- return;
+ return NT_STATUS_UNSUCCESSFUL;
}
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);
if (kdc == NULL) {
task_server_terminate(task, "kdc: out of memory", true);
- return;
+ return NT_STATUS_NO_MEMORY;
}
kdc->task = task;
@@ -314,7 +314,7 @@ static void kdc_task_init(struct task_server *task)
if (!kdc->samdb) {
DEBUG(1,("kdc_task_init: unable to connect to samdb\n"));
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);
@@ -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",
ldb_errstring(kdc->samdb)));
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);
@@ -334,7 +334,7 @@ static void kdc_task_init(struct task_server *task)
DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
error_message(ret)));
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);
@@ -343,14 +343,14 @@ static void kdc_task_init(struct task_server *task)
&kdc_config);
if(ret) {
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->db = talloc(kdc, struct HDB *);
if (!kdc_config->db) {
task_server_terminate(task, "kdc: out of memory", true);
- return;
+ return NT_STATUS_UNSUCCESSFUL;
}
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);
if (!kdc->base_ctx) {
task_server_terminate(task, "kdc: out of memory", true);
- return;
+ return NT_STATUS_NO_MEMORY;
}
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]);
if (!NT_STATUS_IS_OK(status)) {
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,
@@ -402,13 +402,13 @@ static void kdc_task_init(struct task_server *task)
&hdb_samba4_interface);
if(ret) {
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);
if(ret) {
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);
@@ -416,7 +416,7 @@ static void kdc_task_init(struct task_server *task)
task_server_terminate(task,
"kdc: Failed to set keytab name",
true);
- return;
+ return NT_STATUS_UNSUCCESSFUL;
}
/* Register WinDC hooks */
@@ -425,21 +425,21 @@ static void kdc_task_init(struct task_server *task)
&windc_plugin_table);
if(ret) {
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);
if(ret) {
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);
if(ret) {
task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true);
- return;
+ return NT_STATUS_UNSUCCESSFUL;
}
kdc->private_data = kdc_config;
@@ -448,17 +448,19 @@ static void kdc_task_init(struct task_server *task)
task->model_ops);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "kdc failed to setup interfaces", true);
- return;
+ return status;
}
status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS,
kdc_check_generic_kerberos, kdc);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "kdc failed to setup monitoring", true);
- return;
+ return status;
}
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
* 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);
}
diff --git a/source4/kdc/kdc-service-mit.c b/source4/kdc/kdc-service-mit.c
index 5d111ee82d2..8ae1c219dc7 100644
--- a/source4/kdc/kdc-service-mit.c
+++ b/source4/kdc/kdc-service-mit.c
@@ -365,8 +365,9 @@ NTSTATUS server_service_mitkdc_init(TALLOC_CTX *mem_ctx)
* the master process is responsible for managing the worker
* 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,
- &details);
+ return register_server_service(mem_ctx, "kdc", &details);
}
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index 5b1db0c109a..f6329f05c5a 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -1122,7 +1122,7 @@ static NTSTATUS add_socket(struct task_server *task,
/*
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;
#ifdef WITH_LDAPI_PRIV_SOCKET
@@ -1136,11 +1136,11 @@ static void ldapsrv_task_init(struct task_server *task)
case ROLE_STANDALONE:
task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration",
false);
- return;
+ return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "ldap_server: no LDAP server required in member server configuration",
false);
- return;
+ return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want an LDAP server */
break;
@@ -1149,14 +1149,20 @@ static void ldapsrv_task_init(struct task_server *task)
task_server_set_title(task, "task[ldapsrv]");
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;
dns_host_name = talloc_asprintf(ldap_service, "%s.%s",
lpcfg_netbios_name(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,
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");
- 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)) {
struct interface *ifaces;
@@ -1202,6 +1211,7 @@ static void ldapsrv_task_init(struct task_server *task)
wcard = iface_list_wildcard(task);
if (wcard == NULL) {
DEBUG(0,("No wildcard addresses available\n"));
+ status = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
for (i=0; wcard[i]; i++) {
@@ -1213,12 +1223,14 @@ static void ldapsrv_task_init(struct task_server *task)
}
talloc_free(wcard);
if (num_binds == 0) {
+ status = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
}
ldapi_path = lpcfg_private_path(ldap_service, task->lp_ctx, "ldapi");
if (!ldapi_path) {
+ status = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
@@ -1236,6 +1248,7 @@ static void ldapsrv_task_init(struct task_server *task)
#ifdef WITH_LDAPI_PRIV_SOCKET
priv_dir = lpcfg_private_path(ldap_service, task->lp_ctx, "ldap_priv");
if (priv_dir == NULL) {
+ status = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
/*
@@ -1245,11 +1258,12 @@ static void ldapsrv_task_init(struct task_server *task)
if (!directory_create_or_exist(priv_dir, 0750)) {
task_server_terminate(task, "Cannot create ldap "
"privileged ldapi directory", true);
- return;
+ return NT_STATUS_UNSUCCESSFUL;
}
ldapi_path = talloc_asprintf(ldap_service, "%s/ldapi", priv_dir);
talloc_free(priv_dir);
if (ldapi_path == NULL) {
+ status = NT_STATUS_NO_MEMORY;
goto failed;
}
@@ -1269,10 +1283,11 @@ static void ldapsrv_task_init(struct task_server *task)
/* register the server */
irpc_add_name(task->msg_ctx, "ldap_server");
- return;
+ return NT_STATUS_OK;
failed:
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 = {
.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,
- &details);
+ return register_server_service(ctx, "ldap", &details);
}
diff --git a/source4/nbt_server/nbt_server.c b/source4/nbt_server/nbt_server.c
index 84cd507fe13..00c255cf0d3 100644
--- a/source4/nbt_server/nbt_server.c
+++ b/source4/nbt_server/nbt_server.c
@@ -35,7 +35,7 @@ NTSTATUS server_service_nbtd_init(TALLOC_CTX *);
/*
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;
NTSTATUS status;
@@ -45,12 +45,12 @@ static void nbtd_task_init(struct task_server *task)
if (iface_list_count(ifaces) == 0) {
task_server_terminate(task, "nbtd: no network interfaces configured", false);
- return;
+ return NT_STATUS_UNSUCCESSFUL;
}
if (lpcfg_disable_netbios(task->lp_ctx)) {
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]");
@@ -58,7 +58,7 @@ static void nbtd_task_init(struct task_server *task)
nbtsrv = talloc(task, struct nbtd_server);
if (nbtsrv == NULL) {
task_server_terminate(task, "nbtd: out of memory", true);
- return;
+ return NT_STATUS_NO_MEMORY;
}
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);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "nbtd failed to setup interfaces", true);
- return;
+ return status;
}
nbtsrv->sam_ctx = samdb_connect(nbtsrv,
@@ -81,14 +81,14 @@ static void nbtd_task_init(struct task_server *task)
0);
if (nbtsrv->sam_ctx == NULL) {
task_server_terminate(task, "nbtd failed to open samdb", true);
- return;
+ return NT_STATUS_UNSUCCESSFUL;
}
/* start the WINS server, if appropriate */
status = nbtd_winsserver_init(nbtsrv);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "nbtd failed to start WINS server", true);
- return;
+ return status;
}
nbtd_register_irpc(nbtsrv);
@@ -97,6 +97,8 @@ static void nbtd_task_init(struct task_server *task)
nbtd_register_names(nbtsrv);
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 = {
.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);
}
diff --git a/source4/ntp_signd/ntp_signd.c b/source4/ntp_signd/ntp_signd.c
index a392929c78b..5999bf81540 100644
--- a/source4/ntp_signd/ntp_signd.c
+++ b/source4/ntp_signd/ntp_signd.c
@@ -489,7 +489,7 @@ static const struct stream_server_ops ntp_signd_stream_ops = {
/*
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;
NTSTATUS status;
@@ -501,7 +501,7 @@ static void ntp_signd_task_init(struct task_server *task)
lpcfg_ntp_signd_socket_directory(task->lp_ctx));
task_server_terminate(task,
error, true);
- return;
+ return NT_STATUS_UNSUCCESSFUL;
}
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);
if (ntp_signd == NULL) {
task_server_terminate(task, "ntp_signd: out of memory", true);
- return;
+ return NT_STATUS_NO_MEMORY;
}
ntp_signd->task = task;
@@ -523,10 +523,15 @@ static void ntp_signd_task_init(struct task_server *task)
0);
if (ntp_signd->samdb == NULL) {
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));
+ 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,
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)) {
DEBUG(0,("Failed to bind to %s - %s\n",
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 = {
.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,
- &details);
+ return register_server_service(ctx, "ntp_signd", &details);
}
diff --git a/source4/rpc_server/service_rpc.c b/source4/rpc_server/service_rpc.c
index f7d1a9f3c7d..07d6f700687 100644
--- a/source4/rpc_server/service_rpc.c
+++ b/source4/rpc_server/service_rpc.c
@@ -44,9 +44,9 @@ NTSTATUS server_service_rpc_init(TALLOC_CTX *);
/*
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_endpoint *e;
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");
- return;
+ return NT_STATUS_OK;
failed:
task_server_terminate(task, "Failed to startup dcerpc server task", true);
+ return status;
}
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
*/
.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);
}
diff --git a/source4/smb_server/service_smb.c b/source4/smb_server/service_smb.c
index bea7eb9285b..37e8a61afb5 100644
--- a/source4/smb_server/service_smb.c
+++ b/source4/smb_server/service_smb.c
@@ -38,9 +38,9 @@
/*
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]");
@@ -72,6 +72,7 @@ static void smbsrv_task_init(struct task_server *task)
wcard = iface_list_wildcard(task);
if (wcard == NULL) {
DEBUG(0,("No wildcard addresses available\n"));
+ status = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
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");
- return;
+ return NT_STATUS_OK;
failed:
task_server_terminate(task, "Failed to startup smb server task", true);
+ return status;
}
/* 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 = {
.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);
share_init();
- return register_server_service(ctx, "smb", smbsrv_task_init, &details);
+ return register_server_service(ctx, "smb", &details);
}
diff --git a/source4/smbd/process_model.h b/source4/smbd/process_model.h
index 656a7f2e29c..17d70254cf2 100644
--- a/source4/smbd/process_model.h
+++ b/source4/smbd/process_model.h
@@ -58,7 +58,7 @@ struct model_ops {
void (*new_task)(struct tevent_context *,
struct loadparm_context *lp_ctx,
const char *service_name,
- void (*)(struct tevent_context *,
+ struct task_server * (*)(struct tevent_context *,
struct loadparm_context *, struct server_id,
void *, void *),
void *,
diff --git a/source4/smbd/process_prefork.c b/source4/smbd/process_prefork.c
index f6fb80b986d..788aa976390 100644
--- a/source4/smbd/process_prefork.c
+++ b/source4/smbd/process_prefork.c
@@ -227,7 +227,7 @@ static void prefork_new_task(
struct tevent_context *ev,
struct loadparm_context *lp_ctx,
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 server_id , void *, void *),
void *private_data,
@@ -239,6 +239,7 @@ static void prefork_new_task(
int i, num_children;
struct tevent_context *ev2;
+ struct task_server *task = NULL;
t = tfork_create();
if (t == NULL) {
@@ -277,8 +278,14 @@ static void prefork_new_task(
setup_handlers(ev, from_parent_fd);
if (service_details->inhibit_pre_fork) {
- new_task_fn(ev, lp_ctx, cluster_id(pid, 0), private_data, NULL);
- /* The task does not support pre-fork */
+ task = new_task_fn(
+ 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);
TALLOC_FREE(ev);
exit(0);
@@ -298,7 +305,12 @@ static void prefork_new_task(
* process accepting and handling requests, it's responsible for
* 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;
@@ -313,7 +325,9 @@ static void prefork_new_task(
}
DBG_NOTICE("Forking %d %s worker processes\n",
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++) {
struct tfork* w = NULL;
@@ -335,7 +349,9 @@ static void prefork_new_task(
}
tevent_fd_set_auto_close(fde);
} else {
- /* tfork uses malloc */
+ /*
+ * tfork uses malloc
+ */
free(w);
TALLOC_FREE(ev);
@@ -343,6 +359,9 @@ static void prefork_new_task(
service_name);
prefork_reload_after_fork();
setup_handlers(ev2, from_parent_fd);
+ if (service_details->post_fork != NULL) {
+ service_details->post_fork(task);
+ }
tevent_loop_wait(ev2);
talloc_free(ev2);
exit(0);
diff --git a/source4/smbd/process_single.c b/source4/smbd/process_single.c
index 1859c96809e..242622b3b8f 100644
--- a/source4/smbd/process_single.c
+++ b/source4/smbd/process_single.c
@@ -92,7 +92,7 @@ static void single_accept_connection(struct tevent_context *ev,
static void single_new_task(struct tevent_context *ev,
struct loadparm_context *lp_ctx,
const char *service_name,
- void (*new_task)(struct tevent_context *,
+ struct task_server *(*new_task)(struct tevent_context *,
struct loadparm_context *,
struct server_id, void *, void *),
void *private_data,
@@ -102,7 +102,7 @@ static void single_new_task(struct tevent_context *ev,
pid_t pid = getpid();
/* start our taskids at MAX_INT32, the first 2^31 tasks are is reserved for fd numbers */
static uint32_t taskid = INT32_MAX;
-
+ struct task_server *task = NULL;
/*
* We use the PID so we cannot collide in with cluster ids
* 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
* 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);
+ }
}
diff --git a/source4/smbd/process_standard.c b/source4/smbd/process_standard.c
index 677345f2c83..62620096af5 100644
--- a/source4/smbd/process_standard.c
+++ b/source4/smbd/process_standard.c
@@ -393,7 +393,7 @@ static void standard_accept_connection(
static void standard_new_task(struct tevent_context *ev,
struct loadparm_context *lp_ctx,
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,
const struct service_details *service_details,
int from_parent_fd)
@@ -404,6 +404,7 @@ static void standard_new_task(struct tevent_context *ev,
struct tevent_fd *fde = NULL;
struct tevent_signal *se = NULL;
struct process_context *proc_ctx = NULL;
+ struct task_server* task = NULL;
state = setup_standard_child_pipe(ev, service_name);
if (state == NULL) {
@@ -486,7 +487,16 @@ static void standard_new_task(struct tevent_context *ev,
proc_ctx->forked_on_accept = false;
/* 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,
so we now process events in the new event context until there are no
diff --git a/source4/smbd/service.c b/source4/smbd/service.c
index 0874fce20fc..7c8d2cfe3a4 100644
--- a/source4/smbd/service.c
+++ b/source4/smbd/service.c
@@ -30,8 +30,7 @@
static struct registered_server {
struct registered_server *next, *prev;
const char *service_name;
- struct service_details *service_details;
- void (*task_init)(struct task_server *);
+ const struct service_details *service_details;
} *registered_servers;
/*
@@ -39,14 +38,12 @@ static struct registered_server {
*/
NTSTATUS register_server_service(TALLOC_CTX *ctx,
const char *name,
- void (*task_init) (struct task_server *),
const struct service_details *details)
{
struct registered_server *srv;
srv = talloc(ctx, struct registered_server);
NT_STATUS_HAVE_NO_MEMORY(srv);
srv->service_name = name;
- srv->task_init = task_init;
srv->service_details =
talloc_memdup(ctx, details, sizeof(struct 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,
srv->service_name,
model_ops,
- srv->task_init,
srv->service_details,
from_parent_fd);
}
diff --git a/source4/smbd/service.h b/source4/smbd/service.h
index 2d11f142aed..467cb34f6ca 100644
--- a/source4/smbd/service.h
+++ b/source4/smbd/service.h
@@ -40,7 +40,31 @@ struct service_details {
* processes. In this mode pre-fork is equivalent to standard with
* 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"
diff --git a/source4/smbd/service_task.c b/source4/smbd/service_task.c
index 729a1094e75..15e480ec043 100644
--- a/source4/smbd/service_task.c
+++ b/source4/smbd/service_task.c
@@ -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 */
struct task_state {
- void (*task_init)(struct task_server *);
+ const struct service_details *service_details;
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
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 server_id server_id,
void *private_data,
void *context)
{
- struct task_state *state = talloc_get_type(private_data, struct task_state);
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);
- if (task == NULL) return;
+ if (task == NULL) return NULL;
task->event_ctx = event_ctx;
task->model_ops = state->model_ops;
@@ -95,10 +96,14 @@ static void task_server_callback(struct tevent_context *event_ctx,
task->event_ctx);
if (!task->msg_ctx) {
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,
const char *service_name,
const struct model_ops *model_ops,
- void (*task_init)(struct task_server *),
const struct service_details *service_details,
int from_parent_fd)
{
@@ -117,7 +121,7 @@ NTSTATUS task_server_startup(struct tevent_context *event_ctx,
state = talloc(event_ctx, struct task_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->new_task(event_ctx, lp_ctx, service_name,
diff --git a/source4/web_server/web_server.c b/source4/web_server/web_server.c
index d72524c8873..7c2717368e3 100644
--- a/source4/web_server/web_server.c
+++ b/source4/web_server/web_server.c
@@ -293,7 +293,7 @@ static const struct stream_server_ops web_stream_ops = {
/*
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;
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
per connection as that wouldn't allow for session variables */
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;
task->private_data = wdata;
@@ -339,6 +342,7 @@ static void websrv_task_init(struct task_server *task)
wcard = iface_list_wildcard(task);
if (wcard == NULL) {
DEBUG(0,("No wildcard addresses available\n"));
+ status = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
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);
- 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:
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 = {
.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);
}
diff --git a/source4/winbind/winbindd.c b/source4/winbind/winbindd.c
index e422e623b84..e68ddfb68e1 100644
--- a/source4/winbind/winbindd.c
+++ b/source4/winbind/winbindd.c
@@ -54,7 +54,7 @@ static void winbindd_done(struct tevent_req *subreq)
/*
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;
const char *winbindd_path;
@@ -76,12 +76,13 @@ static void winbindd_task_init(struct task_server *task)
if (subreq == NULL) {
DEBUG(0, ("Failed to start winbindd as child daemon\n"));
task_server_terminate(task, "Failed to startup winbindd task", true);
- return;
+ return NT_STATUS_UNSUCCESSFUL;
}
tevent_req_set_callback(subreq, winbindd_done, task);
DEBUG(5,("Started winbindd as a child daemon\n"));
+ return NT_STATUS_OK;
}
/* 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 = {
.inhibit_fork_on_accept = true,
.inhibit_pre_fork = true,
+ .task_init = winbindd_task_init,
+ .post_fork = NULL
};
- NTSTATUS status = register_server_service(ctx, "winbindd",
- winbindd_task_init, &details);
+ NTSTATUS status = register_server_service(ctx, "winbindd", &details);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- return register_server_service(ctx, "winbind", winbindd_task_init,
- &details);
+ return register_server_service(ctx, "winbind", &details);
}
diff --git a/source4/wrepl_server/wrepl_server.c b/source4/wrepl_server/wrepl_server.c
index 269fac0670d..d1e2869b009 100644
--- a/source4/wrepl_server/wrepl_server.c
+++ b/source4/wrepl_server/wrepl_server.c
@@ -446,13 +446,13 @@ static NTSTATUS wreplsrv_setup_partners(struct wreplsrv_service *service)
/*
startup the wrepl task
*/
-static void wreplsrv_task_init(struct task_server *task)
+static NTSTATUS wreplsrv_task_init(struct task_server *task)
{
NTSTATUS status;
struct wreplsrv_service *service;
if (!lpcfg_we_are_a_wins_server(task->lp_ctx)) {
- return;
+ return NT_STATUS_INVALID_DOMAIN_ROLE;
}
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);
if (!service) {
task_server_terminate(task, "wreplsrv_task_init: out of memory", true);
- return;
+ return NT_STATUS_NO_MEMORY;
}
service->task = task;
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);
if (!NT_STATUS_IS_OK(status)) {
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);
if (!NT_STATUS_IS_OK(status)) {
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);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_sockets() failed", true);
- return;
+ return status;
}
status = wreplsrv_setup_periodic(service);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_periodic() failed", true);
- return;
+ return status;
}
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 = {
.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,
- &details);
+ return register_server_service(ctx, "wrepl", &details);
}