]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/execute.c
Merge pull request #1582 from evverx/dump-runtime-dir-mode
[thirdparty/systemd.git] / src / core / execute.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <glob.h>
25 #include <grp.h>
26 #include <poll.h>
27 #include <signal.h>
28 #include <string.h>
29 #include <sys/personality.h>
30 #include <sys/prctl.h>
31 #include <sys/socket.h>
32 #include <sys/stat.h>
33 #include <sys/un.h>
34 #include <unistd.h>
35 #include <utmpx.h>
36
37 #ifdef HAVE_PAM
38 #include <security/pam_appl.h>
39 #endif
40
41 #ifdef HAVE_SELINUX
42 #include <selinux/selinux.h>
43 #endif
44
45 #ifdef HAVE_SECCOMP
46 #include <seccomp.h>
47 #endif
48
49 #ifdef HAVE_APPARMOR
50 #include <sys/apparmor.h>
51 #endif
52
53 #include "sd-messages.h"
54
55 #include "af-list.h"
56 #include "async.h"
57 #include "barrier.h"
58 #include "bus-endpoint.h"
59 #include "cap-list.h"
60 #include "capability.h"
61 #include "def.h"
62 #include "env-util.h"
63 #include "errno-list.h"
64 #include "exit-status.h"
65 #include "fileio.h"
66 #include "formats-util.h"
67 #include "ioprio.h"
68 #include "log.h"
69 #include "macro.h"
70 #include "missing.h"
71 #include "mkdir.h"
72 #include "namespace.h"
73 #include "path-util.h"
74 #include "process-util.h"
75 #include "rm-rf.h"
76 #include "securebits.h"
77 #include "selinux-util.h"
78 #include "signal-util.h"
79 #include "smack-util.h"
80 #include "strv.h"
81 #include "terminal-util.h"
82 #include "unit.h"
83 #include "util.h"
84 #include "utmp-wtmp.h"
85
86 #ifdef HAVE_APPARMOR
87 #include "apparmor-util.h"
88 #endif
89
90 #ifdef HAVE_SECCOMP
91 #include "seccomp-util.h"
92 #endif
93
94 #include "execute.h"
95
96 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
97 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
98
99 /* This assumes there is a 'tty' group */
100 #define TTY_MODE 0620
101
102 #define SNDBUF_SIZE (8*1024*1024)
103
104 static int shift_fds(int fds[], unsigned n_fds) {
105 int start, restart_from;
106
107 if (n_fds <= 0)
108 return 0;
109
110 /* Modifies the fds array! (sorts it) */
111
112 assert(fds);
113
114 start = 0;
115 for (;;) {
116 int i;
117
118 restart_from = -1;
119
120 for (i = start; i < (int) n_fds; i++) {
121 int nfd;
122
123 /* Already at right index? */
124 if (fds[i] == i+3)
125 continue;
126
127 nfd = fcntl(fds[i], F_DUPFD, i + 3);
128 if (nfd < 0)
129 return -errno;
130
131 safe_close(fds[i]);
132 fds[i] = nfd;
133
134 /* Hmm, the fd we wanted isn't free? Then
135 * let's remember that and try again from here */
136 if (nfd != i+3 && restart_from < 0)
137 restart_from = i;
138 }
139
140 if (restart_from < 0)
141 break;
142
143 start = restart_from;
144 }
145
146 return 0;
147 }
148
149 static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
150 unsigned i;
151 int r;
152
153 if (n_fds <= 0)
154 return 0;
155
156 assert(fds);
157
158 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
159
160 for (i = 0; i < n_fds; i++) {
161
162 r = fd_nonblock(fds[i], nonblock);
163 if (r < 0)
164 return r;
165
166 /* We unconditionally drop FD_CLOEXEC from the fds,
167 * since after all we want to pass these fds to our
168 * children */
169
170 r = fd_cloexec(fds[i], false);
171 if (r < 0)
172 return r;
173 }
174
175 return 0;
176 }
177
178 _pure_ static const char *tty_path(const ExecContext *context) {
179 assert(context);
180
181 if (context->tty_path)
182 return context->tty_path;
183
184 return "/dev/console";
185 }
186
187 static void exec_context_tty_reset(const ExecContext *context) {
188 assert(context);
189
190 if (context->tty_vhangup)
191 terminal_vhangup(tty_path(context));
192
193 if (context->tty_reset)
194 reset_terminal(tty_path(context));
195
196 if (context->tty_vt_disallocate && context->tty_path)
197 vt_disallocate(context->tty_path);
198 }
199
200 static bool is_terminal_output(ExecOutput o) {
201 return
202 o == EXEC_OUTPUT_TTY ||
203 o == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
204 o == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
205 o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE;
206 }
207
208 static int open_null_as(int flags, int nfd) {
209 int fd, r;
210
211 assert(nfd >= 0);
212
213 fd = open("/dev/null", flags|O_NOCTTY);
214 if (fd < 0)
215 return -errno;
216
217 if (fd != nfd) {
218 r = dup2(fd, nfd) < 0 ? -errno : nfd;
219 safe_close(fd);
220 } else
221 r = nfd;
222
223 return r;
224 }
225
226 static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
227 union sockaddr_union sa = {
228 .un.sun_family = AF_UNIX,
229 .un.sun_path = "/run/systemd/journal/stdout",
230 };
231 uid_t olduid = UID_INVALID;
232 gid_t oldgid = GID_INVALID;
233 int r;
234
235 if (gid != GID_INVALID) {
236 oldgid = getgid();
237
238 r = setegid(gid);
239 if (r < 0)
240 return -errno;
241 }
242
243 if (uid != UID_INVALID) {
244 olduid = getuid();
245
246 r = seteuid(uid);
247 if (r < 0) {
248 r = -errno;
249 goto restore_gid;
250 }
251 }
252
253 r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
254 if (r < 0)
255 r = -errno;
256
257 /* If we fail to restore the uid or gid, things will likely
258 fail later on. This should only happen if an LSM interferes. */
259
260 if (uid != UID_INVALID)
261 (void) seteuid(olduid);
262
263 restore_gid:
264 if (gid != GID_INVALID)
265 (void) setegid(oldgid);
266
267 return r;
268 }
269
270 static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd, uid_t uid, gid_t gid) {
271 int fd, r;
272
273 assert(context);
274 assert(output < _EXEC_OUTPUT_MAX);
275 assert(ident);
276 assert(nfd >= 0);
277
278 fd = socket(AF_UNIX, SOCK_STREAM, 0);
279 if (fd < 0)
280 return -errno;
281
282 r = connect_journal_socket(fd, uid, gid);
283 if (r < 0)
284 return r;
285
286 if (shutdown(fd, SHUT_RD) < 0) {
287 safe_close(fd);
288 return -errno;
289 }
290
291 fd_inc_sndbuf(fd, SNDBUF_SIZE);
292
293 dprintf(fd,
294 "%s\n"
295 "%s\n"
296 "%i\n"
297 "%i\n"
298 "%i\n"
299 "%i\n"
300 "%i\n",
301 context->syslog_identifier ? context->syslog_identifier : ident,
302 unit_id,
303 context->syslog_priority,
304 !!context->syslog_level_prefix,
305 output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
306 output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE,
307 is_terminal_output(output));
308
309 if (fd != nfd) {
310 r = dup2(fd, nfd) < 0 ? -errno : nfd;
311 safe_close(fd);
312 } else
313 r = nfd;
314
315 return r;
316 }
317 static int open_terminal_as(const char *path, mode_t mode, int nfd) {
318 int fd, r;
319
320 assert(path);
321 assert(nfd >= 0);
322
323 fd = open_terminal(path, mode | O_NOCTTY);
324 if (fd < 0)
325 return fd;
326
327 if (fd != nfd) {
328 r = dup2(fd, nfd) < 0 ? -errno : nfd;
329 safe_close(fd);
330 } else
331 r = nfd;
332
333 return r;
334 }
335
336 static bool is_terminal_input(ExecInput i) {
337 return
338 i == EXEC_INPUT_TTY ||
339 i == EXEC_INPUT_TTY_FORCE ||
340 i == EXEC_INPUT_TTY_FAIL;
341 }
342
343 static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
344
345 if (is_terminal_input(std_input) && !apply_tty_stdin)
346 return EXEC_INPUT_NULL;
347
348 if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
349 return EXEC_INPUT_NULL;
350
351 return std_input;
352 }
353
354 static int fixup_output(ExecOutput std_output, int socket_fd) {
355
356 if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0)
357 return EXEC_OUTPUT_INHERIT;
358
359 return std_output;
360 }
361
362 static int setup_input(
363 const ExecContext *context,
364 const ExecParameters *params,
365 int socket_fd) {
366
367 ExecInput i;
368
369 assert(context);
370 assert(params);
371
372 if (params->stdin_fd >= 0) {
373 if (dup2(params->stdin_fd, STDIN_FILENO) < 0)
374 return -errno;
375
376 /* Try to make this the controlling tty, if it is a tty, and reset it */
377 (void) ioctl(STDIN_FILENO, TIOCSCTTY, context->std_input == EXEC_INPUT_TTY_FORCE);
378 (void) reset_terminal_fd(STDIN_FILENO, true);
379
380 return STDIN_FILENO;
381 }
382
383 i = fixup_input(context->std_input, socket_fd, params->apply_tty_stdin);
384
385 switch (i) {
386
387 case EXEC_INPUT_NULL:
388 return open_null_as(O_RDONLY, STDIN_FILENO);
389
390 case EXEC_INPUT_TTY:
391 case EXEC_INPUT_TTY_FORCE:
392 case EXEC_INPUT_TTY_FAIL: {
393 int fd, r;
394
395 fd = acquire_terminal(tty_path(context),
396 i == EXEC_INPUT_TTY_FAIL,
397 i == EXEC_INPUT_TTY_FORCE,
398 false,
399 USEC_INFINITY);
400 if (fd < 0)
401 return fd;
402
403 if (fd != STDIN_FILENO) {
404 r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
405 safe_close(fd);
406 } else
407 r = STDIN_FILENO;
408
409 return r;
410 }
411
412 case EXEC_INPUT_SOCKET:
413 return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
414
415 default:
416 assert_not_reached("Unknown input type");
417 }
418 }
419
420 static int setup_output(
421 Unit *unit,
422 const ExecContext *context,
423 const ExecParameters *params,
424 int fileno,
425 int socket_fd,
426 const char *ident,
427 uid_t uid, gid_t gid) {
428
429 ExecOutput o;
430 ExecInput i;
431 int r;
432
433 assert(unit);
434 assert(context);
435 assert(params);
436 assert(ident);
437
438 if (fileno == STDOUT_FILENO && params->stdout_fd >= 0) {
439
440 if (dup2(params->stdout_fd, STDOUT_FILENO) < 0)
441 return -errno;
442
443 return STDOUT_FILENO;
444 }
445
446 if (fileno == STDERR_FILENO && params->stderr_fd >= 0) {
447 if (dup2(params->stderr_fd, STDERR_FILENO) < 0)
448 return -errno;
449
450 return STDERR_FILENO;
451 }
452
453 i = fixup_input(context->std_input, socket_fd, params->apply_tty_stdin);
454 o = fixup_output(context->std_output, socket_fd);
455
456 if (fileno == STDERR_FILENO) {
457 ExecOutput e;
458 e = fixup_output(context->std_error, socket_fd);
459
460 /* This expects the input and output are already set up */
461
462 /* Don't change the stderr file descriptor if we inherit all
463 * the way and are not on a tty */
464 if (e == EXEC_OUTPUT_INHERIT &&
465 o == EXEC_OUTPUT_INHERIT &&
466 i == EXEC_INPUT_NULL &&
467 !is_terminal_input(context->std_input) &&
468 getppid () != 1)
469 return fileno;
470
471 /* Duplicate from stdout if possible */
472 if (e == o || e == EXEC_OUTPUT_INHERIT)
473 return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno;
474
475 o = e;
476
477 } else if (o == EXEC_OUTPUT_INHERIT) {
478 /* If input got downgraded, inherit the original value */
479 if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
480 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
481
482 /* If the input is connected to anything that's not a /dev/null, inherit that... */
483 if (i != EXEC_INPUT_NULL)
484 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
485
486 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
487 if (getppid() != 1)
488 return fileno;
489
490 /* We need to open /dev/null here anew, to get the right access mode. */
491 return open_null_as(O_WRONLY, fileno);
492 }
493
494 switch (o) {
495
496 case EXEC_OUTPUT_NULL:
497 return open_null_as(O_WRONLY, fileno);
498
499 case EXEC_OUTPUT_TTY:
500 if (is_terminal_input(i))
501 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
502
503 /* We don't reset the terminal if this is just about output */
504 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
505
506 case EXEC_OUTPUT_SYSLOG:
507 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
508 case EXEC_OUTPUT_KMSG:
509 case EXEC_OUTPUT_KMSG_AND_CONSOLE:
510 case EXEC_OUTPUT_JOURNAL:
511 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
512 r = connect_logger_as(context, o, ident, unit->id, fileno, uid, gid);
513 if (r < 0) {
514 log_unit_error_errno(unit, r, "Failed to connect %s to the journal socket, ignoring: %m", fileno == STDOUT_FILENO ? "stdout" : "stderr");
515 r = open_null_as(O_WRONLY, fileno);
516 }
517 return r;
518
519 case EXEC_OUTPUT_SOCKET:
520 assert(socket_fd >= 0);
521 return dup2(socket_fd, fileno) < 0 ? -errno : fileno;
522
523 default:
524 assert_not_reached("Unknown error type");
525 }
526 }
527
528 static int chown_terminal(int fd, uid_t uid) {
529 struct stat st;
530
531 assert(fd >= 0);
532
533 /* This might fail. What matters are the results. */
534 (void) fchown(fd, uid, -1);
535 (void) fchmod(fd, TTY_MODE);
536
537 if (fstat(fd, &st) < 0)
538 return -errno;
539
540 if (st.st_uid != uid || (st.st_mode & 0777) != TTY_MODE)
541 return -EPERM;
542
543 return 0;
544 }
545
546 static int setup_confirm_stdio(int *_saved_stdin, int *_saved_stdout) {
547 _cleanup_close_ int fd = -1, saved_stdin = -1, saved_stdout = -1;
548 int r;
549
550 assert(_saved_stdin);
551 assert(_saved_stdout);
552
553 saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3);
554 if (saved_stdin < 0)
555 return -errno;
556
557 saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3);
558 if (saved_stdout < 0)
559 return -errno;
560
561 fd = acquire_terminal(
562 "/dev/console",
563 false,
564 false,
565 false,
566 DEFAULT_CONFIRM_USEC);
567 if (fd < 0)
568 return fd;
569
570 r = chown_terminal(fd, getuid());
571 if (r < 0)
572 return r;
573
574 r = reset_terminal_fd(fd, true);
575 if (r < 0)
576 return r;
577
578 if (dup2(fd, STDIN_FILENO) < 0)
579 return -errno;
580
581 if (dup2(fd, STDOUT_FILENO) < 0)
582 return -errno;
583
584 if (fd >= 2)
585 safe_close(fd);
586 fd = -1;
587
588 *_saved_stdin = saved_stdin;
589 *_saved_stdout = saved_stdout;
590
591 saved_stdin = saved_stdout = -1;
592
593 return 0;
594 }
595
596 _printf_(1, 2) static int write_confirm_message(const char *format, ...) {
597 _cleanup_close_ int fd = -1;
598 va_list ap;
599
600 assert(format);
601
602 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
603 if (fd < 0)
604 return fd;
605
606 va_start(ap, format);
607 vdprintf(fd, format, ap);
608 va_end(ap);
609
610 return 0;
611 }
612
613 static int restore_confirm_stdio(int *saved_stdin, int *saved_stdout) {
614 int r = 0;
615
616 assert(saved_stdin);
617 assert(saved_stdout);
618
619 release_terminal();
620
621 if (*saved_stdin >= 0)
622 if (dup2(*saved_stdin, STDIN_FILENO) < 0)
623 r = -errno;
624
625 if (*saved_stdout >= 0)
626 if (dup2(*saved_stdout, STDOUT_FILENO) < 0)
627 r = -errno;
628
629 *saved_stdin = safe_close(*saved_stdin);
630 *saved_stdout = safe_close(*saved_stdout);
631
632 return r;
633 }
634
635 static int ask_for_confirmation(char *response, char **argv) {
636 int saved_stdout = -1, saved_stdin = -1, r;
637 _cleanup_free_ char *line = NULL;
638
639 r = setup_confirm_stdio(&saved_stdin, &saved_stdout);
640 if (r < 0)
641 return r;
642
643 line = exec_command_line(argv);
644 if (!line)
645 return -ENOMEM;
646
647 r = ask_char(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
648
649 restore_confirm_stdio(&saved_stdin, &saved_stdout);
650
651 return r;
652 }
653
654 static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) {
655 bool keep_groups = false;
656 int r;
657
658 assert(context);
659
660 /* Lookup and set GID and supplementary group list. Here too
661 * we avoid NSS lookups for gid=0. */
662
663 if (context->group || username) {
664 /* First step, initialize groups from /etc/groups */
665 if (username && gid != 0) {
666 if (initgroups(username, gid) < 0)
667 return -errno;
668
669 keep_groups = true;
670 }
671
672 /* Second step, set our gids */
673 if (setresgid(gid, gid, gid) < 0)
674 return -errno;
675 }
676
677 if (context->supplementary_groups) {
678 int ngroups_max, k;
679 gid_t *gids;
680 char **i;
681
682 /* Final step, initialize any manually set supplementary groups */
683 assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0);
684
685 if (!(gids = new(gid_t, ngroups_max)))
686 return -ENOMEM;
687
688 if (keep_groups) {
689 k = getgroups(ngroups_max, gids);
690 if (k < 0) {
691 free(gids);
692 return -errno;
693 }
694 } else
695 k = 0;
696
697 STRV_FOREACH(i, context->supplementary_groups) {
698 const char *g;
699
700 if (k >= ngroups_max) {
701 free(gids);
702 return -E2BIG;
703 }
704
705 g = *i;
706 r = get_group_creds(&g, gids+k);
707 if (r < 0) {
708 free(gids);
709 return r;
710 }
711
712 k++;
713 }
714
715 if (setgroups(k, gids) < 0) {
716 free(gids);
717 return -errno;
718 }
719
720 free(gids);
721 }
722
723 return 0;
724 }
725
726 static int enforce_user(const ExecContext *context, uid_t uid) {
727 assert(context);
728
729 /* Sets (but doesn't lookup) the uid and make sure we keep the
730 * capabilities while doing so. */
731
732 if (context->capabilities) {
733 _cleanup_cap_free_ cap_t d = NULL;
734 static const cap_value_t bits[] = {
735 CAP_SETUID, /* Necessary so that we can run setresuid() below */
736 CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */
737 };
738
739 /* First step: If we need to keep capabilities but
740 * drop privileges we need to make sure we keep our
741 * caps, while we drop privileges. */
742 if (uid != 0) {
743 int sb = context->secure_bits | 1<<SECURE_KEEP_CAPS;
744
745 if (prctl(PR_GET_SECUREBITS) != sb)
746 if (prctl(PR_SET_SECUREBITS, sb) < 0)
747 return -errno;
748 }
749
750 /* Second step: set the capabilities. This will reduce
751 * the capabilities to the minimum we need. */
752
753 d = cap_dup(context->capabilities);
754 if (!d)
755 return -errno;
756
757 if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 ||
758 cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0)
759 return -errno;
760
761 if (cap_set_proc(d) < 0)
762 return -errno;
763 }
764
765 /* Third step: actually set the uids */
766 if (setresuid(uid, uid, uid) < 0)
767 return -errno;
768
769 /* At this point we should have all necessary capabilities but
770 are otherwise a normal user. However, the caps might got
771 corrupted due to the setresuid() so we need clean them up
772 later. This is done outside of this call. */
773
774 return 0;
775 }
776
777 #ifdef HAVE_PAM
778
779 static int null_conv(
780 int num_msg,
781 const struct pam_message **msg,
782 struct pam_response **resp,
783 void *appdata_ptr) {
784
785 /* We don't support conversations */
786
787 return PAM_CONV_ERR;
788 }
789
790 static int setup_pam(
791 const char *name,
792 const char *user,
793 uid_t uid,
794 const char *tty,
795 char ***pam_env,
796 int fds[], unsigned n_fds) {
797
798 static const struct pam_conv conv = {
799 .conv = null_conv,
800 .appdata_ptr = NULL
801 };
802
803 _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
804 pam_handle_t *handle = NULL;
805 sigset_t old_ss;
806 int pam_code = PAM_SUCCESS;
807 int err = 0;
808 char **e = NULL;
809 bool close_session = false;
810 pid_t pam_pid = 0, parent_pid;
811 int flags = 0;
812
813 assert(name);
814 assert(user);
815 assert(pam_env);
816
817 /* We set up PAM in the parent process, then fork. The child
818 * will then stay around until killed via PR_GET_PDEATHSIG or
819 * systemd via the cgroup logic. It will then remove the PAM
820 * session again. The parent process will exec() the actual
821 * daemon. We do things this way to ensure that the main PID
822 * of the daemon is the one we initially fork()ed. */
823
824 err = barrier_create(&barrier);
825 if (err < 0)
826 goto fail;
827
828 if (log_get_max_level() < LOG_DEBUG)
829 flags |= PAM_SILENT;
830
831 pam_code = pam_start(name, user, &conv, &handle);
832 if (pam_code != PAM_SUCCESS) {
833 handle = NULL;
834 goto fail;
835 }
836
837 if (tty) {
838 pam_code = pam_set_item(handle, PAM_TTY, tty);
839 if (pam_code != PAM_SUCCESS)
840 goto fail;
841 }
842
843 pam_code = pam_acct_mgmt(handle, flags);
844 if (pam_code != PAM_SUCCESS)
845 goto fail;
846
847 pam_code = pam_open_session(handle, flags);
848 if (pam_code != PAM_SUCCESS)
849 goto fail;
850
851 close_session = true;
852
853 e = pam_getenvlist(handle);
854 if (!e) {
855 pam_code = PAM_BUF_ERR;
856 goto fail;
857 }
858
859 /* Block SIGTERM, so that we know that it won't get lost in
860 * the child */
861
862 assert_se(sigprocmask_many(SIG_BLOCK, &old_ss, SIGTERM, -1) >= 0);
863
864 parent_pid = getpid();
865
866 pam_pid = fork();
867 if (pam_pid < 0)
868 goto fail;
869
870 if (pam_pid == 0) {
871 int sig;
872 int r = EXIT_PAM;
873
874 /* The child's job is to reset the PAM session on
875 * termination */
876 barrier_set_role(&barrier, BARRIER_CHILD);
877
878 /* This string must fit in 10 chars (i.e. the length
879 * of "/sbin/init"), to look pretty in /bin/ps */
880 rename_process("(sd-pam)");
881
882 /* Make sure we don't keep open the passed fds in this
883 child. We assume that otherwise only those fds are
884 open here that have been opened by PAM. */
885 close_many(fds, n_fds);
886
887 /* Drop privileges - we don't need any to pam_close_session
888 * and this will make PR_SET_PDEATHSIG work in most cases.
889 * If this fails, ignore the error - but expect sd-pam threads
890 * to fail to exit normally */
891 if (setresuid(uid, uid, uid) < 0)
892 log_error_errno(r, "Error: Failed to setresuid() in sd-pam: %m");
893
894 (void) ignore_signals(SIGPIPE, -1);
895
896 /* Wait until our parent died. This will only work if
897 * the above setresuid() succeeds, otherwise the kernel
898 * will not allow unprivileged parents kill their privileged
899 * children this way. We rely on the control groups kill logic
900 * to do the rest for us. */
901 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
902 goto child_finish;
903
904 /* Tell the parent that our setup is done. This is especially
905 * important regarding dropping privileges. Otherwise, unit
906 * setup might race against our setresuid(2) call. */
907 barrier_place(&barrier);
908
909 /* Check if our parent process might already have
910 * died? */
911 if (getppid() == parent_pid) {
912 sigset_t ss;
913
914 assert_se(sigemptyset(&ss) >= 0);
915 assert_se(sigaddset(&ss, SIGTERM) >= 0);
916
917 for (;;) {
918 if (sigwait(&ss, &sig) < 0) {
919 if (errno == EINTR)
920 continue;
921
922 goto child_finish;
923 }
924
925 assert(sig == SIGTERM);
926 break;
927 }
928 }
929
930 /* If our parent died we'll end the session */
931 if (getppid() != parent_pid) {
932 pam_code = pam_close_session(handle, flags);
933 if (pam_code != PAM_SUCCESS)
934 goto child_finish;
935 }
936
937 r = 0;
938
939 child_finish:
940 pam_end(handle, pam_code | flags);
941 _exit(r);
942 }
943
944 barrier_set_role(&barrier, BARRIER_PARENT);
945
946 /* If the child was forked off successfully it will do all the
947 * cleanups, so forget about the handle here. */
948 handle = NULL;
949
950 /* Unblock SIGTERM again in the parent */
951 assert_se(sigprocmask(SIG_SETMASK, &old_ss, NULL) >= 0);
952
953 /* We close the log explicitly here, since the PAM modules
954 * might have opened it, but we don't want this fd around. */
955 closelog();
956
957 /* Synchronously wait for the child to initialize. We don't care for
958 * errors as we cannot recover. However, warn loudly if it happens. */
959 if (!barrier_place_and_sync(&barrier))
960 log_error("PAM initialization failed");
961
962 *pam_env = e;
963 e = NULL;
964
965 return 0;
966
967 fail:
968 if (pam_code != PAM_SUCCESS) {
969 log_error("PAM failed: %s", pam_strerror(handle, pam_code));
970 err = -EPERM; /* PAM errors do not map to errno */
971 } else {
972 err = log_error_errno(err < 0 ? err : errno, "PAM failed: %m");
973 }
974
975 if (handle) {
976 if (close_session)
977 pam_code = pam_close_session(handle, flags);
978
979 pam_end(handle, pam_code | flags);
980 }
981
982 strv_free(e);
983
984 closelog();
985
986 if (pam_pid > 1) {
987 kill(pam_pid, SIGTERM);
988 kill(pam_pid, SIGCONT);
989 }
990
991 return err;
992 }
993 #endif
994
995 static void rename_process_from_path(const char *path) {
996 char process_name[11];
997 const char *p;
998 size_t l;
999
1000 /* This resulting string must fit in 10 chars (i.e. the length
1001 * of "/sbin/init") to look pretty in /bin/ps */
1002
1003 p = basename(path);
1004 if (isempty(p)) {
1005 rename_process("(...)");
1006 return;
1007 }
1008
1009 l = strlen(p);
1010 if (l > 8) {
1011 /* The end of the process name is usually more
1012 * interesting, since the first bit might just be
1013 * "systemd-" */
1014 p = p + l - 8;
1015 l = 8;
1016 }
1017
1018 process_name[0] = '(';
1019 memcpy(process_name+1, p, l);
1020 process_name[1+l] = ')';
1021 process_name[1+l+1] = 0;
1022
1023 rename_process(process_name);
1024 }
1025
1026 #ifdef HAVE_SECCOMP
1027
1028 static int apply_seccomp(const ExecContext *c) {
1029 uint32_t negative_action, action;
1030 scmp_filter_ctx *seccomp;
1031 Iterator i;
1032 void *id;
1033 int r;
1034
1035 assert(c);
1036
1037 negative_action = c->syscall_errno == 0 ? SCMP_ACT_KILL : SCMP_ACT_ERRNO(c->syscall_errno);
1038
1039 seccomp = seccomp_init(c->syscall_whitelist ? negative_action : SCMP_ACT_ALLOW);
1040 if (!seccomp)
1041 return -ENOMEM;
1042
1043 if (c->syscall_archs) {
1044
1045 SET_FOREACH(id, c->syscall_archs, i) {
1046 r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
1047 if (r == -EEXIST)
1048 continue;
1049 if (r < 0)
1050 goto finish;
1051 }
1052
1053 } else {
1054 r = seccomp_add_secondary_archs(seccomp);
1055 if (r < 0)
1056 goto finish;
1057 }
1058
1059 action = c->syscall_whitelist ? SCMP_ACT_ALLOW : negative_action;
1060 SET_FOREACH(id, c->syscall_filter, i) {
1061 r = seccomp_rule_add(seccomp, action, PTR_TO_INT(id) - 1, 0);
1062 if (r < 0)
1063 goto finish;
1064 }
1065
1066 r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
1067 if (r < 0)
1068 goto finish;
1069
1070 r = seccomp_load(seccomp);
1071
1072 finish:
1073 seccomp_release(seccomp);
1074 return r;
1075 }
1076
1077 static int apply_address_families(const ExecContext *c) {
1078 scmp_filter_ctx *seccomp;
1079 Iterator i;
1080 int r;
1081
1082 assert(c);
1083
1084 seccomp = seccomp_init(SCMP_ACT_ALLOW);
1085 if (!seccomp)
1086 return -ENOMEM;
1087
1088 r = seccomp_add_secondary_archs(seccomp);
1089 if (r < 0)
1090 goto finish;
1091
1092 if (c->address_families_whitelist) {
1093 int af, first = 0, last = 0;
1094 void *afp;
1095
1096 /* If this is a whitelist, we first block the address
1097 * families that are out of range and then everything
1098 * that is not in the set. First, we find the lowest
1099 * and highest address family in the set. */
1100
1101 SET_FOREACH(afp, c->address_families, i) {
1102 af = PTR_TO_INT(afp);
1103
1104 if (af <= 0 || af >= af_max())
1105 continue;
1106
1107 if (first == 0 || af < first)
1108 first = af;
1109
1110 if (last == 0 || af > last)
1111 last = af;
1112 }
1113
1114 assert((first == 0) == (last == 0));
1115
1116 if (first == 0) {
1117
1118 /* No entries in the valid range, block everything */
1119 r = seccomp_rule_add(
1120 seccomp,
1121 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1122 SCMP_SYS(socket),
1123 0);
1124 if (r < 0)
1125 goto finish;
1126
1127 } else {
1128
1129 /* Block everything below the first entry */
1130 r = seccomp_rule_add(
1131 seccomp,
1132 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1133 SCMP_SYS(socket),
1134 1,
1135 SCMP_A0(SCMP_CMP_LT, first));
1136 if (r < 0)
1137 goto finish;
1138
1139 /* Block everything above the last entry */
1140 r = seccomp_rule_add(
1141 seccomp,
1142 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1143 SCMP_SYS(socket),
1144 1,
1145 SCMP_A0(SCMP_CMP_GT, last));
1146 if (r < 0)
1147 goto finish;
1148
1149 /* Block everything between the first and last
1150 * entry */
1151 for (af = 1; af < af_max(); af++) {
1152
1153 if (set_contains(c->address_families, INT_TO_PTR(af)))
1154 continue;
1155
1156 r = seccomp_rule_add(
1157 seccomp,
1158 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1159 SCMP_SYS(socket),
1160 1,
1161 SCMP_A0(SCMP_CMP_EQ, af));
1162 if (r < 0)
1163 goto finish;
1164 }
1165 }
1166
1167 } else {
1168 void *af;
1169
1170 /* If this is a blacklist, then generate one rule for
1171 * each address family that are then combined in OR
1172 * checks. */
1173
1174 SET_FOREACH(af, c->address_families, i) {
1175
1176 r = seccomp_rule_add(
1177 seccomp,
1178 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1179 SCMP_SYS(socket),
1180 1,
1181 SCMP_A0(SCMP_CMP_EQ, PTR_TO_INT(af)));
1182 if (r < 0)
1183 goto finish;
1184 }
1185 }
1186
1187 r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
1188 if (r < 0)
1189 goto finish;
1190
1191 r = seccomp_load(seccomp);
1192
1193 finish:
1194 seccomp_release(seccomp);
1195 return r;
1196 }
1197
1198 #endif
1199
1200 static void do_idle_pipe_dance(int idle_pipe[4]) {
1201 assert(idle_pipe);
1202
1203
1204 idle_pipe[1] = safe_close(idle_pipe[1]);
1205 idle_pipe[2] = safe_close(idle_pipe[2]);
1206
1207 if (idle_pipe[0] >= 0) {
1208 int r;
1209
1210 r = fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
1211
1212 if (idle_pipe[3] >= 0 && r == 0 /* timeout */) {
1213 ssize_t n;
1214
1215 /* Signal systemd that we are bored and want to continue. */
1216 n = write(idle_pipe[3], "x", 1);
1217 if (n > 0)
1218 /* Wait for systemd to react to the signal above. */
1219 fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC);
1220 }
1221
1222 idle_pipe[0] = safe_close(idle_pipe[0]);
1223
1224 }
1225
1226 idle_pipe[3] = safe_close(idle_pipe[3]);
1227 }
1228
1229 static int build_environment(
1230 const ExecContext *c,
1231 unsigned n_fds,
1232 char ** fd_names,
1233 usec_t watchdog_usec,
1234 const char *home,
1235 const char *username,
1236 const char *shell,
1237 char ***ret) {
1238
1239 _cleanup_strv_free_ char **our_env = NULL;
1240 unsigned n_env = 0;
1241 char *x;
1242
1243 assert(c);
1244 assert(ret);
1245
1246 our_env = new0(char*, 11);
1247 if (!our_env)
1248 return -ENOMEM;
1249
1250 if (n_fds > 0) {
1251 _cleanup_free_ char *joined = NULL;
1252
1253 if (asprintf(&x, "LISTEN_PID="PID_FMT, getpid()) < 0)
1254 return -ENOMEM;
1255 our_env[n_env++] = x;
1256
1257 if (asprintf(&x, "LISTEN_FDS=%u", n_fds) < 0)
1258 return -ENOMEM;
1259 our_env[n_env++] = x;
1260
1261 joined = strv_join(fd_names, ":");
1262 if (!joined)
1263 return -ENOMEM;
1264
1265 x = strjoin("LISTEN_FDNAMES=", joined, NULL);
1266 if (!x)
1267 return -ENOMEM;
1268 our_env[n_env++] = x;
1269 }
1270
1271 if (watchdog_usec > 0) {
1272 if (asprintf(&x, "WATCHDOG_PID="PID_FMT, getpid()) < 0)
1273 return -ENOMEM;
1274 our_env[n_env++] = x;
1275
1276 if (asprintf(&x, "WATCHDOG_USEC="USEC_FMT, watchdog_usec) < 0)
1277 return -ENOMEM;
1278 our_env[n_env++] = x;
1279 }
1280
1281 if (home) {
1282 x = strappend("HOME=", home);
1283 if (!x)
1284 return -ENOMEM;
1285 our_env[n_env++] = x;
1286 }
1287
1288 if (username) {
1289 x = strappend("LOGNAME=", username);
1290 if (!x)
1291 return -ENOMEM;
1292 our_env[n_env++] = x;
1293
1294 x = strappend("USER=", username);
1295 if (!x)
1296 return -ENOMEM;
1297 our_env[n_env++] = x;
1298 }
1299
1300 if (shell) {
1301 x = strappend("SHELL=", shell);
1302 if (!x)
1303 return -ENOMEM;
1304 our_env[n_env++] = x;
1305 }
1306
1307 if (is_terminal_input(c->std_input) ||
1308 c->std_output == EXEC_OUTPUT_TTY ||
1309 c->std_error == EXEC_OUTPUT_TTY ||
1310 c->tty_path) {
1311
1312 x = strdup(default_term_for_tty(tty_path(c)));
1313 if (!x)
1314 return -ENOMEM;
1315 our_env[n_env++] = x;
1316 }
1317
1318 our_env[n_env++] = NULL;
1319 assert(n_env <= 11);
1320
1321 *ret = our_env;
1322 our_env = NULL;
1323
1324 return 0;
1325 }
1326
1327 static bool exec_needs_mount_namespace(
1328 const ExecContext *context,
1329 const ExecParameters *params,
1330 ExecRuntime *runtime) {
1331
1332 assert(context);
1333 assert(params);
1334
1335 if (!strv_isempty(context->read_write_dirs) ||
1336 !strv_isempty(context->read_only_dirs) ||
1337 !strv_isempty(context->inaccessible_dirs))
1338 return true;
1339
1340 if (context->mount_flags != 0)
1341 return true;
1342
1343 if (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir))
1344 return true;
1345
1346 if (params->bus_endpoint_path)
1347 return true;
1348
1349 if (context->private_devices ||
1350 context->protect_system != PROTECT_SYSTEM_NO ||
1351 context->protect_home != PROTECT_HOME_NO)
1352 return true;
1353
1354 return false;
1355 }
1356
1357 static int close_remaining_fds(
1358 const ExecParameters *params,
1359 ExecRuntime *runtime,
1360 int socket_fd,
1361 int *fds, unsigned n_fds) {
1362
1363 unsigned n_dont_close = 0;
1364 int dont_close[n_fds + 7];
1365
1366 assert(params);
1367
1368 if (params->stdin_fd >= 0)
1369 dont_close[n_dont_close++] = params->stdin_fd;
1370 if (params->stdout_fd >= 0)
1371 dont_close[n_dont_close++] = params->stdout_fd;
1372 if (params->stderr_fd >= 0)
1373 dont_close[n_dont_close++] = params->stderr_fd;
1374
1375 if (socket_fd >= 0)
1376 dont_close[n_dont_close++] = socket_fd;
1377 if (n_fds > 0) {
1378 memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds);
1379 n_dont_close += n_fds;
1380 }
1381
1382 if (params->bus_endpoint_fd >= 0)
1383 dont_close[n_dont_close++] = params->bus_endpoint_fd;
1384
1385 if (runtime) {
1386 if (runtime->netns_storage_socket[0] >= 0)
1387 dont_close[n_dont_close++] = runtime->netns_storage_socket[0];
1388 if (runtime->netns_storage_socket[1] >= 0)
1389 dont_close[n_dont_close++] = runtime->netns_storage_socket[1];
1390 }
1391
1392 return close_all_fds(dont_close, n_dont_close);
1393 }
1394
1395 static int exec_child(
1396 Unit *unit,
1397 ExecCommand *command,
1398 const ExecContext *context,
1399 const ExecParameters *params,
1400 ExecRuntime *runtime,
1401 char **argv,
1402 int socket_fd,
1403 int *fds, unsigned n_fds,
1404 char **files_env,
1405 int *exit_status) {
1406
1407 _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
1408 _cleanup_free_ char *mac_selinux_context_net = NULL;
1409 const char *username = NULL, *home = NULL, *shell = NULL, *wd;
1410 uid_t uid = UID_INVALID;
1411 gid_t gid = GID_INVALID;
1412 int i, r;
1413 bool needs_mount_namespace;
1414
1415 assert(unit);
1416 assert(command);
1417 assert(context);
1418 assert(params);
1419 assert(exit_status);
1420
1421 rename_process_from_path(command->path);
1422
1423 /* We reset exactly these signals, since they are the
1424 * only ones we set to SIG_IGN in the main daemon. All
1425 * others we leave untouched because we set them to
1426 * SIG_DFL or a valid handler initially, both of which
1427 * will be demoted to SIG_DFL. */
1428 (void) default_signals(SIGNALS_CRASH_HANDLER,
1429 SIGNALS_IGNORE, -1);
1430
1431 if (context->ignore_sigpipe)
1432 (void) ignore_signals(SIGPIPE, -1);
1433
1434 r = reset_signal_mask();
1435 if (r < 0) {
1436 *exit_status = EXIT_SIGNAL_MASK;
1437 return r;
1438 }
1439
1440 if (params->idle_pipe)
1441 do_idle_pipe_dance(params->idle_pipe);
1442
1443 /* Close sockets very early to make sure we don't
1444 * block init reexecution because it cannot bind its
1445 * sockets */
1446
1447 log_forget_fds();
1448
1449 r = close_remaining_fds(params, runtime, socket_fd, fds, n_fds);
1450 if (r < 0) {
1451 *exit_status = EXIT_FDS;
1452 return r;
1453 }
1454
1455 if (!context->same_pgrp)
1456 if (setsid() < 0) {
1457 *exit_status = EXIT_SETSID;
1458 return -errno;
1459 }
1460
1461 exec_context_tty_reset(context);
1462
1463 if (params->confirm_spawn) {
1464 char response;
1465
1466 r = ask_for_confirmation(&response, argv);
1467 if (r == -ETIMEDOUT)
1468 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1469 else if (r < 0)
1470 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r));
1471 else if (response == 's') {
1472 write_confirm_message("Skipping execution.\n");
1473 *exit_status = EXIT_CONFIRM;
1474 return -ECANCELED;
1475 } else if (response == 'n') {
1476 write_confirm_message("Failing execution.\n");
1477 *exit_status = 0;
1478 return 0;
1479 }
1480 }
1481
1482 if (context->user) {
1483 username = context->user;
1484 r = get_user_creds(&username, &uid, &gid, &home, &shell);
1485 if (r < 0) {
1486 *exit_status = EXIT_USER;
1487 return r;
1488 }
1489 }
1490
1491 if (context->group) {
1492 const char *g = context->group;
1493
1494 r = get_group_creds(&g, &gid);
1495 if (r < 0) {
1496 *exit_status = EXIT_GROUP;
1497 return r;
1498 }
1499 }
1500
1501
1502 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1503 * must sure to drop O_NONBLOCK */
1504 if (socket_fd >= 0)
1505 (void) fd_nonblock(socket_fd, false);
1506
1507 r = setup_input(context, params, socket_fd);
1508 if (r < 0) {
1509 *exit_status = EXIT_STDIN;
1510 return r;
1511 }
1512
1513 r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, basename(command->path), uid, gid);
1514 if (r < 0) {
1515 *exit_status = EXIT_STDOUT;
1516 return r;
1517 }
1518
1519 r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, basename(command->path), uid, gid);
1520 if (r < 0) {
1521 *exit_status = EXIT_STDERR;
1522 return r;
1523 }
1524
1525 if (params->cgroup_path) {
1526 r = cg_attach_everywhere(params->cgroup_supported, params->cgroup_path, 0, NULL, NULL);
1527 if (r < 0) {
1528 *exit_status = EXIT_CGROUP;
1529 return r;
1530 }
1531 }
1532
1533 if (context->oom_score_adjust_set) {
1534 char t[DECIMAL_STR_MAX(context->oom_score_adjust)];
1535
1536 /* When we can't make this change due to EPERM, then
1537 * let's silently skip over it. User namespaces
1538 * prohibit write access to this file, and we
1539 * shouldn't trip up over that. */
1540
1541 sprintf(t, "%i", context->oom_score_adjust);
1542 r = write_string_file("/proc/self/oom_score_adj", t, 0);
1543 if (r == -EPERM || r == -EACCES) {
1544 log_open();
1545 log_unit_debug_errno(unit, r, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1546 log_close();
1547 } else if (r < 0) {
1548 *exit_status = EXIT_OOM_ADJUST;
1549 return -errno;
1550 }
1551 }
1552
1553 if (context->nice_set)
1554 if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
1555 *exit_status = EXIT_NICE;
1556 return -errno;
1557 }
1558
1559 if (context->cpu_sched_set) {
1560 struct sched_param param = {
1561 .sched_priority = context->cpu_sched_priority,
1562 };
1563
1564 r = sched_setscheduler(0,
1565 context->cpu_sched_policy |
1566 (context->cpu_sched_reset_on_fork ?
1567 SCHED_RESET_ON_FORK : 0),
1568 &param);
1569 if (r < 0) {
1570 *exit_status = EXIT_SETSCHEDULER;
1571 return -errno;
1572 }
1573 }
1574
1575 if (context->cpuset)
1576 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
1577 *exit_status = EXIT_CPUAFFINITY;
1578 return -errno;
1579 }
1580
1581 if (context->ioprio_set)
1582 if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
1583 *exit_status = EXIT_IOPRIO;
1584 return -errno;
1585 }
1586
1587 if (context->timer_slack_nsec != NSEC_INFINITY)
1588 if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
1589 *exit_status = EXIT_TIMERSLACK;
1590 return -errno;
1591 }
1592
1593 if (context->personality != PERSONALITY_INVALID)
1594 if (personality(context->personality) < 0) {
1595 *exit_status = EXIT_PERSONALITY;
1596 return -errno;
1597 }
1598
1599 if (context->utmp_id)
1600 utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path,
1601 context->utmp_mode == EXEC_UTMP_INIT ? INIT_PROCESS :
1602 context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS :
1603 USER_PROCESS,
1604 username ? "root" : context->user);
1605
1606 if (context->user && is_terminal_input(context->std_input)) {
1607 r = chown_terminal(STDIN_FILENO, uid);
1608 if (r < 0) {
1609 *exit_status = EXIT_STDIN;
1610 return r;
1611 }
1612 }
1613
1614 if (params->bus_endpoint_fd >= 0 && context->bus_endpoint) {
1615 uid_t ep_uid = (uid == UID_INVALID) ? 0 : uid;
1616
1617 r = bus_kernel_set_endpoint_policy(params->bus_endpoint_fd, ep_uid, context->bus_endpoint);
1618 if (r < 0) {
1619 *exit_status = EXIT_BUS_ENDPOINT;
1620 return r;
1621 }
1622 }
1623
1624 /* If delegation is enabled we'll pass ownership of the cgroup
1625 * (but only in systemd's own controller hierarchy!) to the
1626 * user of the new process. */
1627 if (params->cgroup_path && context->user && params->cgroup_delegate) {
1628 r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0644, uid, gid);
1629 if (r < 0) {
1630 *exit_status = EXIT_CGROUP;
1631 return r;
1632 }
1633
1634
1635 r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0755, uid, gid);
1636 if (r < 0) {
1637 *exit_status = EXIT_CGROUP;
1638 return r;
1639 }
1640 }
1641
1642 if (!strv_isempty(context->runtime_directory) && params->runtime_prefix) {
1643 char **rt;
1644
1645 STRV_FOREACH(rt, context->runtime_directory) {
1646 _cleanup_free_ char *p;
1647
1648 p = strjoin(params->runtime_prefix, "/", *rt, NULL);
1649 if (!p) {
1650 *exit_status = EXIT_RUNTIME_DIRECTORY;
1651 return -ENOMEM;
1652 }
1653
1654 r = mkdir_p_label(p, context->runtime_directory_mode);
1655 if (r < 0) {
1656 *exit_status = EXIT_RUNTIME_DIRECTORY;
1657 return r;
1658 }
1659
1660 r = chmod_and_chown(p, context->runtime_directory_mode, uid, gid);
1661 if (r < 0) {
1662 *exit_status = EXIT_RUNTIME_DIRECTORY;
1663 return r;
1664 }
1665 }
1666 }
1667
1668 umask(context->umask);
1669
1670 if (params->apply_permissions) {
1671 r = enforce_groups(context, username, gid);
1672 if (r < 0) {
1673 *exit_status = EXIT_GROUP;
1674 return r;
1675 }
1676 #ifdef HAVE_SMACK
1677 if (context->smack_process_label) {
1678 r = mac_smack_apply_pid(0, context->smack_process_label);
1679 if (r < 0) {
1680 *exit_status = EXIT_SMACK_PROCESS_LABEL;
1681 return r;
1682 }
1683 }
1684 #ifdef SMACK_DEFAULT_PROCESS_LABEL
1685 else {
1686 _cleanup_free_ char *exec_label = NULL;
1687
1688 r = mac_smack_read(command->path, SMACK_ATTR_EXEC, &exec_label);
1689 if (r < 0 && r != -ENODATA && r != -EOPNOTSUPP) {
1690 *exit_status = EXIT_SMACK_PROCESS_LABEL;
1691 return r;
1692 }
1693
1694 r = mac_smack_apply_pid(0, exec_label ? : SMACK_DEFAULT_PROCESS_LABEL);
1695 if (r < 0) {
1696 *exit_status = EXIT_SMACK_PROCESS_LABEL;
1697 return r;
1698 }
1699 }
1700 #endif
1701 #endif
1702 #ifdef HAVE_PAM
1703 if (context->pam_name && username) {
1704 r = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
1705 if (r < 0) {
1706 *exit_status = EXIT_PAM;
1707 return r;
1708 }
1709 }
1710 #endif
1711 }
1712
1713 if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) {
1714 r = setup_netns(runtime->netns_storage_socket);
1715 if (r < 0) {
1716 *exit_status = EXIT_NETWORK;
1717 return r;
1718 }
1719 }
1720
1721 needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime);
1722
1723 if (needs_mount_namespace) {
1724 char *tmp = NULL, *var = NULL;
1725
1726 /* The runtime struct only contains the parent
1727 * of the private /tmp, which is
1728 * non-accessible to world users. Inside of it
1729 * there's a /tmp that is sticky, and that's
1730 * the one we want to use here. */
1731
1732 if (context->private_tmp && runtime) {
1733 if (runtime->tmp_dir)
1734 tmp = strjoina(runtime->tmp_dir, "/tmp");
1735 if (runtime->var_tmp_dir)
1736 var = strjoina(runtime->var_tmp_dir, "/tmp");
1737 }
1738
1739 r = setup_namespace(
1740 params->apply_chroot ? context->root_directory : NULL,
1741 context->read_write_dirs,
1742 context->read_only_dirs,
1743 context->inaccessible_dirs,
1744 tmp,
1745 var,
1746 params->bus_endpoint_path,
1747 context->private_devices,
1748 context->protect_home,
1749 context->protect_system,
1750 context->mount_flags);
1751
1752 /* If we couldn't set up the namespace this is
1753 * probably due to a missing capability. In this case,
1754 * silently proceeed. */
1755 if (r == -EPERM || r == -EACCES) {
1756 log_open();
1757 log_unit_debug_errno(unit, r, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1758 log_close();
1759 } else if (r < 0) {
1760 *exit_status = EXIT_NAMESPACE;
1761 return r;
1762 }
1763 }
1764
1765 if (context->working_directory_home)
1766 wd = home;
1767 else if (context->working_directory)
1768 wd = context->working_directory;
1769 else
1770 wd = "/";
1771
1772 if (params->apply_chroot) {
1773 if (!needs_mount_namespace && context->root_directory)
1774 if (chroot(context->root_directory) < 0) {
1775 *exit_status = EXIT_CHROOT;
1776 return -errno;
1777 }
1778
1779 if (chdir(wd) < 0 &&
1780 !context->working_directory_missing_ok) {
1781 *exit_status = EXIT_CHDIR;
1782 return -errno;
1783 }
1784 } else {
1785 const char *d;
1786
1787 d = strjoina(strempty(context->root_directory), "/", strempty(wd));
1788 if (chdir(d) < 0 &&
1789 !context->working_directory_missing_ok) {
1790 *exit_status = EXIT_CHDIR;
1791 return -errno;
1792 }
1793 }
1794
1795 #ifdef HAVE_SELINUX
1796 if (params->apply_permissions && mac_selinux_use() && params->selinux_context_net && socket_fd >= 0) {
1797 r = mac_selinux_get_child_mls_label(socket_fd, command->path, context->selinux_context, &mac_selinux_context_net);
1798 if (r < 0) {
1799 *exit_status = EXIT_SELINUX_CONTEXT;
1800 return r;
1801 }
1802 }
1803 #endif
1804
1805 /* We repeat the fd closing here, to make sure that
1806 * nothing is leaked from the PAM modules. Note that
1807 * we are more aggressive this time since socket_fd
1808 * and the netns fds we don't need anymore. The custom
1809 * endpoint fd was needed to upload the policy and can
1810 * now be closed as well. */
1811 r = close_all_fds(fds, n_fds);
1812 if (r >= 0)
1813 r = shift_fds(fds, n_fds);
1814 if (r >= 0)
1815 r = flags_fds(fds, n_fds, context->non_blocking);
1816 if (r < 0) {
1817 *exit_status = EXIT_FDS;
1818 return r;
1819 }
1820
1821 if (params->apply_permissions) {
1822
1823 for (i = 0; i < _RLIMIT_MAX; i++) {
1824 if (!context->rlimit[i])
1825 continue;
1826
1827 if (setrlimit_closest(i, context->rlimit[i]) < 0) {
1828 *exit_status = EXIT_LIMITS;
1829 return -errno;
1830 }
1831 }
1832
1833 if (context->capability_bounding_set_drop) {
1834 r = capability_bounding_set_drop(context->capability_bounding_set_drop, false);
1835 if (r < 0) {
1836 *exit_status = EXIT_CAPABILITIES;
1837 return r;
1838 }
1839 }
1840
1841 if (context->user) {
1842 r = enforce_user(context, uid);
1843 if (r < 0) {
1844 *exit_status = EXIT_USER;
1845 return r;
1846 }
1847 }
1848
1849 /* PR_GET_SECUREBITS is not privileged, while
1850 * PR_SET_SECUREBITS is. So to suppress
1851 * potential EPERMs we'll try not to call
1852 * PR_SET_SECUREBITS unless necessary. */
1853 if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
1854 if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
1855 *exit_status = EXIT_SECUREBITS;
1856 return -errno;
1857 }
1858
1859 if (context->capabilities)
1860 if (cap_set_proc(context->capabilities) < 0) {
1861 *exit_status = EXIT_CAPABILITIES;
1862 return -errno;
1863 }
1864
1865 if (context->no_new_privileges)
1866 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
1867 *exit_status = EXIT_NO_NEW_PRIVILEGES;
1868 return -errno;
1869 }
1870
1871 #ifdef HAVE_SECCOMP
1872 if (context->address_families_whitelist ||
1873 !set_isempty(context->address_families)) {
1874 r = apply_address_families(context);
1875 if (r < 0) {
1876 *exit_status = EXIT_ADDRESS_FAMILIES;
1877 return r;
1878 }
1879 }
1880
1881 if (context->syscall_whitelist ||
1882 !set_isempty(context->syscall_filter) ||
1883 !set_isempty(context->syscall_archs)) {
1884 r = apply_seccomp(context);
1885 if (r < 0) {
1886 *exit_status = EXIT_SECCOMP;
1887 return r;
1888 }
1889 }
1890 #endif
1891
1892 #ifdef HAVE_SELINUX
1893 if (mac_selinux_use()) {
1894 char *exec_context = mac_selinux_context_net ?: context->selinux_context;
1895
1896 if (exec_context) {
1897 r = setexeccon(exec_context);
1898 if (r < 0) {
1899 *exit_status = EXIT_SELINUX_CONTEXT;
1900 return r;
1901 }
1902 }
1903 }
1904 #endif
1905
1906 #ifdef HAVE_APPARMOR
1907 if (context->apparmor_profile && mac_apparmor_use()) {
1908 r = aa_change_onexec(context->apparmor_profile);
1909 if (r < 0 && !context->apparmor_profile_ignore) {
1910 *exit_status = EXIT_APPARMOR_PROFILE;
1911 return -errno;
1912 }
1913 }
1914 #endif
1915 }
1916
1917 r = build_environment(context, n_fds, params->fd_names, params->watchdog_usec, home, username, shell, &our_env);
1918 if (r < 0) {
1919 *exit_status = EXIT_MEMORY;
1920 return r;
1921 }
1922
1923 final_env = strv_env_merge(5,
1924 params->environment,
1925 our_env,
1926 context->environment,
1927 files_env,
1928 pam_env,
1929 NULL);
1930 if (!final_env) {
1931 *exit_status = EXIT_MEMORY;
1932 return -ENOMEM;
1933 }
1934
1935 final_argv = replace_env_argv(argv, final_env);
1936 if (!final_argv) {
1937 *exit_status = EXIT_MEMORY;
1938 return -ENOMEM;
1939 }
1940
1941 final_env = strv_env_clean(final_env);
1942
1943 if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
1944 _cleanup_free_ char *line;
1945
1946 line = exec_command_line(final_argv);
1947 if (line) {
1948 log_open();
1949 log_struct(LOG_DEBUG,
1950 LOG_UNIT_ID(unit),
1951 "EXECUTABLE=%s", command->path,
1952 LOG_UNIT_MESSAGE(unit, "Executing: %s", line),
1953 NULL);
1954 log_close();
1955 }
1956 }
1957
1958 execve(command->path, final_argv, final_env);
1959 *exit_status = EXIT_EXEC;
1960 return -errno;
1961 }
1962
1963 int exec_spawn(Unit *unit,
1964 ExecCommand *command,
1965 const ExecContext *context,
1966 const ExecParameters *params,
1967 ExecRuntime *runtime,
1968 pid_t *ret) {
1969
1970 _cleanup_strv_free_ char **files_env = NULL;
1971 int *fds = NULL; unsigned n_fds = 0;
1972 _cleanup_free_ char *line = NULL;
1973 int socket_fd, r;
1974 char **argv;
1975 pid_t pid;
1976
1977 assert(unit);
1978 assert(command);
1979 assert(context);
1980 assert(ret);
1981 assert(params);
1982 assert(params->fds || params->n_fds <= 0);
1983
1984 if (context->std_input == EXEC_INPUT_SOCKET ||
1985 context->std_output == EXEC_OUTPUT_SOCKET ||
1986 context->std_error == EXEC_OUTPUT_SOCKET) {
1987
1988 if (params->n_fds != 1) {
1989 log_unit_error(unit, "Got more than one socket.");
1990 return -EINVAL;
1991 }
1992
1993 socket_fd = params->fds[0];
1994 } else {
1995 socket_fd = -1;
1996 fds = params->fds;
1997 n_fds = params->n_fds;
1998 }
1999
2000 r = exec_context_load_environment(unit, context, &files_env);
2001 if (r < 0)
2002 return log_unit_error_errno(unit, r, "Failed to load environment files: %m");
2003
2004 argv = params->argv ?: command->argv;
2005 line = exec_command_line(argv);
2006 if (!line)
2007 return log_oom();
2008
2009 log_struct(LOG_DEBUG,
2010 LOG_UNIT_ID(unit),
2011 LOG_UNIT_MESSAGE(unit, "About to execute: %s", line),
2012 "EXECUTABLE=%s", command->path,
2013 NULL);
2014 pid = fork();
2015 if (pid < 0)
2016 return log_unit_error_errno(unit, r, "Failed to fork: %m");
2017
2018 if (pid == 0) {
2019 int exit_status;
2020
2021 r = exec_child(unit,
2022 command,
2023 context,
2024 params,
2025 runtime,
2026 argv,
2027 socket_fd,
2028 fds, n_fds,
2029 files_env,
2030 &exit_status);
2031 if (r < 0) {
2032 log_open();
2033 log_struct_errno(LOG_ERR, r,
2034 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
2035 LOG_UNIT_ID(unit),
2036 LOG_UNIT_MESSAGE(unit, "Failed at step %s spawning %s: %m",
2037 exit_status_to_string(exit_status, EXIT_STATUS_SYSTEMD),
2038 command->path),
2039 "EXECUTABLE=%s", command->path,
2040 NULL);
2041 }
2042
2043 _exit(exit_status);
2044 }
2045
2046 log_unit_debug(unit, "Forked %s as "PID_FMT, command->path, pid);
2047
2048 /* We add the new process to the cgroup both in the child (so
2049 * that we can be sure that no user code is ever executed
2050 * outside of the cgroup) and in the parent (so that we can be
2051 * sure that when we kill the cgroup the process will be
2052 * killed too). */
2053 if (params->cgroup_path)
2054 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, pid);
2055
2056 exec_status_start(&command->exec_status, pid);
2057
2058 *ret = pid;
2059 return 0;
2060 }
2061
2062 void exec_context_init(ExecContext *c) {
2063 assert(c);
2064
2065 c->umask = 0022;
2066 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
2067 c->cpu_sched_policy = SCHED_OTHER;
2068 c->syslog_priority = LOG_DAEMON|LOG_INFO;
2069 c->syslog_level_prefix = true;
2070 c->ignore_sigpipe = true;
2071 c->timer_slack_nsec = NSEC_INFINITY;
2072 c->personality = PERSONALITY_INVALID;
2073 c->runtime_directory_mode = 0755;
2074 }
2075
2076 void exec_context_done(ExecContext *c) {
2077 unsigned l;
2078
2079 assert(c);
2080
2081 c->environment = strv_free(c->environment);
2082 c->environment_files = strv_free(c->environment_files);
2083
2084 for (l = 0; l < ELEMENTSOF(c->rlimit); l++)
2085 c->rlimit[l] = mfree(c->rlimit[l]);
2086
2087 c->working_directory = mfree(c->working_directory);
2088 c->root_directory = mfree(c->root_directory);
2089 c->tty_path = mfree(c->tty_path);
2090 c->syslog_identifier = mfree(c->syslog_identifier);
2091 c->user = mfree(c->user);
2092 c->group = mfree(c->group);
2093
2094 c->supplementary_groups = strv_free(c->supplementary_groups);
2095
2096 c->pam_name = mfree(c->pam_name);
2097
2098 if (c->capabilities) {
2099 cap_free(c->capabilities);
2100 c->capabilities = NULL;
2101 }
2102
2103 c->read_only_dirs = strv_free(c->read_only_dirs);
2104 c->read_write_dirs = strv_free(c->read_write_dirs);
2105 c->inaccessible_dirs = strv_free(c->inaccessible_dirs);
2106
2107 if (c->cpuset)
2108 CPU_FREE(c->cpuset);
2109
2110 c->utmp_id = mfree(c->utmp_id);
2111 c->selinux_context = mfree(c->selinux_context);
2112 c->apparmor_profile = mfree(c->apparmor_profile);
2113
2114 c->syscall_filter = set_free(c->syscall_filter);
2115 c->syscall_archs = set_free(c->syscall_archs);
2116 c->address_families = set_free(c->address_families);
2117
2118 c->runtime_directory = strv_free(c->runtime_directory);
2119
2120 bus_endpoint_free(c->bus_endpoint);
2121 c->bus_endpoint = NULL;
2122 }
2123
2124 int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) {
2125 char **i;
2126
2127 assert(c);
2128
2129 if (!runtime_prefix)
2130 return 0;
2131
2132 STRV_FOREACH(i, c->runtime_directory) {
2133 _cleanup_free_ char *p;
2134
2135 p = strjoin(runtime_prefix, "/", *i, NULL);
2136 if (!p)
2137 return -ENOMEM;
2138
2139 /* We execute this synchronously, since we need to be
2140 * sure this is gone when we start the service
2141 * next. */
2142 (void) rm_rf(p, REMOVE_ROOT);
2143 }
2144
2145 return 0;
2146 }
2147
2148 void exec_command_done(ExecCommand *c) {
2149 assert(c);
2150
2151 c->path = mfree(c->path);
2152
2153 c->argv = strv_free(c->argv);
2154 }
2155
2156 void exec_command_done_array(ExecCommand *c, unsigned n) {
2157 unsigned i;
2158
2159 for (i = 0; i < n; i++)
2160 exec_command_done(c+i);
2161 }
2162
2163 ExecCommand* exec_command_free_list(ExecCommand *c) {
2164 ExecCommand *i;
2165
2166 while ((i = c)) {
2167 LIST_REMOVE(command, c, i);
2168 exec_command_done(i);
2169 free(i);
2170 }
2171
2172 return NULL;
2173 }
2174
2175 void exec_command_free_array(ExecCommand **c, unsigned n) {
2176 unsigned i;
2177
2178 for (i = 0; i < n; i++)
2179 c[i] = exec_command_free_list(c[i]);
2180 }
2181
2182 typedef struct InvalidEnvInfo {
2183 Unit *unit;
2184 const char *path;
2185 } InvalidEnvInfo;
2186
2187 static void invalid_env(const char *p, void *userdata) {
2188 InvalidEnvInfo *info = userdata;
2189
2190 log_unit_error(info->unit, "Ignoring invalid environment assignment '%s': %s", p, info->path);
2191 }
2192
2193 int exec_context_load_environment(Unit *unit, const ExecContext *c, char ***l) {
2194 char **i, **r = NULL;
2195
2196 assert(c);
2197 assert(l);
2198
2199 STRV_FOREACH(i, c->environment_files) {
2200 char *fn;
2201 int k;
2202 bool ignore = false;
2203 char **p;
2204 _cleanup_globfree_ glob_t pglob = {};
2205 int count, n;
2206
2207 fn = *i;
2208
2209 if (fn[0] == '-') {
2210 ignore = true;
2211 fn ++;
2212 }
2213
2214 if (!path_is_absolute(fn)) {
2215 if (ignore)
2216 continue;
2217
2218 strv_free(r);
2219 return -EINVAL;
2220 }
2221
2222 /* Filename supports globbing, take all matching files */
2223 errno = 0;
2224 if (glob(fn, 0, NULL, &pglob) != 0) {
2225 if (ignore)
2226 continue;
2227
2228 strv_free(r);
2229 return errno ? -errno : -EINVAL;
2230 }
2231 count = pglob.gl_pathc;
2232 if (count == 0) {
2233 if (ignore)
2234 continue;
2235
2236 strv_free(r);
2237 return -EINVAL;
2238 }
2239 for (n = 0; n < count; n++) {
2240 k = load_env_file(NULL, pglob.gl_pathv[n], NULL, &p);
2241 if (k < 0) {
2242 if (ignore)
2243 continue;
2244
2245 strv_free(r);
2246 return k;
2247 }
2248 /* Log invalid environment variables with filename */
2249 if (p) {
2250 InvalidEnvInfo info = {
2251 .unit = unit,
2252 .path = pglob.gl_pathv[n]
2253 };
2254
2255 p = strv_env_clean_with_callback(p, invalid_env, &info);
2256 }
2257
2258 if (r == NULL)
2259 r = p;
2260 else {
2261 char **m;
2262
2263 m = strv_env_merge(2, r, p);
2264 strv_free(r);
2265 strv_free(p);
2266 if (!m)
2267 return -ENOMEM;
2268
2269 r = m;
2270 }
2271 }
2272 }
2273
2274 *l = r;
2275
2276 return 0;
2277 }
2278
2279 static bool tty_may_match_dev_console(const char *tty) {
2280 _cleanup_free_ char *active = NULL;
2281 char *console;
2282
2283 if (startswith(tty, "/dev/"))
2284 tty += 5;
2285
2286 /* trivial identity? */
2287 if (streq(tty, "console"))
2288 return true;
2289
2290 console = resolve_dev_console(&active);
2291 /* if we could not resolve, assume it may */
2292 if (!console)
2293 return true;
2294
2295 /* "tty0" means the active VC, so it may be the same sometimes */
2296 return streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
2297 }
2298
2299 bool exec_context_may_touch_console(ExecContext *ec) {
2300 return (ec->tty_reset || ec->tty_vhangup || ec->tty_vt_disallocate ||
2301 is_terminal_input(ec->std_input) ||
2302 is_terminal_output(ec->std_output) ||
2303 is_terminal_output(ec->std_error)) &&
2304 tty_may_match_dev_console(tty_path(ec));
2305 }
2306
2307 static void strv_fprintf(FILE *f, char **l) {
2308 char **g;
2309
2310 assert(f);
2311
2312 STRV_FOREACH(g, l)
2313 fprintf(f, " %s", *g);
2314 }
2315
2316 void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
2317 char **e, **d;
2318 unsigned i;
2319
2320 assert(c);
2321 assert(f);
2322
2323 prefix = strempty(prefix);
2324
2325 fprintf(f,
2326 "%sUMask: %04o\n"
2327 "%sWorkingDirectory: %s\n"
2328 "%sRootDirectory: %s\n"
2329 "%sNonBlocking: %s\n"
2330 "%sPrivateTmp: %s\n"
2331 "%sPrivateNetwork: %s\n"
2332 "%sPrivateDevices: %s\n"
2333 "%sProtectHome: %s\n"
2334 "%sProtectSystem: %s\n"
2335 "%sIgnoreSIGPIPE: %s\n",
2336 prefix, c->umask,
2337 prefix, c->working_directory ? c->working_directory : "/",
2338 prefix, c->root_directory ? c->root_directory : "/",
2339 prefix, yes_no(c->non_blocking),
2340 prefix, yes_no(c->private_tmp),
2341 prefix, yes_no(c->private_network),
2342 prefix, yes_no(c->private_devices),
2343 prefix, protect_home_to_string(c->protect_home),
2344 prefix, protect_system_to_string(c->protect_system),
2345 prefix, yes_no(c->ignore_sigpipe));
2346
2347 STRV_FOREACH(e, c->environment)
2348 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
2349
2350 STRV_FOREACH(e, c->environment_files)
2351 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
2352
2353 fprintf(f, "%sRuntimeDirectoryMode: %04o\n", prefix, c->runtime_directory_mode);
2354
2355 STRV_FOREACH(d, c->runtime_directory)
2356 fprintf(f, "%sRuntimeDirectory: %s\n", prefix, *d);
2357
2358 if (c->nice_set)
2359 fprintf(f,
2360 "%sNice: %i\n",
2361 prefix, c->nice);
2362
2363 if (c->oom_score_adjust_set)
2364 fprintf(f,
2365 "%sOOMScoreAdjust: %i\n",
2366 prefix, c->oom_score_adjust);
2367
2368 for (i = 0; i < RLIM_NLIMITS; i++)
2369 if (c->rlimit[i])
2370 fprintf(f, "%s%s: "RLIM_FMT"\n",
2371 prefix, rlimit_to_string(i), c->rlimit[i]->rlim_max);
2372
2373 if (c->ioprio_set) {
2374 _cleanup_free_ char *class_str = NULL;
2375
2376 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
2377 fprintf(f,
2378 "%sIOSchedulingClass: %s\n"
2379 "%sIOPriority: %i\n",
2380 prefix, strna(class_str),
2381 prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
2382 }
2383
2384 if (c->cpu_sched_set) {
2385 _cleanup_free_ char *policy_str = NULL;
2386
2387 sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
2388 fprintf(f,
2389 "%sCPUSchedulingPolicy: %s\n"
2390 "%sCPUSchedulingPriority: %i\n"
2391 "%sCPUSchedulingResetOnFork: %s\n",
2392 prefix, strna(policy_str),
2393 prefix, c->cpu_sched_priority,
2394 prefix, yes_no(c->cpu_sched_reset_on_fork));
2395 }
2396
2397 if (c->cpuset) {
2398 fprintf(f, "%sCPUAffinity:", prefix);
2399 for (i = 0; i < c->cpuset_ncpus; i++)
2400 if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
2401 fprintf(f, " %u", i);
2402 fputs("\n", f);
2403 }
2404
2405 if (c->timer_slack_nsec != NSEC_INFINITY)
2406 fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec);
2407
2408 fprintf(f,
2409 "%sStandardInput: %s\n"
2410 "%sStandardOutput: %s\n"
2411 "%sStandardError: %s\n",
2412 prefix, exec_input_to_string(c->std_input),
2413 prefix, exec_output_to_string(c->std_output),
2414 prefix, exec_output_to_string(c->std_error));
2415
2416 if (c->tty_path)
2417 fprintf(f,
2418 "%sTTYPath: %s\n"
2419 "%sTTYReset: %s\n"
2420 "%sTTYVHangup: %s\n"
2421 "%sTTYVTDisallocate: %s\n",
2422 prefix, c->tty_path,
2423 prefix, yes_no(c->tty_reset),
2424 prefix, yes_no(c->tty_vhangup),
2425 prefix, yes_no(c->tty_vt_disallocate));
2426
2427 if (c->std_output == EXEC_OUTPUT_SYSLOG ||
2428 c->std_output == EXEC_OUTPUT_KMSG ||
2429 c->std_output == EXEC_OUTPUT_JOURNAL ||
2430 c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
2431 c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
2432 c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
2433 c->std_error == EXEC_OUTPUT_SYSLOG ||
2434 c->std_error == EXEC_OUTPUT_KMSG ||
2435 c->std_error == EXEC_OUTPUT_JOURNAL ||
2436 c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
2437 c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
2438 c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) {
2439
2440 _cleanup_free_ char *fac_str = NULL, *lvl_str = NULL;
2441
2442 log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
2443 log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
2444
2445 fprintf(f,
2446 "%sSyslogFacility: %s\n"
2447 "%sSyslogLevel: %s\n",
2448 prefix, strna(fac_str),
2449 prefix, strna(lvl_str));
2450 }
2451
2452 if (c->capabilities) {
2453 _cleanup_cap_free_charp_ char *t;
2454
2455 t = cap_to_text(c->capabilities, NULL);
2456 if (t)
2457 fprintf(f, "%sCapabilities: %s\n", prefix, t);
2458 }
2459
2460 if (c->secure_bits)
2461 fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
2462 prefix,
2463 (c->secure_bits & 1<<SECURE_KEEP_CAPS) ? " keep-caps" : "",
2464 (c->secure_bits & 1<<SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
2465 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
2466 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
2467 (c->secure_bits & 1<<SECURE_NOROOT) ? " noroot" : "",
2468 (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
2469
2470 if (c->capability_bounding_set_drop) {
2471 unsigned long l;
2472 fprintf(f, "%sCapabilityBoundingSet:", prefix);
2473
2474 for (l = 0; l <= cap_last_cap(); l++)
2475 if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l)))
2476 fprintf(f, " %s", strna(capability_to_name(l)));
2477
2478 fputs("\n", f);
2479 }
2480
2481 if (c->user)
2482 fprintf(f, "%sUser: %s\n", prefix, c->user);
2483 if (c->group)
2484 fprintf(f, "%sGroup: %s\n", prefix, c->group);
2485
2486 if (strv_length(c->supplementary_groups) > 0) {
2487 fprintf(f, "%sSupplementaryGroups:", prefix);
2488 strv_fprintf(f, c->supplementary_groups);
2489 fputs("\n", f);
2490 }
2491
2492 if (c->pam_name)
2493 fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
2494
2495 if (strv_length(c->read_write_dirs) > 0) {
2496 fprintf(f, "%sReadWriteDirs:", prefix);
2497 strv_fprintf(f, c->read_write_dirs);
2498 fputs("\n", f);
2499 }
2500
2501 if (strv_length(c->read_only_dirs) > 0) {
2502 fprintf(f, "%sReadOnlyDirs:", prefix);
2503 strv_fprintf(f, c->read_only_dirs);
2504 fputs("\n", f);
2505 }
2506
2507 if (strv_length(c->inaccessible_dirs) > 0) {
2508 fprintf(f, "%sInaccessibleDirs:", prefix);
2509 strv_fprintf(f, c->inaccessible_dirs);
2510 fputs("\n", f);
2511 }
2512
2513 if (c->utmp_id)
2514 fprintf(f,
2515 "%sUtmpIdentifier: %s\n",
2516 prefix, c->utmp_id);
2517
2518 if (c->selinux_context)
2519 fprintf(f,
2520 "%sSELinuxContext: %s%s\n",
2521 prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context);
2522
2523 if (c->personality != PERSONALITY_INVALID)
2524 fprintf(f,
2525 "%sPersonality: %s\n",
2526 prefix, strna(personality_to_string(c->personality)));
2527
2528 if (c->syscall_filter) {
2529 #ifdef HAVE_SECCOMP
2530 Iterator j;
2531 void *id;
2532 bool first = true;
2533 #endif
2534
2535 fprintf(f,
2536 "%sSystemCallFilter: ",
2537 prefix);
2538
2539 if (!c->syscall_whitelist)
2540 fputc('~', f);
2541
2542 #ifdef HAVE_SECCOMP
2543 SET_FOREACH(id, c->syscall_filter, j) {
2544 _cleanup_free_ char *name = NULL;
2545
2546 if (first)
2547 first = false;
2548 else
2549 fputc(' ', f);
2550
2551 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
2552 fputs(strna(name), f);
2553 }
2554 #endif
2555
2556 fputc('\n', f);
2557 }
2558
2559 if (c->syscall_archs) {
2560 #ifdef HAVE_SECCOMP
2561 Iterator j;
2562 void *id;
2563 #endif
2564
2565 fprintf(f,
2566 "%sSystemCallArchitectures:",
2567 prefix);
2568
2569 #ifdef HAVE_SECCOMP
2570 SET_FOREACH(id, c->syscall_archs, j)
2571 fprintf(f, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id) - 1)));
2572 #endif
2573 fputc('\n', f);
2574 }
2575
2576 if (c->syscall_errno != 0)
2577 fprintf(f,
2578 "%sSystemCallErrorNumber: %s\n",
2579 prefix, strna(errno_to_name(c->syscall_errno)));
2580
2581 if (c->apparmor_profile)
2582 fprintf(f,
2583 "%sAppArmorProfile: %s%s\n",
2584 prefix, c->apparmor_profile_ignore ? "-" : "", c->apparmor_profile);
2585 }
2586
2587 bool exec_context_maintains_privileges(ExecContext *c) {
2588 assert(c);
2589
2590 /* Returns true if the process forked off would run run under
2591 * an unchanged UID or as root. */
2592
2593 if (!c->user)
2594 return true;
2595
2596 if (streq(c->user, "root") || streq(c->user, "0"))
2597 return true;
2598
2599 return false;
2600 }
2601
2602 void exec_status_start(ExecStatus *s, pid_t pid) {
2603 assert(s);
2604
2605 zero(*s);
2606 s->pid = pid;
2607 dual_timestamp_get(&s->start_timestamp);
2608 }
2609
2610 void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
2611 assert(s);
2612
2613 if (s->pid && s->pid != pid)
2614 zero(*s);
2615
2616 s->pid = pid;
2617 dual_timestamp_get(&s->exit_timestamp);
2618
2619 s->code = code;
2620 s->status = status;
2621
2622 if (context) {
2623 if (context->utmp_id)
2624 utmp_put_dead_process(context->utmp_id, pid, code, status);
2625
2626 exec_context_tty_reset(context);
2627 }
2628 }
2629
2630 void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
2631 char buf[FORMAT_TIMESTAMP_MAX];
2632
2633 assert(s);
2634 assert(f);
2635
2636 if (s->pid <= 0)
2637 return;
2638
2639 prefix = strempty(prefix);
2640
2641 fprintf(f,
2642 "%sPID: "PID_FMT"\n",
2643 prefix, s->pid);
2644
2645 if (s->start_timestamp.realtime > 0)
2646 fprintf(f,
2647 "%sStart Timestamp: %s\n",
2648 prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
2649
2650 if (s->exit_timestamp.realtime > 0)
2651 fprintf(f,
2652 "%sExit Timestamp: %s\n"
2653 "%sExit Code: %s\n"
2654 "%sExit Status: %i\n",
2655 prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
2656 prefix, sigchld_code_to_string(s->code),
2657 prefix, s->status);
2658 }
2659
2660 char *exec_command_line(char **argv) {
2661 size_t k;
2662 char *n, *p, **a;
2663 bool first = true;
2664
2665 assert(argv);
2666
2667 k = 1;
2668 STRV_FOREACH(a, argv)
2669 k += strlen(*a)+3;
2670
2671 if (!(n = new(char, k)))
2672 return NULL;
2673
2674 p = n;
2675 STRV_FOREACH(a, argv) {
2676
2677 if (!first)
2678 *(p++) = ' ';
2679 else
2680 first = false;
2681
2682 if (strpbrk(*a, WHITESPACE)) {
2683 *(p++) = '\'';
2684 p = stpcpy(p, *a);
2685 *(p++) = '\'';
2686 } else
2687 p = stpcpy(p, *a);
2688
2689 }
2690
2691 *p = 0;
2692
2693 /* FIXME: this doesn't really handle arguments that have
2694 * spaces and ticks in them */
2695
2696 return n;
2697 }
2698
2699 void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
2700 _cleanup_free_ char *cmd = NULL;
2701 const char *prefix2;
2702
2703 assert(c);
2704 assert(f);
2705
2706 prefix = strempty(prefix);
2707 prefix2 = strjoina(prefix, "\t");
2708
2709 cmd = exec_command_line(c->argv);
2710 fprintf(f,
2711 "%sCommand Line: %s\n",
2712 prefix, cmd ? cmd : strerror(ENOMEM));
2713
2714 exec_status_dump(&c->exec_status, f, prefix2);
2715 }
2716
2717 void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
2718 assert(f);
2719
2720 prefix = strempty(prefix);
2721
2722 LIST_FOREACH(command, c, c)
2723 exec_command_dump(c, f, prefix);
2724 }
2725
2726 void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
2727 ExecCommand *end;
2728
2729 assert(l);
2730 assert(e);
2731
2732 if (*l) {
2733 /* It's kind of important, that we keep the order here */
2734 LIST_FIND_TAIL(command, *l, end);
2735 LIST_INSERT_AFTER(command, *l, end, e);
2736 } else
2737 *l = e;
2738 }
2739
2740 int exec_command_set(ExecCommand *c, const char *path, ...) {
2741 va_list ap;
2742 char **l, *p;
2743
2744 assert(c);
2745 assert(path);
2746
2747 va_start(ap, path);
2748 l = strv_new_ap(path, ap);
2749 va_end(ap);
2750
2751 if (!l)
2752 return -ENOMEM;
2753
2754 p = strdup(path);
2755 if (!p) {
2756 strv_free(l);
2757 return -ENOMEM;
2758 }
2759
2760 free(c->path);
2761 c->path = p;
2762
2763 strv_free(c->argv);
2764 c->argv = l;
2765
2766 return 0;
2767 }
2768
2769 int exec_command_append(ExecCommand *c, const char *path, ...) {
2770 _cleanup_strv_free_ char **l = NULL;
2771 va_list ap;
2772 int r;
2773
2774 assert(c);
2775 assert(path);
2776
2777 va_start(ap, path);
2778 l = strv_new_ap(path, ap);
2779 va_end(ap);
2780
2781 if (!l)
2782 return -ENOMEM;
2783
2784 r = strv_extend_strv(&c->argv, l, false);
2785 if (r < 0)
2786 return r;
2787
2788 return 0;
2789 }
2790
2791
2792 static int exec_runtime_allocate(ExecRuntime **rt) {
2793
2794 if (*rt)
2795 return 0;
2796
2797 *rt = new0(ExecRuntime, 1);
2798 if (!*rt)
2799 return -ENOMEM;
2800
2801 (*rt)->n_ref = 1;
2802 (*rt)->netns_storage_socket[0] = (*rt)->netns_storage_socket[1] = -1;
2803
2804 return 0;
2805 }
2806
2807 int exec_runtime_make(ExecRuntime **rt, ExecContext *c, const char *id) {
2808 int r;
2809
2810 assert(rt);
2811 assert(c);
2812 assert(id);
2813
2814 if (*rt)
2815 return 1;
2816
2817 if (!c->private_network && !c->private_tmp)
2818 return 0;
2819
2820 r = exec_runtime_allocate(rt);
2821 if (r < 0)
2822 return r;
2823
2824 if (c->private_network && (*rt)->netns_storage_socket[0] < 0) {
2825 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, (*rt)->netns_storage_socket) < 0)
2826 return -errno;
2827 }
2828
2829 if (c->private_tmp && !(*rt)->tmp_dir) {
2830 r = setup_tmp_dirs(id, &(*rt)->tmp_dir, &(*rt)->var_tmp_dir);
2831 if (r < 0)
2832 return r;
2833 }
2834
2835 return 1;
2836 }
2837
2838 ExecRuntime *exec_runtime_ref(ExecRuntime *r) {
2839 assert(r);
2840 assert(r->n_ref > 0);
2841
2842 r->n_ref++;
2843 return r;
2844 }
2845
2846 ExecRuntime *exec_runtime_unref(ExecRuntime *r) {
2847
2848 if (!r)
2849 return NULL;
2850
2851 assert(r->n_ref > 0);
2852
2853 r->n_ref--;
2854 if (r->n_ref > 0)
2855 return NULL;
2856
2857 free(r->tmp_dir);
2858 free(r->var_tmp_dir);
2859 safe_close_pair(r->netns_storage_socket);
2860 free(r);
2861
2862 return NULL;
2863 }
2864
2865 int exec_runtime_serialize(Unit *u, ExecRuntime *rt, FILE *f, FDSet *fds) {
2866 assert(u);
2867 assert(f);
2868 assert(fds);
2869
2870 if (!rt)
2871 return 0;
2872
2873 if (rt->tmp_dir)
2874 unit_serialize_item(u, f, "tmp-dir", rt->tmp_dir);
2875
2876 if (rt->var_tmp_dir)
2877 unit_serialize_item(u, f, "var-tmp-dir", rt->var_tmp_dir);
2878
2879 if (rt->netns_storage_socket[0] >= 0) {
2880 int copy;
2881
2882 copy = fdset_put_dup(fds, rt->netns_storage_socket[0]);
2883 if (copy < 0)
2884 return copy;
2885
2886 unit_serialize_item_format(u, f, "netns-socket-0", "%i", copy);
2887 }
2888
2889 if (rt->netns_storage_socket[1] >= 0) {
2890 int copy;
2891
2892 copy = fdset_put_dup(fds, rt->netns_storage_socket[1]);
2893 if (copy < 0)
2894 return copy;
2895
2896 unit_serialize_item_format(u, f, "netns-socket-1", "%i", copy);
2897 }
2898
2899 return 0;
2900 }
2901
2902 int exec_runtime_deserialize_item(Unit *u, ExecRuntime **rt, const char *key, const char *value, FDSet *fds) {
2903 int r;
2904
2905 assert(rt);
2906 assert(key);
2907 assert(value);
2908
2909 if (streq(key, "tmp-dir")) {
2910 char *copy;
2911
2912 r = exec_runtime_allocate(rt);
2913 if (r < 0)
2914 return log_oom();
2915
2916 copy = strdup(value);
2917 if (!copy)
2918 return log_oom();
2919
2920 free((*rt)->tmp_dir);
2921 (*rt)->tmp_dir = copy;
2922
2923 } else if (streq(key, "var-tmp-dir")) {
2924 char *copy;
2925
2926 r = exec_runtime_allocate(rt);
2927 if (r < 0)
2928 return log_oom();
2929
2930 copy = strdup(value);
2931 if (!copy)
2932 return log_oom();
2933
2934 free((*rt)->var_tmp_dir);
2935 (*rt)->var_tmp_dir = copy;
2936
2937 } else if (streq(key, "netns-socket-0")) {
2938 int fd;
2939
2940 r = exec_runtime_allocate(rt);
2941 if (r < 0)
2942 return log_oom();
2943
2944 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
2945 log_unit_debug(u, "Failed to parse netns socket value: %s", value);
2946 else {
2947 safe_close((*rt)->netns_storage_socket[0]);
2948 (*rt)->netns_storage_socket[0] = fdset_remove(fds, fd);
2949 }
2950 } else if (streq(key, "netns-socket-1")) {
2951 int fd;
2952
2953 r = exec_runtime_allocate(rt);
2954 if (r < 0)
2955 return log_oom();
2956
2957 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
2958 log_unit_debug(u, "Failed to parse netns socket value: %s", value);
2959 else {
2960 safe_close((*rt)->netns_storage_socket[1]);
2961 (*rt)->netns_storage_socket[1] = fdset_remove(fds, fd);
2962 }
2963 } else
2964 return 0;
2965
2966 return 1;
2967 }
2968
2969 static void *remove_tmpdir_thread(void *p) {
2970 _cleanup_free_ char *path = p;
2971
2972 (void) rm_rf(path, REMOVE_ROOT|REMOVE_PHYSICAL);
2973 return NULL;
2974 }
2975
2976 void exec_runtime_destroy(ExecRuntime *rt) {
2977 int r;
2978
2979 if (!rt)
2980 return;
2981
2982 /* If there are multiple users of this, let's leave the stuff around */
2983 if (rt->n_ref > 1)
2984 return;
2985
2986 if (rt->tmp_dir) {
2987 log_debug("Spawning thread to nuke %s", rt->tmp_dir);
2988
2989 r = asynchronous_job(remove_tmpdir_thread, rt->tmp_dir);
2990 if (r < 0) {
2991 log_warning_errno(r, "Failed to nuke %s: %m", rt->tmp_dir);
2992 free(rt->tmp_dir);
2993 }
2994
2995 rt->tmp_dir = NULL;
2996 }
2997
2998 if (rt->var_tmp_dir) {
2999 log_debug("Spawning thread to nuke %s", rt->var_tmp_dir);
3000
3001 r = asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir);
3002 if (r < 0) {
3003 log_warning_errno(r, "Failed to nuke %s: %m", rt->var_tmp_dir);
3004 free(rt->var_tmp_dir);
3005 }
3006
3007 rt->var_tmp_dir = NULL;
3008 }
3009
3010 safe_close_pair(rt->netns_storage_socket);
3011 }
3012
3013 static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
3014 [EXEC_INPUT_NULL] = "null",
3015 [EXEC_INPUT_TTY] = "tty",
3016 [EXEC_INPUT_TTY_FORCE] = "tty-force",
3017 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
3018 [EXEC_INPUT_SOCKET] = "socket"
3019 };
3020
3021 DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
3022
3023 static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
3024 [EXEC_OUTPUT_INHERIT] = "inherit",
3025 [EXEC_OUTPUT_NULL] = "null",
3026 [EXEC_OUTPUT_TTY] = "tty",
3027 [EXEC_OUTPUT_SYSLOG] = "syslog",
3028 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
3029 [EXEC_OUTPUT_KMSG] = "kmsg",
3030 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
3031 [EXEC_OUTPUT_JOURNAL] = "journal",
3032 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
3033 [EXEC_OUTPUT_SOCKET] = "socket"
3034 };
3035
3036 DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
3037
3038 static const char* const exec_utmp_mode_table[_EXEC_UTMP_MODE_MAX] = {
3039 [EXEC_UTMP_INIT] = "init",
3040 [EXEC_UTMP_LOGIN] = "login",
3041 [EXEC_UTMP_USER] = "user",
3042 };
3043
3044 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode, ExecUtmpMode);