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 */
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;
}
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;
}
}
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 */
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;
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;
}
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;
}
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;
}
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;
}
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;
}
}
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;
}
}
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 */
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;
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;
}
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;
}
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;
}
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;
}
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;
}
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 */
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;
}
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;
}
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;
}
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;
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;
}
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;
}
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;
}
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;
}
/* 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;
}
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 */
*/
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);
return;
failed:
- task_server_terminate(task, "Failed to startup ldap server task");
+ task_server_terminate(task, "Failed to startup ldap server task", true);
}
#ifndef IRPC_H
#define IRPC_H
+#include "lib/messaging/messaging.h"
#include "librpc/gen_ndr/irpc.h"
#include "librpc/gen_ndr/server_id.h"
/* 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
[out,switch_is(level)] smbsrv_info info
);
+ /*
+ called when samba should shutdown
+ */
+ void samba_terminate(
+ [in] astring reason
+ );
+
}
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;
}
nbtd_getdcname, nbtsrv);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "nbtd failed to setup getdcname "
- "handler");
+ "handler", true);
return;
}
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;
}
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;
}
}
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;
}
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;
}
/* 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;
}
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;
}
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;
}
/* 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;
}
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)
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 */
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 */
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
#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
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.
*/
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));
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;
}
#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 */
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;
}
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);
}
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;
}
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;
}
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;
}
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;
}
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;
*/
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;
}
*/
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;
}
*/
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;
}