]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/execute.c
shared: rework env file reader
[thirdparty/systemd.git] / src / core / execute.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5cb5a6ff 2
a7334b09
LP
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
5430f7f2
LP
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
a7334b09
LP
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
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
5cb5a6ff 22#include <assert.h>
034c6ed7
LP
23#include <dirent.h>
24#include <errno.h>
25#include <fcntl.h>
26#include <unistd.h>
44d8db9e 27#include <string.h>
309bff19 28#include <signal.h>
071830ff
LP
29#include <sys/socket.h>
30#include <sys/un.h>
94f04347 31#include <sys/prctl.h>
66ee3769 32#include <linux/sched.h>
451a074f
LP
33#include <sys/types.h>
34#include <sys/stat.h>
81a2b7ce
LP
35#include <grp.h>
36#include <pwd.h>
15ae422b 37#include <sys/mount.h>
25e870b5 38#include <linux/fs.h>
dd6c17b1 39#include <linux/oom.h>
f2b68789 40#include <sys/poll.h>
8351ceae 41#include <linux/seccomp-bpf.h>
2bef10ab 42#include <glob.h>
d34cd374 43#include <libgen.h>
5cb5a6ff 44
5b6319dc
LP
45#ifdef HAVE_PAM
46#include <security/pam_appl.h>
47#endif
48
5cb5a6ff
LP
49#include "execute.h"
50#include "strv.h"
51#include "macro.h"
d7832d2c 52#include "capability.h"
5cb5a6ff 53#include "util.h"
acbb0225 54#include "log.h"
20ad4cfd 55#include "sd-messages.h"
9eba9da4 56#include "ioprio.h"
94f04347 57#include "securebits.h"
8e274523 58#include "cgroup.h"
15ae422b 59#include "namespace.h"
df1f0afe 60#include "tcpwrap.h"
d06dacd0 61#include "exit-status.h"
dd6c17b1 62#include "missing.h"
169c1bda 63#include "utmp-wtmp.h"
f6a6225e 64#include "def.h"
ff01d048 65#include "loopback-setup.h"
9eb977db 66#include "path-util.h"
8351ceae 67#include "syscall-list.h"
4d1a6904 68#include "env-util.h"
a5c32cff 69#include "fileio.h"
5cb5a6ff 70
e056b01d 71#define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
e6a26745 72
02a51aba
LP
73/* This assumes there is a 'tty' group */
74#define TTY_MODE 0620
75
034c6ed7
LP
76static int shift_fds(int fds[], unsigned n_fds) {
77 int start, restart_from;
78
79 if (n_fds <= 0)
80 return 0;
81
a0d40ac5
LP
82 /* Modifies the fds array! (sorts it) */
83
034c6ed7
LP
84 assert(fds);
85
86 start = 0;
87 for (;;) {
88 int i;
89
90 restart_from = -1;
91
92 for (i = start; i < (int) n_fds; i++) {
93 int nfd;
94
95 /* Already at right index? */
96 if (fds[i] == i+3)
97 continue;
98
99 if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0)
100 return -errno;
101
e1f5e051 102 close_nointr_nofail(fds[i]);
034c6ed7
LP
103 fds[i] = nfd;
104
105 /* Hmm, the fd we wanted isn't free? Then
106 * let's remember that and try again from here*/
107 if (nfd != i+3 && restart_from < 0)
108 restart_from = i;
109 }
110
111 if (restart_from < 0)
112 break;
113
114 start = restart_from;
115 }
116
117 return 0;
118}
119
c2748801 120static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
47a71eed 121 unsigned i;
e2c76839 122 int r;
47a71eed
LP
123
124 if (n_fds <= 0)
125 return 0;
126
127 assert(fds);
128
451a074f 129 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
47a71eed
LP
130
131 for (i = 0; i < n_fds; i++) {
47a71eed 132
e2c76839
LP
133 if ((r = fd_nonblock(fds[i], nonblock)) < 0)
134 return r;
47a71eed 135
451a074f
LP
136 /* We unconditionally drop FD_CLOEXEC from the fds,
137 * since after all we want to pass these fds to our
138 * children */
47a71eed 139
e2c76839
LP
140 if ((r = fd_cloexec(fds[i], false)) < 0)
141 return r;
47a71eed
LP
142 }
143
144 return 0;
145}
146
80876c20
LP
147static const char *tty_path(const ExecContext *context) {
148 assert(context);
149
150 if (context->tty_path)
151 return context->tty_path;
152
153 return "/dev/console";
154}
155
6ea832a2
LP
156void exec_context_tty_reset(const ExecContext *context) {
157 assert(context);
158
159 if (context->tty_vhangup)
160 terminal_vhangup(tty_path(context));
161
162 if (context->tty_reset)
163 reset_terminal(tty_path(context));
164
165 if (context->tty_vt_disallocate && context->tty_path)
166 vt_disallocate(context->tty_path);
167}
168
3a1286b6
MS
169static bool is_terminal_output(ExecOutput o) {
170 return
171 o == EXEC_OUTPUT_TTY ||
172 o == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
173 o == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
174 o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE;
175}
176
c17ec25e
MS
177void exec_context_serialize(const ExecContext *context, Unit *u, FILE *f) {
178 assert(context);
179 assert(u);
180 assert(f);
181
182 if (context->tmp_dir)
183 unit_serialize_item(u, f, "tmp-dir", context->tmp_dir);
184
185 if (context->var_tmp_dir)
186 unit_serialize_item(u, f, "var-tmp-dir", context->var_tmp_dir);
187}
188
80876c20
LP
189static int open_null_as(int flags, int nfd) {
190 int fd, r;
071830ff 191
80876c20 192 assert(nfd >= 0);
071830ff 193
80876c20 194 if ((fd = open("/dev/null", flags|O_NOCTTY)) < 0)
071830ff
LP
195 return -errno;
196
80876c20
LP
197 if (fd != nfd) {
198 r = dup2(fd, nfd) < 0 ? -errno : nfd;
e1f5e051 199 close_nointr_nofail(fd);
80876c20
LP
200 } else
201 r = nfd;
071830ff 202
80876c20 203 return r;
071830ff
LP
204}
205
62bca2c6 206static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd) {
80876c20 207 int fd, r;
54fe0cdb 208 union sockaddr_union sa;
071830ff
LP
209
210 assert(context);
80876c20
LP
211 assert(output < _EXEC_OUTPUT_MAX);
212 assert(ident);
213 assert(nfd >= 0);
071830ff 214
54fe0cdb
LP
215 fd = socket(AF_UNIX, SOCK_STREAM, 0);
216 if (fd < 0)
80876c20 217 return -errno;
071830ff 218
80876c20 219 zero(sa);
54fe0cdb
LP
220 sa.un.sun_family = AF_UNIX;
221 strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path));
071830ff 222
54fe0cdb
LP
223 r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
224 if (r < 0) {
80876c20
LP
225 close_nointr_nofail(fd);
226 return -errno;
227 }
071830ff 228
80876c20
LP
229 if (shutdown(fd, SHUT_RD) < 0) {
230 close_nointr_nofail(fd);
231 return -errno;
232 }
071830ff 233
80876c20 234 dprintf(fd,
62bca2c6 235 "%s\n"
80876c20
LP
236 "%s\n"
237 "%i\n"
54fe0cdb
LP
238 "%i\n"
239 "%i\n"
240 "%i\n"
4f4a1dbf 241 "%i\n",
4f4a1dbf 242 context->syslog_identifier ? context->syslog_identifier : ident,
62bca2c6 243 unit_id,
54fe0cdb
LP
244 context->syslog_priority,
245 !!context->syslog_level_prefix,
246 output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
247 output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE,
3a1286b6 248 is_terminal_output(output));
80876c20
LP
249
250 if (fd != nfd) {
251 r = dup2(fd, nfd) < 0 ? -errno : nfd;
e1f5e051 252 close_nointr_nofail(fd);
80876c20
LP
253 } else
254 r = nfd;
071830ff 255
80876c20
LP
256 return r;
257}
258static int open_terminal_as(const char *path, mode_t mode, int nfd) {
259 int fd, r;
071830ff 260
80876c20
LP
261 assert(path);
262 assert(nfd >= 0);
071830ff 263
80876c20
LP
264 if ((fd = open_terminal(path, mode | O_NOCTTY)) < 0)
265 return fd;
071830ff 266
80876c20
LP
267 if (fd != nfd) {
268 r = dup2(fd, nfd) < 0 ? -errno : nfd;
269 close_nointr_nofail(fd);
270 } else
271 r = nfd;
071830ff 272
80876c20
LP
273 return r;
274}
071830ff 275
80876c20
LP
276static bool is_terminal_input(ExecInput i) {
277 return
278 i == EXEC_INPUT_TTY ||
279 i == EXEC_INPUT_TTY_FORCE ||
280 i == EXEC_INPUT_TTY_FAIL;
281}
071830ff 282
1e3ad081
LP
283static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
284
285 if (is_terminal_input(std_input) && !apply_tty_stdin)
286 return EXEC_INPUT_NULL;
071830ff 287
03fd9c49 288 if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
4f2d528d
LP
289 return EXEC_INPUT_NULL;
290
03fd9c49 291 return std_input;
4f2d528d
LP
292}
293
03fd9c49 294static int fixup_output(ExecOutput std_output, int socket_fd) {
4f2d528d 295
03fd9c49 296 if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0)
4f2d528d
LP
297 return EXEC_OUTPUT_INHERIT;
298
03fd9c49 299 return std_output;
4f2d528d
LP
300}
301
1e3ad081 302static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty_stdin) {
4f2d528d
LP
303 ExecInput i;
304
305 assert(context);
306
1e3ad081 307 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
4f2d528d
LP
308
309 switch (i) {
071830ff 310
80876c20
LP
311 case EXEC_INPUT_NULL:
312 return open_null_as(O_RDONLY, STDIN_FILENO);
313
314 case EXEC_INPUT_TTY:
315 case EXEC_INPUT_TTY_FORCE:
316 case EXEC_INPUT_TTY_FAIL: {
317 int fd, r;
071830ff 318
80876c20
LP
319 if ((fd = acquire_terminal(
320 tty_path(context),
4f2d528d 321 i == EXEC_INPUT_TTY_FAIL,
21de3988 322 i == EXEC_INPUT_TTY_FORCE,
af6da548
LP
323 false,
324 (usec_t) -1)) < 0)
80876c20
LP
325 return fd;
326
327 if (fd != STDIN_FILENO) {
328 r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
071830ff 329 close_nointr_nofail(fd);
80876c20
LP
330 } else
331 r = STDIN_FILENO;
332
333 return r;
334 }
335
4f2d528d
LP
336 case EXEC_INPUT_SOCKET:
337 return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
338
80876c20
LP
339 default:
340 assert_not_reached("Unknown input type");
341 }
342}
343
eb17e935 344static int setup_output(const ExecContext *context, int fileno, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin) {
4f2d528d
LP
345 ExecOutput o;
346 ExecInput i;
47c1d80d 347 int r;
4f2d528d 348
80876c20
LP
349 assert(context);
350 assert(ident);
351
1e3ad081 352 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
03fd9c49 353 o = fixup_output(context->std_output, socket_fd);
4f2d528d 354
eb17e935
MS
355 if (fileno == STDERR_FILENO) {
356 ExecOutput e;
357 e = fixup_output(context->std_error, socket_fd);
80876c20 358
eb17e935
MS
359 /* This expects the input and output are already set up */
360
361 /* Don't change the stderr file descriptor if we inherit all
362 * the way and are not on a tty */
363 if (e == EXEC_OUTPUT_INHERIT &&
364 o == EXEC_OUTPUT_INHERIT &&
365 i == EXEC_INPUT_NULL &&
366 !is_terminal_input(context->std_input) &&
367 getppid () != 1)
368 return fileno;
369
370 /* Duplicate from stdout if possible */
371 if (e == o || e == EXEC_OUTPUT_INHERIT)
372 return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno;
071830ff 373
eb17e935 374 o = e;
80876c20 375
eb17e935 376 } else if (o == EXEC_OUTPUT_INHERIT) {
21d21ea4
LP
377 /* If input got downgraded, inherit the original value */
378 if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
eb17e935 379 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
21d21ea4 380
acb591e4 381 /* If the input is connected to anything that's not a /dev/null, inherit that... */
ff876e28 382 if (i != EXEC_INPUT_NULL)
eb17e935 383 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
071830ff 384
acb591e4
LP
385 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
386 if (getppid() != 1)
eb17e935 387 return fileno;
94f04347 388
eb17e935
MS
389 /* We need to open /dev/null here anew, to get the right access mode. */
390 return open_null_as(O_WRONLY, fileno);
071830ff 391 }
94f04347 392
eb17e935 393 switch (o) {
80876c20
LP
394
395 case EXEC_OUTPUT_NULL:
eb17e935 396 return open_null_as(O_WRONLY, fileno);
80876c20
LP
397
398 case EXEC_OUTPUT_TTY:
4f2d528d 399 if (is_terminal_input(i))
eb17e935 400 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
80876c20
LP
401
402 /* We don't reset the terminal if this is just about output */
eb17e935 403 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
80876c20
LP
404
405 case EXEC_OUTPUT_SYSLOG:
28dbc1e8 406 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
9a6bca7a 407 case EXEC_OUTPUT_KMSG:
28dbc1e8 408 case EXEC_OUTPUT_KMSG_AND_CONSOLE:
706343f4
LP
409 case EXEC_OUTPUT_JOURNAL:
410 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
eb17e935 411 r = connect_logger_as(context, o, ident, unit_id, fileno);
47c1d80d 412 if (r < 0) {
80cbda35
MS
413 log_struct_unit(LOG_CRIT, unit_id,
414 "MESSAGE=Failed to connect std%s of %s to the journal socket: %s",
eb17e935 415 fileno == STDOUT_FILENO ? "out" : "err",
80cbda35
MS
416 unit_id, strerror(-r),
417 "ERRNO=%d", -r,
418 NULL);
eb17e935 419 r = open_null_as(O_WRONLY, fileno);
47c1d80d
MS
420 }
421 return r;
4f2d528d
LP
422
423 case EXEC_OUTPUT_SOCKET:
424 assert(socket_fd >= 0);
eb17e935 425 return dup2(socket_fd, fileno) < 0 ? -errno : fileno;
94f04347
LP
426
427 default:
80876c20 428 assert_not_reached("Unknown error type");
94f04347 429 }
071830ff
LP
430}
431
02a51aba
LP
432static int chown_terminal(int fd, uid_t uid) {
433 struct stat st;
434
435 assert(fd >= 0);
02a51aba
LP
436
437 /* This might fail. What matters are the results. */
bab45044
LP
438 (void) fchown(fd, uid, -1);
439 (void) fchmod(fd, TTY_MODE);
02a51aba
LP
440
441 if (fstat(fd, &st) < 0)
442 return -errno;
443
d8b4e2e9 444 if (st.st_uid != uid || (st.st_mode & 0777) != TTY_MODE)
02a51aba
LP
445 return -EPERM;
446
447 return 0;
448}
449
af6da548 450static int setup_confirm_stdio(int *_saved_stdin,
80876c20
LP
451 int *_saved_stdout) {
452 int fd = -1, saved_stdin, saved_stdout = -1, r;
453
80876c20
LP
454 assert(_saved_stdin);
455 assert(_saved_stdout);
456
af6da548
LP
457 saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3);
458 if (saved_stdin < 0)
459 return -errno;
80876c20 460
af6da548
LP
461 saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3);
462 if (saved_stdout < 0) {
463 r = errno;
80876c20
LP
464 goto fail;
465 }
466
af6da548
LP
467 fd = acquire_terminal(
468 "/dev/console",
469 false,
470 false,
471 false,
472 DEFAULT_CONFIRM_USEC);
473 if (fd < 0) {
474 r = fd;
80876c20
LP
475 goto fail;
476 }
477
af6da548
LP
478 r = chown_terminal(fd, getuid());
479 if (r < 0)
02a51aba 480 goto fail;
02a51aba 481
80876c20 482 if (dup2(fd, STDIN_FILENO) < 0) {
af6da548 483 r = -errno;
80876c20
LP
484 goto fail;
485 }
486
487 if (dup2(fd, STDOUT_FILENO) < 0) {
af6da548 488 r = -errno;
80876c20
LP
489 goto fail;
490 }
491
492 if (fd >= 2)
493 close_nointr_nofail(fd);
494
495 *_saved_stdin = saved_stdin;
496 *_saved_stdout = saved_stdout;
497
498 return 0;
499
500fail:
501 if (saved_stdout >= 0)
502 close_nointr_nofail(saved_stdout);
503
504 if (saved_stdin >= 0)
505 close_nointr_nofail(saved_stdin);
506
507 if (fd >= 0)
508 close_nointr_nofail(fd);
509
510 return r;
511}
512
af6da548
LP
513static int write_confirm_message(const char *format, ...) {
514 int fd;
515 va_list ap;
80876c20 516
af6da548 517 assert(format);
80876c20 518
af6da548
LP
519 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
520 if (fd < 0)
521 return fd;
80876c20 522
af6da548
LP
523 va_start(ap, format);
524 vdprintf(fd, format, ap);
525 va_end(ap);
80876c20 526
af6da548 527 close_nointr_nofail(fd);
80876c20 528
af6da548
LP
529 return 0;
530}
80876c20 531
af6da548
LP
532static int restore_confirm_stdio(int *saved_stdin,
533 int *saved_stdout) {
80876c20 534
af6da548 535 int r = 0;
80876c20 536
af6da548
LP
537 assert(saved_stdin);
538 assert(saved_stdout);
539
540 release_terminal();
541
542 if (*saved_stdin >= 0)
80876c20 543 if (dup2(*saved_stdin, STDIN_FILENO) < 0)
af6da548 544 r = -errno;
80876c20 545
af6da548 546 if (*saved_stdout >= 0)
80876c20 547 if (dup2(*saved_stdout, STDOUT_FILENO) < 0)
af6da548 548 r = -errno;
80876c20 549
af6da548
LP
550 if (*saved_stdin >= 0)
551 close_nointr_nofail(*saved_stdin);
80876c20 552
af6da548
LP
553 if (*saved_stdout >= 0)
554 close_nointr_nofail(*saved_stdout);
555
556 return r;
557}
558
559static int ask_for_confirmation(char *response, char **argv) {
560 int saved_stdout = -1, saved_stdin = -1, r;
561 char *line;
562
563 r = setup_confirm_stdio(&saved_stdin, &saved_stdout);
564 if (r < 0)
565 return r;
566
567 line = exec_command_line(argv);
568 if (!line)
569 return -ENOMEM;
570
571 r = ask(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
572 free(line);
573
574 restore_confirm_stdio(&saved_stdin, &saved_stdout);
575
576 return r;
80876c20
LP
577}
578
81a2b7ce
LP
579static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) {
580 bool keep_groups = false;
581 int r;
582
583 assert(context);
584
35b8ca3a 585 /* Lookup and set GID and supplementary group list. Here too
81a2b7ce
LP
586 * we avoid NSS lookups for gid=0. */
587
588 if (context->group || username) {
589
4b67834e
LP
590 if (context->group) {
591 const char *g = context->group;
592
593 if ((r = get_group_creds(&g, &gid)) < 0)
81a2b7ce 594 return r;
4b67834e 595 }
81a2b7ce
LP
596
597 /* First step, initialize groups from /etc/groups */
598 if (username && gid != 0) {
599 if (initgroups(username, gid) < 0)
600 return -errno;
601
602 keep_groups = true;
603 }
604
605 /* Second step, set our gids */
606 if (setresgid(gid, gid, gid) < 0)
607 return -errno;
608 }
609
610 if (context->supplementary_groups) {
611 int ngroups_max, k;
612 gid_t *gids;
613 char **i;
614
615 /* Final step, initialize any manually set supplementary groups */
da19d5c1 616 assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0);
81a2b7ce
LP
617
618 if (!(gids = new(gid_t, ngroups_max)))
619 return -ENOMEM;
620
621 if (keep_groups) {
622 if ((k = getgroups(ngroups_max, gids)) < 0) {
623 free(gids);
624 return -errno;
625 }
626 } else
627 k = 0;
628
629 STRV_FOREACH(i, context->supplementary_groups) {
4b67834e 630 const char *g;
81a2b7ce
LP
631
632 if (k >= ngroups_max) {
633 free(gids);
634 return -E2BIG;
635 }
636
4b67834e
LP
637 g = *i;
638 r = get_group_creds(&g, gids+k);
639 if (r < 0) {
81a2b7ce
LP
640 free(gids);
641 return r;
642 }
643
644 k++;
645 }
646
647 if (setgroups(k, gids) < 0) {
648 free(gids);
649 return -errno;
650 }
651
652 free(gids);
653 }
654
655 return 0;
656}
657
658static int enforce_user(const ExecContext *context, uid_t uid) {
659 int r;
660 assert(context);
661
662 /* Sets (but doesn't lookup) the uid and make sure we keep the
663 * capabilities while doing so. */
664
665 if (context->capabilities) {
666 cap_t d;
667 static const cap_value_t bits[] = {
668 CAP_SETUID, /* Necessary so that we can run setresuid() below */
669 CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */
670 };
671
672 /* First step: If we need to keep capabilities but
673 * drop privileges we need to make sure we keep our
cbb21cca 674 * caps, while we drop privileges. */
693ced48 675 if (uid != 0) {
cbb21cca 676 int sb = context->secure_bits | 1<<SECURE_KEEP_CAPS;
693ced48
LP
677
678 if (prctl(PR_GET_SECUREBITS) != sb)
679 if (prctl(PR_SET_SECUREBITS, sb) < 0)
680 return -errno;
681 }
81a2b7ce 682
35b8ca3a 683 /* Second step: set the capabilities. This will reduce
81a2b7ce
LP
684 * the capabilities to the minimum we need. */
685
686 if (!(d = cap_dup(context->capabilities)))
687 return -errno;
688
689 if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 ||
690 cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0) {
691 r = -errno;
692 cap_free(d);
693 return r;
694 }
695
696 if (cap_set_proc(d) < 0) {
697 r = -errno;
698 cap_free(d);
699 return r;
700 }
701
702 cap_free(d);
703 }
704
705 /* Third step: actually set the uids */
706 if (setresuid(uid, uid, uid) < 0)
707 return -errno;
708
709 /* At this point we should have all necessary capabilities but
710 are otherwise a normal user. However, the caps might got
711 corrupted due to the setresuid() so we need clean them up
712 later. This is done outside of this call. */
713
714 return 0;
715}
716
5b6319dc
LP
717#ifdef HAVE_PAM
718
719static int null_conv(
720 int num_msg,
721 const struct pam_message **msg,
722 struct pam_response **resp,
723 void *appdata_ptr) {
724
725 /* We don't support conversations */
726
727 return PAM_CONV_ERR;
728}
729
730static int setup_pam(
731 const char *name,
732 const char *user,
940c5210 733 uid_t uid,
5b6319dc
LP
734 const char *tty,
735 char ***pam_env,
736 int fds[], unsigned n_fds) {
737
738 static const struct pam_conv conv = {
739 .conv = null_conv,
740 .appdata_ptr = NULL
741 };
742
743 pam_handle_t *handle = NULL;
744 sigset_t ss, old_ss;
745 int pam_code = PAM_SUCCESS;
9ba35398 746 int err;
5b6319dc
LP
747 char **e = NULL;
748 bool close_session = false;
749 pid_t pam_pid = 0, parent_pid;
750
751 assert(name);
752 assert(user);
753 assert(pam_env);
754
755 /* We set up PAM in the parent process, then fork. The child
35b8ca3a 756 * will then stay around until killed via PR_GET_PDEATHSIG or
5b6319dc
LP
757 * systemd via the cgroup logic. It will then remove the PAM
758 * session again. The parent process will exec() the actual
759 * daemon. We do things this way to ensure that the main PID
760 * of the daemon is the one we initially fork()ed. */
761
762 if ((pam_code = pam_start(name, user, &conv, &handle)) != PAM_SUCCESS) {
763 handle = NULL;
764 goto fail;
765 }
766
767 if (tty)
768 if ((pam_code = pam_set_item(handle, PAM_TTY, tty)) != PAM_SUCCESS)
769 goto fail;
770
771 if ((pam_code = pam_acct_mgmt(handle, PAM_SILENT)) != PAM_SUCCESS)
772 goto fail;
773
774 if ((pam_code = pam_open_session(handle, PAM_SILENT)) != PAM_SUCCESS)
775 goto fail;
776
777 close_session = true;
778
5b6319dc
LP
779 if ((!(e = pam_getenvlist(handle)))) {
780 pam_code = PAM_BUF_ERR;
781 goto fail;
782 }
783
784 /* Block SIGTERM, so that we know that it won't get lost in
785 * the child */
786 if (sigemptyset(&ss) < 0 ||
787 sigaddset(&ss, SIGTERM) < 0 ||
788 sigprocmask(SIG_BLOCK, &ss, &old_ss) < 0)
789 goto fail;
790
791 parent_pid = getpid();
792
793 if ((pam_pid = fork()) < 0)
794 goto fail;
795
796 if (pam_pid == 0) {
797 int sig;
798 int r = EXIT_PAM;
799
800 /* The child's job is to reset the PAM session on
801 * termination */
802
803 /* This string must fit in 10 chars (i.e. the length
5d6b1584
LP
804 * of "/sbin/init"), to look pretty in /bin/ps */
805 rename_process("(sd-pam)");
5b6319dc
LP
806
807 /* Make sure we don't keep open the passed fds in this
808 child. We assume that otherwise only those fds are
809 open here that have been opened by PAM. */
810 close_many(fds, n_fds);
811
940c5210
AK
812 /* Drop privileges - we don't need any to pam_close_session
813 * and this will make PR_SET_PDEATHSIG work in most cases.
814 * If this fails, ignore the error - but expect sd-pam threads
815 * to fail to exit normally */
816 if (setresuid(uid, uid, uid) < 0)
817 log_error("Error: Failed to setresuid() in sd-pam: %s", strerror(-r));
818
819 /* Wait until our parent died. This will only work if
820 * the above setresuid() succeeds, otherwise the kernel
821 * will not allow unprivileged parents kill their privileged
822 * children this way. We rely on the control groups kill logic
5b6319dc
LP
823 * to do the rest for us. */
824 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
825 goto child_finish;
826
827 /* Check if our parent process might already have
828 * died? */
829 if (getppid() == parent_pid) {
3dead8d9
LP
830 for (;;) {
831 if (sigwait(&ss, &sig) < 0) {
832 if (errno == EINTR)
833 continue;
834
835 goto child_finish;
836 }
5b6319dc 837
3dead8d9
LP
838 assert(sig == SIGTERM);
839 break;
840 }
5b6319dc
LP
841 }
842
3dead8d9 843 /* If our parent died we'll end the session */
5b6319dc
LP
844 if (getppid() != parent_pid)
845 if ((pam_code = pam_close_session(handle, PAM_DATA_SILENT)) != PAM_SUCCESS)
846 goto child_finish;
847
848 r = 0;
849
850 child_finish:
851 pam_end(handle, pam_code | PAM_DATA_SILENT);
852 _exit(r);
853 }
854
855 /* If the child was forked off successfully it will do all the
856 * cleanups, so forget about the handle here. */
857 handle = NULL;
858
3b8bddde 859 /* Unblock SIGTERM again in the parent */
5b6319dc
LP
860 if (sigprocmask(SIG_SETMASK, &old_ss, NULL) < 0)
861 goto fail;
862
863 /* We close the log explicitly here, since the PAM modules
864 * might have opened it, but we don't want this fd around. */
865 closelog();
866
aa87e624
LP
867 *pam_env = e;
868 e = NULL;
869
5b6319dc
LP
870 return 0;
871
872fail:
9ba35398
MS
873 if (pam_code != PAM_SUCCESS)
874 err = -EPERM; /* PAM errors do not map to errno */
875 else
876 err = -errno;
877
5b6319dc
LP
878 if (handle) {
879 if (close_session)
880 pam_code = pam_close_session(handle, PAM_DATA_SILENT);
881
882 pam_end(handle, pam_code | PAM_DATA_SILENT);
883 }
884
885 strv_free(e);
886
887 closelog();
888
430c18ed 889 if (pam_pid > 1) {
5b6319dc 890 kill(pam_pid, SIGTERM);
430c18ed
LP
891 kill(pam_pid, SIGCONT);
892 }
5b6319dc 893
9ba35398 894 return err;
5b6319dc
LP
895}
896#endif
897
5d6b1584
LP
898static void rename_process_from_path(const char *path) {
899 char process_name[11];
900 const char *p;
901 size_t l;
902
903 /* This resulting string must fit in 10 chars (i.e. the length
904 * of "/sbin/init") to look pretty in /bin/ps */
905
9eb977db 906 p = path_get_file_name(path);
5d6b1584
LP
907 if (isempty(p)) {
908 rename_process("(...)");
909 return;
910 }
911
912 l = strlen(p);
913 if (l > 8) {
914 /* The end of the process name is usually more
915 * interesting, since the first bit might just be
916 * "systemd-" */
917 p = p + l - 8;
918 l = 8;
919 }
920
921 process_name[0] = '(';
922 memcpy(process_name+1, p, l);
923 process_name[1+l] = ')';
924 process_name[1+l+1] = 0;
925
926 rename_process(process_name);
927}
928
8351ceae
LP
929static int apply_seccomp(uint32_t *syscall_filter) {
930 static const struct sock_filter header[] = {
931 VALIDATE_ARCHITECTURE,
932 EXAMINE_SYSCALL
933 };
934 static const struct sock_filter footer[] = {
935 _KILL_PROCESS
936 };
937
938 int i;
939 unsigned n;
940 struct sock_filter *f;
941 struct sock_fprog prog;
942
943 assert(syscall_filter);
944
945 /* First: count the syscalls to check for */
946 for (i = 0, n = 0; i < syscall_max(); i++)
947 if (syscall_filter[i >> 4] & (1 << (i & 31)))
948 n++;
949
950 /* Second: build the filter program from a header the syscall
951 * matches and the footer */
952 f = alloca(sizeof(struct sock_filter) * (ELEMENTSOF(header) + 2*n + ELEMENTSOF(footer)));
953 memcpy(f, header, sizeof(header));
954
955 for (i = 0, n = 0; i < syscall_max(); i++)
956 if (syscall_filter[i >> 4] & (1 << (i & 31))) {
957 struct sock_filter item[] = {
843fc7f7 958 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, INDEX_TO_SYSCALL(i), 0, 1),
8351ceae
LP
959 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
960 };
961
962 assert_cc(ELEMENTSOF(item) == 2);
963
964 f[ELEMENTSOF(header) + 2*n] = item[0];
965 f[ELEMENTSOF(header) + 2*n+1] = item[1];
966
967 n++;
968 }
969
970 memcpy(f + (ELEMENTSOF(header) + 2*n), footer, sizeof(footer));
971
972 /* Third: install the filter */
973 zero(prog);
974 prog.len = ELEMENTSOF(header) + ELEMENTSOF(footer) + 2*n;
975 prog.filter = f;
976 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0)
977 return -errno;
978
979 return 0;
980}
981
9fb86720 982int exec_spawn(ExecCommand *command,
9e2f7c11 983 char **argv,
c17ec25e 984 ExecContext *context,
c2748801 985 int fds[], unsigned n_fds,
1137a57c 986 char **environment,
81a2b7ce
LP
987 bool apply_permissions,
988 bool apply_chroot,
1e3ad081 989 bool apply_tty_stdin,
80876c20 990 bool confirm_spawn,
8e274523 991 CGroupBonding *cgroup_bondings,
ab1f0633 992 CGroupAttribute *cgroup_attributes,
ecedd90f 993 const char *cgroup_suffix,
62bca2c6 994 const char *unit_id,
f2b68789 995 int idle_pipe[2],
81a2b7ce
LP
996 pid_t *ret) {
997
034c6ed7 998 pid_t pid;
8e274523 999 int r;
1a63a750 1000 char *line;
4f2d528d 1001 int socket_fd;
b66871da 1002 char _cleanup_strv_free_ **files_env = NULL;
034c6ed7 1003
5cb5a6ff
LP
1004 assert(command);
1005 assert(context);
1006 assert(ret);
034c6ed7
LP
1007 assert(fds || n_fds <= 0);
1008
4f2d528d
LP
1009 if (context->std_input == EXEC_INPUT_SOCKET ||
1010 context->std_output == EXEC_OUTPUT_SOCKET ||
1011 context->std_error == EXEC_OUTPUT_SOCKET) {
1012
1013 if (n_fds != 1)
1014 return -EINVAL;
1015
1016 socket_fd = fds[0];
1017
1018 fds = NULL;
1019 n_fds = 0;
1020 } else
1021 socket_fd = -1;
1022
b66871da
ZJS
1023 r = exec_context_load_environment(context, &files_env);
1024 if (r < 0) {
bbc9006e
MT
1025 log_struct_unit(LOG_ERR,
1026 unit_id,
23635a85
ZJS
1027 "MESSAGE=Failed to load environment files: %s", strerror(-r),
1028 "ERRNO=%d", -r,
1029 NULL);
8c7be95e
LP
1030 return r;
1031 }
1032
9e2f7c11
LP
1033 if (!argv)
1034 argv = command->argv;
1035
af6da548 1036 line = exec_command_line(argv);
b66871da
ZJS
1037 if (!line)
1038 return log_oom();
1a63a750 1039
bbc9006e
MT
1040 log_struct_unit(LOG_DEBUG,
1041 unit_id,
23635a85
ZJS
1042 "MESSAGE=About to execute %s", line,
1043 NULL);
1a63a750 1044 free(line);
acbb0225 1045
ab1f0633
LP
1046 r = cgroup_bonding_realize_list(cgroup_bondings);
1047 if (r < 0)
b66871da 1048 return r;
ab1f0633
LP
1049
1050 cgroup_attribute_apply_list(cgroup_attributes, cgroup_bondings);
8e274523 1051
c17ec25e
MS
1052 if (context->private_tmp && !context->tmp_dir && !context->var_tmp_dir) {
1053 r = setup_tmpdirs(&context->tmp_dir, &context->var_tmp_dir);
1054 if (r < 0)
1055 return r;
1056 }
1057
b66871da
ZJS
1058 pid = fork();
1059 if (pid < 0)
1060 return -errno;
034c6ed7
LP
1061
1062 if (pid == 0) {
4c2630eb 1063 int i, err;
309bff19 1064 sigset_t ss;
81a2b7ce
LP
1065 const char *username = NULL, *home = NULL;
1066 uid_t uid = (uid_t) -1;
1067 gid_t gid = (gid_t) -1;
b66871da
ZJS
1068 char _cleanup_strv_free_ **our_env = NULL, **pam_env = NULL,
1069 **final_env = NULL, **final_argv = NULL;
81a2b7ce 1070 unsigned n_env = 0;
af6da548 1071 bool set_access = false;
309bff19 1072
034c6ed7 1073 /* child */
5cb5a6ff 1074
5d6b1584 1075 rename_process_from_path(command->path);
5b6319dc 1076
1b91d3e8
LP
1077 /* We reset exactly these signals, since they are the
1078 * only ones we set to SIG_IGN in the main daemon. All
1079 * others we leave untouched because we set them to
1080 * SIG_DFL or a valid handler initially, both of which
1081 * will be demoted to SIG_DFL. */
1082 default_signals(SIGNALS_CRASH_HANDLER,
9a34ec5f 1083 SIGNALS_IGNORE, -1);
7b683879 1084
353e12c2
LP
1085 if (context->ignore_sigpipe)
1086 ignore_signals(SIGPIPE, -1);
1087
1088 assert_se(sigemptyset(&ss) == 0);
1089 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) {
4c2630eb 1090 err = -errno;
309bff19 1091 r = EXIT_SIGNAL_MASK;
8c7be95e 1092 goto fail_child;
309bff19
LP
1093 }
1094
f2b68789
LP
1095 if (idle_pipe) {
1096 if (idle_pipe[1] >= 0)
1097 close_nointr_nofail(idle_pipe[1]);
1098 if (idle_pipe[0] >= 0) {
e6a26745 1099 fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
f2b68789
LP
1100 close_nointr_nofail(idle_pipe[0]);
1101 }
1102 }
1103
85d73053
LP
1104 /* Close sockets very early to make sure we don't
1105 * block init reexecution because it cannot bind its
1106 * sockets */
4d8a7798 1107 log_forget_fds();
4c2630eb
MS
1108 err = close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
1109 socket_fd >= 0 ? 1 : n_fds);
1110 if (err < 0) {
fc9b2a84 1111 r = EXIT_FDS;
8c7be95e 1112 goto fail_child;
fc9b2a84
LP
1113 }
1114
74922904 1115 if (!context->same_pgrp)
8d567588 1116 if (setsid() < 0) {
4c2630eb 1117 err = -errno;
8d567588 1118 r = EXIT_SETSID;
8c7be95e 1119 goto fail_child;
8d567588 1120 }
80876c20 1121
c5da34ef
LP
1122 if (context->tcpwrap_name) {
1123 if (socket_fd >= 0)
1124 if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) {
4c2630eb 1125 err = -EACCES;
c5da34ef 1126 r = EXIT_TCPWRAP;
8c7be95e 1127 goto fail_child;
c5da34ef
LP
1128 }
1129
1130 for (i = 0; i < (int) n_fds; i++) {
1131 if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) {
4c2630eb 1132 err = -EACCES;
c5da34ef 1133 r = EXIT_TCPWRAP;
8c7be95e 1134 goto fail_child;
c5da34ef 1135 }
df1f0afe 1136 }
c5da34ef 1137 }
df1f0afe 1138
6ea832a2
LP
1139 exec_context_tty_reset(context);
1140
af6da548 1141 if (confirm_spawn) {
80876c20
LP
1142 char response;
1143
af6da548
LP
1144 err = ask_for_confirmation(&response, argv);
1145 if (err == -ETIMEDOUT)
1146 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1147 else if (err < 0)
1148 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-err));
1149 else if (response == 's') {
1150 write_confirm_message("Skipping execution.\n");
4c2630eb 1151 err = -ECANCELED;
80876c20 1152 r = EXIT_CONFIRM;
8c7be95e 1153 goto fail_child;
af6da548
LP
1154 } else if (response == 'n') {
1155 write_confirm_message("Failing execution.\n");
4c2630eb 1156 err = r = 0;
8c7be95e 1157 goto fail_child;
ee2b4894 1158 }
034c6ed7
LP
1159 }
1160
da726a4d
LP
1161 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1162 * must sure to drop O_NONBLOCK */
1163 if (socket_fd >= 0)
1164 fd_nonblock(socket_fd, false);
1165
af6da548
LP
1166 err = setup_input(context, socket_fd, apply_tty_stdin);
1167 if (err < 0) {
1168 r = EXIT_STDIN;
1169 goto fail_child;
4c2630eb 1170 }
9eba9da4 1171
eb17e935 1172 err = setup_output(context, STDOUT_FILENO, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin);
af6da548
LP
1173 if (err < 0) {
1174 r = EXIT_STDOUT;
1175 goto fail_child;
4c2630eb 1176 }
94f04347 1177
eb17e935 1178 err = setup_output(context, STDERR_FILENO, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin);
4c2630eb 1179 if (err < 0) {
80876c20 1180 r = EXIT_STDERR;
8c7be95e 1181 goto fail_child;
071830ff
LP
1182 }
1183
4c2630eb 1184 if (cgroup_bondings) {
ecedd90f 1185 err = cgroup_bonding_install_list(cgroup_bondings, 0, cgroup_suffix);
4c2630eb 1186 if (err < 0) {
8e274523 1187 r = EXIT_CGROUP;
8c7be95e 1188 goto fail_child;
8e274523 1189 }
4c2630eb 1190 }
8e274523 1191
dd6c17b1 1192 if (context->oom_score_adjust_set) {
fb33a393 1193 char t[16];
034c6ed7 1194
dd6c17b1 1195 snprintf(t, sizeof(t), "%i", context->oom_score_adjust);
fb33a393 1196 char_array_0(t);
034c6ed7 1197
574d5f2d 1198 if (write_string_file("/proc/self/oom_score_adj", t) < 0) {
8600c525
KS
1199 err = -errno;
1200 r = EXIT_OOM_ADJUST;
1201 goto fail_child;
fb33a393 1202 }
034c6ed7
LP
1203 }
1204
fb33a393
LP
1205 if (context->nice_set)
1206 if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
4c2630eb 1207 err = -errno;
fb33a393 1208 r = EXIT_NICE;
8c7be95e 1209 goto fail_child;
fb33a393
LP
1210 }
1211
94f04347
LP
1212 if (context->cpu_sched_set) {
1213 struct sched_param param;
1214
1215 zero(param);
1216 param.sched_priority = context->cpu_sched_priority;
1217
e62d8c39
ZJS
1218 r = sched_setscheduler(0,
1219 context->cpu_sched_policy |
1220 (context->cpu_sched_reset_on_fork ?
1221 SCHED_RESET_ON_FORK : 0),
1222 &param);
1223 if (r < 0) {
4c2630eb 1224 err = -errno;
94f04347 1225 r = EXIT_SETSCHEDULER;
8c7be95e 1226 goto fail_child;
94f04347
LP
1227 }
1228 }
1229
82c121a4
LP
1230 if (context->cpuset)
1231 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
4c2630eb 1232 err = -errno;
94f04347 1233 r = EXIT_CPUAFFINITY;
8c7be95e 1234 goto fail_child;
94f04347
LP
1235 }
1236
9eba9da4
LP
1237 if (context->ioprio_set)
1238 if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
4c2630eb 1239 err = -errno;
9eba9da4 1240 r = EXIT_IOPRIO;
8c7be95e 1241 goto fail_child;
9eba9da4
LP
1242 }
1243
d88a251b 1244 if (context->timer_slack_nsec != (nsec_t) -1)
03fae018 1245 if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
4c2630eb 1246 err = -errno;
94f04347 1247 r = EXIT_TIMERSLACK;
8c7be95e 1248 goto fail_child;
94f04347
LP
1249 }
1250
169c1bda 1251 if (context->utmp_id)
0ad26e09 1252 utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path);
169c1bda 1253
81a2b7ce
LP
1254 if (context->user) {
1255 username = context->user;
d05c5031 1256 err = get_user_creds(&username, &uid, &gid, &home, NULL);
4c2630eb 1257 if (err < 0) {
81a2b7ce 1258 r = EXIT_USER;
8c7be95e 1259 goto fail_child;
81a2b7ce 1260 }
d8b4e2e9 1261
4c2630eb
MS
1262 if (is_terminal_input(context->std_input)) {
1263 err = chown_terminal(STDIN_FILENO, uid);
1264 if (err < 0) {
d8b4e2e9 1265 r = EXIT_STDIN;
8c7be95e 1266 goto fail_child;
d8b4e2e9 1267 }
4c2630eb 1268 }
64747e2d 1269
4c2630eb
MS
1270 if (cgroup_bondings && context->control_group_modify) {
1271 err = cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid);
1272 if (err >= 0)
891703e1 1273 err = cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid, context->control_group_persistent);
4c2630eb 1274 if (err < 0) {
64747e2d
LP
1275 r = EXIT_CGROUP;
1276 goto fail_child;
1277 }
8d53b453
LP
1278
1279 set_access = true;
1280 }
1281 }
1282
891703e1
KS
1283 if (cgroup_bondings && !set_access && context->control_group_persistent >= 0) {
1284 err = cgroup_bonding_set_task_access_list(cgroup_bondings, (mode_t) -1, (uid_t) -1, (uid_t) -1, context->control_group_persistent);
8d53b453
LP
1285 if (err < 0) {
1286 r = EXIT_CGROUP;
1287 goto fail_child;
4c2630eb 1288 }
81a2b7ce
LP
1289 }
1290
4c2630eb
MS
1291 if (apply_permissions) {
1292 err = enforce_groups(context, username, gid);
1293 if (err < 0) {
3b8bddde
LP
1294 r = EXIT_GROUP;
1295 goto fail_child;
1296 }
4c2630eb 1297 }
3b8bddde
LP
1298
1299 umask(context->umask);
1300
5b6319dc 1301#ifdef HAVE_PAM
b7848021 1302 if (apply_permissions && context->pam_name && username) {
940c5210 1303 err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
4c2630eb 1304 if (err < 0) {
5b6319dc 1305 r = EXIT_PAM;
8c7be95e 1306 goto fail_child;
5b6319dc
LP
1307 }
1308 }
1309#endif
ff01d048
LP
1310 if (context->private_network) {
1311 if (unshare(CLONE_NEWNET) < 0) {
4c2630eb 1312 err = -errno;
ff01d048
LP
1313 r = EXIT_NETWORK;
1314 goto fail_child;
1315 }
1316
1317 loopback_setup();
1318 }
5b6319dc 1319
04aa0cb9
LP
1320 if (strv_length(context->read_write_dirs) > 0 ||
1321 strv_length(context->read_only_dirs) > 0 ||
1322 strv_length(context->inaccessible_dirs) > 0 ||
ac0930c8 1323 context->mount_flags != 0 ||
4c2630eb
MS
1324 context->private_tmp) {
1325 err = setup_namespace(context->read_write_dirs,
1326 context->read_only_dirs,
1327 context->inaccessible_dirs,
c17ec25e
MS
1328 context->tmp_dir,
1329 context->var_tmp_dir,
4c2630eb
MS
1330 context->private_tmp,
1331 context->mount_flags);
1332 if (err < 0) {
1333 r = EXIT_NAMESPACE;
8c7be95e 1334 goto fail_child;
4c2630eb
MS
1335 }
1336 }
04aa0cb9 1337
81a2b7ce
LP
1338 if (apply_chroot) {
1339 if (context->root_directory)
1340 if (chroot(context->root_directory) < 0) {
4c2630eb 1341 err = -errno;
81a2b7ce 1342 r = EXIT_CHROOT;
8c7be95e 1343 goto fail_child;
81a2b7ce
LP
1344 }
1345
1346 if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
4c2630eb 1347 err = -errno;
81a2b7ce 1348 r = EXIT_CHDIR;
8c7be95e 1349 goto fail_child;
81a2b7ce
LP
1350 }
1351 } else {
b66871da 1352 char _cleanup_free_ *d = NULL;
81a2b7ce
LP
1353
1354 if (asprintf(&d, "%s/%s",
1355 context->root_directory ? context->root_directory : "",
1356 context->working_directory ? context->working_directory : "") < 0) {
4c2630eb 1357 err = -ENOMEM;
81a2b7ce 1358 r = EXIT_MEMORY;
8c7be95e 1359 goto fail_child;
81a2b7ce
LP
1360 }
1361
1362 if (chdir(d) < 0) {
4c2630eb 1363 err = -errno;
81a2b7ce 1364 r = EXIT_CHDIR;
8c7be95e 1365 goto fail_child;
81a2b7ce 1366 }
81a2b7ce
LP
1367 }
1368
fc9b2a84
LP
1369 /* We repeat the fd closing here, to make sure that
1370 * nothing is leaked from the PAM modules */
4c2630eb
MS
1371 err = close_all_fds(fds, n_fds);
1372 if (err >= 0)
1373 err = shift_fds(fds, n_fds);
1374 if (err >= 0)
1375 err = flags_fds(fds, n_fds, context->non_blocking);
1376 if (err < 0) {
034c6ed7 1377 r = EXIT_FDS;
8c7be95e 1378 goto fail_child;
034c6ed7
LP
1379 }
1380
81a2b7ce 1381 if (apply_permissions) {
034c6ed7 1382
81a2b7ce
LP
1383 for (i = 0; i < RLIMIT_NLIMITS; i++) {
1384 if (!context->rlimit[i])
1385 continue;
1386
68faf98c 1387 if (setrlimit_closest(i, context->rlimit[i]) < 0) {
4c2630eb 1388 err = -errno;
81a2b7ce 1389 r = EXIT_LIMITS;
8c7be95e 1390 goto fail_child;
81a2b7ce 1391 }
034c6ed7 1392 }
034c6ed7 1393
4c2630eb 1394 if (context->capability_bounding_set_drop) {
ec8927ca 1395 err = capability_bounding_set_drop(context->capability_bounding_set_drop, false);
4c2630eb 1396 if (err < 0) {
73090dc8
LP
1397 r = EXIT_CAPABILITIES;
1398 goto fail_child;
1399 }
4c2630eb 1400 }
260abb78 1401
4c2630eb
MS
1402 if (context->user) {
1403 err = enforce_user(context, uid);
1404 if (err < 0) {
81a2b7ce 1405 r = EXIT_USER;
8c7be95e 1406 goto fail_child;
81a2b7ce 1407 }
4c2630eb 1408 }
81a2b7ce 1409
35b8ca3a 1410 /* PR_GET_SECUREBITS is not privileged, while
693ced48
LP
1411 * PR_SET_SECUREBITS is. So to suppress
1412 * potential EPERMs we'll try not to call
1413 * PR_SET_SECUREBITS unless necessary. */
1414 if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
1415 if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
4c2630eb 1416 err = -errno;
693ced48 1417 r = EXIT_SECUREBITS;
8c7be95e 1418 goto fail_child;
693ced48 1419 }
81a2b7ce
LP
1420
1421 if (context->capabilities)
1422 if (cap_set_proc(context->capabilities) < 0) {
4c2630eb 1423 err = -errno;
81a2b7ce 1424 r = EXIT_CAPABILITIES;
8c7be95e 1425 goto fail_child;
81a2b7ce 1426 }
8351ceae
LP
1427
1428 if (context->no_new_privileges)
1429 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
1430 err = -errno;
1431 r = EXIT_NO_NEW_PRIVILEGES;
1432 goto fail_child;
1433 }
1434
1435 if (context->syscall_filter) {
1436 err = apply_seccomp(context->syscall_filter);
1437 if (err < 0) {
1438 r = EXIT_SECCOMP;
1439 goto fail_child;
1440 }
1441 }
94f04347
LP
1442 }
1443
e62d8c39
ZJS
1444 our_env = new0(char*, 7);
1445 if (!our_env) {
4c2630eb 1446 err = -ENOMEM;
81a2b7ce 1447 r = EXIT_MEMORY;
8c7be95e 1448 goto fail_child;
81a2b7ce 1449 }
034c6ed7 1450
81a2b7ce 1451 if (n_fds > 0)
bb00e604 1452 if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 ||
81a2b7ce 1453 asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) {
4c2630eb 1454 err = -ENOMEM;
81a2b7ce 1455 r = EXIT_MEMORY;
8c7be95e 1456 goto fail_child;
81a2b7ce 1457 }
034c6ed7 1458
81a2b7ce
LP
1459 if (home)
1460 if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) {
4c2630eb 1461 err = -ENOMEM;
81a2b7ce 1462 r = EXIT_MEMORY;
8c7be95e 1463 goto fail_child;
81a2b7ce 1464 }
034c6ed7 1465
81a2b7ce
LP
1466 if (username)
1467 if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 ||
1468 asprintf(our_env + n_env++, "USER=%s", username) < 0) {
4c2630eb 1469 err = -ENOMEM;
81a2b7ce 1470 r = EXIT_MEMORY;
8c7be95e 1471 goto fail_child;
81a2b7ce 1472 }
034c6ed7 1473
e3aa71c3
LP
1474 if (is_terminal_input(context->std_input) ||
1475 context->std_output == EXEC_OUTPUT_TTY ||
1476 context->std_error == EXEC_OUTPUT_TTY)
1477 if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) {
4c2630eb 1478 err = -ENOMEM;
e3aa71c3 1479 r = EXIT_MEMORY;
8c7be95e 1480 goto fail_child;
e3aa71c3
LP
1481 }
1482
1483 assert(n_env <= 7);
4e85aff4 1484
e62d8c39
ZJS
1485 final_env = strv_env_merge(5,
1486 environment,
1487 our_env,
1488 context->environment,
1489 files_env,
1490 pam_env,
1491 NULL);
1492 if (!final_env) {
4c2630eb 1493 err = -ENOMEM;
81a2b7ce 1494 r = EXIT_MEMORY;
8c7be95e 1495 goto fail_child;
81a2b7ce 1496 }
034c6ed7 1497
e62d8c39
ZJS
1498 final_argv = replace_env_argv(argv, final_env);
1499 if (!final_argv) {
4c2630eb 1500 err = -ENOMEM;
fab56fc5 1501 r = EXIT_MEMORY;
8c7be95e 1502 goto fail_child;
fab56fc5
LP
1503 }
1504
a6ff950e
LP
1505 final_env = strv_env_clean(final_env);
1506
fab56fc5 1507 execve(command->path, final_argv, final_env);
4c2630eb 1508 err = -errno;
034c6ed7
LP
1509 r = EXIT_EXEC;
1510
8c7be95e 1511 fail_child:
4c2630eb
MS
1512 if (r != 0) {
1513 log_open();
23635a85
ZJS
1514 log_struct(LOG_ERR, MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
1515 "EXECUTABLE=%s", command->path,
1516 "MESSAGE=Failed at step %s spawning %s: %s",
1517 exit_status_to_string(r, EXIT_STATUS_SYSTEMD),
1518 command->path, strerror(-err),
1519 "ERRNO=%d", -err,
1520 NULL);
1521 log_close();
4c2630eb
MS
1522 }
1523
034c6ed7
LP
1524 _exit(r);
1525 }
1526
bbc9006e 1527 log_struct_unit(LOG_DEBUG,
e62d8c39
ZJS
1528 unit_id,
1529 "MESSAGE=Forked %s as %lu",
1530 command->path, (unsigned long) pid,
1531 NULL);
23635a85 1532
80876c20
LP
1533 /* We add the new process to the cgroup both in the child (so
1534 * that we can be sure that no user code is ever executed
1535 * outside of the cgroup) and in the parent (so that we can be
1536 * sure that when we kill the cgroup the process will be
1537 * killed too). */
1538 if (cgroup_bondings)
ecedd90f 1539 cgroup_bonding_install_list(cgroup_bondings, pid, cgroup_suffix);
2da3263a 1540
b58b4116 1541 exec_status_start(&command->exec_status, pid);
9fb86720 1542
034c6ed7 1543 *ret = pid;
5cb5a6ff
LP
1544 return 0;
1545}
1546
034c6ed7
LP
1547void exec_context_init(ExecContext *c) {
1548 assert(c);
1549
4c12626c 1550 c->umask = 0022;
9eba9da4 1551 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
94f04347 1552 c->cpu_sched_policy = SCHED_OTHER;
071830ff 1553 c->syslog_priority = LOG_DAEMON|LOG_INFO;
74922904 1554 c->syslog_level_prefix = true;
891703e1 1555 c->control_group_persistent = -1;
353e12c2 1556 c->ignore_sigpipe = true;
d88a251b 1557 c->timer_slack_nsec = (nsec_t) -1;
034c6ed7
LP
1558}
1559
c17ec25e 1560void exec_context_tmp_dirs_done(ExecContext *c) {
d34cd374
ZJS
1561 char* dirs[] = {c->tmp_dir ? c->tmp_dir : c->var_tmp_dir,
1562 c->tmp_dir ? c->var_tmp_dir : NULL,
1563 NULL};
1564 char **dirp;
c17ec25e 1565
d34cd374
ZJS
1566 for(dirp = dirs; *dirp; dirp++) {
1567 char *dir;
ebf4fb3d 1568 int r;
c17ec25e 1569
ebf4fb3d 1570 r = rm_rf_dangerous(*dirp, false, true, false);
d34cd374 1571 dir = dirname(*dirp);
ebf4fb3d
VP
1572 if (r < 0)
1573 log_warning("Failed to remove content of temporary directory %s: %s",
1574 dir, strerror(-r));
1575 else {
1576 r = rmdir(dir);
1577 if (r < 0)
1578 log_warning("Failed to remove temporary directory %s: %s",
1579 dir, strerror(-r));
1580 }
d34cd374
ZJS
1581
1582 free(*dirp);
c17ec25e 1583 }
d34cd374
ZJS
1584
1585 c->tmp_dir = c->var_tmp_dir = NULL;
c17ec25e
MS
1586}
1587
1588void exec_context_done(ExecContext *c, bool reloading_or_reexecuting) {
5cb5a6ff
LP
1589 unsigned l;
1590
1591 assert(c);
1592
1593 strv_free(c->environment);
034c6ed7 1594 c->environment = NULL;
5cb5a6ff 1595
8c7be95e
LP
1596 strv_free(c->environment_files);
1597 c->environment_files = NULL;
1598
034c6ed7 1599 for (l = 0; l < ELEMENTSOF(c->rlimit); l++) {
5cb5a6ff 1600 free(c->rlimit[l]);
034c6ed7
LP
1601 c->rlimit[l] = NULL;
1602 }
1603
9eba9da4
LP
1604 free(c->working_directory);
1605 c->working_directory = NULL;
1606 free(c->root_directory);
1607 c->root_directory = NULL;
5cb5a6ff 1608
80876c20
LP
1609 free(c->tty_path);
1610 c->tty_path = NULL;
1611
df1f0afe
LP
1612 free(c->tcpwrap_name);
1613 c->tcpwrap_name = NULL;
1614
071830ff
LP
1615 free(c->syslog_identifier);
1616 c->syslog_identifier = NULL;
1617
5cb5a6ff 1618 free(c->user);
034c6ed7
LP
1619 c->user = NULL;
1620
5cb5a6ff 1621 free(c->group);
034c6ed7
LP
1622 c->group = NULL;
1623
1624 strv_free(c->supplementary_groups);
1625 c->supplementary_groups = NULL;
94f04347 1626
5b6319dc
LP
1627 free(c->pam_name);
1628 c->pam_name = NULL;
1629
94f04347
LP
1630 if (c->capabilities) {
1631 cap_free(c->capabilities);
1632 c->capabilities = NULL;
1633 }
15ae422b
LP
1634
1635 strv_free(c->read_only_dirs);
1636 c->read_only_dirs = NULL;
1637
1638 strv_free(c->read_write_dirs);
1639 c->read_write_dirs = NULL;
1640
1641 strv_free(c->inaccessible_dirs);
1642 c->inaccessible_dirs = NULL;
82c121a4
LP
1643
1644 if (c->cpuset)
1645 CPU_FREE(c->cpuset);
86a3475b
LP
1646
1647 free(c->utmp_id);
1648 c->utmp_id = NULL;
b9a0e010
LP
1649
1650 free(c->syscall_filter);
1651 c->syscall_filter = NULL;
c17ec25e
MS
1652
1653 if (!reloading_or_reexecuting)
1654 exec_context_tmp_dirs_done(c);
5cb5a6ff
LP
1655}
1656
43d0fcbd
LP
1657void exec_command_done(ExecCommand *c) {
1658 assert(c);
1659
1660 free(c->path);
1661 c->path = NULL;
1662
1663 strv_free(c->argv);
1664 c->argv = NULL;
1665}
1666
1667void exec_command_done_array(ExecCommand *c, unsigned n) {
1668 unsigned i;
1669
1670 for (i = 0; i < n; i++)
1671 exec_command_done(c+i);
1672}
1673
5cb5a6ff
LP
1674void exec_command_free_list(ExecCommand *c) {
1675 ExecCommand *i;
1676
1677 while ((i = c)) {
034c6ed7 1678 LIST_REMOVE(ExecCommand, command, c, i);
43d0fcbd 1679 exec_command_done(i);
5cb5a6ff
LP
1680 free(i);
1681 }
1682}
1683
034c6ed7
LP
1684void exec_command_free_array(ExecCommand **c, unsigned n) {
1685 unsigned i;
1686
1687 for (i = 0; i < n; i++) {
1688 exec_command_free_list(c[i]);
1689 c[i] = NULL;
1690 }
1691}
1692
8c7be95e
LP
1693int exec_context_load_environment(const ExecContext *c, char ***l) {
1694 char **i, **r = NULL;
1695
1696 assert(c);
1697 assert(l);
1698
1699 STRV_FOREACH(i, c->environment_files) {
1700 char *fn;
1701 int k;
1702 bool ignore = false;
1703 char **p;
2bef10ab
PL
1704 glob_t pglob;
1705 int count, n;
8c7be95e
LP
1706
1707 fn = *i;
1708
1709 if (fn[0] == '-') {
1710 ignore = true;
1711 fn ++;
1712 }
1713
1714 if (!path_is_absolute(fn)) {
1715
1716 if (ignore)
1717 continue;
1718
1719 strv_free(r);
1720 return -EINVAL;
1721 }
1722
2bef10ab
PL
1723 /* Filename supports globbing, take all matching files */
1724 zero(pglob);
1725 errno = 0;
1726 if (glob(fn, 0, NULL, &pglob) != 0) {
1727 globfree(&pglob);
1728 if (ignore)
1729 continue;
8c7be95e 1730
2bef10ab
PL
1731 strv_free(r);
1732 return errno ? -errno : -EINVAL;
1733 }
1734 count = pglob.gl_pathc;
1735 if (count == 0) {
1736 globfree(&pglob);
8c7be95e
LP
1737 if (ignore)
1738 continue;
1739
1740 strv_free(r);
2bef10ab 1741 return -EINVAL;
8c7be95e 1742 }
2bef10ab 1743 for (n = 0; n < count; n++) {
f73141d7 1744 k = load_env_file(pglob.gl_pathv[n], NULL, &p);
2bef10ab
PL
1745 if (k < 0) {
1746 if (ignore)
1747 continue;
8c7be95e 1748
2bef10ab
PL
1749 strv_free(r);
1750 globfree(&pglob);
1751 return k;
1752 }
8c7be95e 1753
2bef10ab
PL
1754 if (r == NULL)
1755 r = p;
1756 else {
1757 char **m;
8c7be95e 1758
2bef10ab
PL
1759 m = strv_env_merge(2, r, p);
1760 strv_free(r);
1761 strv_free(p);
8c7be95e 1762
2bef10ab
PL
1763 if (!m) {
1764 globfree(&pglob);
1765 return -ENOMEM;
1766 }
1767
1768 r = m;
1769 }
8c7be95e 1770 }
2bef10ab 1771 globfree(&pglob);
8c7be95e
LP
1772 }
1773
1774 *l = r;
1775
1776 return 0;
1777}
1778
6ac8fdc9
MS
1779static bool tty_may_match_dev_console(const char *tty) {
1780 char *active = NULL, *console;
1781 bool b;
1782
1783 if (startswith(tty, "/dev/"))
1784 tty += 5;
1785
1786 /* trivial identity? */
1787 if (streq(tty, "console"))
1788 return true;
1789
1790 console = resolve_dev_console(&active);
1791 /* if we could not resolve, assume it may */
1792 if (!console)
1793 return true;
1794
1795 /* "tty0" means the active VC, so it may be the same sometimes */
1796 b = streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
1797 free(active);
1798
1799 return b;
1800}
1801
1802bool exec_context_may_touch_console(ExecContext *ec) {
1803 return (ec->tty_reset || ec->tty_vhangup || ec->tty_vt_disallocate ||
1804 is_terminal_input(ec->std_input) ||
1805 is_terminal_output(ec->std_output) ||
1806 is_terminal_output(ec->std_error)) &&
1807 tty_may_match_dev_console(tty_path(ec));
1808}
1809
15ae422b
LP
1810static void strv_fprintf(FILE *f, char **l) {
1811 char **g;
1812
1813 assert(f);
1814
1815 STRV_FOREACH(g, l)
1816 fprintf(f, " %s", *g);
1817}
1818
5cb5a6ff 1819void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
94f04347
LP
1820 char ** e;
1821 unsigned i;
9eba9da4 1822
5cb5a6ff
LP
1823 assert(c);
1824 assert(f);
1825
1826 if (!prefix)
1827 prefix = "";
1828
1829 fprintf(f,
94f04347
LP
1830 "%sUMask: %04o\n"
1831 "%sWorkingDirectory: %s\n"
451a074f 1832 "%sRootDirectory: %s\n"
15ae422b 1833 "%sNonBlocking: %s\n"
64747e2d 1834 "%sPrivateTmp: %s\n"
ff01d048 1835 "%sControlGroupModify: %s\n"
891703e1 1836 "%sControlGroupPersistent: %s\n"
4819ff03
LP
1837 "%sPrivateNetwork: %s\n"
1838 "%sIgnoreSIGPIPE: %s\n",
5cb5a6ff 1839 prefix, c->umask,
9eba9da4 1840 prefix, c->working_directory ? c->working_directory : "/",
451a074f 1841 prefix, c->root_directory ? c->root_directory : "/",
15ae422b 1842 prefix, yes_no(c->non_blocking),
64747e2d 1843 prefix, yes_no(c->private_tmp),
ff01d048 1844 prefix, yes_no(c->control_group_modify),
891703e1 1845 prefix, yes_no(c->control_group_persistent),
4819ff03
LP
1846 prefix, yes_no(c->private_network),
1847 prefix, yes_no(c->ignore_sigpipe));
fb33a393 1848
8c7be95e
LP
1849 STRV_FOREACH(e, c->environment)
1850 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
1851
1852 STRV_FOREACH(e, c->environment_files)
1853 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
94f04347 1854
df1f0afe
LP
1855 if (c->tcpwrap_name)
1856 fprintf(f,
1857 "%sTCPWrapName: %s\n",
1858 prefix, c->tcpwrap_name);
1859
fb33a393
LP
1860 if (c->nice_set)
1861 fprintf(f,
1862 "%sNice: %i\n",
1863 prefix, c->nice);
1864
dd6c17b1 1865 if (c->oom_score_adjust_set)
fb33a393 1866 fprintf(f,
dd6c17b1
LP
1867 "%sOOMScoreAdjust: %i\n",
1868 prefix, c->oom_score_adjust);
9eba9da4 1869
94f04347
LP
1870 for (i = 0; i < RLIM_NLIMITS; i++)
1871 if (c->rlimit[i])
ea430986 1872 fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max);
94f04347 1873
f8b69d1d
MS
1874 if (c->ioprio_set) {
1875 char *class_str;
1876 int r;
1877
1878 r = ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
1879 if (r < 0)
1880 class_str = NULL;
9eba9da4
LP
1881 fprintf(f,
1882 "%sIOSchedulingClass: %s\n"
1883 "%sIOPriority: %i\n",
f8b69d1d 1884 prefix, strna(class_str),
9eba9da4 1885 prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
f8b69d1d
MS
1886 free(class_str);
1887 }
94f04347 1888
f8b69d1d
MS
1889 if (c->cpu_sched_set) {
1890 char *policy_str;
1891 int r;
1892
1893 r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
1894 if (r < 0)
1895 policy_str = NULL;
94f04347
LP
1896 fprintf(f,
1897 "%sCPUSchedulingPolicy: %s\n"
38b48754
LP
1898 "%sCPUSchedulingPriority: %i\n"
1899 "%sCPUSchedulingResetOnFork: %s\n",
f8b69d1d 1900 prefix, strna(policy_str),
38b48754
LP
1901 prefix, c->cpu_sched_priority,
1902 prefix, yes_no(c->cpu_sched_reset_on_fork));
f8b69d1d 1903 free(policy_str);
b929bf04 1904 }
94f04347 1905
82c121a4 1906 if (c->cpuset) {
94f04347 1907 fprintf(f, "%sCPUAffinity:", prefix);
82c121a4
LP
1908 for (i = 0; i < c->cpuset_ncpus; i++)
1909 if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
94f04347
LP
1910 fprintf(f, " %i", i);
1911 fputs("\n", f);
1912 }
1913
d88a251b 1914 if (c->timer_slack_nsec != (nsec_t) -1)
f96096db 1915 fprintf(f, "%sTimerSlackNSec: %lu\n", prefix, (unsigned long)c->timer_slack_nsec);
94f04347
LP
1916
1917 fprintf(f,
80876c20
LP
1918 "%sStandardInput: %s\n"
1919 "%sStandardOutput: %s\n"
1920 "%sStandardError: %s\n",
1921 prefix, exec_input_to_string(c->std_input),
1922 prefix, exec_output_to_string(c->std_output),
1923 prefix, exec_output_to_string(c->std_error));
1924
1925 if (c->tty_path)
1926 fprintf(f,
6ea832a2
LP
1927 "%sTTYPath: %s\n"
1928 "%sTTYReset: %s\n"
1929 "%sTTYVHangup: %s\n"
1930 "%sTTYVTDisallocate: %s\n",
1931 prefix, c->tty_path,
1932 prefix, yes_no(c->tty_reset),
1933 prefix, yes_no(c->tty_vhangup),
1934 prefix, yes_no(c->tty_vt_disallocate));
94f04347 1935
706343f4
LP
1936 if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG || c->std_output == EXEC_OUTPUT_JOURNAL ||
1937 c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
1938 c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG || c->std_error == EXEC_OUTPUT_JOURNAL ||
f8b69d1d
MS
1939 c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) {
1940 char *fac_str, *lvl_str;
1941 int r;
1942
1943 r = log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
1944 if (r < 0)
1945 fac_str = NULL;
1946
1947 r = log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
1948 if (r < 0)
1949 lvl_str = NULL;
1950
94f04347
LP
1951 fprintf(f,
1952 "%sSyslogFacility: %s\n"
1953 "%sSyslogLevel: %s\n",
f8b69d1d
MS
1954 prefix, strna(fac_str),
1955 prefix, strna(lvl_str));
1956 free(lvl_str);
1957 free(fac_str);
1958 }
94f04347
LP
1959
1960 if (c->capabilities) {
1961 char *t;
1962 if ((t = cap_to_text(c->capabilities, NULL))) {
1963 fprintf(f, "%sCapabilities: %s\n",
1964 prefix, t);
1965 cap_free(t);
1966 }
1967 }
1968
1969 if (c->secure_bits)
1970 fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
1971 prefix,
cbb21cca
ZJS
1972 (c->secure_bits & 1<<SECURE_KEEP_CAPS) ? " keep-caps" : "",
1973 (c->secure_bits & 1<<SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
1974 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
1975 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
1976 (c->secure_bits & 1<<SECURE_NOROOT) ? " noroot" : "",
1977 (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
94f04347
LP
1978
1979 if (c->capability_bounding_set_drop) {
ae556c21 1980 unsigned long l;
260abb78 1981 fprintf(f, "%sCapabilityBoundingSet:", prefix);
94f04347 1982
64685e0c 1983 for (l = 0; l <= cap_last_cap(); l++)
ae556c21 1984 if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) {
94f04347
LP
1985 char *t;
1986
ae556c21 1987 if ((t = cap_to_name(l))) {
94f04347 1988 fprintf(f, " %s", t);
260abb78 1989 cap_free(t);
94f04347
LP
1990 }
1991 }
1992
1993 fputs("\n", f);
1994 }
1995
1996 if (c->user)
f2d3769a 1997 fprintf(f, "%sUser: %s\n", prefix, c->user);
94f04347 1998 if (c->group)
f2d3769a 1999 fprintf(f, "%sGroup: %s\n", prefix, c->group);
94f04347 2000
15ae422b 2001 if (strv_length(c->supplementary_groups) > 0) {
94f04347 2002 fprintf(f, "%sSupplementaryGroups:", prefix);
15ae422b
LP
2003 strv_fprintf(f, c->supplementary_groups);
2004 fputs("\n", f);
2005 }
94f04347 2006
5b6319dc 2007 if (c->pam_name)
f2d3769a 2008 fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
5b6319dc 2009
15ae422b
LP
2010 if (strv_length(c->read_write_dirs) > 0) {
2011 fprintf(f, "%sReadWriteDirs:", prefix);
2012 strv_fprintf(f, c->read_write_dirs);
2013 fputs("\n", f);
2014 }
2015
2016 if (strv_length(c->read_only_dirs) > 0) {
2017 fprintf(f, "%sReadOnlyDirs:", prefix);
2018 strv_fprintf(f, c->read_only_dirs);
2019 fputs("\n", f);
2020 }
94f04347 2021
15ae422b
LP
2022 if (strv_length(c->inaccessible_dirs) > 0) {
2023 fprintf(f, "%sInaccessibleDirs:", prefix);
2024 strv_fprintf(f, c->inaccessible_dirs);
94f04347
LP
2025 fputs("\n", f);
2026 }
2e22afe9 2027
169c1bda
LP
2028 if (c->utmp_id)
2029 fprintf(f,
2030 "%sUtmpIdentifier: %s\n",
2031 prefix, c->utmp_id);
5cb5a6ff
LP
2032}
2033
b58b4116 2034void exec_status_start(ExecStatus *s, pid_t pid) {
034c6ed7 2035 assert(s);
5cb5a6ff 2036
b58b4116
LP
2037 zero(*s);
2038 s->pid = pid;
2039 dual_timestamp_get(&s->start_timestamp);
2040}
2041
6ea832a2 2042void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
b58b4116
LP
2043 assert(s);
2044
0b1f4ae6 2045 if (s->pid && s->pid != pid)
b58b4116
LP
2046 zero(*s);
2047
034c6ed7 2048 s->pid = pid;
63983207 2049 dual_timestamp_get(&s->exit_timestamp);
9fb86720 2050
034c6ed7
LP
2051 s->code = code;
2052 s->status = status;
169c1bda 2053
6ea832a2
LP
2054 if (context) {
2055 if (context->utmp_id)
2056 utmp_put_dead_process(context->utmp_id, pid, code, status);
2057
2058 exec_context_tty_reset(context);
2059 }
9fb86720
LP
2060}
2061
2062void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
2063 char buf[FORMAT_TIMESTAMP_MAX];
2064
2065 assert(s);
2066 assert(f);
2067
2068 if (!prefix)
2069 prefix = "";
2070
2071 if (s->pid <= 0)
2072 return;
2073
2074 fprintf(f,
bb00e604
LP
2075 "%sPID: %lu\n",
2076 prefix, (unsigned long) s->pid);
9fb86720 2077
63983207 2078 if (s->start_timestamp.realtime > 0)
9fb86720
LP
2079 fprintf(f,
2080 "%sStart Timestamp: %s\n",
63983207 2081 prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
9fb86720 2082
63983207 2083 if (s->exit_timestamp.realtime > 0)
9fb86720
LP
2084 fprintf(f,
2085 "%sExit Timestamp: %s\n"
2086 "%sExit Code: %s\n"
2087 "%sExit Status: %i\n",
63983207 2088 prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
9fb86720
LP
2089 prefix, sigchld_code_to_string(s->code),
2090 prefix, s->status);
5cb5a6ff 2091}
44d8db9e 2092
9e2f7c11 2093char *exec_command_line(char **argv) {
44d8db9e
LP
2094 size_t k;
2095 char *n, *p, **a;
2096 bool first = true;
2097
9e2f7c11 2098 assert(argv);
44d8db9e 2099
9164977d 2100 k = 1;
9e2f7c11 2101 STRV_FOREACH(a, argv)
44d8db9e
LP
2102 k += strlen(*a)+3;
2103
2104 if (!(n = new(char, k)))
2105 return NULL;
2106
2107 p = n;
9e2f7c11 2108 STRV_FOREACH(a, argv) {
44d8db9e
LP
2109
2110 if (!first)
2111 *(p++) = ' ';
2112 else
2113 first = false;
2114
2115 if (strpbrk(*a, WHITESPACE)) {
2116 *(p++) = '\'';
2117 p = stpcpy(p, *a);
2118 *(p++) = '\'';
2119 } else
2120 p = stpcpy(p, *a);
2121
2122 }
2123
9164977d
LP
2124 *p = 0;
2125
44d8db9e
LP
2126 /* FIXME: this doesn't really handle arguments that have
2127 * spaces and ticks in them */
2128
2129 return n;
2130}
2131
2132void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
9fb86720
LP
2133 char *p2;
2134 const char *prefix2;
2135
44d8db9e
LP
2136 char *cmd;
2137
2138 assert(c);
2139 assert(f);
2140
2141 if (!prefix)
2142 prefix = "";
9fb86720
LP
2143 p2 = strappend(prefix, "\t");
2144 prefix2 = p2 ? p2 : prefix;
44d8db9e 2145
9e2f7c11 2146 cmd = exec_command_line(c->argv);
44d8db9e
LP
2147
2148 fprintf(f,
2149 "%sCommand Line: %s\n",
2150 prefix, cmd ? cmd : strerror(ENOMEM));
2151
2152 free(cmd);
9fb86720
LP
2153
2154 exec_status_dump(&c->exec_status, f, prefix2);
2155
2156 free(p2);
44d8db9e
LP
2157}
2158
2159void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
2160 assert(f);
2161
2162 if (!prefix)
2163 prefix = "";
2164
2165 LIST_FOREACH(command, c, c)
2166 exec_command_dump(c, f, prefix);
2167}
94f04347 2168
a6a80b4f
LP
2169void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
2170 ExecCommand *end;
2171
2172 assert(l);
2173 assert(e);
2174
2175 if (*l) {
35b8ca3a 2176 /* It's kind of important, that we keep the order here */
a6a80b4f
LP
2177 LIST_FIND_TAIL(ExecCommand, command, *l, end);
2178 LIST_INSERT_AFTER(ExecCommand, command, *l, end, e);
2179 } else
2180 *l = e;
2181}
2182
26fd040d
LP
2183int exec_command_set(ExecCommand *c, const char *path, ...) {
2184 va_list ap;
2185 char **l, *p;
2186
2187 assert(c);
2188 assert(path);
2189
2190 va_start(ap, path);
2191 l = strv_new_ap(path, ap);
2192 va_end(ap);
2193
2194 if (!l)
2195 return -ENOMEM;
2196
2197 if (!(p = strdup(path))) {
2198 strv_free(l);
2199 return -ENOMEM;
2200 }
2201
2202 free(c->path);
2203 c->path = p;
2204
2205 strv_free(c->argv);
2206 c->argv = l;
2207
2208 return 0;
2209}
2210
80876c20
LP
2211static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
2212 [EXEC_INPUT_NULL] = "null",
2213 [EXEC_INPUT_TTY] = "tty",
2214 [EXEC_INPUT_TTY_FORCE] = "tty-force",
4f2d528d
LP
2215 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
2216 [EXEC_INPUT_SOCKET] = "socket"
80876c20
LP
2217};
2218
8a0867d6
LP
2219DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
2220
94f04347 2221static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
80876c20 2222 [EXEC_OUTPUT_INHERIT] = "inherit",
94f04347 2223 [EXEC_OUTPUT_NULL] = "null",
80876c20 2224 [EXEC_OUTPUT_TTY] = "tty",
94f04347 2225 [EXEC_OUTPUT_SYSLOG] = "syslog",
28dbc1e8 2226 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
9a6bca7a 2227 [EXEC_OUTPUT_KMSG] = "kmsg",
28dbc1e8 2228 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
706343f4
LP
2229 [EXEC_OUTPUT_JOURNAL] = "journal",
2230 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
4f2d528d 2231 [EXEC_OUTPUT_SOCKET] = "socket"
94f04347
LP
2232};
2233
2234DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);