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