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