1    	/*
2    	   SSSD
3    	
4    	   Service monitor
5    	
6    	   Copyright (C) Simo Sorce			2008
7    	
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.
12   	
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.
17   	
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/>.
20   	*/
21   	
22   	#define _GNU_SOURCE
23   	#include <sys/types.h>
24   	#include <sys/wait.h>
25   	#include <sys/time.h>
26   	#include <sys/param.h>
27   	#include <time.h>
28   	#include <string.h>
29   	#include "config.h"
30   	#ifdef HAVE_SYS_INOTIFY_H
31   	#include <sys/inotify.h>
32   	#endif
33   	#include <sys/types.h>
34   	#include <sys/stat.h>
35   	#include <unistd.h>
36   	#include <fcntl.h>
37   	
38   	/* Needed for res_init() */
39   	#include <netinet/in.h>
40   	#include <arpa/nameser.h>
41   	#include <resolv.h>
42   	
43   	#include "util/util.h"
44   	#include "popt.h"
45   	#include "tevent.h"
46   	#include "confdb/confdb.h"
47   	#include "confdb/confdb_setup.h"
48   	#include "collection.h"
49   	#include "ini_config.h"
50   	#include "db/sysdb.h"
51   	#include "monitor/monitor.h"
52   	#include "dbus/dbus.h"
53   	#include "sbus/sssd_dbus.h"
54   	#include "monitor/monitor_interfaces.h"
55   	
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
59   	
60   	struct svc_spy;
61   	
62   	struct mt_svc {
63   	    struct mt_svc *prev;
64   	    struct mt_svc *next;
65   	    struct sbus_connection *conn;
66   	    struct svc_spy *conn_spy;
67   	
68   	    struct mt_ctx *mt_ctx;
69   	
70   	    char *provider;
71   	    char *command;
72   	    char *name;
73   	    char *identity;
74   	    pid_t pid;
75   	
76   	    int ping_time;
77   	
78   	    bool svc_started;
79   	
80   	    int restarts;
81   	    time_t last_restart;
82   	    time_t last_ping;
83   	    int failed_pongs;
84   	
85   	    int debug_level;
86   	
87   	    struct tevent_timer *ping_ev;
88   	};
89   	
90   	struct config_file_callback {
91   	    int wd;
92   	    int retries;
93   	    monitor_reconf_fn fn;
94   	    char *filename;
95   	    time_t modified;
96   	    struct config_file_callback *next;
97   	    struct config_file_callback *prev;
98   	};
99   	
100  	struct config_file_ctx {
101  	    TALLOC_CTX *parent_ctx;
102  	    struct tevent_timer *timer;
103  	    bool needs_update;
104  	    struct mt_ctx *mt_ctx;
105  	    struct config_file_callback *callbacks;
106  	};
107  	
108  	struct mt_ctx {
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 */
114  	    char **services;
115  	    struct mt_svc *svc_list;
116  	    struct sbus_connection *sbus_srv;
117  	    struct config_file_ctx *file_ctx;
118  	    int inotify_fd;
119  	    int service_id_timeout;
120  	    bool check_children;
121  	    bool services_started;
122  	};
123  	
124  	static int start_service(struct mt_svc *mt_svc);
125  	
126  	static int monitor_service_init(struct sbus_connection *conn, void *data);
127  	
128  	static int service_send_ping(struct mt_svc *svc);
129  	static void ping_check(DBusPendingCall *pending, void *data);
130  	
131  	static int service_check_alive(struct mt_svc *svc);
132  	
133  	static void set_tasks_checker(struct mt_svc *srv);
134  	static void set_global_checker(struct mt_ctx *ctx);
135  	static int monitor_kill_service (struct mt_svc *svc);
136  	
137  	static int get_service_config(struct mt_ctx *ctx, const char *name,
138  	                              struct mt_svc **svc_cfg);
139  	static int get_provider_config(struct mt_ctx *ctx, const char *name,
140  	                              struct mt_svc **svc_cfg);
141  	static int add_new_service(struct mt_ctx *ctx, const char *name);
142  	static int add_new_provider(struct mt_ctx *ctx, const char *name);
143  	
144  	static int mark_service_as_started(struct mt_svc *svc);
145  	
146  	static int monitor_cleanup(void);
147  	
148  	/* dbus_get_monitor_version
149  	 * Return the monitor version over D-BUS */
150  	static int get_monitor_version(DBusMessage *message,
151  	                               struct sbus_connection *conn)
152  	{
153  	    dbus_uint16_t version = MONITOR_VERSION;
154  	    DBusMessage *reply;
155  	    dbus_bool_t ret;
156  	
157  	    reply = dbus_message_new_method_return(message);
158  	    if (!reply) return ENOMEM;
159  	    ret = dbus_message_append_args(reply,
160  	                                   DBUS_TYPE_UINT16, &version,
161  	                                   DBUS_TYPE_INVALID);
162  	    if (!ret) {
163  	        dbus_message_unref(reply);
164  	        return EIO;
165  	    }
166  	
167  	    /* send reply back */
168  	    sbus_conn_send_reply(conn, reply);
169  	    dbus_message_unref(reply);
170  	
171  	    return EOK;
172  	}
173  	
174  	struct mon_init_conn {
175  	    struct mt_ctx *ctx;
176  	    struct sbus_connection *conn;
177  	    struct tevent_timer *timeout;
178  	};
179  	
180  	static int add_svc_conn_spy(struct mt_svc *svc);
181  	
182  	/* registers a new client.
183  	 * if operation is successful also sends back the Monitor version */
184  	static int client_registration(DBusMessage *message,
185  	                               struct sbus_connection *conn)
186  	{
187  	    dbus_uint16_t version = MONITOR_VERSION;
188  	    struct mon_init_conn *mini;
189  	    struct mt_svc *svc;
190  	    void *data;
191  	    DBusMessage *reply;
192  	    DBusError dbus_error;
193  	    dbus_uint16_t svc_ver;
194  	    char *svc_name;
195  	    dbus_bool_t dbret;
196  	    int ret;
197  	
198  	    data = sbus_conn_get_private_data(conn);
199  	    mini = talloc_get_type(data, struct mon_init_conn);
200  	    if (!mini) {
201  	        DEBUG(0, ("Connection holds no valid init data\n"));
202  	        return EINVAL;
203  	    }
204  	
205  	    /* First thing, cancel the timeout */
206  	    talloc_zfree(mini->timeout);
207  	
208  	    dbus_error_init(&dbus_error);
209  	
210  	    dbret = dbus_message_get_args(message, &dbus_error,
211  	                                  DBUS_TYPE_STRING, &svc_name,
212  	                                  DBUS_TYPE_UINT16, &svc_ver,
213  	                                  DBUS_TYPE_INVALID);
214  	    if (!dbret) {
215  	        DEBUG(1, ("Failed to parse message, killing connection\n"));
216  	        if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
217  	        sbus_disconnect(conn);
218  	        /* FIXME: should we just talloc_zfree(conn) ? */
219  	        goto done;
220  	    }
221  	
222  	    DEBUG(4, ("Received ID registration: (%s,%d)\n", svc_name, svc_ver));
223  	
224  	    /* search this service in the list */
225  	    svc = mini->ctx->svc_list;
226  	    while (svc) {
227  	        ret = strcasecmp(svc->identity, svc_name);
228  	        if (ret == 0) {
229  	            break;
230  	        }
231  	        svc = svc->next;
232  	    }
233  	    if (!svc) {
234  	        DEBUG(0, ("Unable to find peer [%s] in list of services,"
235  	                  " killing connection!\n", svc_name));
236  	        sbus_disconnect(conn);
237  	        /* FIXME: should we just talloc_zfree(conn) ? */
238  	        goto done;
239  	    }
240  	
241  	    /* Fill in svc structure with connection data */
242  	    svc->conn = mini->conn;
243  	
244  	    ret = mark_service_as_started(svc);
245  	    if (ret) {
246  	        DEBUG(1, ("Failed to mark service [%s]!\n", svc_name));
247  	        goto done;
248  	    }
249  	
250  	    /* reply that all is ok */
251  	    reply = dbus_message_new_method_return(message);
252  	    if (!reply) return ENOMEM;
253  	
254  	    dbret = dbus_message_append_args(reply,
255  	                                     DBUS_TYPE_UINT16, &version,
256  	                                     DBUS_TYPE_INVALID);
257  	    if (!dbret) {
258  	        dbus_message_unref(reply);
259  	        return EIO;
260  	    }
261  	
262  	    /* send reply back */
263  	    sbus_conn_send_reply(conn, reply);
264  	    dbus_message_unref(reply);
265  	
266  	done:
267  	    /* init complete, get rid of temp init context */
268  	    talloc_zfree(mini);
269  	
270  	    return EOK;
271  	}
272  	
273  	struct svc_spy {
274  	    struct mt_svc *svc;
275  	};
276  	
277  	static int svc_destructor(void *mem)
278  	{
279  	    struct mt_svc *svc = talloc_get_type(mem, struct mt_svc);
280  	    if (!svc) {
281  	        /* ?!?!? */
282  	        return 0;
283  	    }
284  	
285  	    /* try to delist service */
286  	    if (svc->mt_ctx) {
287  	        DLIST_REMOVE(svc->mt_ctx->svc_list, svc);
288  	    }
289  	
290  	    /* svc is beeing freed, neutralize the spy */
291  	    if (svc->conn_spy) {
292  	        talloc_set_destructor((TALLOC_CTX *)svc->conn_spy, NULL);
293  	        talloc_zfree(svc->conn_spy);
294  	    }
295  	    return 0;
296  	}
297  	
298  	static int svc_spy_destructor(void *mem)
299  	{
300  	    struct svc_spy *spy = talloc_get_type(mem, struct svc_spy);
301  	    if (!spy) {
302  	        /* ?!?!? */
303  	        return 0;
304  	    }
305  	
306  	    /* svc->conn has been freed, NULL the pointer in svc */
307  	    spy->svc->conn_spy = NULL;
308  	    spy->svc->conn = NULL;
309  	    return 0;
310  	}
311  	
312  	static int add_svc_conn_spy(struct mt_svc *svc)
313  	{
314  	    struct svc_spy *spy;
315  	
316  	    spy = talloc(svc->conn, struct svc_spy);
317  	    if (!spy) return ENOMEM;
318  	
319  	    spy->svc = svc;
320  	    talloc_set_destructor((TALLOC_CTX *)spy, svc_spy_destructor);
321  	    svc->conn_spy = spy;
322  	
323  	    return EOK;
324  	}
325  	
326  	static int mark_service_as_started(struct mt_svc *svc)
327  	{
328  	    struct mt_ctx *ctx = svc->mt_ctx;
329  	    struct mt_svc *iter;
330  	    int ret;
331  	    int i;
332  	
333  	    DEBUG(5, ("Marking %s as started.\n", svc->name));
334  	    svc->svc_started = true;
335  	
336  	    /* we need to attach a spy to the connection structure so that if some code
337  	     * frees it we can zero it out in the service structure. Otherwise we may
338  	     * try to access or even free, freed memory. */
339  	    ret = add_svc_conn_spy(svc);
340  	    if (ret) {
341  	        DEBUG(0, ("Failed to attch spy\n"));
342  	        goto done;
343  	    }
344  	
345  	    if (!ctx->services_started) {
346  	
347  	        /* check if all providers are up */
348  	        for (iter = ctx->svc_list; iter; iter = iter->next) {
349  	            if (iter->provider && !iter->svc_started) {
350  	                DEBUG(5, ("Still waiting on %s provider.\n", iter->name));
351  	                break;
352  	            }
353  	        }
354  	
355  	        if (iter) {
356  	            /* there are still unstarted providers */
357  	            goto done;
358  	        }
359  	
360  	        ctx->services_started = true;
361  	
362  	        DEBUG(4, ("Now starting services!\n"));
363  	        /* then start all services */
364  	        for (i = 0; ctx->services[i]; i++) {
365  	            add_new_service(ctx, ctx->services[i]);
366  	        }
367  	    }
368  	
369  	done:
370  	    return ret;
371  	}
372  	
373  	static void services_startup_timeout(struct tevent_context *ev,
374  	                                     struct tevent_timer *te,
375  	                                     struct timeval t, void *ptr)
376  	{
377  	    struct mt_ctx *ctx = talloc_get_type(ptr, struct mt_ctx);
378  	    int i;
379  	
380  	    DEBUG(6, ("Handling timeout\n"));
381  	
382  	    if (!ctx->services_started) {
383  	
384  	        DEBUG(1, ("Providers did not start in time, "
385  	                  "forcing services startup!\n"));
386  	
387  	        ctx->services_started = true;
388  	
389  	        DEBUG(4, ("Now starting services!\n"));
390  	        /* then start all services */
391  	        for (i = 0; ctx->services[i]; i++) {
392  	            add_new_service(ctx, ctx->services[i]);
393  	        }
394  	    }
395  	}
396  	
397  	static int add_services_startup_timeout(struct mt_ctx *ctx)
398  	{
399  	    struct tevent_timer *to;
400  	    struct timeval tv;
401  	
402  	    /* 5 seconds should be plenty */
403  	    tv = tevent_timeval_current_ofs(5, 0);
404  	    to = tevent_add_timer(ctx->ev, ctx, tv, services_startup_timeout, ctx);
405  	    if (!to) {
406  	        DEBUG(0,("Out of memory?!\n"));
407  	        return ENOMEM;
408  	    }
409  	
410  	    return EOK;
411  	}
412  	
413  	struct sbus_method monitor_methods[] = {
414  	    { MON_SRV_METHOD_VERSION, get_monitor_version },
415  	    { MON_SRV_METHOD_REGISTER, client_registration },
416  	    { NULL, NULL }
417  	};
418  	
419  	struct sbus_interface monitor_server_interface = {
420  	    MON_SRV_INTERFACE,
421  	    MON_SRV_PATH,
422  	    SBUS_DEFAULT_VTABLE,
423  	    monitor_methods,
424  	    NULL
425  	};
426  	
427  	/* monitor_dbus_init
428  	 * Set up the monitor service as a D-BUS Server */
429  	static int monitor_dbus_init(struct mt_ctx *ctx)
430  	{
431  	    char *monitor_address;
432  	    int ret;
433  	
434  	    ret = monitor_get_sbus_address(ctx, &monitor_address);
435  	    if (ret != EOK) {
436  	        return ret;
437  	    }
438  	
439  	    ret = sbus_new_server(ctx, ctx->ev,
440  	                          monitor_address, &monitor_server_interface,
441  	                          &ctx->sbus_srv, monitor_service_init, ctx);
442  	
443  	    talloc_free(monitor_address);
444  	
445  	    return ret;
446  	}
447  	
448  	static void svc_try_restart(struct mt_svc *svc, time_t now)
449  	{
450  	    int ret;
451  	
452  	    DLIST_REMOVE(svc->mt_ctx->svc_list, svc);
453  	    if (svc->last_restart != 0) {
454  	        if ((now - svc->last_restart) > 30) { /* TODO: get val from config */
455  	            /* it was long ago reset restart threshold */
456  	            svc->restarts = 0;
457  	        }
458  	    }
459  	
460  	    /* restart the process */
461  	    if (svc->restarts > 3) { /* TODO: get val from config */
462  	        DEBUG(0, ("Process [%s], definitely stopped!\n", svc->name));
463  	        talloc_free(svc);
464  	        return;
465  	    }
466  	
467  	    /* Shut down the current ping timer so it will restart
468  	     * cleanly in start_service()
469  	     */
470  	    talloc_free(svc->ping_ev);
471  	
472  	    ret = start_service(svc);
473  	    if (ret != EOK) {
474  	        DEBUG(0,("Failed to restart service '%s'\n", svc->name));
475  	        talloc_free(svc);
476  	        return;
477  	    }
478  	
479  	    svc->restarts++;
480  	    svc->last_restart = now;
481  	    return;
482  	}
483  	
484  	static void tasks_check_handler(struct tevent_context *ev,
485  	                                struct tevent_timer *te,
486  	                                struct timeval t, void *ptr)
487  	{
488  	    struct mt_svc *svc = talloc_get_type(ptr, struct mt_svc);
489  	    time_t now = time(NULL);
490  	    bool process_alive = true;
491  	    int ret;
492  	
493  	    ret = service_check_alive(svc);
494  	    switch (ret) {
495  	    case EOK:
496  	        /* all fine */
497  	        break;
498  	
499  	    case ECHILD:
500  	        DEBUG(1,("Process (%s) is stopped!\n", svc->name));
501  	        process_alive = false;
502  	        break;
503  	
504  	    default:
505  	        /* TODO: should we tear down it ? */
506  	        DEBUG(1,("Checking for service %s(%d) failed!!\n",
507  	                 svc->name, svc->pid));
508  	        break;
509  	    }
510  	
511  	    if (process_alive) {
512  	        ret = service_send_ping(svc);
513  	        switch (ret) {
514  	        case EOK:
515  	            /* all fine */
516  	            break;
517  	
518  	        case ENXIO:
519  	            DEBUG(1,("Child (%s) not responding! (yet)\n", svc->name));
520  	            break;
521  	
522  	        default:
523  	            /* TODO: should we tear it down ? */
524  	            DEBUG(1,("Sending a message to service (%s) failed!!\n", svc->name));
525  	            break;
526  	        }
527  	
528  	        if (svc->last_ping != 0) {
529  	            if ((now - svc->last_ping) > (svc->ping_time)) {
530  	                svc->failed_pongs++;
531  	            } else {
532  	                svc->failed_pongs = 0;
533  	            }
534  	            if (svc->failed_pongs > 3) {
535  	                /* too long since we last heard of this process */
536  	                DEBUG(1, ("Killing service [%s], not responding to pings!\n",
537  	                          svc->name));
538  	                monitor_kill_service(svc);
539  	                process_alive = false;
540  	            }
541  	        }
542  	
543  	        svc->last_ping = now;
544  	    }
545  	
546  	    if (!process_alive) {
547  	        svc_try_restart(svc, now);
548  	        return;
549  	    }
550  	
551  	    /* all fine, set up the task checker again */
552  	    set_tasks_checker(svc);
553  	}
554  	
555  	static void set_tasks_checker(struct mt_svc *svc)
556  	{
557  	    struct tevent_timer *te = NULL;
558  	    struct timeval tv;
559  	
560  	    gettimeofday(&tv, NULL);
561  	    tv.tv_sec += svc->ping_time;
562  	    tv.tv_usec = 0;
563  	    te = tevent_add_timer(svc->mt_ctx->ev, svc, tv, tasks_check_handler, svc);
564  	    if (te == NULL) {
565  	        DEBUG(0, ("failed to add event, monitor offline for [%s]!\n",
566  	                  svc->name));
567  	        /* FIXME: shutdown ? */
568  	    }
569  	    svc->ping_ev = te;
570  	}
571  	
572  	static void global_checks_handler(struct tevent_context *ev,
573  	                                  struct tevent_timer *te,
574  	                                  struct timeval t, void *ptr)
575  	{
576  	    struct mt_ctx *ctx = talloc_get_type(ptr, struct mt_ctx);
577  	    struct mt_svc *svc;
578  	    int status;
579  	    pid_t pid;
580  	
581  	    if (!ctx->check_children) {
582  	        goto done;
583  	    }
584  	
585  	    errno = 0;
586  	    pid = waitpid(0, &status, WNOHANG);
587  	    if (pid == 0) {
588  	        goto done;
589  	    }
590  	
591  	    if (pid == -1) {
592  	        DEBUG(0, ("waitpid returned -1 (errno:%d[%s])\n",
593  	                  errno, strerror(errno)));
594  	        goto done;
595  	    }
596  	
597  	    /* let's see if it is a known service, and try to restart it */
598  	    for (svc = ctx->svc_list; svc; svc = svc->next) {
599  	        if (svc->pid == pid) {
600  	            time_t now = time(NULL);
601  	            DEBUG(1, ("Service [%s] did exit\n", svc->name));
602  	            svc_try_restart(svc, now);
603  	            goto done;
604  	        }
605  	    }
606  	    if (svc == NULL) {
607  	        DEBUG(0, ("Unknown child (%d) did exit\n", pid));
608  	    }
609  	
610  	done:
611  	    set_global_checker(ctx);
612  	}
613  	
614  	static void set_global_checker(struct mt_ctx *ctx)
615  	{
616  	    struct tevent_timer *te = NULL;
617  	    struct timeval tv;
618  	
619  	    gettimeofday(&tv, NULL);
620  	    tv.tv_sec += 1; /* once a second */
621  	    tv.tv_usec = 0;
622  	    te = tevent_add_timer(ctx->ev, ctx, tv, global_checks_handler, ctx);
623  	    if (te == NULL) {
624  	        DEBUG(0, ("failed to add global checker event! PANIC TIME!\n"));
625  	        /* FIXME: is this right ? shoulkd we try to clean up first ?*/
626  	        exit(-1);
627  	    }
628  	}
629  	
630  	static int monitor_kill_service (struct mt_svc *svc)
631  	{
632  	    int ret;
633  	    ret = kill(svc->pid, SIGTERM);
634  	    if (ret != EOK) {
635  	        DEBUG(0,("Sending signal to child (%s:%d) failed! "
636  	                 "Ignore and pretend child is dead.\n",
637  	                 svc->name, svc->pid));
638  	    }
639  	
640  	    return ret;
641  	}
642  	
643  	static void reload_reply(DBusPendingCall *pending, void *data)
644  	{
645  	    DBusMessage *reply;
646  	    struct mt_svc *svc = talloc_get_type(data, struct mt_svc);
647  	
648  	    reply = dbus_pending_call_steal_reply(pending);
649  	    if (!reply) {
650  	        /* reply should never be null. This function shouldn't be called
651  	         * until reply is valid or timeout has occurred. If reply is NULL
652  	         * here, something is seriously wrong and we should bail out.
653  	         */
654  	        DEBUG(0, ("A reply callback was called but no reply was received"
655  	                  " and no timeout occurred\n"));
656  	        /* Destroy this connection */
657  	        sbus_disconnect(svc->conn);
658  	        dbus_pending_call_unref(pending);
659  	        return;
660  	    }
661  	
662  	    /* TODO: Handle cases where the call has timed out or returned
663  	     * with an error.
664  	     */
665  	
666  	    dbus_pending_call_unref(pending);
667  	    dbus_message_unref(reply);
668  	}
669  	
670  	static int service_signal_dns_reload(struct mt_svc *svc);
671  	static int monitor_update_resolv(struct config_file_ctx *file_ctx,
672  	                          const char *filename)
673  	{
674  	    int ret;
675  	    struct mt_svc *cur_svc;
676  	    DEBUG(2, ("Resolv.conf has been updated. Reloading.\n"));
677  	
678  	    ret = res_init();
679  	    if(ret != 0) {
680  	        return EIO;
681  	    }
682  	
683  	    /* Signal all services to reload their DNS configuration */
684  	    for(cur_svc = file_ctx->mt_ctx->svc_list; cur_svc; cur_svc = cur_svc->next) {
685  	        service_signal_dns_reload(cur_svc);
686  	    }
687  	    return EOK;
688  	}
689  	
690  	static int service_signal(struct mt_svc *svc, const char *svc_signal)
691  	{
692  	    DBusMessage *msg;
693  	    int ret;
694  	
695  	    if (svc->provider && strcasecmp(svc->provider, "local") == 0) {
696  	        /* The local provider requires no signaling */
697  	        return EOK;
698  	    }
699  	
700  	    if (!svc->conn) {
701  	        /* Avoid a race condition where we are trying to
702  	         * order a service to reload that hasn't started
703  	         * yet.
704  	         */
705  	        DEBUG(1,("Could not signal service [%s].\n", svc->name));
706  	        return EIO;
707  	    }
708  	
709  	    msg = dbus_message_new_method_call(NULL,
710  	                                       MONITOR_PATH,
711  	                                       MONITOR_INTERFACE,
712  	                                       svc_signal);
713  	    if (!msg) {
714  	        DEBUG(0,("Out of memory?!\n"));
715  	        monitor_kill_service(svc);
716  	        talloc_free(svc);
717  	        return ENOMEM;
718  	    }
719  	
720  	    ret = sbus_conn_send(svc->conn, msg,
721  	                         svc->mt_ctx->service_id_timeout,
722  	                         reload_reply, svc, NULL);
723  	
724  	    dbus_message_unref(msg);
725  	    return ret;
726  	}
727  	
728  	static int service_signal_dns_reload(struct mt_svc *svc)
729  	{
730  	    return service_signal(svc, MON_CLI_METHOD_RES_INIT);
731  	}
732  	static int service_signal_offline(struct mt_svc *svc)
733  	{
734  	    return service_signal(svc, MON_CLI_METHOD_OFFLINE);
735  	}
736  	static int service_signal_rotate(struct mt_svc *svc)
737  	{
738  	    return service_signal(svc, MON_CLI_METHOD_ROTATE);
739  	}
740  	
741  	static int check_domain_ranges(struct sss_domain_info *domains)
742  	{
743  	    struct sss_domain_info *dom = domains, *other = NULL;
744  	    uint32_t id_min, id_max;
745  	
746  	    while (dom) {
747  	        other = dom->next;
748  	        if (dom->id_max && dom->id_min > dom->id_max) {
749  	            DEBUG(1, ("Domain '%s' does not have a valid ID range\n",
750  	                      dom->name));
751  	            return EINVAL;
752  	        }
753  	
754  	        while (other) {
755  	            id_min = MAX(dom->id_min, other->id_min);
756  	            id_max = MIN((dom->id_max ? dom->id_max : UINT32_MAX),
757  	                         (other->id_max ? other->id_max : UINT32_MAX));
758  	            if (id_min <= id_max) {
759  	                DEBUG(1, ("Domains '%s' and '%s' overlap in range %u - %u\n",
760  	                          dom->name, other->name, id_min, id_max));
761  	            }
762  	            other = other->next;
763  	        }
764  	        dom = dom->next;
765  	    }
766  	
767  	    return EOK;
768  	}
769  	
770  	static int check_local_domain_unique(struct sss_domain_info *domains)
771  	{
772  	    uint8_t count = 0;
773  	
774  	    struct sss_domain_info *dom = domains;
775  	
776  	    while (dom) {
777  	        if (strcasecmp(dom->provider, "local") == 0) {
778  	            count++;
779  	        }
780  	
781  	        if (count > 1) {
782  	            break;
783  	        }
784  	
785  	        dom = dom->next;
786  	    }
787  	
788  	    if (count > 1) {
789  	        return EINVAL;
790  	    }
791  	
792  	    return EOK;
793  	}
794  	
795  	static char *check_services(char **services)
796  	{
797  	    const char *known_services[] = { "nss", "pam", NULL };
798  	    int i;
799  	    int ii;
800  	
801  	    /* Check if services we are about to start are in the list if known */
802  	    for (i = 0; services[i]; i++) {
803  	        for (ii=0; known_services[ii]; ii++) {
804  	            if (strcasecmp(services[i], known_services[ii]) == 0) {
805  	                break;
806  	            }
807  	        }
808  	
809  	        if (known_services[ii] == NULL) {
810  	            return services[i];
811  	        }
812  	    }
813  	
814  	    return NULL;
815  	}
816  	
817  	int get_monitor_config(struct mt_ctx *ctx)
818  	{
819  	    int ret;
820  	    int timeout_seconds;
821  	    char *badsrv = NULL;
822  	
823  	    ret = confdb_get_int(ctx->cdb, ctx,
824  	                         CONFDB_MONITOR_CONF_ENTRY,
825  	                         CONFDB_MONITOR_SBUS_TIMEOUT,
826  	                         10, &timeout_seconds);
827  	    if (ret != EOK) {
828  	        return ret;
829  	    }
830  	
831  	    ctx->service_id_timeout = timeout_seconds * 1000; /* service_id_timeout is in ms */
832  	
833  	    ctx->service_ctx = talloc_new(ctx);
834  	    if(!ctx->service_ctx) {
835  	        return ENOMEM;
836  	    }
837  	    ret = confdb_get_string_as_list(ctx->cdb, ctx->service_ctx,
838  	                                    CONFDB_MONITOR_CONF_ENTRY,
839  	                                    CONFDB_MONITOR_ACTIVE_SERVICES,
840  	                                    &ctx->services);
841  	    if (ret != EOK) {
842  	        DEBUG(0, ("No services configured!\n"));
843  	        return EINVAL;
844  	    }
845  	
846  	    badsrv = check_services(ctx->services);
847  	    if (badsrv != NULL) {
848  	        DEBUG(0, ("Invalid service %s\n", badsrv));
849  	        return EINVAL;
850  	    }
851  	
852  	    ctx->domain_ctx = talloc_new(ctx);
853  	    if(!ctx->domain_ctx) {
854  	        return ENOMEM;
855  	    }
856  	    ret = confdb_get_domains(ctx->cdb, &ctx->domains);
857  	    if (ret != EOK) {
858  	        DEBUG(0, ("No domains configured.\n"));
859  	        return ret;
860  	    }
861  	
862  	    ret = check_local_domain_unique(ctx->domains);
863  	    if (ret != EOK) {
864  	        DEBUG(0, ("More than one local domain configured.\n"));
865  	        return ret;
866  	    }
867  	
868  	    /* Check UID/GID overlaps */
869  	    ret = check_domain_ranges(ctx->domains);
870  	    if (ret != EOK) {
871  	        return ret;
872  	    }
873  	
874  	    return EOK;
875  	}
876  	
877  	static int get_service_config(struct mt_ctx *ctx, const char *name,
878  	                              struct mt_svc **svc_cfg)
879  	{
880  	    int ret;
881  	    char *path;
882  	    struct mt_svc *svc;
883  	
884  	    *svc_cfg = NULL;
885  	
886  	    svc = talloc_zero(ctx, struct mt_svc);
887  	    if (!svc) {
888  	        return ENOMEM;
889  	    }
890  	    svc->mt_ctx = ctx;
891  	
892  	    talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor);
893  	
894  	    svc->name = talloc_strdup(svc, name);
895  	    if (!svc->name) {
896  	        talloc_free(svc);
897  	        return ENOMEM;
898  	    }
899  	
900  	    svc->identity = talloc_strdup(svc, name);
901  	    if (!svc->identity) {
902  	        talloc_free(svc);
903  	        return ENOMEM;
904  	    }
905  	
906  	    path = talloc_asprintf(svc, CONFDB_SERVICE_PATH_TMPL, svc->name);
907  	    if (!path) {
908  	        talloc_free(svc);
909  	        return ENOMEM;
910  	    }
911  	
912  	    ret = confdb_get_string(ctx->cdb, svc, path,
913  	                            CONFDB_SERVICE_COMMAND,
914  	                            NULL, &svc->command);
915  	    if (ret != EOK) {
916  	        DEBUG(0,("Failed to start service '%s'\n", svc->name));
917  	        talloc_free(svc);
918  	        return ret;
919  	    }
920  	
921  	    if (!svc->command) {
922  	        svc->command = talloc_asprintf(svc, "%s/sssd_%s -d %d%s%s",
923  	                                       SSSD_LIBEXEC_PATH,
924  	                                       svc->name, debug_level,
925  	                                       (debug_timestamps?
926  	                                              "": " --debug-timestamps=0"),
927  	                                       (debug_to_file ?
928  	                                              " --debug-to-files":""));
929  	        if (!svc->command) {
930  	            talloc_free(svc);
931  	            return ENOMEM;
932  	        }
933  	    }
934  	
935  	    ret = confdb_get_int(ctx->cdb, svc, path,
936  	                         CONFDB_SERVICE_TIMEOUT,
937  	                         MONITOR_DEF_PING_TIME, &svc->ping_time);
938  	    if (ret != EOK) {
939  	        DEBUG(0,("Failed to start service '%s'\n", svc->name));
940  	        talloc_free(svc);
941  	        return ret;
942  	    }
943  	
944  	    /* 'timeout = 0' should be translated to the default */
945  	    if (svc->ping_time == 0) {
946  	        svc->ping_time = MONITOR_DEF_PING_TIME;
947  	    }
948  	
949  	    *svc_cfg = svc;
950  	    talloc_free(path);
951  	
952  	    return EOK;
953  	}
954  	
955  	static int add_new_service(struct mt_ctx *ctx, const char *name)
956  	{
957  	    int ret;
958  	    struct mt_svc *svc;
959  	
960  	    ret = get_service_config(ctx, name, &svc);
961  	
962  	    ret = start_service(svc);
963  	    if (ret != EOK) {
964  	        DEBUG(0,("Failed to start service '%s'\n", svc->name));
965  	        talloc_free(svc);
966  	    }
967  	
968  	    return ret;
969  	}
970  	
971  	static int get_provider_config(struct mt_ctx *ctx, const char *name,
972  	                              struct mt_svc **svc_cfg)
973  	{
974  	    int ret;
975  	    char *path;
976  	    struct mt_svc *svc;
977  	
978  	    *svc_cfg = NULL;
979  	
980  	    svc = talloc_zero(ctx, struct mt_svc);
981  	    if (!svc) {
982  	        return ENOMEM;
983  	    }
984  	    svc->mt_ctx = ctx;
985  	
986  	    talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor);
987  	
988  	    svc->name = talloc_strdup(svc, name);
989  	    if (!svc->name) {
990  	        talloc_free(svc);
991  	        return ENOMEM;
992  	    }
993  	
994  	    svc->identity = talloc_asprintf(svc, "%%BE_%s", svc->name);
995  	    if (!svc->identity) {
996  	        talloc_free(svc);
997  	        return ENOMEM;
998  	    }
999  	
1000 	    path = talloc_asprintf(svc, CONFDB_DOMAIN_PATH_TMPL, name);
1001 	    if (!path) {
1002 	        talloc_free(svc);
1003 	        return ENOMEM;
1004 	    }
1005 	
1006 	    ret = confdb_get_string(ctx->cdb, svc, path,
1007 	                            CONFDB_DOMAIN_ID_PROVIDER,
1008 	                            NULL, &svc->provider);
1009 	    if (ret != EOK) {
1010 	        DEBUG(0, ("Failed to find ID provider from [%s] configuration\n", name));
1011 	        talloc_free(svc);
1012 	        return ret;
1013 	    }
1014 	
1015 	    ret = confdb_get_string(ctx->cdb, svc, path,
1016 	                            CONFDB_DOMAIN_COMMAND,
1017 	                            NULL, &svc->command);
1018 	    if (ret != EOK) {
1019 	        DEBUG(0, ("Failed to find command from [%s] configuration\n", name));
1020 	        talloc_free(svc);
1021 	        return ret;
1022 	    }
1023 	
1024 	    ret = confdb_get_int(ctx->cdb, svc, path,
1025 	                         CONFDB_DOMAIN_TIMEOUT,
1026 	                         MONITOR_DEF_PING_TIME, &svc->ping_time);
1027 	    if (ret != EOK) {
1028 	        DEBUG(0,("Failed to start service '%s'\n", svc->name));
1029 	        talloc_free(svc);
1030 	        return ret;
1031 	    }
1032 	
1033 	    /* 'timeout = 0' should be translated to the default */
1034 	    if (svc->ping_time == 0) {
1035 	        svc->ping_time = MONITOR_DEF_PING_TIME;
1036 	    }
1037 	
1038 	    talloc_free(path);
1039 	
1040 	    /* if no provider is present do not run the domain */
1041 	    if (!svc->provider) {
1042 	        talloc_free(svc);
1043 	        return EIO;
1044 	    }
1045 	
1046 	    /* if there are no custom commands, build a default one */
1047 	    if (!svc->command) {
1048 	        svc->command = talloc_asprintf(svc,
1049 	                            "%s/sssd_be -d %d%s%s --domain %s",
1050 	                            SSSD_LIBEXEC_PATH, debug_level,
1051 	                            (debug_timestamps?"": " --debug-timestamps=0"),
1052 	                            (debug_to_file?" --debug-to-files":""),
1053 	                            svc->name);
1054 	        if (!svc->command) {
1055 	            talloc_free(svc);
1056 	            return ENOMEM;
1057 	        }
1058 	    }
1059 	
1060 	    *svc_cfg = svc;
1061 	    return EOK;
1062 	}
1063 	
1064 	static int add_new_provider(struct mt_ctx *ctx, const char *name)
1065 	{
1066 	    int ret;
1067 	    struct mt_svc *svc;
1068 	
1069 	    ret = get_provider_config(ctx, name, &svc);
1070 	    if (ret != EOK) {
1071 	        DEBUG(0, ("Could not get provider configuration for [%s]\n",
1072 	                  name));
1073 	        return ret;
1074 	    }
1075 	
1076 	    if (strcasecmp(svc->provider, "local") == 0) {
1077 	        /* The LOCAL provider requires no back-end currently
1078 	         * We'll add it to the service list, but we don't need
1079 	         * to poll it.
1080 	         */
1081 	        svc->svc_started = true;
1082 	        DLIST_ADD(ctx->svc_list, svc);
1083 	        return ENOENT;
1084 	    }
1085 	
1086 	    ret = start_service(svc);
1087 	    if (ret != EOK) {
1088 	        DEBUG(0,("Failed to start service '%s'\n", svc->name));
1089 	        talloc_free(svc);
1090 	    }
1091 	
1092 	    return ret;
1093 	}
1094 	
1095 	static void monitor_hup(struct tevent_context *ev,
1096 	                        struct tevent_signal *se,
1097 	                        int signum,
1098 	                        int count,
1099 	                        void *siginfo,
1100 	                        void *private_data)
1101 	{
1102 	    struct mt_ctx *ctx = talloc_get_type(private_data, struct mt_ctx);
1103 	    struct mt_svc *cur_svc;
1104 	
1105 	    DEBUG(1, ("Received SIGHUP.\n"));
1106 	
1107 	    /* Signal all services to rotate debug files */
1108 	    for(cur_svc = ctx->svc_list; cur_svc; cur_svc = cur_svc->next) {
1109 	        service_signal_rotate(cur_svc);
1110 	    }
1111 	}
1112 	
1113 	static int monitor_cleanup(void)
1114 	{
1115 	    char *file;
1116 	    int ret;
1117 	    TALLOC_CTX *tmp_ctx;
1118 	
1119 	    tmp_ctx = talloc_new(NULL);
1120 	    if (!tmp_ctx) return ENOMEM;
1121 	
1122 	    file = talloc_asprintf(tmp_ctx, "%s/%s.pid", PID_PATH, "sssd");
1123 	    if (file == NULL) {
1124 	        return ENOMEM;
1125 	    }
1126 	
1127 	    errno = 0;
1128 	    ret = unlink(file);
1129 	    if (ret == -1) {
1130 	        ret = errno;
1131 	        DEBUG(0, ("Error removing pidfile! (%d [%s])\n",
1132 	                ret, strerror(ret)));
1133 	        talloc_free(file);
1134 	        return errno;
1135 	    }
1136 	
1137 	    talloc_free(file);
1138 	    return EOK;
1139 	}
1140 	
1141 	static void monitor_quit(struct tevent_context *ev,
1142 	                         struct tevent_signal *se,
1143 	                         int signum,
1144 	                         int count,
1145 	                         void *siginfo,
1146 	                         void *private_data)
1147 	{
1148 	    DEBUG(8, ("Received shutdown command\n"));
1149 	    monitor_cleanup();
1150 	
1151 	#if HAVE_GETPGRP
1152 	    if (getpgrp() == getpid()) {
1153 	        DEBUG(0,("%s: killing children\n", strsignal(signum)));
1154 	        kill(-getpgrp(), SIGTERM);
1155 	    }
1156 	#endif
1157 	
1158 	    exit(0);
1159 	}
1160 	
1161 	static void signal_offline(struct tevent_context *ev,
1162 	                           struct tevent_signal *se,
1163 	                           int signum,
1164 	                           int count,
1165 	                           void *siginfo,
1166 	                           void *private_data)
1167 	{
1168 	    struct mt_ctx *monitor;
1169 	    struct mt_svc *cur_svc;
1170 	
1171 	    monitor = talloc_get_type(private_data, struct mt_ctx);
1172 	
1173 	    DEBUG(8, ("Signaling providers to go offline immediately.\n"));
1174 	
1175 	    /* Signal all providers to immediately go offline */
1176 	    for(cur_svc = monitor->svc_list; cur_svc; cur_svc = cur_svc->next) {
1177 	        /* Don't signal services, only providers */
1178 	        if (cur_svc->provider) {
1179 	            service_signal_offline(cur_svc);
1180 	        }
1181 	    }
1182 	}
1183 	
1184 	int read_config_file(const char *config_file)
1185 	{
1186 	    int ret;
1187 	    struct collection_item *sssd_config = NULL;
1188 	    struct collection_item *error_list = NULL;
1189 	
1190 	    /* Read the configuration into a collection */
1191 	    ret = config_from_file("sssd", config_file, &sssd_config,
1192 	                           INI_STOP_ON_ANY, &error_list);
1193 	    if (ret != EOK) {
1194 	        DEBUG(0, ("Parse error reading configuration file [%s]\n",
1195 	                  config_file));
1196 	        print_file_parsing_errors(stderr, error_list);
1197 	    }
1198 	
1199 	    free_ini_config_errors(error_list);
1200 	    free_ini_config(sssd_config);
1201 	    return ret;
1202 	}
1203 	
1204 	static int monitor_ctx_destructor(void *mem)
1205 	{
1206 	    struct mt_ctx *mon = talloc_get_type(mem, struct mt_ctx);
1207 	    struct mt_svc *svc;
1208 	
1209 	    /* zero out references in svcs so that they don't try
1210 	     * to access the monitor context on process shutdown */
1211 	
1212 	    for (svc = mon->svc_list; svc; svc = svc->next) {
1213 	        svc->mt_ctx = NULL;
1214 	    }
1215 	    return 0;
1216 	}
1217 	
1218 	static errno_t load_configuration(TALLOC_CTX *mem_ctx,
1219 	                                  const char *config_file,
1220 	                                  struct mt_ctx **monitor)
1221 	{
1222 	    errno_t ret;
1223 	    struct mt_ctx *ctx;
1224 	    char *cdb_file = NULL;
1225 	
1226 	    ctx = talloc_zero(mem_ctx, struct mt_ctx);
1227 	    if(!ctx) {
1228 	        return ENOMEM;
1229 	    }
1230 	    talloc_set_destructor((TALLOC_CTX *)ctx, monitor_ctx_destructor);
1231 	
1232 	    cdb_file = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE);
1233 	    if (cdb_file == NULL) {
1234 	        DEBUG(0,("Out of memory, aborting!\n"));
1235 	        ret = ENOMEM;
1236 	        goto done;
1237 	    }
1238 	
1239 	    ret = confdb_init(ctx, &ctx->cdb, cdb_file);
1240 	    if (ret != EOK) {
1241 	        DEBUG(0,("The confdb initialization failed\n"));
1242 	        goto done;
1243 	    }
1244 	
1245 	    /* Initialize the CDB from the configuration file */
1246 	    ret = confdb_test(ctx->cdb);
1247 	    if (ret == ENOENT) {
1248 	        /* First-time setup */
1249 	
1250 	        /* Purge any existing confdb in case an old
1251 	         * misconfiguration gets in the way
1252 	         */
1253 	        talloc_zfree(ctx->cdb);
1254 	        unlink(cdb_file);
1255 	
1256 	        ret = confdb_init(ctx, &ctx->cdb, cdb_file);
1257 	        if (ret != EOK) {
1258 	            DEBUG(0,("The confdb initialization failed\n"));
1259 	            goto done;
1260 	        }
1261 	
1262 	        /* Load special entries */
1263 	        ret = confdb_create_base(ctx->cdb);
1264 	        if (ret != EOK) {
1265 	            DEBUG(0, ("Unable to load special entries into confdb\n"));
1266 	            goto done;
1267 	        }
1268 	    } else if (ret != EOK) {
1269 	        DEBUG(0, ("Fatal error initializing confdb\n"));
1270 	        goto done;
1271 	    }
1272 	    talloc_zfree(cdb_file);
1273 	
1274 	    ret = confdb_init_db(config_file, ctx->cdb);
1275 	    if (ret != EOK) {
1276 	        DEBUG(0, ("ConfDB initialization has failed [%s]\n",
1277 	              strerror(ret)));
1278 	        goto done;
1279 	    }
1280 	
1281 	    /* Validate the configuration in the database */
1282 	    /* Read in the monitor's configuration */
1283 	    ret = get_monitor_config(ctx);
1284 	    if (ret != EOK) {
1285 	        goto done;
1286 	    }
1287 	
1288 	    *monitor = ctx;
1289 	
1290 	    ret = EOK;
1291 	
1292 	done:
1293 	    if (ret != EOK) {
1294 	        talloc_free(ctx);
1295 	    }
1296 	    return ret;
1297 	}
1298 	
1299 	#ifdef HAVE_SYS_INOTIFY_H
1300 	static void process_config_file(struct tevent_context *ev,
1301 	                                struct tevent_timer *te,
1302 	                                struct timeval t, void *ptr);
1303 	
1304 	static void config_file_changed(struct tevent_context *ev,
1305 	                                struct tevent_fd *fde,
1306 	                                uint16_t flags, void *data)
1307 	{
1308 	    struct tevent_timer *te = NULL;
1309 	    struct timeval tv;
1310 	    struct config_file_ctx *file_ctx;
1311 	
1312 	    file_ctx = talloc_get_type(data, struct config_file_ctx);
1313 	    if (file_ctx->needs_update) {
1314 	        /* Skip updating. It's already queued for update.
1315 	         */
1316 	        return;
1317 	    }
1318 	
1319 	    /* We will queue the file for update in one second.
1320 	     * This way, if there is a script writing to the file
1321 	     * repeatedly, we won't be attempting to update multiple
1322 	     * times.
1323 	     */
1324 	    gettimeofday(&tv, NULL);
1325 	    tv.tv_sec += 1;
1326 	
1327 	    te = tevent_add_timer(ev, ev, tv, process_config_file, file_ctx);
1328 	    if (!te) {
1329 	        DEBUG(0, ("Unable to queue config file update! Exiting.\n"));
1330 	        kill(getpid(), SIGTERM);
1331 	        return;
1332 	    }
1333 	    file_ctx->needs_update = 1;
1334 	}
1335 	
1336 	struct rewatch_ctx {
1337 	    struct config_file_callback *cb;
1338 	    struct config_file_ctx *file_ctx;
1339 	};
1340 	static void rewatch_config_file(struct tevent_context *ev,
1341 	                                struct tevent_timer *te,
1342 	                                struct timeval t, void *ptr);
1343 	static void process_config_file(struct tevent_context *ev,
1344 	                                struct tevent_timer *te,
1345 	                                struct timeval t, void *ptr)
1346 	{
1347 	    TALLOC_CTX *tmp_ctx;
1348 	    struct inotify_event *in_event;
1349 	    char *buf;
1350 	    char *name;
1351 	    ssize_t len, total_len;
1352 	    ssize_t event_size;
1353 	    struct config_file_ctx *file_ctx;
1354 	    struct config_file_callback *cb;
1355 	    struct rewatch_ctx *rw_ctx;
1356 	
1357 	    event_size = sizeof(struct inotify_event);
1358 	    file_ctx = talloc_get_type(ptr, struct config_file_ctx);
1359 	
1360 	    DEBUG(1, ("Processing config file changes\n"));
1361 	
1362 	    tmp_ctx = talloc_new(NULL);
1363 	    if (!tmp_ctx) return;
1364 	
1365 	    buf = talloc_size(tmp_ctx, event_size);
1366 	    if (!buf) {
1367 	        goto done;
1368 	    }
1369 	
1370 	    total_len = 0;
1371 	    while (total_len < event_size) {
1372 	        len = read(file_ctx->mt_ctx->inotify_fd, buf+total_len,
1373 	                   event_size-total_len);
1374 	        if (len == -1) {
1375 	            if (errno == EINTR) continue;
1376 	            DEBUG(0, ("Critical error reading inotify file descriptor.\n"));
1377 	            goto done;
1378 	        }
1379 	        total_len += len;
1380 	    }
1381 	
1382 	    in_event = (struct inotify_event *)buf;
1383 	
1384 	    if (in_event->len > 0) {
1385 	        /* Read in the name, even though we don't use it,
1386 	         * so that read ptr is in the right place
1387 	         */
1388 	        name = talloc_size(tmp_ctx, len);
1389 	        if (!name) {
1390 	            goto done;
1391 	        }
1392 	        total_len = 0;
1393 	        while (total_len < in_event->len) {
1394 	            len = read(file_ctx->mt_ctx->inotify_fd, &name, in_event->len);
1395 	            if (len == -1) {
1396 	                if (errno == EINTR) continue;
1397 	                DEBUG(0, ("Critical error reading inotify file descriptor.\n"));
1398 	                goto done;
1399 	            }
1400 	            total_len += len;
1401 	        }
1402 	    }
1403 	
1404 	    for (cb = file_ctx->callbacks; cb; cb = cb->next) {
1405 	        if (cb->wd == in_event->wd) {
1406 	            break;
1407 	        }
1408 	    }
1409 	    if (!cb) {
1410 	        DEBUG(0, ("Unknown watch descriptor\n"));
1411 	        goto done;
1412 	    }
1413 	
1414 	    if (in_event->mask & IN_IGNORED) {
1415 	        /* Some text editors will move a new file on top of the
1416 	         * existing one instead of modifying it. In this case,
1417 	         * the kernel will send us an IN_IGNORE signal.
1418 	         * We will try to open a new watch descriptor on the
1419 	         * new file.
1420 	         */
1421 	        struct timeval tv;
1422 	        struct tevent_timer *tev;
1423 	        tv.tv_sec = t.tv_sec+5;
1424 	        tv.tv_usec = t.tv_usec;
1425 	
1426 	        cb->retries = 0;
1427 	        rw_ctx = talloc(file_ctx, struct rewatch_ctx);
1428 	        if(!rw_ctx) {
1429 	            DEBUG(0, ("Could not restore inotify watch. Quitting!\n"));
1430 	            close(file_ctx->mt_ctx->inotify_fd);
1431 	            kill(getpid(), SIGTERM);
1432 	            goto done;
1433 	        }
1434 	        rw_ctx->cb = cb;
1435 	        rw_ctx->file_ctx = file_ctx;
1436 	
1437 	        tev = tevent_add_timer(ev, rw_ctx, tv, rewatch_config_file, rw_ctx);
1438 	        if (te == NULL) {
1439 	            DEBUG(0, ("Could not restore inotify watch. Quitting!\n"));
1440 	            close(file_ctx->mt_ctx->inotify_fd);
1441 	            kill(getpid(), SIGTERM);
1442 	        }
1443 	        goto done;
1444 	    }
1445 	
1446 	    /* Tell the monitor to signal the children */
1447 	    cb->fn(file_ctx, cb->filename);
1448 	    file_ctx->needs_update = 0;
1449 	
1450 	done:
1451 	    talloc_free(tmp_ctx);
1452 	}
1453 	
1454 	static void rewatch_config_file(struct tevent_context *ev,
1455 	                                struct tevent_timer *te,
1456 	                                struct timeval t, void *ptr)
1457 	{
1458 	    int err;
1459 	    struct tevent_timer *tev = NULL;
1460 	    struct timeval tv;
1461 	    struct config_file_callback *cb;
1462 	
1463 	    struct rewatch_ctx *rw_ctx;
1464 	    struct config_file_ctx *file_ctx;
1465 	
1466 	    rw_ctx = talloc_get_type(ptr, struct rewatch_ctx);
1467 	
1468 	    cb = rw_ctx->cb;
1469 	    file_ctx = rw_ctx->file_ctx;
1470 	
1471 	    /* Retry six times at five-second intervals before giving up */
1472 	    cb->retries++;
1473 	    if (cb->retries > 6) {
1474 	        DEBUG(0, ("Could not restore inotify watch. Quitting!\n"));
1475 	        close(file_ctx->mt_ctx->inotify_fd);
1476 	        kill(getpid(), SIGTERM);
1477 	    }
1478 	
1479 	    cb->wd = inotify_add_watch(file_ctx->mt_ctx->inotify_fd,
1480 	                               cb->filename, IN_MODIFY);
1481 	    if (cb->wd < 0) {
1482 	        err = errno;
1483 	
1484 	        tv.tv_sec = t.tv_sec+5;
1485 	        tv.tv_usec = t.tv_usec;
1486 	
1487 	        DEBUG(1, ("Could not add inotify watch for file [%s]. Error [%d:%s]\n",
1488 	                  cb->filename, err, strerror(err)));
1489 	
Event returned_pointer: Pointer "tev" returned by "_tevent_add_timer(ev, ev, tv, rewatch_config_file, rw_ctx, &"rewatch_config_file", &"monitor/monitor.c:1490")" is never used.
1490 	        tev = tevent_add_timer(ev, ev, tv, rewatch_config_file, rw_ctx);
1491 	        if (te == NULL) {
1492 	            DEBUG(0, ("Could not restore inotify watch. Quitting!\n"));
1493 	            close(file_ctx->mt_ctx->inotify_fd);
1494 	            kill(getpid(), SIGTERM);
1495 	        }
1496 	
1497 	        return;
1498 	    }
1499 	    cb->retries = 0;
1500 	
1501 	    /* Tell the monitor to signal the children */
1502 	    cb->fn(file_ctx, cb->filename);
1503 	
1504 	    talloc_free(rw_ctx);
1505 	    file_ctx->needs_update = 0;
1506 	}
1507 	#endif
1508 	
1509 	static void poll_config_file(struct tevent_context *ev,
1510 	                                    struct tevent_timer *te,
1511 	                                    struct timeval t, void *ptr)
1512 	{
1513 	    int ret, err;
1514 	    struct stat file_stat;
1515 	    struct timeval tv;
1516 	    struct config_file_ctx *file_ctx;
1517 	    struct config_file_callback *cb;
1518 	
1519 	    file_ctx = talloc_get_type(ptr,struct config_file_ctx);
1520 	
1521 	    for (cb = file_ctx->callbacks; cb; cb = cb->next) {
1522 	        ret = stat(cb->filename, &file_stat);
1523 	        if (ret < 0) {
1524 	            err = errno;
1525 	            DEBUG(0, ("Could not stat file [%s]. Error [%d:%s]\n",
1526 	                      cb->filename, err, strerror(err)));
1527 	            /* TODO: If the config file is missing, should we shut down? */
1528 	            return;
1529 	        }
1530 	
1531 	        if (file_stat.st_mtime != cb->modified) {
1532 	            /* Parse the configuration file and signal the children */
1533 	            /* Note: this will fire if the modification time changes into the past
1534 	             * as well as the future.
1535 	             */
1536 	            DEBUG(1, ("Config file changed\n"));
1537 	            cb->modified = file_stat.st_mtime;
1538 	
1539 	            /* Tell the monitor to signal the children */
1540 	            cb->fn(file_ctx, cb->filename);
1541 	        }
1542 	    }
1543 	
1544 	    gettimeofday(&tv, NULL);
1545 	    tv.tv_sec += CONFIG_FILE_POLL_INTERVAL;
1546 	    tv.tv_usec = 0;
1547 	    file_ctx->timer = tevent_add_timer(ev, file_ctx->parent_ctx, tv,
1548 	                             poll_config_file, file_ctx);
1549 	    if (!file_ctx->timer) {
1550 	        DEBUG(0, ("Error: Config file no longer monitored for changes!\n"));
1551 	    }
1552 	}
1553 	
1554 	static int try_inotify(struct config_file_ctx *file_ctx, const char *filename,
1555 	                       monitor_reconf_fn fn)
1556 	{
1557 	#ifdef HAVE_SYS_INOTIFY_H
1558 	    int err, fd_args, ret;
1559 	    struct tevent_fd *tfd;
1560 	    struct config_file_callback *cb;
1561 	
1562 	    /* Monitoring the file descriptor should be global */
1563 	    if (!file_ctx->mt_ctx->inotify_fd) {
1564 	        /* Set up inotify to monitor the config file for changes */
1565 	        file_ctx->mt_ctx->inotify_fd = inotify_init();
1566 	        if (file_ctx->mt_ctx->inotify_fd < 0) {
1567 	            err = errno;
1568 	            DEBUG(0, ("Could not initialize inotify, error [%d:%s]\n",
1569 	                      err, strerror(err)));
1570 	            return err;
1571 	        }
1572 	
1573 	        fd_args = fcntl(file_ctx->mt_ctx->inotify_fd, F_GETFL, NULL);
1574 	        if (fd_args < 0) {
1575 	            /* Could not set nonblocking */
1576 	            close(file_ctx->mt_ctx->inotify_fd);
1577 	            return EINVAL;
1578 	        }
1579 	
1580 	        fd_args |= O_NONBLOCK;
1581 	        ret = fcntl(file_ctx->mt_ctx->inotify_fd, F_SETFL, fd_args);
1582 	        if (ret < 0) {
1583 	            /* Could not set nonblocking */
1584 	            close(file_ctx->mt_ctx->inotify_fd);
1585 	            return EINVAL;
1586 	        }
1587 	
1588 	        /* Add the inotify file descriptor to the TEvent context */
1589 	        tfd = tevent_add_fd(file_ctx->mt_ctx->ev, file_ctx,
1590 	                            file_ctx->mt_ctx->inotify_fd,
1591 	                            TEVENT_FD_READ, config_file_changed,
1592 	                            file_ctx);
1593 	        if (!tfd) {
1594 	            close(file_ctx->mt_ctx->inotify_fd);
1595 	            return EIO;
1596 	        }
1597 	    }
1598 	
1599 	    cb = talloc_zero(file_ctx, struct config_file_callback);
1600 	    if(!cb) {
1601 	        close(file_ctx->mt_ctx->inotify_fd);
1602 	        return EIO;
1603 	    }
1604 	
1605 	    cb->filename = talloc_strdup(cb, filename);
1606 	    if (!cb->filename) {
1607 	        close(file_ctx->mt_ctx->inotify_fd);
1608 	        return ENOMEM;
1609 	    }
1610 	    cb->wd = inotify_add_watch(file_ctx->mt_ctx->inotify_fd,
1611 	                               cb->filename, IN_MODIFY);
1612 	    if (cb->wd < 0) {
1613 	        err = errno;
1614 	        DEBUG(0, ("Could not add inotify watch for file [%s]. Error [%d:%s]\n",
1615 	                  cb->filename, err, strerror(err)));
1616 	        close(file_ctx->mt_ctx->inotify_fd);
1617 	        return err;
1618 	    }
1619 	    cb->fn = fn;
1620 	
1621 	    DLIST_ADD(file_ctx->callbacks, cb);
1622 	
1623 	    return EOK;
1624 	#else
1625 	    return EINVAL;
1626 	#endif
1627 	}
1628 	
1629 	static int monitor_config_file(TALLOC_CTX *mem_ctx,
1630 	                               struct mt_ctx *ctx,
1631 	                               const char *file,
1632 	                               monitor_reconf_fn fn)
1633 	{
1634 	    int ret, err;
1635 	    struct timeval tv;
1636 	    struct stat file_stat;
1637 	    struct config_file_callback *cb = NULL;
1638 	
1639 	    ret = stat(file, &file_stat);
1640 	    if (ret < 0) {
1641 	        err = errno;
1642 	        DEBUG(0, ("Could not stat file [%s]. Error [%d:%s]\n",
1643 	                  file, err, strerror(err)));
1644 	        return err;
1645 	    }
1646 	    if (!ctx->file_ctx) {
1647 	        ctx->file_ctx = talloc_zero(mem_ctx, struct config_file_ctx);
1648 	        if (!ctx->file_ctx) return ENOMEM;
1649 	
1650 	        ctx->file_ctx->parent_ctx = mem_ctx;
1651 	        ctx->file_ctx->mt_ctx = ctx;
1652 	    }
1653 	    ret = try_inotify(ctx->file_ctx, file, fn);
1654 	    if (ret != EOK) {
1655 	        /* Could not monitor file with inotify, fall back to polling */
1656 	        cb = talloc_zero(ctx->file_ctx, struct config_file_callback);
1657 	        if (!cb) {
1658 	            talloc_free(ctx->file_ctx);
1659 	            return ENOMEM;
1660 	        }
1661 	        cb->filename = talloc_strdup(cb, file);
1662 	        if (!cb->filename) {
1663 	            talloc_free(ctx->file_ctx);
1664 	            return ENOMEM;
1665 	        }
1666 	        cb->fn = fn;
1667 	        cb->modified = file_stat.st_mtime;
1668 	
1669 	        DLIST_ADD(ctx->file_ctx->callbacks, cb);
1670 	
1671 	        if(!ctx->file_ctx->timer) {
1672 	            gettimeofday(&tv, NULL);
1673 	            tv.tv_sec += CONFIG_FILE_POLL_INTERVAL;
1674 	            tv.tv_usec = 0;
1675 	            ctx->file_ctx->timer = tevent_add_timer(ctx->ev, mem_ctx, tv,
1676 	                                   poll_config_file, ctx->file_ctx);
1677 	            if (!ctx->file_ctx->timer) {
1678 	                talloc_free(ctx->file_ctx);
1679 	                return EIO;
1680 	            }
1681 	        }
1682 	    }
1683 	
1684 	    return EOK;
1685 	}
1686 	
1687 	int monitor_process_init(struct mt_ctx *ctx,
1688 	                         const char *config_file)
1689 	{
1690 	    TALLOC_CTX *tmp_ctx;
1691 	    struct sysdb_ctx_list *db_list;
1692 	    struct tevent_signal *tes;
1693 	    struct sss_domain_info *dom;
1694 	    int num_providers;
1695 	    int ret;
1696 	
1697 	#if 0
1698 	    This feature is incomplete and can leave the SSSD in a bad state if the
1699 	    config file is changed while the SSSD is running.
1700 	
1701 	    Uncomment this once the backends are honoring reloadConfig()
1702 	
1703 	    /* Watch for changes to the confdb config file */
1704 	    ret = monitor_config_file(ctx, ctx, config_file, monitor_signal_reconf);
1705 	    if (ret != EOK) {
1706 	        return ret;
1707 	    }
1708 	#endif
1709 	    /* Watch for changes to the DNS resolv.conf */
1710 	    ret = monitor_config_file(ctx, ctx, RESOLV_CONF_PATH,
1711 	                              monitor_update_resolv);
1712 	    if (ret != EOK) {
1713 	        return ret;
1714 	    }
1715 	
1716 	    /* Avoid a startup race condition between process.
1717 	     * We need to handle DB upgrades or DB creation only
1718 	     * in one process before all other start.
1719 	     */
1720 	    tmp_ctx = talloc_new(NULL);
1721 	    if (!tmp_ctx) {
1722 	        return ENOMEM;
1723 	    }
1724 	    ret = sysdb_init(tmp_ctx, ctx->ev, ctx->cdb, NULL, true, &db_list);
1725 	    if (ret != EOK) {
1726 	        return ret;
1727 	    }
1728 	    talloc_zfree(tmp_ctx);
1729 	
1730 	    /* Initialize D-BUS Server
1731 	     * The monitor will act as a D-BUS server for all
1732 	     * SSSD processes */
1733 	    ret = monitor_dbus_init(ctx);
1734 	    if (ret != EOK) {
1735 	        return ret;
1736 	    }
1737 	
1738 	    /* start providers */
1739 	    num_providers = 0;
1740 	    for (dom = ctx->domains; dom; dom = dom->next) {
1741 	        ret = add_new_provider(ctx, dom->name);
1742 	        if (ret != EOK && ret != ENOENT) {
1743 	            return ret;
1744 	        }
1745 	        if (ret != ENOENT) {
1746 	            num_providers++;
1747 	        }
1748 	    }
1749 	
1750 	    if (num_providers > 0) {
1751 	        /* now set the services stratup timeout *
1752 	         * (responders will be started automatically when all
1753 	         *  providers are up and running or when the tomeout
1754 	         *  expires) */
1755 	        ret = add_services_startup_timeout(ctx);
1756 	        if (ret != EOK) {
1757 	            return ret;
1758 	        }
1759 	    } else {
1760 	        int i;
1761 	
1762 	        ctx->services_started = true;
1763 	
1764 	        /* No providers start services immediately
1765 	         * Normally this means only LOCAL is configured */
1766 	        for (i = 0; ctx->services[i]; i++) {
1767 	            add_new_service(ctx, ctx->services[i]);
1768 	        }
1769 	    }
1770 	
1771 	    /* now start checking for global events */
1772 	    set_global_checker(ctx);
1773 	
1774 	    /* Set up an event handler for a SIGHUP */
1775 	    tes = tevent_add_signal(ctx->ev, ctx, SIGHUP, 0,
1776 	                            monitor_hup, ctx);
1777 	    if (tes == NULL) {
1778 	        return EIO;
1779 	    }
1780 	
1781 	    /* Set up an event handler for a SIGINT */
1782 	    tes = tevent_add_signal(ctx->ev, ctx, SIGINT, 0,
1783 	                            monitor_quit, ctx);
1784 	    if (tes == NULL) {
1785 	        return EIO;
1786 	    }
1787 	
1788 	    /* Set up an event handler for a SIGTERM */
1789 	    tes = tevent_add_signal(ctx->ev, ctx, SIGTERM, 0,
1790 	                            monitor_quit, ctx);
1791 	    if (tes == NULL) {
1792 	        return EIO;
1793 	    }
1794 	
1795 	    /* Handle SIGUSR1 (tell all providers to go offline) */
1796 	    BlockSignals(false, SIGUSR1);
1797 	    tes = tevent_add_signal(ctx->ev, ctx, SIGUSR1, 0,
1798 	                            signal_offline, ctx);
1799 	    if (tes == NULL) {
1800 	        return EIO;
1801 	    }
1802 	
1803 	    return EOK;
1804 	}
1805 	
1806 	static void init_timeout(struct tevent_context *ev,
1807 	                         struct tevent_timer *te,
1808 	                         struct timeval t, void *ptr)
1809 	{
1810 	    struct mon_init_conn *mini;
1811 	
1812 	    DEBUG(2, ("Client timed out before Identification!\n"));
1813 	
1814 	    mini = talloc_get_type(ptr, struct mon_init_conn);
1815 	
1816 	    sbus_disconnect(mini->conn);
1817 	    talloc_zfree(mini);
1818 	}
1819 	
1820 	/*
1821 	 * monitor_service_init
1822 	 * Set up a timeout function and temporary connection structure.
1823 	 * If the client does not identify before the timeout kicks in,
1824 	 * the client is forcibly disconnected.
1825 	 */
1826 	static int monitor_service_init(struct sbus_connection *conn, void *data)
1827 	{
1828 	    struct mt_ctx *ctx;
1829 	    struct mon_init_conn *mini;
1830 	    struct timeval tv;
1831 	
1832 	    DEBUG(3, ("Initializing D-BUS Service\n"));
1833 	
1834 	    ctx = talloc_get_type(data, struct mt_ctx);
1835 	
1836 	    mini = talloc(conn, struct mon_init_conn);
1837 	    if (!mini) {
1838 	        DEBUG(0,("Out of memory?!\n"));
1839 	        talloc_zfree(conn);
1840 	        return ENOMEM;
1841 	    }
1842 	    mini->ctx = ctx;
1843 	    mini->conn = conn;
1844 	
1845 	    /* 5 seconds should be plenty */
1846 	    tv = tevent_timeval_current_ofs(10, 0);
1847 	
1848 	    mini->timeout = tevent_add_timer(ctx->ev, mini, tv, init_timeout, mini);
1849 	    if (!mini->timeout) {
1850 	        DEBUG(0,("Out of memory?!\n"));
1851 	        talloc_zfree(conn);
1852 	        return ENOMEM;
1853 	    }
1854 	
1855 	    sbus_conn_set_private_data(conn, mini);
1856 	
1857 	    return EOK;
1858 	}
1859 	
1860 	/* service_send_ping
1861 	 * this function send a dbus ping to a service.
1862 	 * It returns EOK if all is fine or ENXIO if the connection is
1863 	 * not available (either not yet set up or teared down).
1864 	 * Returns e generic error in other cases.
1865 	 */
1866 	static int service_send_ping(struct mt_svc *svc)
1867 	{
1868 	    DBusMessage *msg;
1869 	    int ret;
1870 	
1871 	    if (!svc->conn) {
1872 	        DEBUG(8, ("Service not yet initialized\n"));
1873 	        return ENXIO;
1874 	    }
1875 	
1876 	    DEBUG(4,("Pinging %s\n", svc->name));
1877 	
1878 	    /*
1879 	     * Set up identity request
1880 	     * This should be a well-known path and method
1881 	     * for all services
1882 	     */
1883 	    msg = dbus_message_new_method_call(NULL,
1884 	                                       MONITOR_PATH,
1885 	                                       MONITOR_INTERFACE,
1886 	                                       MON_CLI_METHOD_PING);
1887 	    if (!msg) {
1888 	        DEBUG(0,("Out of memory?!\n"));
1889 	        talloc_zfree(svc->conn);
1890 	        return ENOMEM;
1891 	    }
1892 	
1893 	    ret = sbus_conn_send(svc->conn, msg,
1894 	                         svc->mt_ctx->service_id_timeout,
1895 	                         ping_check, svc, NULL);
1896 	    dbus_message_unref(msg);
1897 	    return ret;
1898 	}
1899 	
1900 	static void ping_check(DBusPendingCall *pending, void *data)
1901 	{
1902 	    struct mt_svc *svc;
1903 	    DBusMessage *reply;
1904 	    const char *dbus_error_name;
1905 	    int type;
1906 	
1907 	    svc = talloc_get_type(data, struct mt_svc);
1908 	
1909 	    reply = dbus_pending_call_steal_reply(pending);
1910 	    if (!reply) {
1911 	        /* reply should never be null. This function shouldn't be called
1912 	         * until reply is valid or timeout has occurred. If reply is NULL
1913 	         * here, something is seriously wrong and we should bail out.
1914 	         */
1915 	        DEBUG(0, ("A reply callback was called but no reply was received"
1916 	                  " and no timeout occurred\n"));
1917 	
1918 	        /* Destroy this connection */
1919 	        sbus_disconnect(svc->conn);
1920 	        goto done;
1921 	    }
1922 	
1923 	    type = dbus_message_get_type(reply);
1924 	    switch (type) {
1925 	    case DBUS_MESSAGE_TYPE_METHOD_RETURN:
1926 	        /* ok peer replied,
1927 	         * make sure we reset the failure counter in the service structure */
1928 	
1929 	        DEBUG(4,("Service %s replied to ping\n", svc->name));
1930 	
1931 	        svc->failed_pongs = 0;
1932 	        break;
1933 	
1934 	    case DBUS_MESSAGE_TYPE_ERROR:
1935 	
1936 	        dbus_error_name = dbus_message_get_error_name(reply);
1937 	
1938 	        /* timeouts are handled in the main service check function */
1939 	        if (strcmp(dbus_error_name, DBUS_ERROR_TIMEOUT) == 0)
1940 	            break;
1941 	
1942 	        DEBUG(0,("A service PING returned an error [%s], closing connection.\n",
1943 	                 dbus_error_name));
1944 	        /* Falling through to default intentionally*/
1945 	    default:
1946 	        /*
1947 	         * Timeout or other error occurred or something
1948 	         * unexpected happened.
1949 	         * It doesn't matter which, because either way we
1950 	         * know that this connection isn't trustworthy.
1951 	         * We'll destroy it now.
1952 	         */
1953 	        sbus_disconnect(svc->conn);
1954 	    }
1955 	
1956 	done:
1957 	    dbus_pending_call_unref(pending);
1958 	    dbus_message_unref(reply);
1959 	}
1960 	
1961 	
1962 	
1963 	/* service_check_alive
1964 	 * This function checks if the service child is still alive
1965 	 */
1966 	static int service_check_alive(struct mt_svc *svc)
1967 	{
1968 	    int status;
1969 	    pid_t pid;
1970 	
1971 	    DEBUG(4,("Checking service %s(%d) is still alive\n", svc->name, svc->pid));
1972 	
1973 	    pid = waitpid(svc->pid, &status, WNOHANG);
1974 	    if (pid == 0) {
1975 	        return EOK;
1976 	    }
1977 	
1978 	    if (pid != svc->pid) {
1979 	        DEBUG(1, ("bad return (%d) from waitpid() waiting for %d\n",
1980 	                  pid, svc->pid));
1981 	        /* TODO: what do we do now ? */
1982 	        return EINVAL;
1983 	    }
1984 	
1985 	    if (WIFEXITED(status)) { /* children exited on it's own */
1986 	        /* TODO: check configuration to see if it was removed
1987 	         * from the list of process to run */
1988 	        DEBUG(0,("Process [%s] exited\n", svc->name));
1989 	    }
1990 	
1991 	    return ECHILD;
1992 	}
1993 	
1994 	static void service_startup_handler(struct tevent_context *ev,
1995 	                                    struct tevent_timer *te,
1996 	                                    struct timeval t, void *ptr);
1997 	
1998 	static int start_service(struct mt_svc *svc)
1999 	{
2000 	    struct tevent_timer *te;
2001 	    struct timeval tv;
2002 	
2003 	    DEBUG(4,("Queueing service %s for startup\n", svc->name));
2004 	
2005 	    /* at startup we need to start the data providers before the responders
2006 	     * to avoid races where a service starts before sbus pipes are ready
2007 	     * to accept connections. So if startup is true delay by 2 seconds any
2008 	     * process that is not a data provider */
2009 	
2010 	    tv = tevent_timeval_current();
2011 	
2012 	    /* Add a timed event to start up the service.
2013 	     * We have to do this in order to avoid a race
2014 	     * condition where the service being started forks
2015 	     * and attempts to connect to the SBUS before
2016 	     * the monitor is serving it.
2017 	     */
2018 	    te = tevent_add_timer(svc->mt_ctx->ev, svc, tv,
2019 	                          service_startup_handler, svc);
2020 	    if (te == NULL) {
2021 	        DEBUG(0, ("Unable to queue service %s for startup\n", svc->name));
2022 	        return ENOMEM;
2023 	    }
2024 	    return EOK;
2025 	}
2026 	
2027 	static void service_startup_handler(struct tevent_context *ev,
2028 	                                    struct tevent_timer *te,
2029 	                                    struct timeval t, void *ptr)
2030 	{
2031 	    struct mt_svc *mt_svc;
2032 	    char **args;
2033 	
2034 	    mt_svc = talloc_get_type(ptr, struct mt_svc);
2035 	    if (mt_svc == NULL) {
2036 	        return;
2037 	    }
2038 	
2039 	    mt_svc->pid = fork();
2040 	    if (mt_svc->pid != 0) {
2041 	        if (mt_svc->pid == -1) {
2042 	            DEBUG(0, ("Could not fork child to start service [%s]. Continuing.\n", mt_svc->name))
2043 	            return;
2044 	        }
2045 	
2046 	        /* Parent */
2047 	        mt_svc->mt_ctx->check_children = true;
2048 	        mt_svc->failed_pongs = 0;
2049 	        DLIST_ADD(mt_svc->mt_ctx->svc_list, mt_svc);
2050 	        set_tasks_checker(mt_svc);
2051 	
2052 	        return;
2053 	    }
2054 	
2055 	    /* child */
2056 	
2057 	    args = parse_args(mt_svc->command);
2058 	    execvp(args[0], args);
2059 	
2060 	    /* If we are here, exec() has failed
2061 	     * Print errno and abort quickly */
2062 	    DEBUG(0,("Could not exec %s, reason: %s\n", mt_svc->command, strerror(errno)));
2063 	
2064 	    /* We have to call _exit() instead of exit() here
2065 	     * because a bug in D-BUS will cause the server to
2066 	     * close its socket at exit() */
2067 	    _exit(1);
2068 	}
2069 	
2070 	int main(int argc, const char *argv[])
2071 	{
2072 	    int opt;
2073 	    poptContext pc;
2074 	    int opt_daemon = 0;
2075 	    int opt_interactive = 0;
2076 	    char *opt_config_file = NULL;
2077 	    char *config_file = NULL;
2078 	    int flags = 0;
2079 	    struct main_context *main_ctx;
2080 	    TALLOC_CTX *tmp_ctx;
2081 	    struct mt_ctx *monitor;
2082 	    int ret;
2083 	    uid_t uid;
2084 	
2085 	    struct poptOption long_options[] = {
2086 	        POPT_AUTOHELP
2087 	        SSSD_MAIN_OPTS
2088 	        {"daemon", 'D', POPT_ARG_NONE, &opt_daemon, 0, \
2089 	         _("Become a daemon (default)"), NULL }, \
2090 	        {"interactive", 'i', POPT_ARG_NONE, &opt_interactive, 0, \
2091 	         _("Run interactive (not a daemon)"), NULL}, \
2092 	        {"config", 'c', POPT_ARG_STRING, &opt_config_file, 0, \
2093 	         _("Specify a non-default config file"), NULL}, \
2094 	        POPT_TABLEEND
2095 	    };
2096 	
2097 	    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
2098 	    while((opt = poptGetNextOpt(pc)) != -1) {
2099 	        switch(opt) {
2100 	        default:
2101 	            fprintf(stderr, "\nInvalid option %s: %s\n\n",
2102 	                    poptBadOption(pc, 0), poptStrerror(opt));
2103 	            poptPrintUsage(pc, stderr, 0);
2104 	            return 1;
2105 	        }
2106 	    }
2107 	
2108 	    if (opt_daemon && opt_interactive) {
2109 	        fprintf(stderr, "Option -i|--interactive is not allowed together with -D|--daemon\n");
2110 	        poptPrintUsage(pc, stderr, 0);
2111 	        return 1;
2112 	    }
2113 	
2114 	    poptFreeContext(pc);
2115 	
2116 	    uid = getuid();
2117 	    if (uid != 0) {
2118 	        DEBUG(1, ("Running under %d, must be root\n", uid));
2119 	        ERROR("sssd must be run as root\n");
2120 	        return 8;
2121 	    }
2122 	
2123 	    tmp_ctx = talloc_new(NULL);
2124 	    if (!tmp_ctx) {
2125 	        return 7;
2126 	    }
2127 	
2128 	    if (opt_daemon) flags |= FLAGS_DAEMON;
2129 	    if (opt_interactive) flags |= FLAGS_INTERACTIVE;
2130 	
2131 	    if (opt_config_file)
2132 	        config_file = talloc_strdup(tmp_ctx, opt_config_file);
2133 	    else
2134 	        config_file = talloc_strdup(tmp_ctx, CONFDB_DEFAULT_CONFIG_FILE);
2135 	    if(!config_file)
2136 	        return 6;
2137 	
2138 	    /* we want a pid file check */
2139 	    flags |= FLAGS_PID_FILE;
2140 	
2141 	    /* Open before server_setup() does to have logging
2142 	     * during configuration checking */
2143 	    if (debug_to_file) {
2144 	        ret = open_debug_file();
2145 	        if (ret) {
2146 	            return 7;
2147 	        }
2148 	    }
2149 	
2150 	    /* Warn if nscd seems to be running */
2151 	    ret = check_file(NSCD_SOCKET_PATH, -1, -1, -1, CHECK_SOCK, NULL);
2152 	    if (ret == EOK) {
2153 	        DEBUG(0, ("WARNING: nscd appears to be running\n"));
2154 	        ERROR("nscd socket was detected.  As nscd caching capabilities "
2155 	              "may conflict with SSSD, it is recommended to not run "
2156 	              "nscd in parallel with SSSD\n");
2157 	    }
2158 	
2159 	    /* Parse config file, fail if cannot be done */
2160 	    ret = load_configuration(tmp_ctx, config_file, &monitor);
2161 	    if (ret != EOK) {
2162 	        if (ret == EPERM) {
2163 	            DEBUG(1, ("Cannot read configuration file %s\n", config_file));
2164 	            ERROR("Cannot read config file %s, please check if permissions "
2165 	                  "are 0600 and the file is owned by root.root\n", config_file);
2166 	        } else {
2167 	            DEBUG(1, ("Error loading configuration database: [%d]: %s",
2168 	                      ret, strerror(ret)));
2169 	            ERROR("Cannot load configuration database\n");
2170 	        }
2171 	        return 4;
2172 	    }
2173 	
2174 	    /* set up things like debug , signals, daemonization, etc... */
2175 	    ret = server_setup("sssd", flags, CONFDB_MONITOR_CONF_ENTRY, &main_ctx);
2176 	    if (ret != EOK) return 2;
2177 	
2178 	    monitor->ev = main_ctx->event_ctx;
2179 	    talloc_steal(main_ctx, monitor);
2180 	
2181 	    ret = monitor_process_init(monitor,
2182 	                               config_file);
2183 	    if (ret != EOK) return 3;
2184 	    talloc_free(tmp_ctx);
2185 	
2186 	    /* loop on main */
2187 	    server_loop(main_ctx);
2188 	
2189 	    ret = monitor_cleanup();
2190 	    if (ret != EOK) return 5;
2191 	
2192 	    return 0;
2193 	}