summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-09-18 18:05:55 -0700
committerAndrew Tridgell <tridge@samba.org>2009-09-18 18:05:55 -0700
commite9a589feac531379e569bc39d803b16179002cfa (patch)
tree81fcaf840fa0ed4513e4d17d6e20f47434ca5ac5
parentade5d43c5ceb915dd2210a735a21fd9bed531dd3 (diff)
downloadsamba-e9a589feac531379e569bc39d803b16179002cfa.tar.gz
samba-e9a589feac531379e569bc39d803b16179002cfa.tar.bz2
samba-e9a589feac531379e569bc39d803b16179002cfa.zip
s4-server: kill main daemon if a task fails to initialise
When one of our core tasks fails to initialise it can now ask for the server as a whole to die, rather than limping along in a degraded state.
-rw-r--r--source4/cldap_server/cldap_server.c14
-rw-r--r--source4/dsdb/kcc/kcc_periodic.c2
-rw-r--r--source4/dsdb/kcc/kcc_service.c19
-rw-r--r--source4/dsdb/repl/drepl_notify.c2
-rw-r--r--source4/dsdb/repl/drepl_periodic.c2
-rw-r--r--source4/dsdb/repl/drepl_service.c18
-rw-r--r--source4/kdc/kdc.c28
-rw-r--r--source4/ldap_server/ldap_server.c10
-rw-r--r--source4/lib/messaging/irpc.h1
-rw-r--r--source4/lib/messaging/messaging.h3
-rw-r--r--source4/librpc/idl/irpc.idl7
-rw-r--r--source4/nbt_server/irpc.c8
-rw-r--r--source4/nbt_server/nbt_server.c10
-rw-r--r--source4/ntp_signd/ntp_signd.c6
-rw-r--r--source4/rpc_server/service_rpc.c2
-rw-r--r--source4/smb_server/smb_samba3.c2
-rw-r--r--source4/smb_server/smb_server.c2
-rw-r--r--source4/smbd/process_single.c4
-rw-r--r--source4/smbd/server.c46
-rw-r--r--source4/smbd/service_named_pipe.c2
-rw-r--r--source4/smbd/service_task.c18
-rw-r--r--source4/web_server/web_server.c2
-rw-r--r--source4/winbind/wb_server.c16
-rw-r--r--source4/wrepl_server/wrepl_periodic.c2
-rw-r--r--source4/wrepl_server/wrepl_server.c10
25 files changed, 159 insertions, 77 deletions
diff --git a/source4/cldap_server/cldap_server.c b/source4/cldap_server/cldap_server.c
index 1a08cd21f9..ee8c76ef2c 100644
--- a/source4/cldap_server/cldap_server.c
+++ b/source4/cldap_server/cldap_server.c
@@ -187,16 +187,18 @@ static void cldapd_task_init(struct task_server *task)
load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces);
if (iface_count(ifaces) == 0) {
- task_server_terminate(task, "cldapd: no network interfaces configured");
+ task_server_terminate(task, "cldapd: no network interfaces configured", false);
return;
}
switch (lp_server_role(task->lp_ctx)) {
case ROLE_STANDALONE:
- task_server_terminate(task, "cldap_server: no CLDAP server required in standalone configuration");
+ task_server_terminate(task, "cldap_server: no CLDAP server required in standalone configuration",
+ false);
return;
case ROLE_DOMAIN_MEMBER:
- task_server_terminate(task, "cldap_server: no CLDAP server required in member server configuration");
+ task_server_terminate(task, "cldap_server: no CLDAP server required in member server configuration",
+ false);
return;
case ROLE_DOMAIN_CONTROLLER:
/* Yes, we want an CLDAP server */
@@ -207,21 +209,21 @@ 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");
+ task_server_terminate(task, "cldapd: out of memory", true);
return;
}
cldapd->task = task;
cldapd->samctx = samdb_connect(cldapd, task->event_ctx, task->lp_ctx, system_session(cldapd, task->lp_ctx));
if (cldapd->samctx == NULL) {
- task_server_terminate(task, "cldapd failed to open samdb");
+ task_server_terminate(task, "cldapd failed to open samdb", true);
return;
}
/* 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");
+ task_server_terminate(task, "cldapd failed to setup interfaces", true);
return;
}
diff --git a/source4/dsdb/kcc/kcc_periodic.c b/source4/dsdb/kcc/kcc_periodic.c
index 3af79d8b89..dae0c1e235 100644
--- a/source4/dsdb/kcc/kcc_periodic.c
+++ b/source4/dsdb/kcc/kcc_periodic.c
@@ -172,7 +172,7 @@ static void kccsrv_periodic_handler_te(struct tevent_context *ev, struct tevent_
status = kccsrv_periodic_schedule(service, service->periodic.interval);
if (!W_ERROR_IS_OK(status)) {
- task_server_terminate(service->task, win_errstr(status));
+ task_server_terminate(service->task, win_errstr(status), true);
return;
}
}
diff --git a/source4/dsdb/kcc/kcc_service.c b/source4/dsdb/kcc/kcc_service.c
index 2279879000..32e09ac989 100644
--- a/source4/dsdb/kcc/kcc_service.c
+++ b/source4/dsdb/kcc/kcc_service.c
@@ -151,10 +151,10 @@ static void kccsrv_task_init(struct task_server *task)
switch (lp_server_role(task->lp_ctx)) {
case ROLE_STANDALONE:
- task_server_terminate(task, "kccsrv: no KCC required in standalone configuration");
+ task_server_terminate(task, "kccsrv: no KCC required in standalone configuration", false);
return;
case ROLE_DOMAIN_MEMBER:
- task_server_terminate(task, "kccsrv: no KCC required in domain member configuration");
+ task_server_terminate(task, "kccsrv: no KCC required in domain member configuration", false);
return;
case ROLE_DOMAIN_CONTROLLER:
/* Yes, we want a KCC */
@@ -165,7 +165,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");
+ task_server_terminate(task, "kccsrv_task_init: out of memory", true);
return;
}
service->task = task;
@@ -174,9 +174,10 @@ static void kccsrv_task_init(struct task_server *task)
status = kccsrv_init_creds(service);
if (!W_ERROR_IS_OK(status)) {
- task_server_terminate(task, talloc_asprintf(task,
- "kccsrv: Failed to obtain server credentials: %s\n",
- win_errstr(status)));
+ task_server_terminate(task,
+ talloc_asprintf(task,
+ "kccsrv: Failed to obtain server credentials: %s\n",
+ win_errstr(status)), true);
return;
}
@@ -184,7 +185,7 @@ static void kccsrv_task_init(struct task_server *task)
if (!W_ERROR_IS_OK(status)) {
task_server_terminate(task, talloc_asprintf(task,
"kccsrv: Failed to connect to local samdb: %s\n",
- win_errstr(status)));
+ win_errstr(status)), true);
return;
}
@@ -192,7 +193,7 @@ static void kccsrv_task_init(struct task_server *task)
if (!W_ERROR_IS_OK(status)) {
task_server_terminate(task, talloc_asprintf(task,
"kccsrv: Failed to load partitions: %s\n",
- win_errstr(status)));
+ win_errstr(status)), true);
return;
}
@@ -205,7 +206,7 @@ static void kccsrv_task_init(struct task_server *task)
if (!W_ERROR_IS_OK(status)) {
task_server_terminate(task, talloc_asprintf(task,
"kccsrv: Failed to periodic schedule: %s\n",
- win_errstr(status)));
+ win_errstr(status)), true);
return;
}
diff --git a/source4/dsdb/repl/drepl_notify.c b/source4/dsdb/repl/drepl_notify.c
index 73280917c5..d354b4e299 100644
--- a/source4/dsdb/repl/drepl_notify.c
+++ b/source4/dsdb/repl/drepl_notify.c
@@ -368,7 +368,7 @@ static void dreplsrv_notify_handler_te(struct tevent_context *ev, struct tevent_
status = dreplsrv_notify_schedule(service, service->notify.interval);
if (!W_ERROR_IS_OK(status)) {
- task_server_terminate(service->task, win_errstr(status));
+ task_server_terminate(service->task, win_errstr(status), false);
return;
}
}
diff --git a/source4/dsdb/repl/drepl_periodic.c b/source4/dsdb/repl/drepl_periodic.c
index 377cecbe99..61d5598207 100644
--- a/source4/dsdb/repl/drepl_periodic.c
+++ b/source4/dsdb/repl/drepl_periodic.c
@@ -46,7 +46,7 @@ static void dreplsrv_periodic_handler_te(struct tevent_context *ev, struct teven
status = dreplsrv_periodic_schedule(service, service->periodic.interval);
if (!W_ERROR_IS_OK(status)) {
- task_server_terminate(service->task, win_errstr(status));
+ task_server_terminate(service->task, win_errstr(status), false);
return;
}
}
diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c
index 75ce42b91a..34853c85f9 100644
--- a/source4/dsdb/repl/drepl_service.c
+++ b/source4/dsdb/repl/drepl_service.c
@@ -138,10 +138,12 @@ static void dreplsrv_task_init(struct task_server *task)
switch (lp_server_role(task->lp_ctx)) {
case ROLE_STANDALONE:
- task_server_terminate(task, "dreplsrv: no DSDB replication required in standalone configuration");
+ task_server_terminate(task, "dreplsrv: no DSDB replication required in standalone configuration",
+ false);
return;
case ROLE_DOMAIN_MEMBER:
- task_server_terminate(task, "dreplsrv: no DSDB replication required in domain member configuration");
+ task_server_terminate(task, "dreplsrv: no DSDB replication required in domain member configuration",
+ false);
return;
case ROLE_DOMAIN_CONTROLLER:
/* Yes, we want DSDB replication */
@@ -152,7 +154,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");
+ task_server_terminate(task, "dreplsrv_task_init: out of memory", true);
return;
}
service->task = task;
@@ -163,7 +165,7 @@ static void dreplsrv_task_init(struct task_server *task)
if (!W_ERROR_IS_OK(status)) {
task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to obtain server credentials: %s\n",
- win_errstr(status)));
+ win_errstr(status)), true);
return;
}
@@ -171,7 +173,7 @@ static void dreplsrv_task_init(struct task_server *task)
if (!W_ERROR_IS_OK(status)) {
task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to connect to local samdb: %s\n",
- win_errstr(status)));
+ win_errstr(status)), true);
return;
}
@@ -179,7 +181,7 @@ static void dreplsrv_task_init(struct task_server *task)
if (!W_ERROR_IS_OK(status)) {
task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to load partitions: %s\n",
- win_errstr(status)));
+ win_errstr(status)), true);
return;
}
@@ -190,7 +192,7 @@ static void dreplsrv_task_init(struct task_server *task)
if (!W_ERROR_IS_OK(status)) {
task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to periodic schedule: %s\n",
- win_errstr(status)));
+ win_errstr(status)), true);
return;
}
@@ -200,7 +202,7 @@ static void dreplsrv_task_init(struct task_server *task)
if (!W_ERROR_IS_OK(status)) {
task_server_terminate(task, talloc_asprintf(task,
"dreplsrv: Failed to setup notify schedule: %s\n",
- win_errstr(status)));
+ win_errstr(status)), true);
return;
}
diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c
index c861f7ae3e..a67aa09461 100644
--- a/source4/kdc/kdc.c
+++ b/source4/kdc/kdc.c
@@ -662,10 +662,10 @@ static void kdc_task_init(struct task_server *task)
switch (lp_server_role(task->lp_ctx)) {
case ROLE_STANDALONE:
- task_server_terminate(task, "kdc: no KDC required in standalone configuration");
+ task_server_terminate(task, "kdc: no KDC required in standalone configuration", false);
return;
case ROLE_DOMAIN_MEMBER:
- task_server_terminate(task, "kdc: no KDC required in member server configuration");
+ task_server_terminate(task, "kdc: no KDC required in member server configuration", false);
return;
case ROLE_DOMAIN_CONTROLLER:
/* Yes, we want a KDC */
@@ -675,7 +675,7 @@ static void kdc_task_init(struct task_server *task)
load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces);
if (iface_count(ifaces) == 0) {
- task_server_terminate(task, "kdc: no network interfaces configured");
+ task_server_terminate(task, "kdc: no network interfaces configured", false);
return;
}
@@ -683,7 +683,7 @@ static void kdc_task_init(struct task_server *task)
kdc = talloc(task, struct kdc_server);
if (kdc == NULL) {
- task_server_terminate(task, "kdc: out of memory");
+ task_server_terminate(task, "kdc: out of memory", true);
return;
}
@@ -695,7 +695,7 @@ static void kdc_task_init(struct task_server *task)
if (ret) {
DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
error_message(ret)));
- task_server_terminate(task, "kdc: krb5_init_context failed");
+ task_server_terminate(task, "kdc: krb5_init_context failed", true);
return;
}
@@ -704,14 +704,14 @@ static void kdc_task_init(struct task_server *task)
ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context,
&kdc->config);
if(ret) {
- task_server_terminate(task, "kdc: failed to get KDC configuration");
+ task_server_terminate(task, "kdc: failed to get KDC configuration", true);
return;
}
kdc->config->logf = kdc->smb_krb5_context->logf;
kdc->config->db = talloc(kdc, struct HDB *);
if (!kdc->config->db) {
- task_server_terminate(task, "kdc: out of memory");
+ task_server_terminate(task, "kdc: out of memory", true);
return;
}
kdc->config->num_db = 1;
@@ -720,7 +720,7 @@ static void kdc_task_init(struct task_server *task)
kdc->smb_krb5_context->krb5_context,
&kdc->config->db[0]);
if (!NT_STATUS_IS_OK(status)) {
- task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed");
+ task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true);
return;
}
@@ -728,7 +728,7 @@ static void kdc_task_init(struct task_server *task)
kdc->hdb_samba4_context = talloc(kdc, struct hdb_samba4_context);
if (!kdc->hdb_samba4_context) {
- task_server_terminate(task, "kdc: out of memory");
+ task_server_terminate(task, "kdc: out of memory", true);
return;
}
@@ -739,13 +739,13 @@ static void kdc_task_init(struct task_server *task)
PLUGIN_TYPE_DATA, "hdb",
&hdb_samba4);
if(ret) {
- task_server_terminate(task, "kdc: failed to register hdb keytab");
+ task_server_terminate(task, "kdc: failed to register hdb keytab", true);
return;
}
ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops);
if(ret) {
- task_server_terminate(task, "kdc: failed to register hdb keytab");
+ task_server_terminate(task, "kdc: failed to register hdb keytab", true);
return;
}
@@ -754,7 +754,7 @@ static void kdc_task_init(struct task_server *task)
PLUGIN_TYPE_DATA, "windc",
&windc_plugin_table);
if(ret) {
- task_server_terminate(task, "kdc: failed to register hdb keytab");
+ task_server_terminate(task, "kdc: failed to register hdb keytab", true);
return;
}
@@ -763,14 +763,14 @@ static void kdc_task_init(struct task_server *task)
/* start listening on the configured network interfaces */
status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces);
if (!NT_STATUS_IS_OK(status)) {
- task_server_terminate(task, "kdc failed to setup interfaces");
+ task_server_terminate(task, "kdc failed to setup interfaces", true);
return;
}
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, "nbtd failed to setup monitoring");
+ task_server_terminate(task, "nbtd failed to setup monitoring", true);
return;
}
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index b119620339..344015892e 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -568,10 +568,12 @@ static void ldapsrv_task_init(struct task_server *task)
switch (lp_server_role(task->lp_ctx)) {
case ROLE_STANDALONE:
- task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration");
+ task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration",
+ false);
return;
case ROLE_DOMAIN_MEMBER:
- task_server_terminate(task, "ldap_server: no LDAP server required in member server configuration");
+ task_server_terminate(task, "ldap_server: no LDAP server required in member server configuration",
+ false);
return;
case ROLE_DOMAIN_CONTROLLER:
/* Yes, we want an LDAP server */
@@ -642,7 +644,7 @@ static void ldapsrv_task_init(struct task_server *task)
*/
if (!directory_create_or_exist(priv_dir, geteuid(), 0750)) {
task_server_terminate(task, "Cannot create ldap "
- "privileged ldapi directory");
+ "privileged ldapi directory", true);
return;
}
ldapi_path = talloc_asprintf(ldap_service, "%s/ldapi", priv_dir);
@@ -666,7 +668,7 @@ static void ldapsrv_task_init(struct task_server *task)
return;
failed:
- task_server_terminate(task, "Failed to startup ldap server task");
+ task_server_terminate(task, "Failed to startup ldap server task", true);
}
diff --git a/source4/lib/messaging/irpc.h b/source4/lib/messaging/irpc.h
index 3c518828ab..c82ad398ff 100644
--- a/source4/lib/messaging/irpc.h
+++ b/source4/lib/messaging/irpc.h
@@ -22,6 +22,7 @@
#ifndef IRPC_H
#define IRPC_H
+#include "lib/messaging/messaging.h"
#include "librpc/gen_ndr/irpc.h"
#include "librpc/gen_ndr/server_id.h"
diff --git a/source4/lib/messaging/messaging.h b/source4/lib/messaging/messaging.h
index c91a31d285..4ec69c8f34 100644
--- a/source4/lib/messaging/messaging.h
+++ b/source4/lib/messaging/messaging.h
@@ -36,4 +36,7 @@ struct messaging_context;
/* temporary messaging endpoints are allocated above this line */
#define MSG_TMP_BASE 1000
+/* taskid for messaging of parent process */
+#define SAMBA_PARENT_TASKID 0
+
#endif
diff --git a/source4/librpc/idl/irpc.idl b/source4/librpc/idl/irpc.idl
index 41787355a9..24326e434e 100644
--- a/source4/librpc/idl/irpc.idl
+++ b/source4/librpc/idl/irpc.idl
@@ -141,4 +141,11 @@ import "misc.idl", "security.idl", "nbt.idl";
[out,switch_is(level)] smbsrv_info info
);
+ /*
+ called when samba should shutdown
+ */
+ void samba_terminate(
+ [in] astring reason
+ );
+
}
diff --git a/source4/nbt_server/irpc.c b/source4/nbt_server/irpc.c
index 951f1d296a..dbaebf66f7 100644
--- a/source4/nbt_server/irpc.c
+++ b/source4/nbt_server/irpc.c
@@ -180,7 +180,7 @@ void nbtd_register_irpc(struct nbtd_server *nbtsrv)
status = IRPC_REGISTER(task->msg_ctx, irpc, NBTD_INFORMATION,
nbtd_information, nbtsrv);
if (!NT_STATUS_IS_OK(status)) {
- task_server_terminate(task, "nbtd failed to setup monitoring");
+ task_server_terminate(task, "nbtd failed to setup monitoring", true);
return;
}
@@ -188,7 +188,7 @@ void nbtd_register_irpc(struct nbtd_server *nbtsrv)
nbtd_getdcname, nbtsrv);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "nbtd failed to setup getdcname "
- "handler");
+ "handler", true);
return;
}
@@ -196,7 +196,7 @@ void nbtd_register_irpc(struct nbtd_server *nbtsrv)
nbtd_proxy_wins_challenge, nbtsrv);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "nbtd failed to setup wins challenge "
- "handler");
+ "handler", true);
return;
}
@@ -204,7 +204,7 @@ void nbtd_register_irpc(struct nbtd_server *nbtsrv)
nbtd_proxy_wins_release_demand, nbtsrv);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "nbtd failed to setup wins release demand "
- "handler");
+ "handler", true);
return;
}
}
diff --git a/source4/nbt_server/nbt_server.c b/source4/nbt_server/nbt_server.c
index e6ff5003bf..4a02feb6fc 100644
--- a/source4/nbt_server/nbt_server.c
+++ b/source4/nbt_server/nbt_server.c
@@ -42,7 +42,7 @@ static void nbtd_task_init(struct task_server *task)
load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces);
if (iface_count(ifaces) == 0) {
- task_server_terminate(task, "nbtd: no network interfaces configured");
+ task_server_terminate(task, "nbtd: no network interfaces configured", false);
return;
}
@@ -50,7 +50,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");
+ task_server_terminate(task, "nbtd: out of memory", true);
return;
}
@@ -62,20 +62,20 @@ static void nbtd_task_init(struct task_server *task)
/* start listening on the configured network interfaces */
status = nbtd_startup_interfaces(nbtsrv, task->lp_ctx, ifaces);
if (!NT_STATUS_IS_OK(status)) {
- task_server_terminate(task, "nbtd failed to setup interfaces");
+ task_server_terminate(task, "nbtd failed to setup interfaces", true);
return;
}
nbtsrv->sam_ctx = samdb_connect(nbtsrv, task->event_ctx, task->lp_ctx, system_session(nbtsrv, task->lp_ctx));
if (nbtsrv->sam_ctx == NULL) {
- task_server_terminate(task, "nbtd failed to open samdb");
+ task_server_terminate(task, "nbtd failed to open samdb", true);
return;
}
/* 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");
+ task_server_terminate(task, "nbtd failed to start WINS server", true);
return;
}
diff --git a/source4/ntp_signd/ntp_signd.c b/source4/ntp_signd/ntp_signd.c
index 8ea7fe4ff9..a9c6769821 100644
--- a/source4/ntp_signd/ntp_signd.c
+++ b/source4/ntp_signd/ntp_signd.c
@@ -347,7 +347,7 @@ static void ntp_signd_task_init(struct task_server *task)
char *error = talloc_asprintf(task, "Cannot create NTP signd pipe directory: %s",
lp_ntp_signd_socket_directory(task->lp_ctx));
task_server_terminate(task,
- error);
+ error, true);
return;
}
@@ -364,7 +364,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");
+ task_server_terminate(task, "ntp_signd: out of memory", true);
return;
}
@@ -373,7 +373,7 @@ static void ntp_signd_task_init(struct task_server *task)
/* Must be system to get at the password hashes */
ntp_signd->samdb = samdb_connect(ntp_signd, task->event_ctx, task->lp_ctx, system_session(ntp_signd, task->lp_ctx));
if (ntp_signd->samdb == NULL) {
- task_server_terminate(task, "ntp_signd failed to open samdb");
+ task_server_terminate(task, "ntp_signd failed to open samdb", true);
return;
}
diff --git a/source4/rpc_server/service_rpc.c b/source4/rpc_server/service_rpc.c
index 3d5c364ec9..1c23eb967c 100644
--- a/source4/rpc_server/service_rpc.c
+++ b/source4/rpc_server/service_rpc.c
@@ -714,7 +714,7 @@ static void dcesrv_task_init(struct task_server *task)
return;
failed:
- task_server_terminate(task, "Failed to startup dcerpc server task");
+ task_server_terminate(task, "Failed to startup dcerpc server task", true);
}
NTSTATUS server_service_rpc_init(void)
diff --git a/source4/smb_server/smb_samba3.c b/source4/smb_server/smb_samba3.c
index 1c84392b0c..e201cdb1e9 100644
--- a/source4/smb_server/smb_samba3.c
+++ b/source4/smb_server/smb_samba3.c
@@ -165,7 +165,7 @@ static void samba3_smb_task_init(struct task_server *task)
return;
failed:
- task_server_terminate(task, "Failed to startup samba3 smb task");
+ task_server_terminate(task, "Failed to startup samba3 smb task", true);
}
/* called at smbd startup - register ourselves as a server service */
diff --git a/source4/smb_server/smb_server.c b/source4/smb_server/smb_server.c
index 2811693800..9b10f66b2c 100644
--- a/source4/smb_server/smb_server.c
+++ b/source4/smb_server/smb_server.c
@@ -249,7 +249,7 @@ static void smbsrv_task_init(struct task_server *task)
return;
failed:
- task_server_terminate(task, "Failed to startup smb server task");
+ task_server_terminate(task, "Failed to startup smb server task", true);
}
/* called at smbd startup - register ourselves as a server service */
diff --git a/source4/smbd/process_single.c b/source4/smbd/process_single.c
index 738ace95c7..ff57a0bc34 100644
--- a/source4/smbd/process_single.c
+++ b/source4/smbd/process_single.c
@@ -84,7 +84,9 @@ static void single_new_task(struct tevent_context *ev,
void (*new_task)(struct tevent_context *, struct loadparm_context *, struct server_id, void *),
void *private_data)
{
- static uint32_t taskid = 0;
+ /* start our taskids at 1, zero is reserved for the top
+ level samba task */
+ static uint32_t taskid = 1;
/* We use 1 so we cannot collide in with cluster ids generated
* in the accept connection above, and unlikly to collide with
diff --git a/source4/smbd/server.c b/source4/smbd/server.c
index 73dbec0120..d150161e05 100644
--- a/source4/smbd/server.c
+++ b/source4/smbd/server.c
@@ -40,6 +40,9 @@
#include "param/param.h"
#include "dsdb/samdb/samdb.h"
#include "auth/session.h"
+#include "lib/messaging/irpc.h"
+#include "librpc/gen_ndr/ndr_irpc.h"
+#include "cluster/cluster.h"
/*
recursively delete a directory tree
@@ -192,6 +195,43 @@ static void prime_samdb_schema(struct tevent_context *event_ctx)
talloc_free(samdb_context);
}
+
+/*
+ called when a fatal condition occurs in a child task
+ */
+static NTSTATUS samba_terminate(struct irpc_message *msg,
+ struct samba_terminate *r)
+{
+ DEBUG(0,("samba_terminate: %s\n", r->in.reason));
+ exit(1);
+}
+
+/*
+ setup messaging for the top level samba (parent) task
+ */
+static NTSTATUS setup_parent_messaging(struct tevent_context *event_ctx,
+ struct loadparm_context *lp_ctx)
+{
+ struct messaging_context *msg;
+ NTSTATUS status;
+
+ msg = messaging_init(talloc_autofree_context(),
+ lp_messaging_path(event_ctx, lp_ctx),
+ cluster_id(0, SAMBA_PARENT_TASKID),
+ lp_iconv_convenience(lp_ctx),
+ event_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(msg);
+
+ irpc_add_name(msg, "samba");
+
+ status = IRPC_REGISTER(msg, irpc, SAMBA_TERMINATE,
+ samba_terminate, NULL);
+
+ return status;
+}
+
+
+
/*
main server.
*/
@@ -363,6 +403,12 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
prime_samdb_schema(event_ctx);
+ status = setup_parent_messaging(event_ctx, cmdline_lp_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to setup parent messaging - %s\n", nt_errstr(status)));
+ return 1;
+ }
+
DEBUG(0,("%s: using '%s' process model\n", binary_name, model));
status = server_service_startup(event_ctx, cmdline_lp_ctx, model,
lp_server_services(cmdline_lp_ctx));
diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c
index 940edf2cb5..96d572e813 100644
--- a/source4/smbd/service_named_pipe.c
+++ b/source4/smbd/service_named_pipe.c
@@ -477,6 +477,8 @@ NTSTATUS stream_setup_named_pipe(struct tevent_context *event_context,
if (!directory_create_or_exist(dirname, geteuid(), 0700)) {
status = map_nt_error_from_unix(errno);
+ DEBUG(0,(__location__ ": Failed to create stream pipe directory %s - %s\n",
+ dirname, nt_errstr(status)));
goto fail;
}
diff --git a/source4/smbd/service_task.c b/source4/smbd/service_task.c
index c4fd3d4e98..5db8995764 100644
--- a/source4/smbd/service_task.c
+++ b/source4/smbd/service_task.c
@@ -25,15 +25,29 @@
#include "smbd/service_task.h"
#include "lib/messaging/irpc.h"
#include "param/param.h"
+#include "librpc/gen_ndr/ndr_irpc.h"
/*
terminate a task service
*/
-void task_server_terminate(struct task_server *task, const char *reason)
+void task_server_terminate(struct task_server *task, const char *reason, bool fatal)
{
struct tevent_context *event_ctx = task->event_ctx;
const struct model_ops *model_ops = task->model_ops;
DEBUG(0,("task_server_terminate: [%s]\n", reason));
+
+ if (fatal) {
+ struct samba_terminate r;
+ struct server_id *sid;
+
+ sid = irpc_servers_byname(task->msg_ctx, task, "samba");
+
+ r.in.reason = reason;
+ IRPC_CALL(task->msg_ctx, sid[0],
+ irpc, SAMBA_TERMINATE,
+ &r, NULL);
+ }
+
model_ops->terminate(event_ctx, task->lp_ctx, reason);
/* don't free this above, it might contain the 'reason' being printed */
@@ -72,7 +86,7 @@ static void task_server_callback(struct tevent_context *event_ctx,
lp_iconv_convenience(task->lp_ctx),
task->event_ctx);
if (!task->msg_ctx) {
- task_server_terminate(task, "messaging_init() failed");
+ task_server_terminate(task, "messaging_init() failed", true);
return;
}
diff --git a/source4/web_server/web_server.c b/source4/web_server/web_server.c
index 2a2bfbb13b..af11def5a5 100644
--- a/source4/web_server/web_server.c
+++ b/source4/web_server/web_server.c
@@ -353,7 +353,7 @@ static void websrv_task_init(struct task_server *task)
return;
failed:
- task_server_terminate(task, "websrv_task_init: failed to startup web server task");
+ task_server_terminate(task, "websrv_task_init: failed to startup web server task", true);
}
diff --git a/source4/winbind/wb_server.c b/source4/winbind/wb_server.c
index 95be49d1e3..d3142ff52a 100644
--- a/source4/winbind/wb_server.c
+++ b/source4/winbind/wb_server.c
@@ -125,21 +125,21 @@ static void winbind_task_init(struct task_server *task)
model_ops = process_model_startup(task->event_ctx, "single");
if (!model_ops) {
task_server_terminate(task,
- "Can't find 'single' process model_ops");
+ "Can't find 'single' process model_ops", true);
return;
}
/* Make sure the directory for the Samba3 socket exists, and is of the correct permissions */
if (!directory_create_or_exist(lp_winbindd_socket_directory(task->lp_ctx), geteuid(), 0755)) {
task_server_terminate(task,
- "Cannot create winbindd pipe directory");
+ "Cannot create winbindd pipe directory", true);
return;
}
/* Make sure the directory for the Samba3 socket exists, and is of the correct permissions */
if (!directory_create_or_exist(lp_winbindd_privileged_socket_directory(task->lp_ctx), geteuid(), 0750)) {
task_server_terminate(task,
- "Cannot create winbindd privileged pipe directory");
+ "Cannot create winbindd privileged pipe directory", true);
return;
}
@@ -149,13 +149,13 @@ static void winbind_task_init(struct task_server *task)
status = wbsrv_setup_domains(service);
if (!NT_STATUS_IS_OK(status)) {
- task_server_terminate(task, nt_errstr(status));
+ task_server_terminate(task, nt_errstr(status), true);
return;
}
service->idmap_ctx = idmap_init(service, task->event_ctx, task->lp_ctx);
if (service->idmap_ctx == NULL) {
- task_server_terminate(task, "Failed to load idmap database");
+ task_server_terminate(task, "Failed to load idmap database", true);
return;
}
@@ -202,15 +202,15 @@ static void winbind_task_init(struct task_server *task)
listen_failed:
DEBUG(0,("stream_setup_socket(path=%s) failed - %s\n",
listen_socket->socket_path, nt_errstr(status)));
- task_server_terminate(task, nt_errstr(status));
+ task_server_terminate(task, nt_errstr(status), true);
return;
irpc_failed:
DEBUG(0,("wbsrv_init_irpc() failed - %s\n",
nt_errstr(status)));
- task_server_terminate(task, nt_errstr(status));
+ task_server_terminate(task, nt_errstr(status), true);
return;
nomem:
- task_server_terminate(task, nt_errstr(NT_STATUS_NO_MEMORY));
+ task_server_terminate(task, nt_errstr(NT_STATUS_NO_MEMORY), true);
return;
}
diff --git a/source4/wrepl_server/wrepl_periodic.c b/source4/wrepl_server/wrepl_periodic.c
index 4771544428..94391273ca 100644
--- a/source4/wrepl_server/wrepl_periodic.c
+++ b/source4/wrepl_server/wrepl_periodic.c
@@ -55,7 +55,7 @@ static void wreplsrv_periodic_handler_te(struct tevent_context *ev, struct teven
status = wreplsrv_periodic_schedule(service, service->config.periodic_interval);
if (!NT_STATUS_IS_OK(status)) {
- task_server_terminate(service->task, nt_errstr(status));
+ task_server_terminate(service->task, nt_errstr(status), false);
return;
}
diff --git a/source4/wrepl_server/wrepl_server.c b/source4/wrepl_server/wrepl_server.c
index c8316a5f4c..a33a3d685e 100644
--- a/source4/wrepl_server/wrepl_server.c
+++ b/source4/wrepl_server/wrepl_server.c
@@ -459,7 +459,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");
+ task_server_terminate(task, "wreplsrv_task_init: out of memory", true);
return;
}
service->task = task;
@@ -471,7 +471,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");
+ task_server_terminate(task, "wreplsrv_task_init: wreplsrv_open_winsdb() failed", true);
return;
}
@@ -480,7 +480,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");
+ task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_partners() failed", true);
return;
}
@@ -490,13 +490,13 @@ 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");
+ task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_sockets() failed", true);
return;
}
status = wreplsrv_setup_periodic(service);
if (!NT_STATUS_IS_OK(status)) {
- task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_periodic() failed");
+ task_server_terminate(task, "wreplsrv_task_init: wreplsrv_setup_periodic() failed", true);
return;
}