Branch data Line data Source code
1 : : /*
2 : : SSSD
3 : :
4 : : Servers setup routines
5 : :
6 : : Copyright (C) Andrew Tridgell 1992-2005
7 : : Copyright (C) Martin Pool 2002
8 : : Copyright (C) Jelmer Vernooij 2002
9 : : Copyright (C) James J Myers 2003 <myersjj@samba.org>
10 : : Copyright (C) Simo Sorce 2008
11 : :
12 : : This program is free software; you can redistribute it and/or modify
13 : : it under the terms of the GNU General Public License as published by
14 : : the Free Software Foundation; either version 3 of the License, or
15 : : (at your option) any later version.
16 : :
17 : : This program is distributed in the hope that it will be useful,
18 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : : GNU General Public License for more details.
21 : :
22 : : You should have received a copy of the GNU General Public License
23 : : along with this program. If not, see <http://www.gnu.org/licenses/>.
24 : : */
25 : :
26 : : #include <sys/types.h>
27 : : #include <sys/wait.h>
28 : : #include <sys/stat.h>
29 : : #include <fcntl.h>
30 : : #include <unistd.h>
31 : : #include "util/util.h"
32 : : #include "ldb.h"
33 : : #include "confdb/confdb.h"
34 : : #include "monitor/monitor_interfaces.h"
35 : :
36 : : #ifdef HAVE_PRCTL
37 : : #include <sys/prctl.h>
38 : : #endif
39 : :
40 : : /*******************************************************************
41 : : Close the low 3 fd's and open dev/null in their place.
42 : : ********************************************************************/
43 : 0 : static void close_low_fds(void)
44 : : {
45 : : #ifndef VALGRIND
46 : : int fd;
47 : : int i;
48 : :
49 : 0 : close(0);
50 : 0 : close(1);
51 : 0 : close(2);
52 : :
53 : : /* try and use up these file descriptors, so silly
54 : : library routines writing to stdout etc won't cause havoc */
55 [ # # ]: 0 : for (i = 0; i < 3; i++) {
56 : 0 : fd = open("/dev/null", O_RDWR, 0);
57 [ # # ]: 0 : if (fd < 0)
58 : 0 : fd = open("/dev/null", O_WRONLY, 0);
59 [ # # ]: 0 : if (fd < 0) {
60 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Can't open /dev/null\n"));
[ # # ][ # # ]
[ # # ]
61 : : return;
62 : : }
63 [ # # ]: 0 : if (fd != i) {
64 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Didn't get file descriptor %d\n",i));
[ # # ][ # # ]
[ # # ]
65 : : return;
66 : : }
67 : : }
68 : : #endif
69 : : }
70 : :
71 : 0 : static void deamon_parent_sigterm(int sig)
72 : : {
73 : 0 : _exit(0);
74 : : }
75 : :
76 : : /**
77 : : Become a daemon, discarding the controlling terminal.
78 : : **/
79 : :
80 : 0 : void become_daemon(bool Fork)
81 : : {
82 : : pid_t pid, cpid;
83 : : int status;
84 : : int ret, error;
85 : :
86 [ # # ]: 0 : if (Fork) {
87 : 0 : pid = fork();
88 [ # # ]: 0 : if (pid != 0) {
89 : : /* Terminate parent process on demand so we can hold systemd
90 : : * or initd from starting next service until sssd in initialized.
91 : : * We use signals directly here because we don't have a tevent
92 : : * context yet. */
93 : 0 : CatchSignal(SIGTERM, deamon_parent_sigterm);
94 : :
95 : : /* or exit when sssd monitor is terminated */
96 : : do {
97 : 0 : errno = 0;
98 : 0 : cpid = waitpid(pid, &status, 0);
99 [ # # ]: 0 : if (cpid == 1) {
100 : : /* An error occurred while waiting */
101 : 0 : error = errno;
102 [ # # ]: 0 : if (error != EINTR) {
103 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
104 : : ("Error [%d][%s] while waiting for child\n",
105 : : error, strerror(error)));
106 : : /* Forcibly kill this child */
107 : 0 : kill(pid, SIGKILL);
108 : 0 : ret = 1;
109 : : }
110 : : }
111 : :
112 : 0 : error = 0;
113 : : /* return error if we didn't exited normally */
114 : 0 : ret = 1;
115 : :
116 [ # # ]: 0 : if (WIFEXITED(status)) {
117 : : /* but return our exit code otherwise */
118 : 0 : ret = WEXITSTATUS(status);
119 : : }
120 : : } while (error == EINTR);
121 : :
122 : 0 : _exit(ret);
123 : : }
124 : : }
125 : :
126 : : /* detach from the terminal */
127 : 0 : setsid();
128 : :
129 : : /* chdir to / to be sure we're not on a remote filesystem */
130 : 0 : errno = 0;
131 [ # # ]: 0 : if(chdir("/") == -1) {
132 : 0 : ret = errno;
133 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Cannot change directory (%d [%s])\n",
[ # # ][ # # ]
[ # # ]
134 : : ret, strerror(ret)));
135 : 0 : return;
136 : : }
137 : :
138 : : /* Close fd's 0,1,2. Needed if started by rsh */
139 : 0 : close_low_fds();
140 : : }
141 : :
142 : 0 : int pidfile(const char *path, const char *name)
143 : : {
144 : : char pid_str[32];
145 : : pid_t pid;
146 : : char *file;
147 : : int fd;
148 : : int ret, err;
149 : : ssize_t len;
150 : : ssize_t size;
151 : : ssize_t written;
152 : 0 : ssize_t pidlen = sizeof(pid_str) - 1;
153 : :
154 : 0 : file = talloc_asprintf(NULL, "%s/%s.pid", path, name);
155 [ # # ]: 0 : if (!file) {
156 : : return ENOMEM;
157 : : }
158 : :
159 : 0 : fd = open(file, O_RDONLY, 0644);
160 : 0 : err = errno;
161 [ # # ]: 0 : if (fd != -1) {
162 : 0 : errno = 0;
163 : 0 : len = sss_atomic_read_s(fd, pid_str, pidlen);
164 : 0 : ret = errno;
165 [ # # ]: 0 : if (len == -1) {
166 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
167 : : ("read failed [%d][%s].\n", ret, strerror(ret)));
168 : 0 : close(fd);
169 : 0 : talloc_free(file);
170 : : return EINVAL;
171 : : }
172 : :
173 : : /* Ensure NULL-termination */
174 : 0 : pid_str[len] = '\0';
175 : :
176 : : /* let's check the pid */
177 : 0 : pid = (pid_t)atoi(pid_str);
178 [ # # ]: 0 : if (pid != 0) {
179 : 0 : errno = 0;
180 : 0 : ret = kill(pid, 0);
181 : : /* succeeded in signaling the process -> another sssd process */
182 [ # # ]: 0 : if (ret == 0) {
183 : 0 : close(fd);
184 : 0 : talloc_free(file);
185 : : return EEXIST;
186 : : }
187 [ # # ][ # # ]: 0 : if (ret != 0 && errno != ESRCH) {
188 : 0 : err = errno;
189 : 0 : close(fd);
190 : 0 : talloc_free(file);
191 : : return err;
192 : : }
193 : : }
194 : :
195 : : /* nothing in the file or no process */
196 : 0 : close(fd);
197 : 0 : unlink(file);
198 : :
199 : : } else {
200 [ # # ]: 0 : if (err != ENOENT) {
201 : 0 : talloc_free(file);
202 : : return err;
203 : : }
204 : : }
205 : :
206 : 0 : fd = open(file, O_CREAT | O_WRONLY | O_EXCL, 0644);
207 : 0 : err = errno;
208 [ # # ]: 0 : if (fd == -1) {
209 : 0 : talloc_free(file);
210 : : return err;
211 : : }
212 : 0 : talloc_free(file);
213 : :
214 : 0 : memset(pid_str, 0, sizeof(pid_str));
215 : 0 : snprintf(pid_str, sizeof(pid_str) -1, "%u\n", (unsigned int) getpid());
216 : 0 : size = strlen(pid_str);
217 : :
218 : 0 : errno = 0;
219 : 0 : written = sss_atomic_write_s(fd, pid_str, size);
220 [ # # ]: 0 : if (written == -1) {
221 : 0 : err = errno;
222 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
223 : : ("write failed [%d][%s]\n", err, strerror(err)));
224 : : return err;
225 : : }
226 : :
227 [ # # ]: 0 : if (written != size) {
228 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
229 : : ("Wrote %d bytes expected %d\n", written, size));
230 : 0 : close(fd);
231 : : return EIO;
232 : : }
233 : :
234 : 0 : close(fd);
235 : :
236 : : return 0;
237 : : }
238 : :
239 : 0 : static void sig_hup(int sig)
240 : : {
241 : : /* cycle log/debug files */
242 : 0 : return;
243 : : }
244 : :
245 : 0 : void sig_term(int sig)
246 : : {
247 : : #if HAVE_GETPGRP
248 : : static int done_sigterm;
249 [ # # ][ # # ]: 0 : if (done_sigterm == 0 && getpgrp() == getpid()) {
250 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("SIGTERM: killing children\n"));
[ # # ][ # # ]
[ # # ]
251 : 0 : done_sigterm = 1;
252 : 0 : kill(-getpgrp(), SIGTERM);
253 : : }
254 : : #endif
255 : 0 : sss_log(SSS_LOG_INFO, "Shutting down");
256 : 0 : exit(0);
257 : : }
258 : :
259 : 0 : static void default_quit(struct tevent_context *ev,
260 : : struct tevent_signal *se,
261 : : int signum,
262 : : int count,
263 : : void *siginfo,
264 : : void *private_data)
265 : : {
266 : : #if HAVE_GETPGRP
267 : : static int done_sigterm;
268 [ # # ][ # # ]: 0 : if (done_sigterm == 0 && getpgrp() == getpid()) {
269 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("SIGTERM: killing children\n"));
[ # # ][ # # ]
[ # # ]
270 : 0 : done_sigterm = 1;
271 : 0 : kill(-getpgrp(), SIGTERM);
272 : : }
273 : : #endif
274 : 0 : sss_log(SSS_LOG_INFO, "Shutting down");
275 : 0 : exit(0);
276 : : }
277 : :
278 : : #ifndef HAVE_PRCTL
279 : : static void sig_segv_abrt(int sig)
280 : : {
281 : : #if HAVE_GETPGRP
282 : : static int done;
283 : : if (done == 0 && getpgrp() == getpid()) {
284 : : DEBUG(SSSDBG_FATAL_FAILURE, ("%s: killing children\n",
285 : : strsignal(sig)));
286 : : done = 1;
287 : : kill(-getpgrp(), SIGTERM);
288 : : }
289 : : #endif /* HAVE_GETPGRP */
290 : : exit(1);
291 : : }
292 : : #endif /* HAVE_PRCTL */
293 : :
294 : : /*
295 : : setup signal masks
296 : : */
297 : 0 : static void setup_signals(void)
298 : : {
299 : : /* we are never interested in SIGPIPE */
300 : 0 : BlockSignals(true, SIGPIPE);
301 : :
302 : : #if defined(SIGFPE)
303 : : /* we are never interested in SIGFPE */
304 : 0 : BlockSignals(true, SIGFPE);
305 : : #endif
306 : :
307 : : /* We are no longer interested in USR1 */
308 : 0 : BlockSignals(true, SIGUSR1);
309 : :
310 : : /* We are no longer interested in SIGINT except for monitor */
311 : 0 : BlockSignals(true, SIGINT);
312 : :
313 : : #if defined(SIGUSR2)
314 : : /* We are no longer interested in USR2 */
315 : 0 : BlockSignals(true, SIGUSR2);
316 : : #endif
317 : :
318 : : /* POSIX demands that signals are inherited. If the invoking process has
319 : : * these signals masked, we will have problems, as we won't recieve them. */
320 : 0 : BlockSignals(false, SIGHUP);
321 : 0 : BlockSignals(false, SIGTERM);
322 : :
323 : 0 : CatchSignal(SIGHUP, sig_hup);
324 : :
325 : : #ifndef HAVE_PRCTL
326 : : /* If prctl is not defined on the system, try to handle
327 : : * some common termination signals gracefully */
328 : : CatchSignal(SIGSEGV, sig_segv_abrt);
329 : : CatchSignal(SIGABRT, sig_segv_abrt);
330 : : #endif
331 : :
332 : 0 : }
333 : :
334 : : /*
335 : : handle io on stdin
336 : : */
337 : 0 : static void server_stdin_handler(struct tevent_context *event_ctx,
338 : : struct tevent_fd *fde,
339 : : uint16_t flags, void *private)
340 : : {
341 : 0 : const char *binary_name = (const char *)private;
342 : : uint8_t c;
343 : :
344 : 0 : errno = 0;
345 [ # # ]: 0 : if (sss_atomic_read_s(0, &c, 1) == 0) {
346 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE, ("%s: EOF on stdin - terminating\n",
[ # # ][ # # ]
[ # # ]
347 : : binary_name));
348 : : #if HAVE_GETPGRP
349 [ # # ]: 0 : if (getpgrp() == getpid()) {
350 : 0 : kill(-getpgrp(), SIGTERM);
351 : : }
352 : : #endif
353 : 0 : exit(0);
354 : : }
355 : 0 : }
356 : :
357 : : /*
358 : : main server helpers.
359 : : */
360 : :
361 : 0 : int die_if_parent_died(void)
362 : : {
363 : : #ifdef HAVE_PRCTL
364 : : int ret;
365 : :
366 : 0 : errno = 0;
367 : 0 : ret = prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0);
368 [ # # ]: 0 : if (ret != 0) {
369 : 0 : ret = errno;
370 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_OP_FAILURE, ("prctl failed [%d]: %s",
[ # # ][ # # ]
[ # # ]
371 : : ret, strerror(ret)));
372 : 0 : return ret;
373 : : }
374 : : #endif
375 : : return EOK;
376 : : }
377 : :
378 : : struct logrotate_ctx {
379 : : struct confdb_ctx *confdb;
380 : : const char *confdb_path;
381 : : };
382 : :
383 : 0 : static void te_server_hup(struct tevent_context *ev,
384 : : struct tevent_signal *se,
385 : : int signum,
386 : : int count,
387 : : void *siginfo,
388 : : void *private_data)
389 : : {
390 : : errno_t ret;
391 : 0 : struct logrotate_ctx *lctx =
392 : : talloc_get_type(private_data, struct logrotate_ctx);
393 : :
394 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE, ("Received SIGHUP. Rotating logfiles.\n"));
[ # # ][ # # ]
[ # # ]
395 : :
396 : 0 : ret = monitor_common_rotate_logs(lctx->confdb, lctx->confdb_path);
397 [ # # ]: 0 : if (ret != EOK) {
398 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Could not reopen log file [%s]\n",
[ # # ][ # # ]
[ # # ]
399 : : strerror(ret)));
400 : : }
401 : 0 : }
402 : :
403 : 0 : int server_setup(const char *name, int flags,
404 : : const char *conf_entry,
405 : : struct main_context **main_ctx)
406 : : {
407 : : struct tevent_context *event_ctx;
408 : : struct main_context *ctx;
409 : : uint16_t stdin_event_flags;
410 : : char *conf_db;
411 : 0 : int ret = EOK;
412 : : bool dt;
413 : : bool dl;
414 : : bool dm;
415 : : struct tevent_signal *tes;
416 : : struct logrotate_ctx *lctx;
417 : :
418 : 0 : debug_prg_name = strdup(name);
419 [ # # ]: 0 : if (!debug_prg_name) {
420 : : return ENOMEM;
421 : : }
422 : :
423 : 0 : setenv("_SSS_LOOPS", "NO", 0);
424 : :
425 : 0 : setup_signals();
426 : :
427 : : /* we want default permissions on created files to be very strict,
428 : : so set our umask to 0177 */
429 : 0 : umask(0177);
430 : :
431 [ # # ]: 0 : if (flags & FLAGS_DAEMON) {
432 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_IMPORTANT_INFO, ("Becoming a daemon.\n"));
[ # # ][ # # ]
[ # # ]
433 : 0 : become_daemon(true);
434 : : }
435 : :
436 [ # # ]: 0 : if (flags & FLAGS_PID_FILE) {
437 : 0 : ret = pidfile(PID_PATH, name);
438 [ # # ]: 0 : if (ret != EOK) {
439 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Error creating pidfile: %s/%s! "
[ # # ][ # # ]
[ # # ]
440 : : "(%d [%s])\n", PID_PATH, name, ret, strerror(ret)));
441 : : return ret;
442 : : }
443 : : }
444 : :
445 : : /* Set up locale */
446 : 0 : setlocale(LC_ALL, "");
447 : 0 : bindtextdomain(PACKAGE, LOCALEDIR);
448 : 0 : textdomain(PACKAGE);
449 : :
450 : : /* the event context is the top level structure.
451 : : * Everything else should hang off that */
452 : 0 : event_ctx = tevent_context_init(talloc_autofree_context());
453 [ # # ]: 0 : if (event_ctx == NULL) {
454 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE,
[ # # ][ # # ]
[ # # ]
455 : : ("The event context initialiaziton failed\n"));
456 : : return 1;
457 : : }
458 : :
459 : : /* Set up an event handler for a SIGINT */
460 : 0 : tes = tevent_add_signal(event_ctx, event_ctx, SIGINT, 0,
461 : : default_quit, NULL);
462 [ # # ]: 0 : if (tes == NULL) {
463 : : return EIO;
464 : : }
465 : :
466 : : /* Set up an event handler for a SIGTERM */
467 : 0 : tes = tevent_add_signal(event_ctx, event_ctx, SIGTERM, 0,
468 : : default_quit, NULL);
469 [ # # ]: 0 : if (tes == NULL) {
470 : : return EIO;
471 : : }
472 : :
473 : 0 : ctx = talloc(event_ctx, struct main_context);
474 [ # # ]: 0 : if (ctx == NULL) {
475 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Out of memory, aborting!\n"));
[ # # ][ # # ]
[ # # ]
476 : : return ENOMEM;
477 : : }
478 : :
479 : 0 : ctx->parent_pid = getppid();
480 : 0 : ctx->event_ctx = event_ctx;
481 : :
482 : 0 : conf_db = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE);
483 [ # # ]: 0 : if (conf_db == NULL) {
484 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Out of memory, aborting!\n"));
[ # # ][ # # ]
[ # # ]
485 : : return ENOMEM;
486 : : }
487 : :
488 : 0 : ret = confdb_init(ctx, &ctx->confdb_ctx, conf_db);
489 [ # # ]: 0 : if (ret != EOK) {
490 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("The confdb initialization failed\n"));
[ # # ][ # # ]
[ # # ]
491 : : return ret;
492 : : }
493 : :
494 [ # # ]: 0 : if (debug_level == SSSDBG_UNRESOLVED) {
495 : : /* set debug level if any in conf_entry */
496 : 0 : ret = confdb_get_int(ctx->confdb_ctx, conf_entry,
497 : : CONFDB_SERVICE_DEBUG_LEVEL,
498 : : SSSDBG_DEFAULT,
499 : : &debug_level);
500 [ # # ]: 0 : if (ret != EOK) {
501 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Error reading from confdb (%d) "
[ # # ][ # # ]
[ # # ]
502 : : "[%s]\n", ret, strerror(ret)));
503 : : return ret;
504 : : }
505 : :
506 : 0 : debug_level = debug_convert_old_level(debug_level);
507 : : }
508 : :
509 : : /* same for debug timestamps */
510 [ # # ]: 0 : if (debug_timestamps == SSSDBG_TIMESTAMP_UNRESOLVED) {
511 : 0 : ret = confdb_get_bool(ctx->confdb_ctx, conf_entry,
512 : : CONFDB_SERVICE_DEBUG_TIMESTAMPS,
513 : : SSSDBG_TIMESTAMP_DEFAULT,
514 : : &dt);
515 [ # # ]: 0 : if (ret != EOK) {
516 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Error reading from confdb (%d) "
[ # # ][ # # ]
[ # # ]
517 : : "[%s]\n", ret, strerror(ret)));
518 : : return ret;
519 : : }
520 [ # # ]: 0 : if (dt) debug_timestamps = 1;
521 : 0 : else debug_timestamps = 0;
522 : : }
523 : :
524 : : /* same for debug microseconds */
525 [ # # ]: 0 : if (debug_microseconds == SSSDBG_MICROSECONDS_UNRESOLVED) {
526 : 0 : ret = confdb_get_bool(ctx->confdb_ctx, conf_entry,
527 : : CONFDB_SERVICE_DEBUG_MICROSECONDS,
528 : : SSSDBG_MICROSECONDS_DEFAULT,
529 : : &dm);
530 [ # # ]: 0 : if (ret != EOK) {
531 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Error reading from confdb (%d) "
[ # # ][ # # ]
[ # # ]
532 : : "[%s]\n", ret, strerror(ret)));
533 : : return ret;
534 : : }
535 [ # # ]: 0 : if (dm) debug_microseconds = 1;
536 : 0 : else debug_microseconds = 0;
537 : : }
538 : :
539 : : /* same for debug to file */
540 : 0 : dl = (debug_to_file != 0);
541 : 0 : ret = confdb_get_bool(ctx->confdb_ctx, conf_entry,
542 : : CONFDB_SERVICE_DEBUG_TO_FILES,
543 : : dl, &dl);
544 [ # # ]: 0 : if (ret != EOK) {
545 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Error reading from confdb (%d) [%s]\n",
[ # # ][ # # ]
[ # # ]
546 : : ret, strerror(ret)));
547 : : return ret;
548 : : }
549 [ # # ]: 0 : if (dl) debug_to_file = 1;
550 : :
551 : : /* before opening the log file set up log rotation */
552 : 0 : lctx = talloc_zero(ctx, struct logrotate_ctx);
553 [ # # ]: 0 : if (!lctx) return ENOMEM;
554 : :
555 : 0 : lctx->confdb = ctx->confdb_ctx;
556 : 0 : lctx->confdb_path = conf_entry;
557 : :
558 : 0 : tes = tevent_add_signal(ctx->event_ctx, ctx, SIGHUP, 0,
559 : : te_server_hup, lctx);
560 [ # # ]: 0 : if (tes == NULL) {
561 : : return EIO;
562 : : }
563 : :
564 : : /* open log file if told so */
565 [ # # ]: 0 : if (debug_to_file) {
566 : 0 : ret = open_debug_file();
567 [ # # ]: 0 : if (ret != EOK) {
568 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, ("Error setting up logging (%d) "
[ # # ][ # # ]
[ # # ]
569 : : "[%s]\n", ret, strerror(ret)));
570 : : return ret;
571 : : }
572 : : }
573 : :
574 : 0 : sss_log(SSS_LOG_INFO, "Starting up");
575 : :
576 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_TRACE_FUNC, ("CONFDB: %s\n", conf_db));
[ # # ][ # # ]
[ # # ]
577 : :
578 [ # # ]: 0 : if (flags & FLAGS_INTERACTIVE) {
579 : : /* terminate when stdin goes away */
580 : : stdin_event_flags = TEVENT_FD_READ;
581 : : } else {
582 : : /* stay alive forever */
583 : 0 : stdin_event_flags = 0;
584 : : }
585 : :
586 : : /* catch EOF on stdin */
587 : : #ifdef SIGTTIN
588 : 0 : signal(SIGTTIN, SIG_IGN);
589 : : #endif
590 : 0 : tevent_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
591 : : server_stdin_handler, discard_const(name));
592 : :
593 : 0 : *main_ctx = ctx;
594 : : return EOK;
595 : : }
596 : :
597 : 0 : void server_loop(struct main_context *main_ctx)
598 : : {
599 : : /* wait for events - this is where the server sits for most of its
600 : : life */
601 : 0 : tevent_loop_wait(main_ctx->event_ctx);
602 : :
603 : : /* as everything hangs off this event context, freeing it
604 : : should initiate a clean shutdown of all services */
605 : 0 : talloc_free(main_ctx->event_ctx);
606 : 0 : }
|