]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/execute.c
selinux: rework method tail, make it into a nulstr array
[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>
5cb5a6ff 42
5b6319dc
LP
43#ifdef HAVE_PAM
44#include <security/pam_appl.h>
45#endif
46
5cb5a6ff
LP
47#include "execute.h"
48#include "strv.h"
49#include "macro.h"
d7832d2c 50#include "capability.h"
5cb5a6ff 51#include "util.h"
acbb0225 52#include "log.h"
9eba9da4 53#include "ioprio.h"
94f04347 54#include "securebits.h"
8e274523 55#include "cgroup.h"
15ae422b 56#include "namespace.h"
df1f0afe 57#include "tcpwrap.h"
d06dacd0 58#include "exit-status.h"
dd6c17b1 59#include "missing.h"
169c1bda 60#include "utmp-wtmp.h"
f6a6225e 61#include "def.h"
ff01d048 62#include "loopback-setup.h"
9eb977db 63#include "path-util.h"
8351ceae 64#include "syscall-list.h"
5cb5a6ff 65
e056b01d 66#define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
e6a26745 67
02a51aba
LP
68/* This assumes there is a 'tty' group */
69#define TTY_MODE 0620
70
034c6ed7
LP
71static int shift_fds(int fds[], unsigned n_fds) {
72 int start, restart_from;
73
74 if (n_fds <= 0)
75 return 0;
76
a0d40ac5
LP
77 /* Modifies the fds array! (sorts it) */
78
034c6ed7
LP
79 assert(fds);
80
81 start = 0;
82 for (;;) {
83 int i;
84
85 restart_from = -1;
86
87 for (i = start; i < (int) n_fds; i++) {
88 int nfd;
89
90 /* Already at right index? */
91 if (fds[i] == i+3)
92 continue;
93
94 if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0)
95 return -errno;
96
e1f5e051 97 close_nointr_nofail(fds[i]);
034c6ed7
LP
98 fds[i] = nfd;
99
100 /* Hmm, the fd we wanted isn't free? Then
101 * let's remember that and try again from here*/
102 if (nfd != i+3 && restart_from < 0)
103 restart_from = i;
104 }
105
106 if (restart_from < 0)
107 break;
108
109 start = restart_from;
110 }
111
112 return 0;
113}
114
c2748801 115static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
47a71eed 116 unsigned i;
e2c76839 117 int r;
47a71eed
LP
118
119 if (n_fds <= 0)
120 return 0;
121
122 assert(fds);
123
451a074f 124 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
47a71eed
LP
125
126 for (i = 0; i < n_fds; i++) {
47a71eed 127
e2c76839
LP
128 if ((r = fd_nonblock(fds[i], nonblock)) < 0)
129 return r;
47a71eed 130
451a074f
LP
131 /* We unconditionally drop FD_CLOEXEC from the fds,
132 * since after all we want to pass these fds to our
133 * children */
47a71eed 134
e2c76839
LP
135 if ((r = fd_cloexec(fds[i], false)) < 0)
136 return r;
47a71eed
LP
137 }
138
139 return 0;
140}
141
80876c20
LP
142static const char *tty_path(const ExecContext *context) {
143 assert(context);
144
145 if (context->tty_path)
146 return context->tty_path;
147
148 return "/dev/console";
149}
150
6ea832a2
LP
151void exec_context_tty_reset(const ExecContext *context) {
152 assert(context);
153
154 if (context->tty_vhangup)
155 terminal_vhangup(tty_path(context));
156
157 if (context->tty_reset)
158 reset_terminal(tty_path(context));
159
160 if (context->tty_vt_disallocate && context->tty_path)
161 vt_disallocate(context->tty_path);
162}
163
80876c20
LP
164static int open_null_as(int flags, int nfd) {
165 int fd, r;
071830ff 166
80876c20 167 assert(nfd >= 0);
071830ff 168
80876c20 169 if ((fd = open("/dev/null", flags|O_NOCTTY)) < 0)
071830ff
LP
170 return -errno;
171
80876c20
LP
172 if (fd != nfd) {
173 r = dup2(fd, nfd) < 0 ? -errno : nfd;
e1f5e051 174 close_nointr_nofail(fd);
80876c20
LP
175 } else
176 r = nfd;
071830ff 177
80876c20 178 return r;
071830ff
LP
179}
180
62bca2c6 181static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd) {
80876c20 182 int fd, r;
54fe0cdb 183 union sockaddr_union sa;
071830ff
LP
184
185 assert(context);
80876c20
LP
186 assert(output < _EXEC_OUTPUT_MAX);
187 assert(ident);
188 assert(nfd >= 0);
071830ff 189
54fe0cdb
LP
190 fd = socket(AF_UNIX, SOCK_STREAM, 0);
191 if (fd < 0)
80876c20 192 return -errno;
071830ff 193
80876c20 194 zero(sa);
54fe0cdb
LP
195 sa.un.sun_family = AF_UNIX;
196 strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path));
071830ff 197
54fe0cdb
LP
198 r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
199 if (r < 0) {
80876c20
LP
200 close_nointr_nofail(fd);
201 return -errno;
202 }
071830ff 203
80876c20
LP
204 if (shutdown(fd, SHUT_RD) < 0) {
205 close_nointr_nofail(fd);
206 return -errno;
207 }
071830ff 208
80876c20 209 dprintf(fd,
62bca2c6 210 "%s\n"
80876c20
LP
211 "%s\n"
212 "%i\n"
54fe0cdb
LP
213 "%i\n"
214 "%i\n"
215 "%i\n"
4f4a1dbf 216 "%i\n",
4f4a1dbf 217 context->syslog_identifier ? context->syslog_identifier : ident,
62bca2c6 218 unit_id,
54fe0cdb
LP
219 context->syslog_priority,
220 !!context->syslog_level_prefix,
221 output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
222 output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE,
706343f4 223 output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || output == EXEC_OUTPUT_KMSG_AND_CONSOLE || output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE);
80876c20
LP
224
225 if (fd != nfd) {
226 r = dup2(fd, nfd) < 0 ? -errno : nfd;
e1f5e051 227 close_nointr_nofail(fd);
80876c20
LP
228 } else
229 r = nfd;
071830ff 230
80876c20
LP
231 return r;
232}
233static int open_terminal_as(const char *path, mode_t mode, int nfd) {
234 int fd, r;
071830ff 235
80876c20
LP
236 assert(path);
237 assert(nfd >= 0);
071830ff 238
80876c20
LP
239 if ((fd = open_terminal(path, mode | O_NOCTTY)) < 0)
240 return fd;
071830ff 241
80876c20
LP
242 if (fd != nfd) {
243 r = dup2(fd, nfd) < 0 ? -errno : nfd;
244 close_nointr_nofail(fd);
245 } else
246 r = nfd;
071830ff 247
80876c20
LP
248 return r;
249}
071830ff 250
80876c20
LP
251static bool is_terminal_input(ExecInput i) {
252 return
253 i == EXEC_INPUT_TTY ||
254 i == EXEC_INPUT_TTY_FORCE ||
255 i == EXEC_INPUT_TTY_FAIL;
256}
071830ff 257
1e3ad081
LP
258static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
259
260 if (is_terminal_input(std_input) && !apply_tty_stdin)
261 return EXEC_INPUT_NULL;
071830ff 262
03fd9c49 263 if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
4f2d528d
LP
264 return EXEC_INPUT_NULL;
265
03fd9c49 266 return std_input;
4f2d528d
LP
267}
268
03fd9c49 269static int fixup_output(ExecOutput std_output, int socket_fd) {
4f2d528d 270
03fd9c49 271 if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0)
4f2d528d
LP
272 return EXEC_OUTPUT_INHERIT;
273
03fd9c49 274 return std_output;
4f2d528d
LP
275}
276
1e3ad081 277static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty_stdin) {
4f2d528d
LP
278 ExecInput i;
279
280 assert(context);
281
1e3ad081 282 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
4f2d528d
LP
283
284 switch (i) {
071830ff 285
80876c20
LP
286 case EXEC_INPUT_NULL:
287 return open_null_as(O_RDONLY, STDIN_FILENO);
288
289 case EXEC_INPUT_TTY:
290 case EXEC_INPUT_TTY_FORCE:
291 case EXEC_INPUT_TTY_FAIL: {
292 int fd, r;
071830ff 293
80876c20
LP
294 if ((fd = acquire_terminal(
295 tty_path(context),
4f2d528d 296 i == EXEC_INPUT_TTY_FAIL,
21de3988 297 i == EXEC_INPUT_TTY_FORCE,
af6da548
LP
298 false,
299 (usec_t) -1)) < 0)
80876c20
LP
300 return fd;
301
302 if (fd != STDIN_FILENO) {
303 r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
071830ff 304 close_nointr_nofail(fd);
80876c20
LP
305 } else
306 r = STDIN_FILENO;
307
308 return r;
309 }
310
4f2d528d
LP
311 case EXEC_INPUT_SOCKET:
312 return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
313
80876c20
LP
314 default:
315 assert_not_reached("Unknown input type");
316 }
317}
318
62bca2c6 319static int setup_output(const ExecContext *context, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin) {
4f2d528d
LP
320 ExecOutput o;
321 ExecInput i;
322
80876c20
LP
323 assert(context);
324 assert(ident);
325
1e3ad081 326 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
03fd9c49 327 o = fixup_output(context->std_output, socket_fd);
4f2d528d 328
80876c20
LP
329 /* This expects the input is already set up */
330
4f2d528d 331 switch (o) {
071830ff 332
80876c20
LP
333 case EXEC_OUTPUT_INHERIT:
334
21d21ea4
LP
335 /* If input got downgraded, inherit the original value */
336 if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
337 return open_terminal_as(tty_path(context), O_WRONLY, STDOUT_FILENO);
338
acb591e4 339 /* If the input is connected to anything that's not a /dev/null, inherit that... */
ff876e28 340 if (i != EXEC_INPUT_NULL)
80876c20 341 return dup2(STDIN_FILENO, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO;
071830ff 342
acb591e4
LP
343 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
344 if (getppid() != 1)
345 return STDOUT_FILENO;
ff876e28 346
acb591e4
LP
347 /* We need to open /dev/null here anew, to get the
348 * right access mode. So we fall through */
80876c20
LP
349
350 case EXEC_OUTPUT_NULL:
351 return open_null_as(O_WRONLY, STDOUT_FILENO);
352
4f2d528d
LP
353 case EXEC_OUTPUT_TTY:
354 if (is_terminal_input(i))
80876c20
LP
355 return dup2(STDIN_FILENO, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO;
356
357 /* We don't reset the terminal if this is just about output */
358 return open_terminal_as(tty_path(context), O_WRONLY, STDOUT_FILENO);
94f04347 359
80876c20 360 case EXEC_OUTPUT_SYSLOG:
28dbc1e8 361 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
9a6bca7a 362 case EXEC_OUTPUT_KMSG:
28dbc1e8 363 case EXEC_OUTPUT_KMSG_AND_CONSOLE:
706343f4
LP
364 case EXEC_OUTPUT_JOURNAL:
365 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
62bca2c6 366 return connect_logger_as(context, o, ident, unit_id, STDOUT_FILENO);
4f2d528d
LP
367
368 case EXEC_OUTPUT_SOCKET:
369 assert(socket_fd >= 0);
370 return dup2(socket_fd, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO;
80876c20 371
94f04347
LP
372 default:
373 assert_not_reached("Unknown output type");
071830ff 374 }
94f04347
LP
375}
376
62bca2c6 377static int setup_error(const ExecContext *context, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin) {
4f2d528d
LP
378 ExecOutput o, e;
379 ExecInput i;
380
94f04347 381 assert(context);
02a51aba 382 assert(ident);
071830ff 383
1e3ad081 384 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
03fd9c49
LP
385 o = fixup_output(context->std_output, socket_fd);
386 e = fixup_output(context->std_error, socket_fd);
4f2d528d 387
80876c20 388 /* This expects the input and output are already set up */
94f04347 389
80876c20
LP
390 /* Don't change the stderr file descriptor if we inherit all
391 * the way and are not on a tty */
4f2d528d
LP
392 if (e == EXEC_OUTPUT_INHERIT &&
393 o == EXEC_OUTPUT_INHERIT &&
acb591e4 394 i == EXEC_INPUT_NULL &&
21d21ea4 395 !is_terminal_input(context->std_input) &&
dec5d552 396 getppid () != 1)
80876c20 397 return STDERR_FILENO;
94f04347 398
21d21ea4 399 /* Duplicate from stdout if possible */
4f2d528d 400 if (e == o || e == EXEC_OUTPUT_INHERIT)
80876c20 401 return dup2(STDOUT_FILENO, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO;
94f04347 402
4f2d528d 403 switch (e) {
80876c20
LP
404
405 case EXEC_OUTPUT_NULL:
406 return open_null_as(O_WRONLY, STDERR_FILENO);
407
408 case EXEC_OUTPUT_TTY:
4f2d528d 409 if (is_terminal_input(i))
80876c20
LP
410 return dup2(STDIN_FILENO, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO;
411
412 /* We don't reset the terminal if this is just about output */
413 return open_terminal_as(tty_path(context), O_WRONLY, STDERR_FILENO);
414
415 case EXEC_OUTPUT_SYSLOG:
28dbc1e8 416 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
9a6bca7a 417 case EXEC_OUTPUT_KMSG:
28dbc1e8 418 case EXEC_OUTPUT_KMSG_AND_CONSOLE:
706343f4
LP
419 case EXEC_OUTPUT_JOURNAL:
420 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
62bca2c6 421 return connect_logger_as(context, e, ident, unit_id, STDERR_FILENO);
4f2d528d
LP
422
423 case EXEC_OUTPUT_SOCKET:
424 assert(socket_fd >= 0);
425 return dup2(socket_fd, STDERR_FILENO) < 0 ? -errno : STDERR_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
35b8ca3a 674 * caps, whiel we drop privileges. */
693ced48
LP
675 if (uid != 0) {
676 int sb = context->secure_bits|SECURE_KEEP_CAPS;
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[] = {
958 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, i, 0, 1),
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,
81a2b7ce 984 const 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;
8c7be95e 1002 char **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
8c7be95e
LP
1023 if ((r = exec_context_load_environment(context, &files_env)) < 0) {
1024 log_error("Failed to load environment files: %s", strerror(-r));
1025 return r;
1026 }
1027
9e2f7c11
LP
1028 if (!argv)
1029 argv = command->argv;
1030
af6da548
LP
1031 line = exec_command_line(argv);
1032 if (!line) {
8c7be95e
LP
1033 r = -ENOMEM;
1034 goto fail_parent;
1035 }
1a63a750
LP
1036
1037 log_debug("About to execute: %s", line);
1038 free(line);
acbb0225 1039
ab1f0633
LP
1040 r = cgroup_bonding_realize_list(cgroup_bondings);
1041 if (r < 0)
1042 goto fail_parent;
1043
1044 cgroup_attribute_apply_list(cgroup_attributes, cgroup_bondings);
8e274523 1045
8c7be95e
LP
1046 if ((pid = fork()) < 0) {
1047 r = -errno;
1048 goto fail_parent;
1049 }
034c6ed7
LP
1050
1051 if (pid == 0) {
4c2630eb 1052 int i, err;
309bff19 1053 sigset_t ss;
81a2b7ce
LP
1054 const char *username = NULL, *home = NULL;
1055 uid_t uid = (uid_t) -1;
1056 gid_t gid = (gid_t) -1;
fab56fc5 1057 char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
81a2b7ce 1058 unsigned n_env = 0;
af6da548 1059 bool set_access = false;
309bff19 1060
034c6ed7 1061 /* child */
5cb5a6ff 1062
5d6b1584 1063 rename_process_from_path(command->path);
5b6319dc 1064
1b91d3e8
LP
1065 /* We reset exactly these signals, since they are the
1066 * only ones we set to SIG_IGN in the main daemon. All
1067 * others we leave untouched because we set them to
1068 * SIG_DFL or a valid handler initially, both of which
1069 * will be demoted to SIG_DFL. */
1070 default_signals(SIGNALS_CRASH_HANDLER,
9a34ec5f 1071 SIGNALS_IGNORE, -1);
7b683879 1072
353e12c2
LP
1073 if (context->ignore_sigpipe)
1074 ignore_signals(SIGPIPE, -1);
1075
1076 assert_se(sigemptyset(&ss) == 0);
1077 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) {
4c2630eb 1078 err = -errno;
309bff19 1079 r = EXIT_SIGNAL_MASK;
8c7be95e 1080 goto fail_child;
309bff19
LP
1081 }
1082
f2b68789
LP
1083 if (idle_pipe) {
1084 if (idle_pipe[1] >= 0)
1085 close_nointr_nofail(idle_pipe[1]);
1086 if (idle_pipe[0] >= 0) {
e6a26745 1087 fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
f2b68789
LP
1088 close_nointr_nofail(idle_pipe[0]);
1089 }
1090 }
1091
85d73053
LP
1092 /* Close sockets very early to make sure we don't
1093 * block init reexecution because it cannot bind its
1094 * sockets */
4d8a7798 1095 log_forget_fds();
4c2630eb
MS
1096 err = close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
1097 socket_fd >= 0 ? 1 : n_fds);
1098 if (err < 0) {
fc9b2a84 1099 r = EXIT_FDS;
8c7be95e 1100 goto fail_child;
fc9b2a84
LP
1101 }
1102
74922904 1103 if (!context->same_pgrp)
8d567588 1104 if (setsid() < 0) {
4c2630eb 1105 err = -errno;
8d567588 1106 r = EXIT_SETSID;
8c7be95e 1107 goto fail_child;
8d567588 1108 }
80876c20 1109
c5da34ef
LP
1110 if (context->tcpwrap_name) {
1111 if (socket_fd >= 0)
1112 if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) {
4c2630eb 1113 err = -EACCES;
c5da34ef 1114 r = EXIT_TCPWRAP;
8c7be95e 1115 goto fail_child;
c5da34ef
LP
1116 }
1117
1118 for (i = 0; i < (int) n_fds; i++) {
1119 if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) {
4c2630eb 1120 err = -EACCES;
c5da34ef 1121 r = EXIT_TCPWRAP;
8c7be95e 1122 goto fail_child;
c5da34ef 1123 }
df1f0afe 1124 }
c5da34ef 1125 }
df1f0afe 1126
6ea832a2
LP
1127 exec_context_tty_reset(context);
1128
af6da548 1129 if (confirm_spawn) {
80876c20
LP
1130 char response;
1131
af6da548
LP
1132 err = ask_for_confirmation(&response, argv);
1133 if (err == -ETIMEDOUT)
1134 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1135 else if (err < 0)
1136 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-err));
1137 else if (response == 's') {
1138 write_confirm_message("Skipping execution.\n");
4c2630eb 1139 err = -ECANCELED;
80876c20 1140 r = EXIT_CONFIRM;
8c7be95e 1141 goto fail_child;
af6da548
LP
1142 } else if (response == 'n') {
1143 write_confirm_message("Failing execution.\n");
4c2630eb 1144 err = r = 0;
8c7be95e 1145 goto fail_child;
ee2b4894 1146 }
034c6ed7
LP
1147 }
1148
da726a4d
LP
1149 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1150 * must sure to drop O_NONBLOCK */
1151 if (socket_fd >= 0)
1152 fd_nonblock(socket_fd, false);
1153
af6da548
LP
1154 err = setup_input(context, socket_fd, apply_tty_stdin);
1155 if (err < 0) {
1156 r = EXIT_STDIN;
1157 goto fail_child;
4c2630eb 1158 }
9eba9da4 1159
af6da548
LP
1160 err = setup_output(context, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin);
1161 if (err < 0) {
1162 r = EXIT_STDOUT;
1163 goto fail_child;
4c2630eb 1164 }
94f04347 1165
62bca2c6 1166 err = setup_error(context, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin);
4c2630eb 1167 if (err < 0) {
80876c20 1168 r = EXIT_STDERR;
8c7be95e 1169 goto fail_child;
071830ff
LP
1170 }
1171
4c2630eb 1172 if (cgroup_bondings) {
ecedd90f 1173 err = cgroup_bonding_install_list(cgroup_bondings, 0, cgroup_suffix);
4c2630eb 1174 if (err < 0) {
8e274523 1175 r = EXIT_CGROUP;
8c7be95e 1176 goto fail_child;
8e274523 1177 }
4c2630eb 1178 }
8e274523 1179
dd6c17b1 1180 if (context->oom_score_adjust_set) {
fb33a393 1181 char t[16];
034c6ed7 1182
dd6c17b1 1183 snprintf(t, sizeof(t), "%i", context->oom_score_adjust);
fb33a393 1184 char_array_0(t);
034c6ed7 1185
dd6c17b1 1186 if (write_one_line_file("/proc/self/oom_score_adj", t) < 0) {
8600c525
KS
1187 err = -errno;
1188 r = EXIT_OOM_ADJUST;
1189 goto fail_child;
fb33a393 1190 }
034c6ed7
LP
1191 }
1192
fb33a393
LP
1193 if (context->nice_set)
1194 if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
4c2630eb 1195 err = -errno;
fb33a393 1196 r = EXIT_NICE;
8c7be95e 1197 goto fail_child;
fb33a393
LP
1198 }
1199
94f04347
LP
1200 if (context->cpu_sched_set) {
1201 struct sched_param param;
1202
1203 zero(param);
1204 param.sched_priority = context->cpu_sched_priority;
1205
38b48754
LP
1206 if (sched_setscheduler(0, context->cpu_sched_policy |
1207 (context->cpu_sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0), &param) < 0) {
4c2630eb 1208 err = -errno;
94f04347 1209 r = EXIT_SETSCHEDULER;
8c7be95e 1210 goto fail_child;
94f04347
LP
1211 }
1212 }
1213
82c121a4
LP
1214 if (context->cpuset)
1215 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
4c2630eb 1216 err = -errno;
94f04347 1217 r = EXIT_CPUAFFINITY;
8c7be95e 1218 goto fail_child;
94f04347
LP
1219 }
1220
9eba9da4
LP
1221 if (context->ioprio_set)
1222 if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
4c2630eb 1223 err = -errno;
9eba9da4 1224 r = EXIT_IOPRIO;
8c7be95e 1225 goto fail_child;
9eba9da4
LP
1226 }
1227
d88a251b 1228 if (context->timer_slack_nsec != (nsec_t) -1)
03fae018 1229 if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
4c2630eb 1230 err = -errno;
94f04347 1231 r = EXIT_TIMERSLACK;
8c7be95e 1232 goto fail_child;
94f04347
LP
1233 }
1234
169c1bda 1235 if (context->utmp_id)
0ad26e09 1236 utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path);
169c1bda 1237
81a2b7ce
LP
1238 if (context->user) {
1239 username = context->user;
d05c5031 1240 err = get_user_creds(&username, &uid, &gid, &home, NULL);
4c2630eb 1241 if (err < 0) {
81a2b7ce 1242 r = EXIT_USER;
8c7be95e 1243 goto fail_child;
81a2b7ce 1244 }
d8b4e2e9 1245
4c2630eb
MS
1246 if (is_terminal_input(context->std_input)) {
1247 err = chown_terminal(STDIN_FILENO, uid);
1248 if (err < 0) {
d8b4e2e9 1249 r = EXIT_STDIN;
8c7be95e 1250 goto fail_child;
d8b4e2e9 1251 }
4c2630eb 1252 }
64747e2d 1253
4c2630eb
MS
1254 if (cgroup_bondings && context->control_group_modify) {
1255 err = cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid);
1256 if (err >= 0)
891703e1 1257 err = cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid, context->control_group_persistent);
4c2630eb 1258 if (err < 0) {
64747e2d
LP
1259 r = EXIT_CGROUP;
1260 goto fail_child;
1261 }
8d53b453
LP
1262
1263 set_access = true;
1264 }
1265 }
1266
891703e1
KS
1267 if (cgroup_bondings && !set_access && context->control_group_persistent >= 0) {
1268 err = cgroup_bonding_set_task_access_list(cgroup_bondings, (mode_t) -1, (uid_t) -1, (uid_t) -1, context->control_group_persistent);
8d53b453
LP
1269 if (err < 0) {
1270 r = EXIT_CGROUP;
1271 goto fail_child;
4c2630eb 1272 }
81a2b7ce
LP
1273 }
1274
4c2630eb
MS
1275 if (apply_permissions) {
1276 err = enforce_groups(context, username, gid);
1277 if (err < 0) {
3b8bddde
LP
1278 r = EXIT_GROUP;
1279 goto fail_child;
1280 }
4c2630eb 1281 }
3b8bddde
LP
1282
1283 umask(context->umask);
1284
5b6319dc
LP
1285#ifdef HAVE_PAM
1286 if (context->pam_name && username) {
940c5210 1287 err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
4c2630eb 1288 if (err < 0) {
5b6319dc 1289 r = EXIT_PAM;
8c7be95e 1290 goto fail_child;
5b6319dc
LP
1291 }
1292 }
1293#endif
ff01d048
LP
1294 if (context->private_network) {
1295 if (unshare(CLONE_NEWNET) < 0) {
4c2630eb 1296 err = -errno;
ff01d048
LP
1297 r = EXIT_NETWORK;
1298 goto fail_child;
1299 }
1300
1301 loopback_setup();
1302 }
5b6319dc 1303
04aa0cb9
LP
1304 if (strv_length(context->read_write_dirs) > 0 ||
1305 strv_length(context->read_only_dirs) > 0 ||
1306 strv_length(context->inaccessible_dirs) > 0 ||
ac0930c8 1307 context->mount_flags != 0 ||
4c2630eb
MS
1308 context->private_tmp) {
1309 err = setup_namespace(context->read_write_dirs,
1310 context->read_only_dirs,
1311 context->inaccessible_dirs,
1312 context->private_tmp,
1313 context->mount_flags);
1314 if (err < 0) {
1315 r = EXIT_NAMESPACE;
8c7be95e 1316 goto fail_child;
4c2630eb
MS
1317 }
1318 }
04aa0cb9 1319
81a2b7ce
LP
1320 if (apply_chroot) {
1321 if (context->root_directory)
1322 if (chroot(context->root_directory) < 0) {
4c2630eb 1323 err = -errno;
81a2b7ce 1324 r = EXIT_CHROOT;
8c7be95e 1325 goto fail_child;
81a2b7ce
LP
1326 }
1327
1328 if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
4c2630eb 1329 err = -errno;
81a2b7ce 1330 r = EXIT_CHDIR;
8c7be95e 1331 goto fail_child;
81a2b7ce
LP
1332 }
1333 } else {
1334
1335 char *d;
1336
1337 if (asprintf(&d, "%s/%s",
1338 context->root_directory ? context->root_directory : "",
1339 context->working_directory ? context->working_directory : "") < 0) {
4c2630eb 1340 err = -ENOMEM;
81a2b7ce 1341 r = EXIT_MEMORY;
8c7be95e 1342 goto fail_child;
81a2b7ce
LP
1343 }
1344
1345 if (chdir(d) < 0) {
4c2630eb 1346 err = -errno;
81a2b7ce
LP
1347 free(d);
1348 r = EXIT_CHDIR;
8c7be95e 1349 goto fail_child;
81a2b7ce
LP
1350 }
1351
1352 free(d);
1353 }
1354
fc9b2a84
LP
1355 /* We repeat the fd closing here, to make sure that
1356 * nothing is leaked from the PAM modules */
4c2630eb
MS
1357 err = close_all_fds(fds, n_fds);
1358 if (err >= 0)
1359 err = shift_fds(fds, n_fds);
1360 if (err >= 0)
1361 err = flags_fds(fds, n_fds, context->non_blocking);
1362 if (err < 0) {
034c6ed7 1363 r = EXIT_FDS;
8c7be95e 1364 goto fail_child;
034c6ed7
LP
1365 }
1366
81a2b7ce 1367 if (apply_permissions) {
034c6ed7 1368
81a2b7ce
LP
1369 for (i = 0; i < RLIMIT_NLIMITS; i++) {
1370 if (!context->rlimit[i])
1371 continue;
1372
68faf98c 1373 if (setrlimit_closest(i, context->rlimit[i]) < 0) {
4c2630eb 1374 err = -errno;
81a2b7ce 1375 r = EXIT_LIMITS;
8c7be95e 1376 goto fail_child;
81a2b7ce 1377 }
034c6ed7 1378 }
034c6ed7 1379
4c2630eb 1380 if (context->capability_bounding_set_drop) {
ec8927ca 1381 err = capability_bounding_set_drop(context->capability_bounding_set_drop, false);
4c2630eb 1382 if (err < 0) {
73090dc8
LP
1383 r = EXIT_CAPABILITIES;
1384 goto fail_child;
1385 }
4c2630eb 1386 }
260abb78 1387
4c2630eb
MS
1388 if (context->user) {
1389 err = enforce_user(context, uid);
1390 if (err < 0) {
81a2b7ce 1391 r = EXIT_USER;
8c7be95e 1392 goto fail_child;
81a2b7ce 1393 }
4c2630eb 1394 }
81a2b7ce 1395
35b8ca3a 1396 /* PR_GET_SECUREBITS is not privileged, while
693ced48
LP
1397 * PR_SET_SECUREBITS is. So to suppress
1398 * potential EPERMs we'll try not to call
1399 * PR_SET_SECUREBITS unless necessary. */
1400 if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
1401 if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
4c2630eb 1402 err = -errno;
693ced48 1403 r = EXIT_SECUREBITS;
8c7be95e 1404 goto fail_child;
693ced48 1405 }
81a2b7ce
LP
1406
1407 if (context->capabilities)
1408 if (cap_set_proc(context->capabilities) < 0) {
4c2630eb 1409 err = -errno;
81a2b7ce 1410 r = EXIT_CAPABILITIES;
8c7be95e 1411 goto fail_child;
81a2b7ce 1412 }
8351ceae
LP
1413
1414 if (context->no_new_privileges)
1415 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
1416 err = -errno;
1417 r = EXIT_NO_NEW_PRIVILEGES;
1418 goto fail_child;
1419 }
1420
1421 if (context->syscall_filter) {
1422 err = apply_seccomp(context->syscall_filter);
1423 if (err < 0) {
1424 r = EXIT_SECCOMP;
1425 goto fail_child;
1426 }
1427 }
94f04347
LP
1428 }
1429
e3aa71c3 1430 if (!(our_env = new0(char*, 7))) {
4c2630eb 1431 err = -ENOMEM;
81a2b7ce 1432 r = EXIT_MEMORY;
8c7be95e 1433 goto fail_child;
81a2b7ce 1434 }
034c6ed7 1435
81a2b7ce 1436 if (n_fds > 0)
bb00e604 1437 if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 ||
81a2b7ce 1438 asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) {
4c2630eb 1439 err = -ENOMEM;
81a2b7ce 1440 r = EXIT_MEMORY;
8c7be95e 1441 goto fail_child;
81a2b7ce 1442 }
034c6ed7 1443
81a2b7ce
LP
1444 if (home)
1445 if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) {
4c2630eb 1446 err = -ENOMEM;
81a2b7ce 1447 r = EXIT_MEMORY;
8c7be95e 1448 goto fail_child;
81a2b7ce 1449 }
034c6ed7 1450
81a2b7ce
LP
1451 if (username)
1452 if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 ||
1453 asprintf(our_env + n_env++, "USER=%s", username) < 0) {
4c2630eb 1454 err = -ENOMEM;
81a2b7ce 1455 r = EXIT_MEMORY;
8c7be95e 1456 goto fail_child;
81a2b7ce 1457 }
034c6ed7 1458
e3aa71c3
LP
1459 if (is_terminal_input(context->std_input) ||
1460 context->std_output == EXEC_OUTPUT_TTY ||
1461 context->std_error == EXEC_OUTPUT_TTY)
1462 if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) {
4c2630eb 1463 err = -ENOMEM;
e3aa71c3 1464 r = EXIT_MEMORY;
8c7be95e 1465 goto fail_child;
e3aa71c3
LP
1466 }
1467
1468 assert(n_env <= 7);
4e85aff4 1469
5b6319dc 1470 if (!(final_env = strv_env_merge(
8c7be95e 1471 5,
5b6319dc
LP
1472 environment,
1473 our_env,
1474 context->environment,
8c7be95e 1475 files_env,
5b6319dc
LP
1476 pam_env,
1477 NULL))) {
4c2630eb 1478 err = -ENOMEM;
81a2b7ce 1479 r = EXIT_MEMORY;
8c7be95e 1480 goto fail_child;
81a2b7ce 1481 }
034c6ed7 1482
fab56fc5 1483 if (!(final_argv = replace_env_argv(argv, final_env))) {
4c2630eb 1484 err = -ENOMEM;
fab56fc5 1485 r = EXIT_MEMORY;
8c7be95e 1486 goto fail_child;
fab56fc5
LP
1487 }
1488
a6ff950e
LP
1489 final_env = strv_env_clean(final_env);
1490
fab56fc5 1491 execve(command->path, final_argv, final_env);
4c2630eb 1492 err = -errno;
034c6ed7
LP
1493 r = EXIT_EXEC;
1494
8c7be95e 1495 fail_child:
4c2630eb
MS
1496 if (r != 0) {
1497 log_open();
1498 log_warning("Failed at step %s spawning %s: %s",
1499 exit_status_to_string(r, EXIT_STATUS_SYSTEMD),
1500 command->path, strerror(-err));
1501 }
1502
81a2b7ce
LP
1503 strv_free(our_env);
1504 strv_free(final_env);
5b6319dc 1505 strv_free(pam_env);
8c7be95e 1506 strv_free(files_env);
fab56fc5 1507 strv_free(final_argv);
81a2b7ce 1508
034c6ed7
LP
1509 _exit(r);
1510 }
1511
8c7be95e
LP
1512 strv_free(files_env);
1513
80876c20
LP
1514 /* We add the new process to the cgroup both in the child (so
1515 * that we can be sure that no user code is ever executed
1516 * outside of the cgroup) and in the parent (so that we can be
1517 * sure that when we kill the cgroup the process will be
1518 * killed too). */
1519 if (cgroup_bondings)
ecedd90f 1520 cgroup_bonding_install_list(cgroup_bondings, pid, cgroup_suffix);
2da3263a 1521
bb00e604 1522 log_debug("Forked %s as %lu", command->path, (unsigned long) pid);
2da3263a 1523
b58b4116 1524 exec_status_start(&command->exec_status, pid);
9fb86720 1525
034c6ed7 1526 *ret = pid;
5cb5a6ff 1527 return 0;
8c7be95e
LP
1528
1529fail_parent:
1530 strv_free(files_env);
1531
1532 return r;
5cb5a6ff
LP
1533}
1534
034c6ed7
LP
1535void exec_context_init(ExecContext *c) {
1536 assert(c);
1537
4c12626c 1538 c->umask = 0022;
9eba9da4 1539 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
94f04347 1540 c->cpu_sched_policy = SCHED_OTHER;
071830ff 1541 c->syslog_priority = LOG_DAEMON|LOG_INFO;
74922904 1542 c->syslog_level_prefix = true;
891703e1 1543 c->control_group_persistent = -1;
353e12c2 1544 c->ignore_sigpipe = true;
d88a251b 1545 c->timer_slack_nsec = (nsec_t) -1;
034c6ed7
LP
1546}
1547
1548void exec_context_done(ExecContext *c) {
5cb5a6ff
LP
1549 unsigned l;
1550
1551 assert(c);
1552
1553 strv_free(c->environment);
034c6ed7 1554 c->environment = NULL;
5cb5a6ff 1555
8c7be95e
LP
1556 strv_free(c->environment_files);
1557 c->environment_files = NULL;
1558
034c6ed7 1559 for (l = 0; l < ELEMENTSOF(c->rlimit); l++) {
5cb5a6ff 1560 free(c->rlimit[l]);
034c6ed7
LP
1561 c->rlimit[l] = NULL;
1562 }
1563
9eba9da4
LP
1564 free(c->working_directory);
1565 c->working_directory = NULL;
1566 free(c->root_directory);
1567 c->root_directory = NULL;
5cb5a6ff 1568
80876c20
LP
1569 free(c->tty_path);
1570 c->tty_path = NULL;
1571
df1f0afe
LP
1572 free(c->tcpwrap_name);
1573 c->tcpwrap_name = NULL;
1574
071830ff
LP
1575 free(c->syslog_identifier);
1576 c->syslog_identifier = NULL;
1577
5cb5a6ff 1578 free(c->user);
034c6ed7
LP
1579 c->user = NULL;
1580
5cb5a6ff 1581 free(c->group);
034c6ed7
LP
1582 c->group = NULL;
1583
1584 strv_free(c->supplementary_groups);
1585 c->supplementary_groups = NULL;
94f04347 1586
5b6319dc
LP
1587 free(c->pam_name);
1588 c->pam_name = NULL;
1589
94f04347
LP
1590 if (c->capabilities) {
1591 cap_free(c->capabilities);
1592 c->capabilities = NULL;
1593 }
15ae422b
LP
1594
1595 strv_free(c->read_only_dirs);
1596 c->read_only_dirs = NULL;
1597
1598 strv_free(c->read_write_dirs);
1599 c->read_write_dirs = NULL;
1600
1601 strv_free(c->inaccessible_dirs);
1602 c->inaccessible_dirs = NULL;
82c121a4
LP
1603
1604 if (c->cpuset)
1605 CPU_FREE(c->cpuset);
86a3475b
LP
1606
1607 free(c->utmp_id);
1608 c->utmp_id = NULL;
b9a0e010
LP
1609
1610 free(c->syscall_filter);
1611 c->syscall_filter = NULL;
5cb5a6ff
LP
1612}
1613
43d0fcbd
LP
1614void exec_command_done(ExecCommand *c) {
1615 assert(c);
1616
1617 free(c->path);
1618 c->path = NULL;
1619
1620 strv_free(c->argv);
1621 c->argv = NULL;
1622}
1623
1624void exec_command_done_array(ExecCommand *c, unsigned n) {
1625 unsigned i;
1626
1627 for (i = 0; i < n; i++)
1628 exec_command_done(c+i);
1629}
1630
5cb5a6ff
LP
1631void exec_command_free_list(ExecCommand *c) {
1632 ExecCommand *i;
1633
1634 while ((i = c)) {
034c6ed7 1635 LIST_REMOVE(ExecCommand, command, c, i);
43d0fcbd 1636 exec_command_done(i);
5cb5a6ff
LP
1637 free(i);
1638 }
1639}
1640
034c6ed7
LP
1641void exec_command_free_array(ExecCommand **c, unsigned n) {
1642 unsigned i;
1643
1644 for (i = 0; i < n; i++) {
1645 exec_command_free_list(c[i]);
1646 c[i] = NULL;
1647 }
1648}
1649
8c7be95e
LP
1650int exec_context_load_environment(const ExecContext *c, char ***l) {
1651 char **i, **r = NULL;
1652
1653 assert(c);
1654 assert(l);
1655
1656 STRV_FOREACH(i, c->environment_files) {
1657 char *fn;
1658 int k;
1659 bool ignore = false;
1660 char **p;
1661
1662 fn = *i;
1663
1664 if (fn[0] == '-') {
1665 ignore = true;
1666 fn ++;
1667 }
1668
1669 if (!path_is_absolute(fn)) {
1670
1671 if (ignore)
1672 continue;
1673
1674 strv_free(r);
1675 return -EINVAL;
1676 }
1677
1678 if ((k = load_env_file(fn, &p)) < 0) {
1679
1680 if (ignore)
1681 continue;
1682
1683 strv_free(r);
1684 return k;
1685 }
1686
1687 if (r == NULL)
1688 r = p;
1689 else {
1690 char **m;
1691
1692 m = strv_env_merge(2, r, p);
1693 strv_free(r);
1694 strv_free(p);
1695
1696 if (!m)
1697 return -ENOMEM;
1698
1699 r = m;
1700 }
1701 }
1702
1703 *l = r;
1704
1705 return 0;
1706}
1707
15ae422b
LP
1708static void strv_fprintf(FILE *f, char **l) {
1709 char **g;
1710
1711 assert(f);
1712
1713 STRV_FOREACH(g, l)
1714 fprintf(f, " %s", *g);
1715}
1716
5cb5a6ff 1717void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
94f04347
LP
1718 char ** e;
1719 unsigned i;
9eba9da4 1720
5cb5a6ff
LP
1721 assert(c);
1722 assert(f);
1723
1724 if (!prefix)
1725 prefix = "";
1726
1727 fprintf(f,
94f04347
LP
1728 "%sUMask: %04o\n"
1729 "%sWorkingDirectory: %s\n"
451a074f 1730 "%sRootDirectory: %s\n"
15ae422b 1731 "%sNonBlocking: %s\n"
64747e2d 1732 "%sPrivateTmp: %s\n"
ff01d048 1733 "%sControlGroupModify: %s\n"
891703e1 1734 "%sControlGroupPersistent: %s\n"
4819ff03
LP
1735 "%sPrivateNetwork: %s\n"
1736 "%sIgnoreSIGPIPE: %s\n",
5cb5a6ff 1737 prefix, c->umask,
9eba9da4 1738 prefix, c->working_directory ? c->working_directory : "/",
451a074f 1739 prefix, c->root_directory ? c->root_directory : "/",
15ae422b 1740 prefix, yes_no(c->non_blocking),
64747e2d 1741 prefix, yes_no(c->private_tmp),
ff01d048 1742 prefix, yes_no(c->control_group_modify),
891703e1 1743 prefix, yes_no(c->control_group_persistent),
4819ff03
LP
1744 prefix, yes_no(c->private_network),
1745 prefix, yes_no(c->ignore_sigpipe));
fb33a393 1746
8c7be95e
LP
1747 STRV_FOREACH(e, c->environment)
1748 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
1749
1750 STRV_FOREACH(e, c->environment_files)
1751 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
94f04347 1752
df1f0afe
LP
1753 if (c->tcpwrap_name)
1754 fprintf(f,
1755 "%sTCPWrapName: %s\n",
1756 prefix, c->tcpwrap_name);
1757
fb33a393
LP
1758 if (c->nice_set)
1759 fprintf(f,
1760 "%sNice: %i\n",
1761 prefix, c->nice);
1762
dd6c17b1 1763 if (c->oom_score_adjust_set)
fb33a393 1764 fprintf(f,
dd6c17b1
LP
1765 "%sOOMScoreAdjust: %i\n",
1766 prefix, c->oom_score_adjust);
9eba9da4 1767
94f04347
LP
1768 for (i = 0; i < RLIM_NLIMITS; i++)
1769 if (c->rlimit[i])
ea430986 1770 fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max);
94f04347 1771
9eba9da4
LP
1772 if (c->ioprio_set)
1773 fprintf(f,
1774 "%sIOSchedulingClass: %s\n"
1775 "%sIOPriority: %i\n",
94f04347 1776 prefix, ioprio_class_to_string(IOPRIO_PRIO_CLASS(c->ioprio)),
9eba9da4 1777 prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
94f04347
LP
1778
1779 if (c->cpu_sched_set)
1780 fprintf(f,
1781 "%sCPUSchedulingPolicy: %s\n"
38b48754
LP
1782 "%sCPUSchedulingPriority: %i\n"
1783 "%sCPUSchedulingResetOnFork: %s\n",
94f04347 1784 prefix, sched_policy_to_string(c->cpu_sched_policy),
38b48754
LP
1785 prefix, c->cpu_sched_priority,
1786 prefix, yes_no(c->cpu_sched_reset_on_fork));
94f04347 1787
82c121a4 1788 if (c->cpuset) {
94f04347 1789 fprintf(f, "%sCPUAffinity:", prefix);
82c121a4
LP
1790 for (i = 0; i < c->cpuset_ncpus; i++)
1791 if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
94f04347
LP
1792 fprintf(f, " %i", i);
1793 fputs("\n", f);
1794 }
1795
d88a251b 1796 if (c->timer_slack_nsec != (nsec_t) -1)
f96096db 1797 fprintf(f, "%sTimerSlackNSec: %lu\n", prefix, (unsigned long)c->timer_slack_nsec);
94f04347
LP
1798
1799 fprintf(f,
80876c20
LP
1800 "%sStandardInput: %s\n"
1801 "%sStandardOutput: %s\n"
1802 "%sStandardError: %s\n",
1803 prefix, exec_input_to_string(c->std_input),
1804 prefix, exec_output_to_string(c->std_output),
1805 prefix, exec_output_to_string(c->std_error));
1806
1807 if (c->tty_path)
1808 fprintf(f,
6ea832a2
LP
1809 "%sTTYPath: %s\n"
1810 "%sTTYReset: %s\n"
1811 "%sTTYVHangup: %s\n"
1812 "%sTTYVTDisallocate: %s\n",
1813 prefix, c->tty_path,
1814 prefix, yes_no(c->tty_reset),
1815 prefix, yes_no(c->tty_vhangup),
1816 prefix, yes_no(c->tty_vt_disallocate));
94f04347 1817
706343f4
LP
1818 if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG || c->std_output == EXEC_OUTPUT_JOURNAL ||
1819 c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
1820 c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG || c->std_error == EXEC_OUTPUT_JOURNAL ||
1821 c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE)
94f04347
LP
1822 fprintf(f,
1823 "%sSyslogFacility: %s\n"
1824 "%sSyslogLevel: %s\n",
7d76f312 1825 prefix, log_facility_unshifted_to_string(c->syslog_priority >> 3),
94f04347
LP
1826 prefix, log_level_to_string(LOG_PRI(c->syslog_priority)));
1827
1828 if (c->capabilities) {
1829 char *t;
1830 if ((t = cap_to_text(c->capabilities, NULL))) {
1831 fprintf(f, "%sCapabilities: %s\n",
1832 prefix, t);
1833 cap_free(t);
1834 }
1835 }
1836
1837 if (c->secure_bits)
1838 fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
1839 prefix,
1840 (c->secure_bits & SECURE_KEEP_CAPS) ? " keep-caps" : "",
1841 (c->secure_bits & SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
1842 (c->secure_bits & SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
1843 (c->secure_bits & SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
1844 (c->secure_bits & SECURE_NOROOT) ? " noroot" : "",
1845 (c->secure_bits & SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
1846
1847 if (c->capability_bounding_set_drop) {
ae556c21 1848 unsigned long l;
260abb78 1849 fprintf(f, "%sCapabilityBoundingSet:", prefix);
94f04347 1850
64685e0c 1851 for (l = 0; l <= cap_last_cap(); l++)
ae556c21 1852 if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) {
94f04347
LP
1853 char *t;
1854
ae556c21 1855 if ((t = cap_to_name(l))) {
94f04347 1856 fprintf(f, " %s", t);
260abb78 1857 cap_free(t);
94f04347
LP
1858 }
1859 }
1860
1861 fputs("\n", f);
1862 }
1863
1864 if (c->user)
f2d3769a 1865 fprintf(f, "%sUser: %s\n", prefix, c->user);
94f04347 1866 if (c->group)
f2d3769a 1867 fprintf(f, "%sGroup: %s\n", prefix, c->group);
94f04347 1868
15ae422b 1869 if (strv_length(c->supplementary_groups) > 0) {
94f04347 1870 fprintf(f, "%sSupplementaryGroups:", prefix);
15ae422b
LP
1871 strv_fprintf(f, c->supplementary_groups);
1872 fputs("\n", f);
1873 }
94f04347 1874
5b6319dc 1875 if (c->pam_name)
f2d3769a 1876 fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
5b6319dc 1877
15ae422b
LP
1878 if (strv_length(c->read_write_dirs) > 0) {
1879 fprintf(f, "%sReadWriteDirs:", prefix);
1880 strv_fprintf(f, c->read_write_dirs);
1881 fputs("\n", f);
1882 }
1883
1884 if (strv_length(c->read_only_dirs) > 0) {
1885 fprintf(f, "%sReadOnlyDirs:", prefix);
1886 strv_fprintf(f, c->read_only_dirs);
1887 fputs("\n", f);
1888 }
94f04347 1889
15ae422b
LP
1890 if (strv_length(c->inaccessible_dirs) > 0) {
1891 fprintf(f, "%sInaccessibleDirs:", prefix);
1892 strv_fprintf(f, c->inaccessible_dirs);
94f04347
LP
1893 fputs("\n", f);
1894 }
2e22afe9 1895
169c1bda
LP
1896 if (c->utmp_id)
1897 fprintf(f,
1898 "%sUtmpIdentifier: %s\n",
1899 prefix, c->utmp_id);
5cb5a6ff
LP
1900}
1901
b58b4116 1902void exec_status_start(ExecStatus *s, pid_t pid) {
034c6ed7 1903 assert(s);
5cb5a6ff 1904
b58b4116
LP
1905 zero(*s);
1906 s->pid = pid;
1907 dual_timestamp_get(&s->start_timestamp);
1908}
1909
6ea832a2 1910void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
b58b4116
LP
1911 assert(s);
1912
0b1f4ae6 1913 if (s->pid && s->pid != pid)
b58b4116
LP
1914 zero(*s);
1915
034c6ed7 1916 s->pid = pid;
63983207 1917 dual_timestamp_get(&s->exit_timestamp);
9fb86720 1918
034c6ed7
LP
1919 s->code = code;
1920 s->status = status;
169c1bda 1921
6ea832a2
LP
1922 if (context) {
1923 if (context->utmp_id)
1924 utmp_put_dead_process(context->utmp_id, pid, code, status);
1925
1926 exec_context_tty_reset(context);
1927 }
9fb86720
LP
1928}
1929
1930void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
1931 char buf[FORMAT_TIMESTAMP_MAX];
1932
1933 assert(s);
1934 assert(f);
1935
1936 if (!prefix)
1937 prefix = "";
1938
1939 if (s->pid <= 0)
1940 return;
1941
1942 fprintf(f,
bb00e604
LP
1943 "%sPID: %lu\n",
1944 prefix, (unsigned long) s->pid);
9fb86720 1945
63983207 1946 if (s->start_timestamp.realtime > 0)
9fb86720
LP
1947 fprintf(f,
1948 "%sStart Timestamp: %s\n",
63983207 1949 prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
9fb86720 1950
63983207 1951 if (s->exit_timestamp.realtime > 0)
9fb86720
LP
1952 fprintf(f,
1953 "%sExit Timestamp: %s\n"
1954 "%sExit Code: %s\n"
1955 "%sExit Status: %i\n",
63983207 1956 prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
9fb86720
LP
1957 prefix, sigchld_code_to_string(s->code),
1958 prefix, s->status);
5cb5a6ff 1959}
44d8db9e 1960
9e2f7c11 1961char *exec_command_line(char **argv) {
44d8db9e
LP
1962 size_t k;
1963 char *n, *p, **a;
1964 bool first = true;
1965
9e2f7c11 1966 assert(argv);
44d8db9e 1967
9164977d 1968 k = 1;
9e2f7c11 1969 STRV_FOREACH(a, argv)
44d8db9e
LP
1970 k += strlen(*a)+3;
1971
1972 if (!(n = new(char, k)))
1973 return NULL;
1974
1975 p = n;
9e2f7c11 1976 STRV_FOREACH(a, argv) {
44d8db9e
LP
1977
1978 if (!first)
1979 *(p++) = ' ';
1980 else
1981 first = false;
1982
1983 if (strpbrk(*a, WHITESPACE)) {
1984 *(p++) = '\'';
1985 p = stpcpy(p, *a);
1986 *(p++) = '\'';
1987 } else
1988 p = stpcpy(p, *a);
1989
1990 }
1991
9164977d
LP
1992 *p = 0;
1993
44d8db9e
LP
1994 /* FIXME: this doesn't really handle arguments that have
1995 * spaces and ticks in them */
1996
1997 return n;
1998}
1999
2000void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
9fb86720
LP
2001 char *p2;
2002 const char *prefix2;
2003
44d8db9e
LP
2004 char *cmd;
2005
2006 assert(c);
2007 assert(f);
2008
2009 if (!prefix)
2010 prefix = "";
9fb86720
LP
2011 p2 = strappend(prefix, "\t");
2012 prefix2 = p2 ? p2 : prefix;
44d8db9e 2013
9e2f7c11 2014 cmd = exec_command_line(c->argv);
44d8db9e
LP
2015
2016 fprintf(f,
2017 "%sCommand Line: %s\n",
2018 prefix, cmd ? cmd : strerror(ENOMEM));
2019
2020 free(cmd);
9fb86720
LP
2021
2022 exec_status_dump(&c->exec_status, f, prefix2);
2023
2024 free(p2);
44d8db9e
LP
2025}
2026
2027void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
2028 assert(f);
2029
2030 if (!prefix)
2031 prefix = "";
2032
2033 LIST_FOREACH(command, c, c)
2034 exec_command_dump(c, f, prefix);
2035}
94f04347 2036
a6a80b4f
LP
2037void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
2038 ExecCommand *end;
2039
2040 assert(l);
2041 assert(e);
2042
2043 if (*l) {
35b8ca3a 2044 /* It's kind of important, that we keep the order here */
a6a80b4f
LP
2045 LIST_FIND_TAIL(ExecCommand, command, *l, end);
2046 LIST_INSERT_AFTER(ExecCommand, command, *l, end, e);
2047 } else
2048 *l = e;
2049}
2050
26fd040d
LP
2051int exec_command_set(ExecCommand *c, const char *path, ...) {
2052 va_list ap;
2053 char **l, *p;
2054
2055 assert(c);
2056 assert(path);
2057
2058 va_start(ap, path);
2059 l = strv_new_ap(path, ap);
2060 va_end(ap);
2061
2062 if (!l)
2063 return -ENOMEM;
2064
2065 if (!(p = strdup(path))) {
2066 strv_free(l);
2067 return -ENOMEM;
2068 }
2069
2070 free(c->path);
2071 c->path = p;
2072
2073 strv_free(c->argv);
2074 c->argv = l;
2075
2076 return 0;
2077}
2078
80876c20
LP
2079static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
2080 [EXEC_INPUT_NULL] = "null",
2081 [EXEC_INPUT_TTY] = "tty",
2082 [EXEC_INPUT_TTY_FORCE] = "tty-force",
4f2d528d
LP
2083 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
2084 [EXEC_INPUT_SOCKET] = "socket"
80876c20
LP
2085};
2086
8a0867d6
LP
2087DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
2088
94f04347 2089static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
80876c20 2090 [EXEC_OUTPUT_INHERIT] = "inherit",
94f04347 2091 [EXEC_OUTPUT_NULL] = "null",
80876c20 2092 [EXEC_OUTPUT_TTY] = "tty",
94f04347 2093 [EXEC_OUTPUT_SYSLOG] = "syslog",
28dbc1e8 2094 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
9a6bca7a 2095 [EXEC_OUTPUT_KMSG] = "kmsg",
28dbc1e8 2096 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
706343f4
LP
2097 [EXEC_OUTPUT_JOURNAL] = "journal",
2098 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
4f2d528d 2099 [EXEC_OUTPUT_SOCKET] = "socket"
94f04347
LP
2100};
2101
2102DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);