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
Event returned_pointer: Pointer "tev" returned by "_tevent_add_timer(ev, rw_ctx, tv, rewatch_config_file, rw_ctx, &"rewatch_config_file", &"monitor/monitor.c:1437")" is never used.
|
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
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 }