6
Copyright (C) Simo Sorce 2008
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program. If not, see <http://www.gnu.org/licenses/>.
23
#include <sys/types.h>
26
#include <sys/param.h>
30
#ifdef HAVE_SYS_INOTIFY_H
31
#include <sys/inotify.h>
33
#include <sys/types.h>
38
/* Needed for res_init() */
39
#include <netinet/in.h>
40
#include <arpa/nameser.h>
43
#include "util/util.h"
46
#include "confdb/confdb.h"
47
#include "confdb/confdb_setup.h"
48
#include "collection.h"
49
#include "ini_config.h"
51
#include "monitor/monitor.h"
52
#include "dbus/dbus.h"
53
#include "sbus/sssd_dbus.h"
54
#include "monitor/monitor_interfaces.h"
56
/* ping time cannot be less then once every few seconds or the
57
* monitor will get crazy hammering children with messages */
58
#define MONITOR_DEF_PING_TIME 10
65
struct sbus_connection *conn;
66
struct svc_spy *conn_spy;
68
struct mt_ctx *mt_ctx;
87
struct tevent_timer *ping_ev;
90
struct config_file_callback {
96
struct config_file_callback *next;
97
struct config_file_callback *prev;
100
struct config_file_ctx {
101
TALLOC_CTX *parent_ctx;
102
struct tevent_timer *timer;
104
struct mt_ctx *mt_ctx;
105
struct config_file_callback *callbacks;
109
struct tevent_context *ev;
110
struct confdb_ctx *cdb;
111
TALLOC_CTX *domain_ctx; /* Memory context for domain list */
112
struct sss_domain_info *domains;
113
TALLOC_CTX *service_ctx; /* Memory context for services */
115
struct mt_svc *svc_list;
116
struct sbus_connection *sbus_srv;
117
struct config_file_ctx *file_ctx;
119
int service_id_timeout;
121
bool services_started;
122
struct netlink_ctx *nlctx;
125
static int start_service(struct mt_svc *mt_svc);
127
static int monitor_service_init(struct sbus_connection *conn, void *data);
129
static int service_send_ping(struct mt_svc *svc);
130
static int service_signal_reset_offline(struct mt_svc *svc);
131
static void ping_check(DBusPendingCall *pending, void *data);
133
static int service_check_alive(struct mt_svc *svc);
135
static void set_tasks_checker(struct mt_svc *srv);
136
static void set_global_checker(struct mt_ctx *ctx);
137
static int monitor_kill_service (struct mt_svc *svc);
139
static int get_service_config(struct mt_ctx *ctx, const char *name,
140
struct mt_svc **svc_cfg);
141
static int get_provider_config(struct mt_ctx *ctx, const char *name,
142
struct mt_svc **svc_cfg);
143
static int add_new_service(struct mt_ctx *ctx, const char *name);
144
static int add_new_provider(struct mt_ctx *ctx, const char *name);
146
static int mark_service_as_started(struct mt_svc *svc);
148
static int monitor_cleanup(void);
150
static void network_status_change_cb(enum network_change state,
154
struct mt_ctx *ctx = (struct mt_ctx *) cb_data;
156
if (state != NL_ROUTE_UP) return;
158
DEBUG(9, ("A new route has appeared, signaling providers to reset offline status\n"));
159
for (iter = ctx->svc_list; iter; iter = iter->next) {
160
/* Don't signal services, only providers */
161
if (iter->provider) {
162
service_signal_reset_offline(iter);
167
/* dbus_get_monitor_version
168
* Return the monitor version over D-BUS */
169
static int get_monitor_version(DBusMessage *message,
170
struct sbus_connection *conn)
172
dbus_uint16_t version = MONITOR_VERSION;
176
reply = dbus_message_new_method_return(message);
177
if (!reply) return ENOMEM;
178
ret = dbus_message_append_args(reply,
179
DBUS_TYPE_UINT16, &version,
182
dbus_message_unref(reply);
186
/* send reply back */
187
sbus_conn_send_reply(conn, reply);
188
dbus_message_unref(reply);
193
struct mon_init_conn {
195
struct sbus_connection *conn;
196
struct tevent_timer *timeout;
199
static int add_svc_conn_spy(struct mt_svc *svc);
201
/* registers a new client.
202
* if operation is successful also sends back the Monitor version */
203
static int client_registration(DBusMessage *message,
204
struct sbus_connection *conn)
206
dbus_uint16_t version = MONITOR_VERSION;
207
struct mon_init_conn *mini;
211
DBusError dbus_error;
212
dbus_uint16_t svc_ver;
217
data = sbus_conn_get_private_data(conn);
218
mini = talloc_get_type(data, struct mon_init_conn);
220
DEBUG(0, ("Connection holds no valid init data\n"));
224
/* First thing, cancel the timeout */
225
talloc_zfree(mini->timeout);
227
dbus_error_init(&dbus_error);
229
dbret = dbus_message_get_args(message, &dbus_error,
230
DBUS_TYPE_STRING, &svc_name,
231
DBUS_TYPE_UINT16, &svc_ver,
234
DEBUG(1, ("Failed to parse message, killing connection\n"));
235
if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
236
sbus_disconnect(conn);
237
/* FIXME: should we just talloc_zfree(conn) ? */
241
DEBUG(4, ("Received ID registration: (%s,%d)\n", svc_name, svc_ver));
243
/* search this service in the list */
244
svc = mini->ctx->svc_list;
246
ret = strcasecmp(svc->identity, svc_name);
253
DEBUG(0, ("Unable to find peer [%s] in list of services,"
254
" killing connection!\n", svc_name));
255
sbus_disconnect(conn);
256
/* FIXME: should we just talloc_zfree(conn) ? */
260
/* Fill in svc structure with connection data */
261
svc->conn = mini->conn;
263
ret = mark_service_as_started(svc);
265
DEBUG(1, ("Failed to mark service [%s]!\n", svc_name));
269
/* reply that all is ok */
270
reply = dbus_message_new_method_return(message);
271
if (!reply) return ENOMEM;
273
dbret = dbus_message_append_args(reply,
274
DBUS_TYPE_UINT16, &version,
277
dbus_message_unref(reply);
281
/* send reply back */
282
sbus_conn_send_reply(conn, reply);
283
dbus_message_unref(reply);
286
/* init complete, get rid of temp init context */
296
static int svc_destructor(void *mem)
298
struct mt_svc *svc = talloc_get_type(mem, struct mt_svc);
304
/* try to delist service */
306
DLIST_REMOVE(svc->mt_ctx->svc_list, svc);
309
/* svc is beeing freed, neutralize the spy */
311
talloc_set_destructor((TALLOC_CTX *)svc->conn_spy, NULL);
312
talloc_zfree(svc->conn_spy);
317
static int svc_spy_destructor(void *mem)
319
struct svc_spy *spy = talloc_get_type(mem, struct svc_spy);
325
/* svc->conn has been freed, NULL the pointer in svc */
326
spy->svc->conn_spy = NULL;
327
spy->svc->conn = NULL;
331
static int add_svc_conn_spy(struct mt_svc *svc)
335
spy = talloc(svc->conn, struct svc_spy);
336
if (!spy) return ENOMEM;
339
talloc_set_destructor((TALLOC_CTX *)spy, svc_spy_destructor);
345
static int mark_service_as_started(struct mt_svc *svc)
347
struct mt_ctx *ctx = svc->mt_ctx;
352
DEBUG(5, ("Marking %s as started.\n", svc->name));
353
svc->svc_started = true;
355
/* we need to attach a spy to the connection structure so that if some code
356
* frees it we can zero it out in the service structure. Otherwise we may
357
* try to access or even free, freed memory. */
358
ret = add_svc_conn_spy(svc);
360
DEBUG(0, ("Failed to attch spy\n"));
364
if (!ctx->services_started) {
366
/* check if all providers are up */
367
for (iter = ctx->svc_list; iter; iter = iter->next) {
368
if (iter->provider && !iter->svc_started) {
369
DEBUG(5, ("Still waiting on %s provider.\n", iter->name));
375
/* there are still unstarted providers */
379
ctx->services_started = true;
381
DEBUG(4, ("Now starting services!\n"));
382
/* then start all services */
383
for (i = 0; ctx->services[i]; i++) {
384
add_new_service(ctx, ctx->services[i]);
392
static void services_startup_timeout(struct tevent_context *ev,
393
struct tevent_timer *te,
394
struct timeval t, void *ptr)
396
struct mt_ctx *ctx = talloc_get_type(ptr, struct mt_ctx);
399
DEBUG(6, ("Handling timeout\n"));
401
if (!ctx->services_started) {
403
DEBUG(1, ("Providers did not start in time, "
404
"forcing services startup!\n"));
406
ctx->services_started = true;
408
DEBUG(4, ("Now starting services!\n"));
409
/* then start all services */
410
for (i = 0; ctx->services[i]; i++) {
411
add_new_service(ctx, ctx->services[i]);
416
static int add_services_startup_timeout(struct mt_ctx *ctx)
418
struct tevent_timer *to;
421
/* 5 seconds should be plenty */
422
tv = tevent_timeval_current_ofs(5, 0);
423
to = tevent_add_timer(ctx->ev, ctx, tv, services_startup_timeout, ctx);
425
DEBUG(0,("Out of memory?!\n"));
432
struct sbus_method monitor_methods[] = {
433
{ MON_SRV_METHOD_VERSION, get_monitor_version },
434
{ MON_SRV_METHOD_REGISTER, client_registration },
438
struct sbus_interface monitor_server_interface = {
447
* Set up the monitor service as a D-BUS Server */
448
static int monitor_dbus_init(struct mt_ctx *ctx)
450
char *monitor_address;
453
ret = monitor_get_sbus_address(ctx, &monitor_address);
458
ret = sbus_new_server(ctx, ctx->ev,
459
monitor_address, &monitor_server_interface,
460
&ctx->sbus_srv, monitor_service_init, ctx);
462
talloc_free(monitor_address);
467
static void svc_try_restart(struct mt_svc *svc, time_t now)
471
DLIST_REMOVE(svc->mt_ctx->svc_list, svc);
472
if (svc->last_restart != 0) {
473
if ((now - svc->last_restart) > 30) { /* TODO: get val from config */
474
/* it was long ago reset restart threshold */
479
/* restart the process */
480
if (svc->restarts > 3) { /* TODO: get val from config */
481
DEBUG(0, ("Process [%s], definitely stopped!\n", svc->name));
486
/* Shut down the current ping timer so it will restart
487
* cleanly in start_service()
489
talloc_free(svc->ping_ev);
491
ret = start_service(svc);
493
DEBUG(0,("Failed to restart service '%s'\n", svc->name));
499
svc->last_restart = now;
503
static void tasks_check_handler(struct tevent_context *ev,
504
struct tevent_timer *te,
505
struct timeval t, void *ptr)
507
struct mt_svc *svc = talloc_get_type(ptr, struct mt_svc);
508
time_t now = time(NULL);
509
bool process_alive = true;
512
ret = service_check_alive(svc);
519
DEBUG(1,("Process (%s) is stopped!\n", svc->name));
520
process_alive = false;
524
/* TODO: should we tear down it ? */
525
DEBUG(1,("Checking for service %s(%d) failed!!\n",
526
svc->name, svc->pid));
531
ret = service_send_ping(svc);
538
DEBUG(1,("Child (%s) not responding! (yet)\n", svc->name));
542
/* TODO: should we tear it down ? */
543
DEBUG(1,("Sending a message to service (%s) failed!!\n", svc->name));
547
if (svc->last_ping != 0) {
548
if ((now - svc->last_ping) > (svc->ping_time)) {
551
svc->failed_pongs = 0;
553
if (svc->failed_pongs > 3) {
554
/* too long since we last heard of this process */
555
DEBUG(1, ("Killing service [%s], not responding to pings!\n",
557
monitor_kill_service(svc);
558
process_alive = false;
562
svc->last_ping = now;
565
if (!process_alive) {
566
svc_try_restart(svc, now);
570
/* all fine, set up the task checker again */
571
set_tasks_checker(svc);
574
static void set_tasks_checker(struct mt_svc *svc)
576
struct tevent_timer *te = NULL;
579
gettimeofday(&tv, NULL);
580
tv.tv_sec += svc->ping_time;
582
te = tevent_add_timer(svc->mt_ctx->ev, svc, tv, tasks_check_handler, svc);
584
DEBUG(0, ("failed to add event, monitor offline for [%s]!\n",
586
/* FIXME: shutdown ? */
591
static void global_checks_handler(struct tevent_context *ev,
592
struct tevent_timer *te,
593
struct timeval t, void *ptr)
595
struct mt_ctx *ctx = talloc_get_type(ptr, struct mt_ctx);
600
if (!ctx->check_children) {
605
pid = waitpid(0, &status, WNOHANG);
611
DEBUG(0, ("waitpid returned -1 (errno:%d[%s])\n",
612
errno, strerror(errno)));
616
/* let's see if it is a known service, and try to restart it */
617
for (svc = ctx->svc_list; svc; svc = svc->next) {
618
if (svc->pid == pid) {
619
time_t now = time(NULL);
620
DEBUG(1, ("Service [%s] did exit\n", svc->name));
621
svc_try_restart(svc, now);
626
DEBUG(0, ("Unknown child (%d) did exit\n", pid));
630
set_global_checker(ctx);
633
static void set_global_checker(struct mt_ctx *ctx)
635
struct tevent_timer *te = NULL;
638
gettimeofday(&tv, NULL);
639
tv.tv_sec += 1; /* once a second */
641
te = tevent_add_timer(ctx->ev, ctx, tv, global_checks_handler, ctx);
643
DEBUG(0, ("failed to add global checker event! PANIC TIME!\n"));
644
/* FIXME: is this right ? shoulkd we try to clean up first ?*/
649
static int monitor_kill_service (struct mt_svc *svc)
652
ret = kill(svc->pid, SIGTERM);
654
DEBUG(0,("Sending signal to child (%s:%d) failed! "
655
"Ignore and pretend child is dead.\n",
656
svc->name, svc->pid));
662
static void reload_reply(DBusPendingCall *pending, void *data)
665
struct mt_svc *svc = talloc_get_type(data, struct mt_svc);
667
reply = dbus_pending_call_steal_reply(pending);
669
/* reply should never be null. This function shouldn't be called
670
* until reply is valid or timeout has occurred. If reply is NULL
671
* here, something is seriously wrong and we should bail out.
673
DEBUG(0, ("A reply callback was called but no reply was received"
674
" and no timeout occurred\n"));
675
/* Destroy this connection */
676
sbus_disconnect(svc->conn);
677
dbus_pending_call_unref(pending);
681
/* TODO: Handle cases where the call has timed out or returned
685
dbus_pending_call_unref(pending);
686
dbus_message_unref(reply);
689
static int service_signal_dns_reload(struct mt_svc *svc);
690
static int monitor_update_resolv(struct config_file_ctx *file_ctx,
691
const char *filename)
694
struct mt_svc *cur_svc;
695
DEBUG(2, ("Resolv.conf has been updated. Reloading.\n"));
702
/* Signal all services to reload their DNS configuration */
703
for(cur_svc = file_ctx->mt_ctx->svc_list; cur_svc; cur_svc = cur_svc->next) {
704
service_signal_dns_reload(cur_svc);
709
static int service_signal(struct mt_svc *svc, const char *svc_signal)
714
if (svc->provider && strcasecmp(svc->provider, "local") == 0) {
715
/* The local provider requires no signaling */
720
/* Avoid a race condition where we are trying to
721
* order a service to reload that hasn't started
724
DEBUG(1,("Could not signal service [%s].\n", svc->name));
728
msg = dbus_message_new_method_call(NULL,
733
DEBUG(0,("Out of memory?!\n"));
734
monitor_kill_service(svc);
739
ret = sbus_conn_send(svc->conn, msg,
740
svc->mt_ctx->service_id_timeout,
741
reload_reply, svc, NULL);
743
dbus_message_unref(msg);
747
static int service_signal_dns_reload(struct mt_svc *svc)
749
return service_signal(svc, MON_CLI_METHOD_RES_INIT);
751
static int service_signal_offline(struct mt_svc *svc)
753
return service_signal(svc, MON_CLI_METHOD_OFFLINE);
755
static int service_signal_reset_offline(struct mt_svc *svc)
757
return service_signal(svc, MON_CLI_METHOD_RESET_OFFLINE);
759
static int service_signal_rotate(struct mt_svc *svc)
761
return service_signal(svc, MON_CLI_METHOD_ROTATE);
764
static int check_domain_ranges(struct sss_domain_info *domains)
766
struct sss_domain_info *dom = domains, *other = NULL;
767
uint32_t id_min, id_max;
771
if (dom->id_max && dom->id_min > dom->id_max) {
772
DEBUG(1, ("Domain '%s' does not have a valid ID range\n",
778
id_min = MAX(dom->id_min, other->id_min);
779
id_max = MIN((dom->id_max ? dom->id_max : UINT32_MAX),
780
(other->id_max ? other->id_max : UINT32_MAX));
781
if (id_min <= id_max) {
782
DEBUG(1, ("Domains '%s' and '%s' overlap in range %u - %u\n",
783
dom->name, other->name, id_min, id_max));
793
static int check_local_domain_unique(struct sss_domain_info *domains)
797
struct sss_domain_info *dom = domains;
800
if (strcasecmp(dom->provider, "local") == 0) {
818
static char *check_services(char **services)
820
const char *known_services[] = { "nss", "pam", NULL };
824
/* Check if services we are about to start are in the list if known */
825
for (i = 0; services[i]; i++) {
826
for (ii=0; known_services[ii]; ii++) {
827
if (strcasecmp(services[i], known_services[ii]) == 0) {
832
if (known_services[ii] == NULL) {
840
int get_monitor_config(struct mt_ctx *ctx)
846
ret = confdb_get_int(ctx->cdb, ctx,
847
CONFDB_MONITOR_CONF_ENTRY,
848
CONFDB_MONITOR_SBUS_TIMEOUT,
849
10, &timeout_seconds);
854
ctx->service_id_timeout = timeout_seconds * 1000; /* service_id_timeout is in ms */
856
ctx->service_ctx = talloc_new(ctx);
857
if(!ctx->service_ctx) {
860
ret = confdb_get_string_as_list(ctx->cdb, ctx->service_ctx,
861
CONFDB_MONITOR_CONF_ENTRY,
862
CONFDB_MONITOR_ACTIVE_SERVICES,
865
DEBUG(0, ("No services configured!\n"));
869
badsrv = check_services(ctx->services);
870
if (badsrv != NULL) {
871
DEBUG(0, ("Invalid service %s\n", badsrv));
875
ctx->domain_ctx = talloc_new(ctx);
876
if(!ctx->domain_ctx) {
879
ret = confdb_get_domains(ctx->cdb, &ctx->domains);
881
DEBUG(0, ("No domains configured.\n"));
885
ret = check_local_domain_unique(ctx->domains);
887
DEBUG(0, ("More than one local domain configured.\n"));
891
/* Check UID/GID overlaps */
892
ret = check_domain_ranges(ctx->domains);
900
static int get_service_config(struct mt_ctx *ctx, const char *name,
901
struct mt_svc **svc_cfg)
909
svc = talloc_zero(ctx, struct mt_svc);
915
talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor);
917
svc->name = talloc_strdup(svc, name);
923
svc->identity = talloc_strdup(svc, name);
924
if (!svc->identity) {
929
path = talloc_asprintf(svc, CONFDB_SERVICE_PATH_TMPL, svc->name);
935
ret = confdb_get_string(ctx->cdb, svc, path,
936
CONFDB_SERVICE_COMMAND,
937
NULL, &svc->command);
939
DEBUG(0,("Failed to start service '%s'\n", svc->name));
945
svc->command = talloc_asprintf(svc, "%s/sssd_%s -d %d%s%s",
947
svc->name, debug_level,
949
"": " --debug-timestamps=0"),
951
" --debug-to-files":""));
958
ret = confdb_get_int(ctx->cdb, svc, path,
959
CONFDB_SERVICE_TIMEOUT,
960
MONITOR_DEF_PING_TIME, &svc->ping_time);
962
DEBUG(0,("Failed to start service '%s'\n", svc->name));
967
/* 'timeout = 0' should be translated to the default */
968
if (svc->ping_time == 0) {
969
svc->ping_time = MONITOR_DEF_PING_TIME;
978
static int add_new_service(struct mt_ctx *ctx, const char *name)
983
ret = get_service_config(ctx, name, &svc);
988
ret = start_service(svc);
990
DEBUG(0,("Failed to start service '%s'\n", svc->name));
997
static int get_provider_config(struct mt_ctx *ctx, const char *name,
998
struct mt_svc **svc_cfg)
1006
svc = talloc_zero(ctx, struct mt_svc);
1012
talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor);
1014
svc->name = talloc_strdup(svc, name);
1020
svc->identity = talloc_asprintf(svc, "%%BE_%s", svc->name);
1021
if (!svc->identity) {
1026
path = talloc_asprintf(svc, CONFDB_DOMAIN_PATH_TMPL, name);
1032
ret = confdb_get_string(ctx->cdb, svc, path,
1033
CONFDB_DOMAIN_ID_PROVIDER,
1034
NULL, &svc->provider);
1036
DEBUG(0, ("Failed to find ID provider from [%s] configuration\n", name));
1041
ret = confdb_get_string(ctx->cdb, svc, path,
1042
CONFDB_DOMAIN_COMMAND,
1043
NULL, &svc->command);
1045
DEBUG(0, ("Failed to find command from [%s] configuration\n", name));
1050
ret = confdb_get_int(ctx->cdb, svc, path,
1051
CONFDB_DOMAIN_TIMEOUT,
1052
MONITOR_DEF_PING_TIME, &svc->ping_time);
1054
DEBUG(0,("Failed to start service '%s'\n", svc->name));
1059
/* 'timeout = 0' should be translated to the default */
1060
if (svc->ping_time == 0) {
1061
svc->ping_time = MONITOR_DEF_PING_TIME;
1066
/* if no provider is present do not run the domain */
1067
if (!svc->provider) {
1072
/* if there are no custom commands, build a default one */
1073
if (!svc->command) {
1074
svc->command = talloc_asprintf(svc,
1075
"%s/sssd_be -d %d%s%s --domain %s",
1076
SSSD_LIBEXEC_PATH, debug_level,
1077
(debug_timestamps?"": " --debug-timestamps=0"),
1078
(debug_to_file?" --debug-to-files":""),
1080
if (!svc->command) {
1090
static int add_new_provider(struct mt_ctx *ctx, const char *name)
1095
ret = get_provider_config(ctx, name, &svc);
1097
DEBUG(0, ("Could not get provider configuration for [%s]\n",
1102
if (strcasecmp(svc->provider, "local") == 0) {
1103
/* The LOCAL provider requires no back-end currently
1104
* We'll add it to the service list, but we don't need
1107
svc->svc_started = true;
1108
DLIST_ADD(ctx->svc_list, svc);
1112
ret = start_service(svc);
1114
DEBUG(0,("Failed to start service '%s'\n", svc->name));
1121
static void monitor_hup(struct tevent_context *ev,
1122
struct tevent_signal *se,
1128
struct mt_ctx *ctx = talloc_get_type(private_data, struct mt_ctx);
1129
struct mt_svc *cur_svc;
1131
DEBUG(1, ("Received SIGHUP.\n"));
1133
/* Signal all services to rotate debug files */
1134
for(cur_svc = ctx->svc_list; cur_svc; cur_svc = cur_svc->next) {
1135
service_signal_rotate(cur_svc);
1139
static int monitor_cleanup(void)
1143
TALLOC_CTX *tmp_ctx;
1145
tmp_ctx = talloc_new(NULL);
1146
if (!tmp_ctx) return ENOMEM;
1148
file = talloc_asprintf(tmp_ctx, "%s/%s.pid", PID_PATH, "sssd");
1157
DEBUG(0, ("Error removing pidfile! (%d [%s])\n",
1158
ret, strerror(ret)));
1167
static void monitor_quit(struct tevent_context *ev,
1168
struct tevent_signal *se,
1174
struct mt_ctx *mt_ctx = talloc_get_type(private_data, struct mt_ctx);
1182
DEBUG(8, ("Received shutdown command\n"));
1184
DEBUG(0, ("Monitor received %s: terminating children\n",
1185
strsignal(signum)));
1187
/* Kill all of our known children manually */
1188
DLIST_FOR_EACH(svc, mt_ctx->svc_list) {
1189
if (svc->pid == 0) {
1190
/* The local provider has no PID */
1195
DEBUG(1, ("Terminating [%s][%d]\n", svc->name, svc->pid));
1198
kret = kill(svc->pid, SIGTERM);
1201
DEBUG(1, ("Couldn't kill [%s][%d]: [%s]\n",
1202
svc->name, svc->pid, strerror(error)));
1208
pid = waitpid(svc->pid, &status, WNOHANG);
1210
/* An error occurred while waiting */
1212
if (error != EINTR) {
1213
DEBUG(0, ("[%d][%s] while waiting for [%s]\n",
1214
error, strerror(error), svc->name));
1215
/* Forcibly kill this child */
1216
kill(svc->pid, SIGKILL);
1219
} else if (pid != 0) {
1221
if WIFEXITED(status) {
1222
DEBUG(1, ("Child [%s] exited gracefully\n", svc->name));
1223
} else if WIFSIGNALED(status) {
1224
DEBUG(1, ("Child [%s] terminated with a signal\n", svc->name));
1226
DEBUG(0, ("Child [%s] did not exit cleanly\n", svc->name));
1227
/* Forcibly kill this child */
1228
kill(svc->pid, SIGKILL);
1232
} while (error == EINTR);
1234
/* Sleep 10ms and try again */
1241
/* Kill any remaining children in our process group, just in case
1242
* we have any leftover children we don't expect. For example, if
1243
* a krb5_child or ldap_child is running at the same moment.
1246
if (getpgrp() == getpid()) {
1247
kill(-getpgrp(), SIGTERM);
1250
pid = waitpid(0, &status, 0);
1254
} while (error == EINTR || pid > 0);
1263
static void signal_offline(struct tevent_context *ev,
1264
struct tevent_signal *se,
1270
struct mt_ctx *monitor;
1271
struct mt_svc *cur_svc;
1273
monitor = talloc_get_type(private_data, struct mt_ctx);
1275
DEBUG(8, ("Signaling providers to go offline immediately.\n"));
1277
/* Signal all providers to immediately go offline */
1278
for(cur_svc = monitor->svc_list; cur_svc; cur_svc = cur_svc->next) {
1279
/* Don't signal services, only providers */
1280
if (cur_svc->provider) {
1281
service_signal_offline(cur_svc);
1286
static void signal_offline_reset(struct tevent_context *ev,
1287
struct tevent_signal *se,
1293
struct mt_ctx *monitor;
1294
struct mt_svc *cur_svc;
1296
monitor = talloc_get_type(private_data, struct mt_ctx);
1298
DEBUG(8, ("Signaling providers to reset offline immediately.\n"));
1300
for(cur_svc = monitor->svc_list; cur_svc; cur_svc = cur_svc->next) {
1301
if (cur_svc->provider) {
1302
service_signal_reset_offline(cur_svc);
1307
int read_config_file(const char *config_file)
1310
struct collection_item *sssd_config = NULL;
1311
struct collection_item *error_list = NULL;
1313
/* Read the configuration into a collection */
1314
ret = config_from_file("sssd", config_file, &sssd_config,
1315
INI_STOP_ON_ANY, &error_list);
1317
DEBUG(0, ("Parse error reading configuration file [%s]\n",
1319
print_file_parsing_errors(stderr, error_list);
1322
free_ini_config_errors(error_list);
1323
free_ini_config(sssd_config);
1327
static int monitor_ctx_destructor(void *mem)
1329
struct mt_ctx *mon = talloc_get_type(mem, struct mt_ctx);
1332
/* zero out references in svcs so that they don't try
1333
* to access the monitor context on process shutdown */
1335
for (svc = mon->svc_list; svc; svc = svc->next) {
1341
static errno_t load_configuration(TALLOC_CTX *mem_ctx,
1342
const char *config_file,
1343
struct mt_ctx **monitor)
1347
char *cdb_file = NULL;
1349
ctx = talloc_zero(mem_ctx, struct mt_ctx);
1353
talloc_set_destructor((TALLOC_CTX *)ctx, monitor_ctx_destructor);
1355
cdb_file = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE);
1356
if (cdb_file == NULL) {
1357
DEBUG(0,("Out of memory, aborting!\n"));
1362
ret = confdb_init(ctx, &ctx->cdb, cdb_file);
1364
DEBUG(0,("The confdb initialization failed\n"));
1368
/* Initialize the CDB from the configuration file */
1369
ret = confdb_test(ctx->cdb);
1370
if (ret == ENOENT) {
1371
/* First-time setup */
1373
/* Purge any existing confdb in case an old
1374
* misconfiguration gets in the way
1376
talloc_zfree(ctx->cdb);
1379
ret = confdb_init(ctx, &ctx->cdb, cdb_file);
1381
DEBUG(0,("The confdb initialization failed\n"));
1385
/* Load special entries */
1386
ret = confdb_create_base(ctx->cdb);
1388
DEBUG(0, ("Unable to load special entries into confdb\n"));
1391
} else if (ret != EOK) {
1392
DEBUG(0, ("Fatal error initializing confdb\n"));
1395
talloc_zfree(cdb_file);
1397
ret = confdb_init_db(config_file, ctx->cdb);
1399
DEBUG(0, ("ConfDB initialization has failed [%s]\n",
1404
/* Validate the configuration in the database */
1405
/* Read in the monitor's configuration */
1406
ret = get_monitor_config(ctx);
1422
#ifdef HAVE_SYS_INOTIFY_H
1423
static void process_config_file(struct tevent_context *ev,
1424
struct tevent_timer *te,
1425
struct timeval t, void *ptr);
1427
static void config_file_changed(struct tevent_context *ev,
1428
struct tevent_fd *fde,
1429
uint16_t flags, void *data)
1431
struct tevent_timer *te = NULL;
1433
struct config_file_ctx *file_ctx;
1435
file_ctx = talloc_get_type(data, struct config_file_ctx);
1436
if (file_ctx->needs_update) {
1437
/* Skip updating. It's already queued for update.
1442
/* We will queue the file for update in one second.
1443
* This way, if there is a script writing to the file
1444
* repeatedly, we won't be attempting to update multiple
1447
gettimeofday(&tv, NULL);
1450
te = tevent_add_timer(ev, ev, tv, process_config_file, file_ctx);
1452
DEBUG(0, ("Unable to queue config file update! Exiting.\n"));
1453
kill(getpid(), SIGTERM);
1456
file_ctx->needs_update = 1;
1459
struct rewatch_ctx {
1460
struct config_file_callback *cb;
1461
struct config_file_ctx *file_ctx;
1463
static void rewatch_config_file(struct tevent_context *ev,
1464
struct tevent_timer *te,
1465
struct timeval t, void *ptr);
1466
static void process_config_file(struct tevent_context *ev,
1467
struct tevent_timer *te,
1468
struct timeval t, void *ptr)
1470
TALLOC_CTX *tmp_ctx;
1471
struct inotify_event *in_event;
1474
ssize_t len, total_len;
1476
struct config_file_ctx *file_ctx;
1477
struct config_file_callback *cb;
1478
struct rewatch_ctx *rw_ctx;
1480
event_size = sizeof(struct inotify_event);
1481
file_ctx = talloc_get_type(ptr, struct config_file_ctx);
1483
DEBUG(1, ("Processing config file changes\n"));
1485
tmp_ctx = talloc_new(NULL);
1486
if (!tmp_ctx) return;
1488
buf = talloc_size(tmp_ctx, event_size);
1494
while (total_len < event_size) {
1495
len = read(file_ctx->mt_ctx->inotify_fd, buf+total_len,
1496
event_size-total_len);
1498
if (errno == EINTR || errno == EAGAIN) continue;
1499
DEBUG(0, ("Critical error reading inotify file descriptor.\n"));
1505
in_event = (struct inotify_event *)buf;
1507
if (in_event->len > 0) {
1508
/* Read in the name, even though we don't use it,
1509
* so that read ptr is in the right place
1511
name = talloc_size(tmp_ctx, len);
1516
while (total_len < in_event->len) {
1517
len = read(file_ctx->mt_ctx->inotify_fd, &name, in_event->len);
1519
if (errno == EINTR || errno == EAGAIN) continue;
1520
DEBUG(0, ("Critical error reading inotify file descriptor.\n"));
1527
for (cb = file_ctx->callbacks; cb; cb = cb->next) {
1528
if (cb->wd == in_event->wd) {
1533
DEBUG(0, ("Unknown watch descriptor\n"));
1537
if (in_event->mask & IN_IGNORED) {
1538
/* Some text editors will move a new file on top of the
1539
* existing one instead of modifying it. In this case,
1540
* the kernel will send us an IN_IGNORE signal.
1541
* We will try to open a new watch descriptor on the
1545
struct tevent_timer *tev;
1546
tv.tv_sec = t.tv_sec+5;
1547
tv.tv_usec = t.tv_usec;
1550
rw_ctx = talloc(file_ctx, struct rewatch_ctx);
1552
DEBUG(0, ("Could not restore inotify watch. Quitting!\n"));
1553
close(file_ctx->mt_ctx->inotify_fd);
1554
kill(getpid(), SIGTERM);
1558
rw_ctx->file_ctx = file_ctx;
1560
tev = tevent_add_timer(ev, rw_ctx, tv, rewatch_config_file, rw_ctx);
1562
DEBUG(0, ("Could not restore inotify watch. Quitting!\n"));
1563
close(file_ctx->mt_ctx->inotify_fd);
1564
kill(getpid(), SIGTERM);
1569
/* Tell the monitor to signal the children */
1570
cb->fn(file_ctx, cb->filename);
1571
file_ctx->needs_update = 0;
1574
talloc_free(tmp_ctx);
1577
static void rewatch_config_file(struct tevent_context *ev,
1578
struct tevent_timer *te,
1579
struct timeval t, void *ptr)
1582
struct tevent_timer *tev = NULL;
1584
struct config_file_callback *cb;
1586
struct rewatch_ctx *rw_ctx;
1587
struct config_file_ctx *file_ctx;
1589
rw_ctx = talloc_get_type(ptr, struct rewatch_ctx);
1592
file_ctx = rw_ctx->file_ctx;
1594
/* Retry six times at five-second intervals before giving up */
1596
if (cb->retries > 6) {
1597
DEBUG(0, ("Could not restore inotify watch. Quitting!\n"));
1598
close(file_ctx->mt_ctx->inotify_fd);
1599
kill(getpid(), SIGTERM);
1602
cb->wd = inotify_add_watch(file_ctx->mt_ctx->inotify_fd,
1603
cb->filename, IN_MODIFY);
1607
tv.tv_sec = t.tv_sec+5;
1608
tv.tv_usec = t.tv_usec;
1610
DEBUG(1, ("Could not add inotify watch for file [%s]. Error [%d:%s]\n",
1611
cb->filename, err, strerror(err)));
1613
tev = tevent_add_timer(ev, ev, tv, rewatch_config_file, rw_ctx);
1615
DEBUG(0, ("Could not restore inotify watch. Quitting!\n"));
1616
close(file_ctx->mt_ctx->inotify_fd);
1617
kill(getpid(), SIGTERM);
1624
/* Tell the monitor to signal the children */
1625
cb->fn(file_ctx, cb->filename);
1627
talloc_free(rw_ctx);
1628
file_ctx->needs_update = 0;
1632
static void poll_config_file(struct tevent_context *ev,
1633
struct tevent_timer *te,
1634
struct timeval t, void *ptr)
1637
struct stat file_stat;
1639
struct config_file_ctx *file_ctx;
1640
struct config_file_callback *cb;
1642
file_ctx = talloc_get_type(ptr,struct config_file_ctx);
1644
for (cb = file_ctx->callbacks; cb; cb = cb->next) {
1645
ret = stat(cb->filename, &file_stat);
1648
DEBUG(0, ("Could not stat file [%s]. Error [%d:%s]\n",
1649
cb->filename, err, strerror(err)));
1650
/* TODO: If the config file is missing, should we shut down? */
1654
if (file_stat.st_mtime != cb->modified) {
1655
/* Parse the configuration file and signal the children */
1656
/* Note: this will fire if the modification time changes into the past
1657
* as well as the future.
1659
DEBUG(1, ("Config file changed\n"));
1660
cb->modified = file_stat.st_mtime;
1662
/* Tell the monitor to signal the children */
1663
cb->fn(file_ctx, cb->filename);
1667
gettimeofday(&tv, NULL);
1668
tv.tv_sec += CONFIG_FILE_POLL_INTERVAL;
1670
file_ctx->timer = tevent_add_timer(ev, file_ctx->parent_ctx, tv,
1671
poll_config_file, file_ctx);
1672
if (!file_ctx->timer) {
1673
DEBUG(0, ("Error: Config file no longer monitored for changes!\n"));
1677
static int try_inotify(struct config_file_ctx *file_ctx, const char *filename,
1678
monitor_reconf_fn fn)
1680
#ifdef HAVE_SYS_INOTIFY_H
1681
int err, fd_args, ret;
1682
struct tevent_fd *tfd;
1683
struct config_file_callback *cb;
1685
/* Monitoring the file descriptor should be global */
1686
if (!file_ctx->mt_ctx->inotify_fd) {
1687
/* Set up inotify to monitor the config file for changes */
1688
file_ctx->mt_ctx->inotify_fd = inotify_init();
1689
if (file_ctx->mt_ctx->inotify_fd < 0) {
1691
DEBUG(0, ("Could not initialize inotify, error [%d:%s]\n",
1692
err, strerror(err)));
1696
fd_args = fcntl(file_ctx->mt_ctx->inotify_fd, F_GETFL, NULL);
1698
/* Could not set nonblocking */
1699
close(file_ctx->mt_ctx->inotify_fd);
1703
fd_args |= O_NONBLOCK;
1704
ret = fcntl(file_ctx->mt_ctx->inotify_fd, F_SETFL, fd_args);
1706
/* Could not set nonblocking */
1707
close(file_ctx->mt_ctx->inotify_fd);
1711
/* Add the inotify file descriptor to the TEvent context */
1712
tfd = tevent_add_fd(file_ctx->mt_ctx->ev, file_ctx,
1713
file_ctx->mt_ctx->inotify_fd,
1714
TEVENT_FD_READ, config_file_changed,
1717
close(file_ctx->mt_ctx->inotify_fd);
1722
cb = talloc_zero(file_ctx, struct config_file_callback);
1724
close(file_ctx->mt_ctx->inotify_fd);
1728
cb->filename = talloc_strdup(cb, filename);
1729
if (!cb->filename) {
1730
close(file_ctx->mt_ctx->inotify_fd);
1733
cb->wd = inotify_add_watch(file_ctx->mt_ctx->inotify_fd,
1734
cb->filename, IN_MODIFY);
1737
DEBUG(0, ("Could not add inotify watch for file [%s]. Error [%d:%s]\n",
1738
cb->filename, err, strerror(err)));
1739
close(file_ctx->mt_ctx->inotify_fd);
1744
DLIST_ADD(file_ctx->callbacks, cb);
1752
static int monitor_config_file(TALLOC_CTX *mem_ctx,
1755
monitor_reconf_fn fn)
1760
struct stat file_stat;
1761
struct config_file_callback *cb = NULL;
1763
ret = stat(file, &file_stat);
1766
DEBUG(0, ("Could not stat file [%s]. Error [%d:%s]\n",
1767
file, err, strerror(err)));
1770
if (!ctx->file_ctx) {
1771
ctx->file_ctx = talloc_zero(mem_ctx, struct config_file_ctx);
1772
if (!ctx->file_ctx) return ENOMEM;
1774
ctx->file_ctx->parent_ctx = mem_ctx;
1775
ctx->file_ctx->mt_ctx = ctx;
1778
ret = confdb_get_bool(ctx->cdb, ctx,
1779
CONFDB_MONITOR_CONF_ENTRY,
1780
CONFDB_MONITOR_TRY_INOTIFY,
1781
true, &use_inotify);
1783
talloc_free(ctx->file_ctx);
1788
ret = try_inotify(ctx->file_ctx, file, fn);
1790
use_inotify = false;
1795
/* Could not monitor file with inotify, fall back to polling */
1796
cb = talloc_zero(ctx->file_ctx, struct config_file_callback);
1798
talloc_free(ctx->file_ctx);
1801
cb->filename = talloc_strdup(cb, file);
1802
if (!cb->filename) {
1803
talloc_free(ctx->file_ctx);
1807
cb->modified = file_stat.st_mtime;
1809
DLIST_ADD(ctx->file_ctx->callbacks, cb);
1811
if(!ctx->file_ctx->timer) {
1812
gettimeofday(&tv, NULL);
1813
tv.tv_sec += CONFIG_FILE_POLL_INTERVAL;
1815
ctx->file_ctx->timer = tevent_add_timer(ctx->ev, mem_ctx, tv,
1816
poll_config_file, ctx->file_ctx);
1817
if (!ctx->file_ctx->timer) {
1818
talloc_free(ctx->file_ctx);
1827
int monitor_process_init(struct mt_ctx *ctx,
1828
const char *config_file)
1830
TALLOC_CTX *tmp_ctx;
1831
struct sysdb_ctx_list *db_list;
1832
struct tevent_signal *tes;
1833
struct sss_domain_info *dom;
1837
/* Set up an event handler for a SIGHUP */
1838
tes = tevent_add_signal(ctx->ev, ctx, SIGHUP, 0,
1844
/* Set up an event handler for a SIGINT */
1845
BlockSignals(false, SIGINT);
1846
tes = tevent_add_signal(ctx->ev, ctx, SIGINT, 0,
1852
/* Set up an event handler for a SIGTERM */
1853
tes = tevent_add_signal(ctx->ev, ctx, SIGTERM, 0,
1859
/* Handle SIGUSR1 (tell all providers to go offline) */
1860
BlockSignals(false, SIGUSR1);
1861
tes = tevent_add_signal(ctx->ev, ctx, SIGUSR1, 0,
1862
signal_offline, ctx);
1867
/* Handle SIGUSR2 (tell all providers to go reset offline) */
1868
BlockSignals(false, SIGUSR2);
1869
tes = tevent_add_signal(ctx->ev, ctx, SIGUSR2, 0,
1870
signal_offline_reset, ctx);
1876
This feature is incomplete and can leave the SSSD in a bad state if the
1877
config file is changed while the SSSD is running.
1879
Uncomment this once the backends are honoring reloadConfig()
1881
/* Watch for changes to the confdb config file */
1882
ret = monitor_config_file(ctx, ctx, config_file, monitor_signal_reconf);
1887
/* Watch for changes to the DNS resolv.conf */
1888
ret = monitor_config_file(ctx, ctx, RESOLV_CONF_PATH,
1889
monitor_update_resolv);
1894
/* Avoid a startup race condition between process.
1895
* We need to handle DB upgrades or DB creation only
1896
* in one process before all other start.
1898
tmp_ctx = talloc_new(NULL);
1902
ret = sysdb_init(tmp_ctx, ctx->cdb, NULL, true, &db_list);
1906
talloc_zfree(tmp_ctx);
1908
/* Initialize D-BUS Server
1909
* The monitor will act as a D-BUS server for all
1911
ret = monitor_dbus_init(ctx);
1916
ret = setup_netlink(ctx, ctx->ev, network_status_change_cb,
1919
DEBUG(2, ("Cannot set up listening for network notifications\n"));
1923
/* start providers */
1925
for (dom = ctx->domains; dom; dom = dom->next) {
1926
ret = add_new_provider(ctx, dom->name);
1927
if (ret != EOK && ret != ENOENT) {
1930
if (ret != ENOENT) {
1935
if (num_providers > 0) {
1936
/* now set the services stratup timeout *
1937
* (responders will be started automatically when all
1938
* providers are up and running or when the tomeout
1940
ret = add_services_startup_timeout(ctx);
1947
ctx->services_started = true;
1949
/* No providers start services immediately
1950
* Normally this means only LOCAL is configured */
1951
for (i = 0; ctx->services[i]; i++) {
1952
add_new_service(ctx, ctx->services[i]);
1956
/* now start checking for global events */
1957
set_global_checker(ctx);
1962
static void init_timeout(struct tevent_context *ev,
1963
struct tevent_timer *te,
1964
struct timeval t, void *ptr)
1966
struct mon_init_conn *mini;
1968
DEBUG(2, ("Client timed out before Identification!\n"));
1970
mini = talloc_get_type(ptr, struct mon_init_conn);
1972
sbus_disconnect(mini->conn);
1977
* monitor_service_init
1978
* Set up a timeout function and temporary connection structure.
1979
* If the client does not identify before the timeout kicks in,
1980
* the client is forcibly disconnected.
1982
static int monitor_service_init(struct sbus_connection *conn, void *data)
1985
struct mon_init_conn *mini;
1988
DEBUG(3, ("Initializing D-BUS Service\n"));
1990
ctx = talloc_get_type(data, struct mt_ctx);
1992
mini = talloc(conn, struct mon_init_conn);
1994
DEBUG(0,("Out of memory?!\n"));
2001
/* 5 seconds should be plenty */
2002
tv = tevent_timeval_current_ofs(10, 0);
2004
mini->timeout = tevent_add_timer(ctx->ev, mini, tv, init_timeout, mini);
2005
if (!mini->timeout) {
2006
DEBUG(0,("Out of memory?!\n"));
2011
sbus_conn_set_private_data(conn, mini);
2016
/* service_send_ping
2017
* this function send a dbus ping to a service.
2018
* It returns EOK if all is fine or ENXIO if the connection is
2019
* not available (either not yet set up or teared down).
2020
* Returns e generic error in other cases.
2022
static int service_send_ping(struct mt_svc *svc)
2028
DEBUG(8, ("Service not yet initialized\n"));
2032
DEBUG(4,("Pinging %s\n", svc->name));
2035
* Set up identity request
2036
* This should be a well-known path and method
2039
msg = dbus_message_new_method_call(NULL,
2042
MON_CLI_METHOD_PING);
2044
DEBUG(0,("Out of memory?!\n"));
2045
talloc_zfree(svc->conn);
2049
ret = sbus_conn_send(svc->conn, msg,
2050
svc->mt_ctx->service_id_timeout,
2051
ping_check, svc, NULL);
2052
dbus_message_unref(msg);
2056
static void ping_check(DBusPendingCall *pending, void *data)
2060
const char *dbus_error_name;
2063
svc = talloc_get_type(data, struct mt_svc);
2065
reply = dbus_pending_call_steal_reply(pending);
2067
/* reply should never be null. This function shouldn't be called
2068
* until reply is valid or timeout has occurred. If reply is NULL
2069
* here, something is seriously wrong and we should bail out.
2071
DEBUG(0, ("A reply callback was called but no reply was received"
2072
" and no timeout occurred\n"));
2074
/* Destroy this connection */
2075
sbus_disconnect(svc->conn);
2079
type = dbus_message_get_type(reply);
2081
case DBUS_MESSAGE_TYPE_METHOD_RETURN:
2083
* make sure we reset the failure counter in the service structure */
2085
DEBUG(4,("Service %s replied to ping\n", svc->name));
2087
svc->failed_pongs = 0;
2090
case DBUS_MESSAGE_TYPE_ERROR:
2092
dbus_error_name = dbus_message_get_error_name(reply);
2094
/* timeouts are handled in the main service check function */
2095
if (strcmp(dbus_error_name, DBUS_ERROR_TIMEOUT) == 0)
2098
DEBUG(0,("A service PING returned an error [%s], closing connection.\n",
2100
/* Falling through to default intentionally*/
2103
* Timeout or other error occurred or something
2104
* unexpected happened.
2105
* It doesn't matter which, because either way we
2106
* know that this connection isn't trustworthy.
2107
* We'll destroy it now.
2109
sbus_disconnect(svc->conn);
2113
dbus_pending_call_unref(pending);
2114
dbus_message_unref(reply);
2119
/* service_check_alive
2120
* This function checks if the service child is still alive
2122
static int service_check_alive(struct mt_svc *svc)
2127
DEBUG(4,("Checking service %s(%d) is still alive\n", svc->name, svc->pid));
2129
pid = waitpid(svc->pid, &status, WNOHANG);
2134
if (pid != svc->pid) {
2135
DEBUG(1, ("bad return (%d) from waitpid() waiting for %d\n",
2137
/* TODO: what do we do now ? */
2141
if (WIFEXITED(status)) { /* children exited on it's own */
2142
/* TODO: check configuration to see if it was removed
2143
* from the list of process to run */
2144
DEBUG(0,("Process [%s] exited\n", svc->name));
2150
static void service_startup_handler(struct tevent_context *ev,
2151
struct tevent_timer *te,
2152
struct timeval t, void *ptr);
2154
static int start_service(struct mt_svc *svc)
2156
struct tevent_timer *te;
2159
DEBUG(4,("Queueing service %s for startup\n", svc->name));
2161
/* at startup we need to start the data providers before the responders
2162
* to avoid races where a service starts before sbus pipes are ready
2163
* to accept connections. So if startup is true delay by 2 seconds any
2164
* process that is not a data provider */
2166
tv = tevent_timeval_current();
2168
/* Add a timed event to start up the service.
2169
* We have to do this in order to avoid a race
2170
* condition where the service being started forks
2171
* and attempts to connect to the SBUS before
2172
* the monitor is serving it.
2174
te = tevent_add_timer(svc->mt_ctx->ev, svc, tv,
2175
service_startup_handler, svc);
2177
DEBUG(0, ("Unable to queue service %s for startup\n", svc->name));
2183
static void service_startup_handler(struct tevent_context *ev,
2184
struct tevent_timer *te,
2185
struct timeval t, void *ptr)
2187
struct mt_svc *mt_svc;
2190
mt_svc = talloc_get_type(ptr, struct mt_svc);
2191
if (mt_svc == NULL) {
2195
mt_svc->pid = fork();
2196
if (mt_svc->pid != 0) {
2197
if (mt_svc->pid == -1) {
2198
DEBUG(0, ("Could not fork child to start service [%s]. Continuing.\n", mt_svc->name))
2203
mt_svc->mt_ctx->check_children = true;
2204
mt_svc->failed_pongs = 0;
2205
DLIST_ADD(mt_svc->mt_ctx->svc_list, mt_svc);
2206
set_tasks_checker(mt_svc);
2213
args = parse_args(mt_svc->command);
2214
execvp(args[0], args);
2216
/* If we are here, exec() has failed
2217
* Print errno and abort quickly */
2218
DEBUG(0,("Could not exec %s, reason: %s\n", mt_svc->command, strerror(errno)));
2220
/* We have to call _exit() instead of exit() here
2221
* because a bug in D-BUS will cause the server to
2222
* close its socket at exit() */
2226
int main(int argc, const char *argv[])
2231
int opt_interactive = 0;
2232
char *opt_config_file = NULL;
2233
char *config_file = NULL;
2235
struct main_context *main_ctx;
2236
TALLOC_CTX *tmp_ctx;
2237
struct mt_ctx *monitor;
2241
struct poptOption long_options[] = {
2244
{"daemon", 'D', POPT_ARG_NONE, &opt_daemon, 0, \
2245
_("Become a daemon (default)"), NULL }, \
2246
{"interactive", 'i', POPT_ARG_NONE, &opt_interactive, 0, \
2247
_("Run interactive (not a daemon)"), NULL}, \
2248
{"config", 'c', POPT_ARG_STRING, &opt_config_file, 0, \
2249
_("Specify a non-default config file"), NULL}, \
2253
pc = poptGetContext(argv[0], argc, argv, long_options, 0);
2254
while((opt = poptGetNextOpt(pc)) != -1) {
2257
fprintf(stderr, "\nInvalid option %s: %s\n\n",
2258
poptBadOption(pc, 0), poptStrerror(opt));
2259
poptPrintUsage(pc, stderr, 0);
2264
if (opt_daemon && opt_interactive) {
2265
fprintf(stderr, "Option -i|--interactive is not allowed together with -D|--daemon\n");
2266
poptPrintUsage(pc, stderr, 0);
2270
if (!opt_daemon && !opt_interactive) {
2274
poptFreeContext(pc);
2278
DEBUG(1, ("Running under %d, must be root\n", uid));
2279
sss_log(SSS_LOG_ALERT, "sssd must be run as root");
2283
tmp_ctx = talloc_new(NULL);
2288
if (opt_daemon) flags |= FLAGS_DAEMON;
2289
if (opt_interactive) flags |= FLAGS_INTERACTIVE;
2291
if (opt_config_file)
2292
config_file = talloc_strdup(tmp_ctx, opt_config_file);
2294
config_file = talloc_strdup(tmp_ctx, CONFDB_DEFAULT_CONFIG_FILE);
2298
/* we want a pid file check */
2299
flags |= FLAGS_PID_FILE;
2301
/* Open before server_setup() does to have logging
2302
* during configuration checking */
2303
if (debug_to_file) {
2304
ret = open_debug_file();
2310
/* Warn if nscd seems to be running */
2311
ret = check_file(NSCD_SOCKET_PATH, -1, -1, -1, CHECK_SOCK, NULL);
2313
sss_log(SSS_LOG_NOTICE,
2314
"nscd socket was detected. Nscd caching capabilities "
2315
"may conflict with SSSD for users and groups. It is "
2316
"recommended not to run nscd in parallel with SSSD, unless "
2317
"nscd is configured not to cache the passwd, group and "
2318
"netgroup nsswitch maps.");
2321
/* Parse config file, fail if cannot be done */
2322
ret = load_configuration(tmp_ctx, config_file, &monitor);
2325
DEBUG(1, ("Cannot read configuration file %s\n", config_file));
2326
sss_log(SSS_LOG_ALERT,
2327
"Cannot read config file %s, please check if permissions "
2328
"are 0600 and the file is owned by root.root", config_file);
2330
DEBUG(1, ("Error loading configuration database: [%d]: %s",
2331
ret, strerror(ret)));
2332
sss_log(SSS_LOG_ALERT, "Cannot load configuration database");
2337
/* set up things like debug , signals, daemonization, etc... */
2338
ret = server_setup("sssd", flags, CONFDB_MONITOR_CONF_ENTRY, &main_ctx);
2339
if (ret != EOK) return 2;
2341
monitor->ev = main_ctx->event_ctx;
2342
talloc_steal(main_ctx, monitor);
2344
ret = monitor_process_init(monitor,
2346
if (ret != EOK) return 3;
2347
talloc_free(tmp_ctx);
2350
server_loop(main_ctx);
2352
ret = monitor_cleanup();
2353
if (ret != EOK) return 5;