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
*/
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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

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 */
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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 *,

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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"

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 */
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,

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}