1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include <sys/socket.h>
31 #include <sys/prctl.h>
32 #include <linux/sched.h>
33 #include <sys/types.h>
37 #include <sys/mount.h>
39 #include <linux/oom.h>
41 #include <linux/seccomp-bpf.h>
46 #include <security/pam_appl.h>
52 #include "capability.h"
55 #include "sd-messages.h"
57 #include "securebits.h"
58 #include "namespace.h"
60 #include "exit-status.h"
62 #include "utmp-wtmp.h"
64 #include "loopback-setup.h"
65 #include "path-util.h"
66 #include "syscall-list.h"
72 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
73 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
75 /* This assumes there is a 'tty' group */
78 static int shift_fds(int fds[], unsigned n_fds) {
79 int start, restart_from;
84 /* Modifies the fds array! (sorts it) */
94 for (i = start; i < (int) n_fds; i++) {
97 /* Already at right index? */
101 if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0)
104 close_nointr_nofail(fds[i]);
107 /* Hmm, the fd we wanted isn't free? Then
108 * let's remember that and try again from here*/
109 if (nfd != i+3 && restart_from < 0)
113 if (restart_from < 0)
116 start = restart_from;
122 static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
131 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
133 for (i = 0; i < n_fds; i++) {
135 if ((r = fd_nonblock(fds[i], nonblock)) < 0)
138 /* We unconditionally drop FD_CLOEXEC from the fds,
139 * since after all we want to pass these fds to our
142 if ((r = fd_cloexec(fds[i], false)) < 0)
149 _pure_ static const char *tty_path(const ExecContext *context) {
152 if (context->tty_path)
153 return context->tty_path;
155 return "/dev/console";
158 void exec_context_tty_reset(const ExecContext *context) {
161 if (context->tty_vhangup)
162 terminal_vhangup(tty_path(context));
164 if (context->tty_reset)
165 reset_terminal(tty_path(context));
167 if (context->tty_vt_disallocate && context->tty_path)
168 vt_disallocate(context->tty_path);
171 static bool is_terminal_output(ExecOutput o) {
173 o == EXEC_OUTPUT_TTY ||
174 o == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
175 o == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
176 o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE;
179 void exec_context_serialize(const ExecContext *context, Unit *u, FILE *f) {
184 if (context->tmp_dir)
185 unit_serialize_item(u, f, "tmp-dir", context->tmp_dir);
187 if (context->var_tmp_dir)
188 unit_serialize_item(u, f, "var-tmp-dir", context->var_tmp_dir);
191 static int open_null_as(int flags, int nfd) {
196 if ((fd = open("/dev/null", flags|O_NOCTTY)) < 0)
200 r = dup2(fd, nfd) < 0 ? -errno : nfd;
201 close_nointr_nofail(fd);
208 static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd) {
210 union sockaddr_union sa = {
211 .un.sun_family = AF_UNIX,
212 .un.sun_path = "/run/systemd/journal/stdout",
216 assert(output < _EXEC_OUTPUT_MAX);
220 fd = socket(AF_UNIX, SOCK_STREAM, 0);
224 r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
226 close_nointr_nofail(fd);
230 if (shutdown(fd, SHUT_RD) < 0) {
231 close_nointr_nofail(fd);
243 context->syslog_identifier ? context->syslog_identifier : ident,
245 context->syslog_priority,
246 !!context->syslog_level_prefix,
247 output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
248 output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE,
249 is_terminal_output(output));
252 r = dup2(fd, nfd) < 0 ? -errno : nfd;
253 close_nointr_nofail(fd);
259 static int open_terminal_as(const char *path, mode_t mode, int nfd) {
265 if ((fd = open_terminal(path, mode | O_NOCTTY)) < 0)
269 r = dup2(fd, nfd) < 0 ? -errno : nfd;
270 close_nointr_nofail(fd);
277 static bool is_terminal_input(ExecInput i) {
279 i == EXEC_INPUT_TTY ||
280 i == EXEC_INPUT_TTY_FORCE ||
281 i == EXEC_INPUT_TTY_FAIL;
284 static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
286 if (is_terminal_input(std_input) && !apply_tty_stdin)
287 return EXEC_INPUT_NULL;
289 if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
290 return EXEC_INPUT_NULL;
295 static int fixup_output(ExecOutput std_output, int socket_fd) {
297 if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0)
298 return EXEC_OUTPUT_INHERIT;
303 static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty_stdin) {
308 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
312 case EXEC_INPUT_NULL:
313 return open_null_as(O_RDONLY, STDIN_FILENO);
316 case EXEC_INPUT_TTY_FORCE:
317 case EXEC_INPUT_TTY_FAIL: {
320 if ((fd = acquire_terminal(
322 i == EXEC_INPUT_TTY_FAIL,
323 i == EXEC_INPUT_TTY_FORCE,
328 if (fd != STDIN_FILENO) {
329 r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
330 close_nointr_nofail(fd);
337 case EXEC_INPUT_SOCKET:
338 return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
341 assert_not_reached("Unknown input type");
345 static int setup_output(const ExecContext *context, int fileno, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin) {
353 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
354 o = fixup_output(context->std_output, socket_fd);
356 if (fileno == STDERR_FILENO) {
358 e = fixup_output(context->std_error, socket_fd);
360 /* This expects the input and output are already set up */
362 /* Don't change the stderr file descriptor if we inherit all
363 * the way and are not on a tty */
364 if (e == EXEC_OUTPUT_INHERIT &&
365 o == EXEC_OUTPUT_INHERIT &&
366 i == EXEC_INPUT_NULL &&
367 !is_terminal_input(context->std_input) &&
371 /* Duplicate from stdout if possible */
372 if (e == o || e == EXEC_OUTPUT_INHERIT)
373 return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno;
377 } else if (o == EXEC_OUTPUT_INHERIT) {
378 /* If input got downgraded, inherit the original value */
379 if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
380 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
382 /* If the input is connected to anything that's not a /dev/null, inherit that... */
383 if (i != EXEC_INPUT_NULL)
384 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
386 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
390 /* We need to open /dev/null here anew, to get the right access mode. */
391 return open_null_as(O_WRONLY, fileno);
396 case EXEC_OUTPUT_NULL:
397 return open_null_as(O_WRONLY, fileno);
399 case EXEC_OUTPUT_TTY:
400 if (is_terminal_input(i))
401 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
403 /* We don't reset the terminal if this is just about output */
404 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
406 case EXEC_OUTPUT_SYSLOG:
407 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
408 case EXEC_OUTPUT_KMSG:
409 case EXEC_OUTPUT_KMSG_AND_CONSOLE:
410 case EXEC_OUTPUT_JOURNAL:
411 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
412 r = connect_logger_as(context, o, ident, unit_id, fileno);
414 log_struct_unit(LOG_CRIT, unit_id,
415 "MESSAGE=Failed to connect std%s of %s to the journal socket: %s",
416 fileno == STDOUT_FILENO ? "out" : "err",
417 unit_id, strerror(-r),
420 r = open_null_as(O_WRONLY, fileno);
424 case EXEC_OUTPUT_SOCKET:
425 assert(socket_fd >= 0);
426 return dup2(socket_fd, fileno) < 0 ? -errno : fileno;
429 assert_not_reached("Unknown error type");
433 static int chown_terminal(int fd, uid_t uid) {
438 /* This might fail. What matters are the results. */
439 (void) fchown(fd, uid, -1);
440 (void) fchmod(fd, TTY_MODE);
442 if (fstat(fd, &st) < 0)
445 if (st.st_uid != uid || (st.st_mode & 0777) != TTY_MODE)
451 static int setup_confirm_stdio(int *_saved_stdin,
452 int *_saved_stdout) {
453 int fd = -1, saved_stdin, saved_stdout = -1, r;
455 assert(_saved_stdin);
456 assert(_saved_stdout);
458 saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3);
462 saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3);
463 if (saved_stdout < 0) {
468 fd = acquire_terminal(
473 DEFAULT_CONFIRM_USEC);
479 r = chown_terminal(fd, getuid());
483 if (dup2(fd, STDIN_FILENO) < 0) {
488 if (dup2(fd, STDOUT_FILENO) < 0) {
494 close_nointr_nofail(fd);
496 *_saved_stdin = saved_stdin;
497 *_saved_stdout = saved_stdout;
502 if (saved_stdout >= 0)
503 close_nointr_nofail(saved_stdout);
505 if (saved_stdin >= 0)
506 close_nointr_nofail(saved_stdin);
509 close_nointr_nofail(fd);
514 _printf_attr_(1, 2) static int write_confirm_message(const char *format, ...) {
520 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
524 va_start(ap, format);
525 vdprintf(fd, format, ap);
528 close_nointr_nofail(fd);
533 static int restore_confirm_stdio(int *saved_stdin,
539 assert(saved_stdout);
543 if (*saved_stdin >= 0)
544 if (dup2(*saved_stdin, STDIN_FILENO) < 0)
547 if (*saved_stdout >= 0)
548 if (dup2(*saved_stdout, STDOUT_FILENO) < 0)
551 if (*saved_stdin >= 0)
552 close_nointr_nofail(*saved_stdin);
554 if (*saved_stdout >= 0)
555 close_nointr_nofail(*saved_stdout);
560 static int ask_for_confirmation(char *response, char **argv) {
561 int saved_stdout = -1, saved_stdin = -1, r;
564 r = setup_confirm_stdio(&saved_stdin, &saved_stdout);
568 line = exec_command_line(argv);
572 r = ask(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
575 restore_confirm_stdio(&saved_stdin, &saved_stdout);
580 static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) {
581 bool keep_groups = false;
586 /* Lookup and set GID and supplementary group list. Here too
587 * we avoid NSS lookups for gid=0. */
589 if (context->group || username) {
591 if (context->group) {
592 const char *g = context->group;
594 if ((r = get_group_creds(&g, &gid)) < 0)
598 /* First step, initialize groups from /etc/groups */
599 if (username && gid != 0) {
600 if (initgroups(username, gid) < 0)
606 /* Second step, set our gids */
607 if (setresgid(gid, gid, gid) < 0)
611 if (context->supplementary_groups) {
616 /* Final step, initialize any manually set supplementary groups */
617 assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0);
619 if (!(gids = new(gid_t, ngroups_max)))
623 if ((k = getgroups(ngroups_max, gids)) < 0) {
630 STRV_FOREACH(i, context->supplementary_groups) {
633 if (k >= ngroups_max) {
639 r = get_group_creds(&g, gids+k);
648 if (setgroups(k, gids) < 0) {
659 static int enforce_user(const ExecContext *context, uid_t uid) {
663 /* Sets (but doesn't lookup) the uid and make sure we keep the
664 * capabilities while doing so. */
666 if (context->capabilities) {
668 static const cap_value_t bits[] = {
669 CAP_SETUID, /* Necessary so that we can run setresuid() below */
670 CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */
673 /* First step: If we need to keep capabilities but
674 * drop privileges we need to make sure we keep our
675 * caps, while we drop privileges. */
677 int sb = context->secure_bits | 1<<SECURE_KEEP_CAPS;
679 if (prctl(PR_GET_SECUREBITS) != sb)
680 if (prctl(PR_SET_SECUREBITS, sb) < 0)
684 /* Second step: set the capabilities. This will reduce
685 * the capabilities to the minimum we need. */
687 if (!(d = cap_dup(context->capabilities)))
690 if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 ||
691 cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0) {
697 if (cap_set_proc(d) < 0) {
706 /* Third step: actually set the uids */
707 if (setresuid(uid, uid, uid) < 0)
710 /* At this point we should have all necessary capabilities but
711 are otherwise a normal user. However, the caps might got
712 corrupted due to the setresuid() so we need clean them up
713 later. This is done outside of this call. */
720 static int null_conv(
722 const struct pam_message **msg,
723 struct pam_response **resp,
726 /* We don't support conversations */
731 static int setup_pam(
737 int fds[], unsigned n_fds) {
739 static const struct pam_conv conv = {
744 pam_handle_t *handle = NULL;
746 int pam_code = PAM_SUCCESS;
749 bool close_session = false;
750 pid_t pam_pid = 0, parent_pid;
756 /* We set up PAM in the parent process, then fork. The child
757 * will then stay around until killed via PR_GET_PDEATHSIG or
758 * systemd via the cgroup logic. It will then remove the PAM
759 * session again. The parent process will exec() the actual
760 * daemon. We do things this way to ensure that the main PID
761 * of the daemon is the one we initially fork()ed. */
763 if ((pam_code = pam_start(name, user, &conv, &handle)) != PAM_SUCCESS) {
769 if ((pam_code = pam_set_item(handle, PAM_TTY, tty)) != PAM_SUCCESS)
772 if ((pam_code = pam_acct_mgmt(handle, PAM_SILENT)) != PAM_SUCCESS)
775 if ((pam_code = pam_open_session(handle, PAM_SILENT)) != PAM_SUCCESS)
778 close_session = true;
780 if ((!(e = pam_getenvlist(handle)))) {
781 pam_code = PAM_BUF_ERR;
785 /* Block SIGTERM, so that we know that it won't get lost in
787 if (sigemptyset(&ss) < 0 ||
788 sigaddset(&ss, SIGTERM) < 0 ||
789 sigprocmask(SIG_BLOCK, &ss, &old_ss) < 0)
792 parent_pid = getpid();
794 if ((pam_pid = fork()) < 0)
801 /* The child's job is to reset the PAM session on
804 /* This string must fit in 10 chars (i.e. the length
805 * of "/sbin/init"), to look pretty in /bin/ps */
806 rename_process("(sd-pam)");
808 /* Make sure we don't keep open the passed fds in this
809 child. We assume that otherwise only those fds are
810 open here that have been opened by PAM. */
811 close_many(fds, n_fds);
813 /* Drop privileges - we don't need any to pam_close_session
814 * and this will make PR_SET_PDEATHSIG work in most cases.
815 * If this fails, ignore the error - but expect sd-pam threads
816 * to fail to exit normally */
817 if (setresuid(uid, uid, uid) < 0)
818 log_error("Error: Failed to setresuid() in sd-pam: %s", strerror(-r));
820 /* Wait until our parent died. This will only work if
821 * the above setresuid() succeeds, otherwise the kernel
822 * will not allow unprivileged parents kill their privileged
823 * children this way. We rely on the control groups kill logic
824 * to do the rest for us. */
825 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
828 /* Check if our parent process might already have
830 if (getppid() == parent_pid) {
832 if (sigwait(&ss, &sig) < 0) {
839 assert(sig == SIGTERM);
844 /* If our parent died we'll end the session */
845 if (getppid() != parent_pid)
846 if ((pam_code = pam_close_session(handle, PAM_DATA_SILENT)) != PAM_SUCCESS)
852 pam_end(handle, pam_code | PAM_DATA_SILENT);
856 /* If the child was forked off successfully it will do all the
857 * cleanups, so forget about the handle here. */
860 /* Unblock SIGTERM again in the parent */
861 if (sigprocmask(SIG_SETMASK, &old_ss, NULL) < 0)
864 /* We close the log explicitly here, since the PAM modules
865 * might have opened it, but we don't want this fd around. */
874 if (pam_code != PAM_SUCCESS)
875 err = -EPERM; /* PAM errors do not map to errno */
881 pam_code = pam_close_session(handle, PAM_DATA_SILENT);
883 pam_end(handle, pam_code | PAM_DATA_SILENT);
891 kill(pam_pid, SIGTERM);
892 kill(pam_pid, SIGCONT);
899 static void rename_process_from_path(const char *path) {
900 char process_name[11];
904 /* This resulting string must fit in 10 chars (i.e. the length
905 * of "/sbin/init") to look pretty in /bin/ps */
907 p = path_get_file_name(path);
909 rename_process("(...)");
915 /* The end of the process name is usually more
916 * interesting, since the first bit might just be
922 process_name[0] = '(';
923 memcpy(process_name+1, p, l);
924 process_name[1+l] = ')';
925 process_name[1+l+1] = 0;
927 rename_process(process_name);
930 static int apply_seccomp(uint32_t *syscall_filter) {
931 static const struct sock_filter header[] = {
932 VALIDATE_ARCHITECTURE,
935 static const struct sock_filter footer[] = {
941 struct sock_filter *f;
942 struct sock_fprog prog = {};
944 assert(syscall_filter);
946 /* First: count the syscalls to check for */
947 for (i = 0, n = 0; i < syscall_max(); i++)
948 if (syscall_filter[i >> 4] & (1 << (i & 31)))
951 /* Second: build the filter program from a header the syscall
952 * matches and the footer */
953 f = alloca(sizeof(struct sock_filter) * (ELEMENTSOF(header) + 2*n + ELEMENTSOF(footer)));
954 memcpy(f, header, sizeof(header));
956 for (i = 0, n = 0; i < syscall_max(); i++)
957 if (syscall_filter[i >> 4] & (1 << (i & 31))) {
958 struct sock_filter item[] = {
959 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, INDEX_TO_SYSCALL(i), 0, 1),
960 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
963 assert_cc(ELEMENTSOF(item) == 2);
965 f[ELEMENTSOF(header) + 2*n] = item[0];
966 f[ELEMENTSOF(header) + 2*n+1] = item[1];
971 memcpy(f + (ELEMENTSOF(header) + 2*n), footer, sizeof(footer));
973 /* Third: install the filter */
974 prog.len = ELEMENTSOF(header) + ELEMENTSOF(footer) + 2*n;
976 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0)
982 static void do_idle_pipe_dance(int idle_pipe[4]) {
985 if (idle_pipe[1] >= 0)
986 close_nointr_nofail(idle_pipe[1]);
987 if (idle_pipe[2] >= 0)
988 close_nointr_nofail(idle_pipe[2]);
990 if (idle_pipe[0] >= 0) {
993 r = fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
995 if (idle_pipe[3] >= 0 && r == 0 /* timeout */) {
996 /* Signal systemd that we are bored and want to continue. */
997 write(idle_pipe[3], "x", 1);
999 /* Wait for systemd to react to the signal above. */
1000 fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC);
1003 close_nointr_nofail(idle_pipe[0]);
1007 if (idle_pipe[3] >= 0)
1008 close_nointr_nofail(idle_pipe[3]);
1011 int exec_spawn(ExecCommand *command,
1013 ExecContext *context,
1014 int fds[], unsigned n_fds,
1016 bool apply_permissions,
1018 bool apply_tty_stdin,
1020 CGroupControllerMask cgroup_mask,
1021 const char *cgroup_path,
1022 const char *unit_id,
1026 _cleanup_strv_free_ char **files_env = NULL;
1035 assert(fds || n_fds <= 0);
1037 if (context->std_input == EXEC_INPUT_SOCKET ||
1038 context->std_output == EXEC_OUTPUT_SOCKET ||
1039 context->std_error == EXEC_OUTPUT_SOCKET) {
1051 r = exec_context_load_environment(context, &files_env);
1053 log_struct_unit(LOG_ERR,
1055 "MESSAGE=Failed to load environment files: %s", strerror(-r),
1062 argv = command->argv;
1064 line = exec_command_line(argv);
1068 log_struct_unit(LOG_DEBUG,
1070 "EXECUTABLE=%s", command->path,
1071 "MESSAGE=About to execute: %s", line,
1075 if (context->private_tmp && !context->tmp_dir && !context->var_tmp_dir) {
1076 r = setup_tmpdirs(&context->tmp_dir, &context->var_tmp_dir);
1088 const char *username = NULL, *home = NULL;
1089 uid_t uid = (uid_t) -1;
1090 gid_t gid = (gid_t) -1;
1091 _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL,
1092 **final_env = NULL, **final_argv = NULL;
1097 rename_process_from_path(command->path);
1099 /* We reset exactly these signals, since they are the
1100 * only ones we set to SIG_IGN in the main daemon. All
1101 * others we leave untouched because we set them to
1102 * SIG_DFL or a valid handler initially, both of which
1103 * will be demoted to SIG_DFL. */
1104 default_signals(SIGNALS_CRASH_HANDLER,
1105 SIGNALS_IGNORE, -1);
1107 if (context->ignore_sigpipe)
1108 ignore_signals(SIGPIPE, -1);
1110 assert_se(sigemptyset(&ss) == 0);
1111 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) {
1113 r = EXIT_SIGNAL_MASK;
1118 do_idle_pipe_dance(idle_pipe);
1120 /* Close sockets very early to make sure we don't
1121 * block init reexecution because it cannot bind its
1124 err = close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
1125 socket_fd >= 0 ? 1 : n_fds);
1131 if (!context->same_pgrp)
1138 if (context->tcpwrap_name) {
1140 if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) {
1146 for (i = 0; i < (int) n_fds; i++) {
1147 if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) {
1155 exec_context_tty_reset(context);
1157 if (confirm_spawn) {
1160 err = ask_for_confirmation(&response, argv);
1161 if (err == -ETIMEDOUT)
1162 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1164 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-err));
1165 else if (response == 's') {
1166 write_confirm_message("Skipping execution.\n");
1170 } else if (response == 'n') {
1171 write_confirm_message("Failing execution.\n");
1177 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1178 * must sure to drop O_NONBLOCK */
1180 fd_nonblock(socket_fd, false);
1182 err = setup_input(context, socket_fd, apply_tty_stdin);
1188 err = setup_output(context, STDOUT_FILENO, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin);
1194 err = setup_output(context, STDERR_FILENO, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin);
1201 err = cg_attach_with_mask(cgroup_mask, cgroup_path, 0);
1208 if (context->oom_score_adjust_set) {
1211 snprintf(t, sizeof(t), "%i", context->oom_score_adjust);
1214 if (write_string_file("/proc/self/oom_score_adj", t) < 0) {
1216 r = EXIT_OOM_ADJUST;
1221 if (context->nice_set)
1222 if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
1228 if (context->cpu_sched_set) {
1229 struct sched_param param = {
1230 .sched_priority = context->cpu_sched_priority,
1233 r = sched_setscheduler(0,
1234 context->cpu_sched_policy |
1235 (context->cpu_sched_reset_on_fork ?
1236 SCHED_RESET_ON_FORK : 0),
1240 r = EXIT_SETSCHEDULER;
1245 if (context->cpuset)
1246 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
1248 r = EXIT_CPUAFFINITY;
1252 if (context->ioprio_set)
1253 if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
1259 if (context->timer_slack_nsec != (nsec_t) -1)
1260 if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
1262 r = EXIT_TIMERSLACK;
1266 if (context->utmp_id)
1267 utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path);
1269 if (context->user) {
1270 username = context->user;
1271 err = get_user_creds(&username, &uid, &gid, &home, NULL);
1277 if (is_terminal_input(context->std_input)) {
1278 err = chown_terminal(STDIN_FILENO, uid);
1287 if (cgroup_path && context->user && context->pam_name) {
1288 err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0644, uid, gid);
1295 err = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0755, uid, gid);
1303 if (apply_permissions) {
1304 err = enforce_groups(context, username, gid);
1311 umask(context->umask);
1314 if (apply_permissions && context->pam_name && username) {
1315 err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
1322 if (context->private_network) {
1323 if (unshare(CLONE_NEWNET) < 0) {
1332 if (strv_length(context->read_write_dirs) > 0 ||
1333 strv_length(context->read_only_dirs) > 0 ||
1334 strv_length(context->inaccessible_dirs) > 0 ||
1335 context->mount_flags != 0 ||
1336 context->private_tmp) {
1337 err = setup_namespace(context->read_write_dirs,
1338 context->read_only_dirs,
1339 context->inaccessible_dirs,
1341 context->var_tmp_dir,
1342 context->private_tmp,
1343 context->mount_flags);
1351 if (context->root_directory)
1352 if (chroot(context->root_directory) < 0) {
1358 if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
1364 _cleanup_free_ char *d = NULL;
1366 if (asprintf(&d, "%s/%s",
1367 context->root_directory ? context->root_directory : "",
1368 context->working_directory ? context->working_directory : "") < 0) {
1381 /* We repeat the fd closing here, to make sure that
1382 * nothing is leaked from the PAM modules */
1383 err = close_all_fds(fds, n_fds);
1385 err = shift_fds(fds, n_fds);
1387 err = flags_fds(fds, n_fds, context->non_blocking);
1393 if (apply_permissions) {
1395 for (i = 0; i < RLIMIT_NLIMITS; i++) {
1396 if (!context->rlimit[i])
1399 if (setrlimit_closest(i, context->rlimit[i]) < 0) {
1406 if (context->capability_bounding_set_drop) {
1407 err = capability_bounding_set_drop(context->capability_bounding_set_drop, false);
1409 r = EXIT_CAPABILITIES;
1414 if (context->user) {
1415 err = enforce_user(context, uid);
1422 /* PR_GET_SECUREBITS is not privileged, while
1423 * PR_SET_SECUREBITS is. So to suppress
1424 * potential EPERMs we'll try not to call
1425 * PR_SET_SECUREBITS unless necessary. */
1426 if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
1427 if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
1429 r = EXIT_SECUREBITS;
1433 if (context->capabilities)
1434 if (cap_set_proc(context->capabilities) < 0) {
1436 r = EXIT_CAPABILITIES;
1440 if (context->no_new_privileges)
1441 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
1443 r = EXIT_NO_NEW_PRIVILEGES;
1447 if (context->syscall_filter) {
1448 err = apply_seccomp(context->syscall_filter);
1456 our_env = new0(char*, 7);
1464 if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 ||
1465 asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) {
1472 if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) {
1479 if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 ||
1480 asprintf(our_env + n_env++, "USER=%s", username) < 0) {
1486 if (is_terminal_input(context->std_input) ||
1487 context->std_output == EXEC_OUTPUT_TTY ||
1488 context->std_error == EXEC_OUTPUT_TTY)
1489 if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) {
1497 final_env = strv_env_merge(5,
1500 context->environment,
1510 final_argv = replace_env_argv(argv, final_env);
1517 final_env = strv_env_clean(final_env);
1519 if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) {
1520 line = exec_command_line(final_argv);
1523 log_struct_unit(LOG_DEBUG,
1525 "EXECUTABLE=%s", command->path,
1526 "MESSAGE=Executing: %s", line,
1533 execve(command->path, final_argv, final_env);
1540 log_struct(LOG_ERR, MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
1541 "EXECUTABLE=%s", command->path,
1542 "MESSAGE=Failed at step %s spawning %s: %s",
1543 exit_status_to_string(r, EXIT_STATUS_SYSTEMD),
1544 command->path, strerror(-err),
1553 log_struct_unit(LOG_DEBUG,
1555 "MESSAGE=Forked %s as %lu",
1556 command->path, (unsigned long) pid,
1559 /* We add the new process to the cgroup both in the child (so
1560 * that we can be sure that no user code is ever executed
1561 * outside of the cgroup) and in the parent (so that we can be
1562 * sure that when we kill the cgroup the process will be
1565 cg_attach(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, pid);
1567 exec_status_start(&command->exec_status, pid);
1573 void exec_context_init(ExecContext *c) {
1577 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
1578 c->cpu_sched_policy = SCHED_OTHER;
1579 c->syslog_priority = LOG_DAEMON|LOG_INFO;
1580 c->syslog_level_prefix = true;
1581 c->ignore_sigpipe = true;
1582 c->timer_slack_nsec = (nsec_t) -1;
1585 static void *remove_tmpdir_thread(void *p) {
1587 _cleanup_free_ char *dirp = p;
1592 r = rm_rf_dangerous(dirp, false, true, false);
1593 dir = dirname(dirp);
1595 log_warning("Failed to remove content of temporary directory %s: %s",
1600 log_warning("Failed to remove temporary directory %s: %s",
1607 void exec_context_tmp_dirs_done(ExecContext *c) {
1608 char* dirs[] = {c->tmp_dir ? c->tmp_dir : c->var_tmp_dir,
1609 c->tmp_dir ? c->var_tmp_dir : NULL,
1613 for(dirp = dirs; *dirp; dirp++) {
1614 log_debug("Spawning thread to nuke %s", *dirp);
1615 asynchronous_job(remove_tmpdir_thread, *dirp);
1618 c->tmp_dir = c->var_tmp_dir = NULL;
1621 void exec_context_done(ExecContext *c, bool reloading_or_reexecuting) {
1626 strv_free(c->environment);
1627 c->environment = NULL;
1629 strv_free(c->environment_files);
1630 c->environment_files = NULL;
1632 for (l = 0; l < ELEMENTSOF(c->rlimit); l++) {
1634 c->rlimit[l] = NULL;
1637 free(c->working_directory);
1638 c->working_directory = NULL;
1639 free(c->root_directory);
1640 c->root_directory = NULL;
1645 free(c->tcpwrap_name);
1646 c->tcpwrap_name = NULL;
1648 free(c->syslog_identifier);
1649 c->syslog_identifier = NULL;
1657 strv_free(c->supplementary_groups);
1658 c->supplementary_groups = NULL;
1663 if (c->capabilities) {
1664 cap_free(c->capabilities);
1665 c->capabilities = NULL;
1668 strv_free(c->read_only_dirs);
1669 c->read_only_dirs = NULL;
1671 strv_free(c->read_write_dirs);
1672 c->read_write_dirs = NULL;
1674 strv_free(c->inaccessible_dirs);
1675 c->inaccessible_dirs = NULL;
1678 CPU_FREE(c->cpuset);
1683 free(c->syscall_filter);
1684 c->syscall_filter = NULL;
1686 if (!reloading_or_reexecuting)
1687 exec_context_tmp_dirs_done(c);
1690 void exec_command_done(ExecCommand *c) {
1700 void exec_command_done_array(ExecCommand *c, unsigned n) {
1703 for (i = 0; i < n; i++)
1704 exec_command_done(c+i);
1707 void exec_command_free_list(ExecCommand *c) {
1711 LIST_REMOVE(ExecCommand, command, c, i);
1712 exec_command_done(i);
1717 void exec_command_free_array(ExecCommand **c, unsigned n) {
1720 for (i = 0; i < n; i++) {
1721 exec_command_free_list(c[i]);
1726 int exec_context_load_environment(const ExecContext *c, char ***l) {
1727 char **i, **r = NULL;
1732 STRV_FOREACH(i, c->environment_files) {
1735 bool ignore = false;
1737 _cleanup_globfree_ glob_t pglob = {};
1747 if (!path_is_absolute(fn)) {
1755 /* Filename supports globbing, take all matching files */
1757 if (glob(fn, 0, NULL, &pglob) != 0) {
1762 return errno ? -errno : -EINVAL;
1764 count = pglob.gl_pathc;
1772 for (n = 0; n < count; n++) {
1773 k = load_env_file(pglob.gl_pathv[n], NULL, &p);
1781 /* Log invalid environment variables with filename */
1783 p = strv_env_clean_log(p, pglob.gl_pathv[n]);
1790 m = strv_env_merge(2, r, p);
1806 static bool tty_may_match_dev_console(const char *tty) {
1807 char *active = NULL, *console;
1810 if (startswith(tty, "/dev/"))
1813 /* trivial identity? */
1814 if (streq(tty, "console"))
1817 console = resolve_dev_console(&active);
1818 /* if we could not resolve, assume it may */
1822 /* "tty0" means the active VC, so it may be the same sometimes */
1823 b = streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
1829 bool exec_context_may_touch_console(ExecContext *ec) {
1830 return (ec->tty_reset || ec->tty_vhangup || ec->tty_vt_disallocate ||
1831 is_terminal_input(ec->std_input) ||
1832 is_terminal_output(ec->std_output) ||
1833 is_terminal_output(ec->std_error)) &&
1834 tty_may_match_dev_console(tty_path(ec));
1837 static void strv_fprintf(FILE *f, char **l) {
1843 fprintf(f, " %s", *g);
1846 void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
1853 prefix = strempty(prefix);
1857 "%sWorkingDirectory: %s\n"
1858 "%sRootDirectory: %s\n"
1859 "%sNonBlocking: %s\n"
1860 "%sPrivateTmp: %s\n"
1861 "%sPrivateNetwork: %s\n"
1862 "%sIgnoreSIGPIPE: %s\n",
1864 prefix, c->working_directory ? c->working_directory : "/",
1865 prefix, c->root_directory ? c->root_directory : "/",
1866 prefix, yes_no(c->non_blocking),
1867 prefix, yes_no(c->private_tmp),
1868 prefix, yes_no(c->private_network),
1869 prefix, yes_no(c->ignore_sigpipe));
1871 STRV_FOREACH(e, c->environment)
1872 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
1874 STRV_FOREACH(e, c->environment_files)
1875 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
1877 if (c->tcpwrap_name)
1879 "%sTCPWrapName: %s\n",
1880 prefix, c->tcpwrap_name);
1887 if (c->oom_score_adjust_set)
1889 "%sOOMScoreAdjust: %i\n",
1890 prefix, c->oom_score_adjust);
1892 for (i = 0; i < RLIM_NLIMITS; i++)
1894 fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max);
1896 if (c->ioprio_set) {
1900 r = ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
1904 "%sIOSchedulingClass: %s\n"
1905 "%sIOPriority: %i\n",
1906 prefix, strna(class_str),
1907 prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
1911 if (c->cpu_sched_set) {
1915 r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
1919 "%sCPUSchedulingPolicy: %s\n"
1920 "%sCPUSchedulingPriority: %i\n"
1921 "%sCPUSchedulingResetOnFork: %s\n",
1922 prefix, strna(policy_str),
1923 prefix, c->cpu_sched_priority,
1924 prefix, yes_no(c->cpu_sched_reset_on_fork));
1929 fprintf(f, "%sCPUAffinity:", prefix);
1930 for (i = 0; i < c->cpuset_ncpus; i++)
1931 if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
1932 fprintf(f, " %i", i);
1936 if (c->timer_slack_nsec != (nsec_t) -1)
1937 fprintf(f, "%sTimerSlackNSec: %lu\n", prefix, (unsigned long)c->timer_slack_nsec);
1940 "%sStandardInput: %s\n"
1941 "%sStandardOutput: %s\n"
1942 "%sStandardError: %s\n",
1943 prefix, exec_input_to_string(c->std_input),
1944 prefix, exec_output_to_string(c->std_output),
1945 prefix, exec_output_to_string(c->std_error));
1951 "%sTTYVHangup: %s\n"
1952 "%sTTYVTDisallocate: %s\n",
1953 prefix, c->tty_path,
1954 prefix, yes_no(c->tty_reset),
1955 prefix, yes_no(c->tty_vhangup),
1956 prefix, yes_no(c->tty_vt_disallocate));
1958 if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG || c->std_output == EXEC_OUTPUT_JOURNAL ||
1959 c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
1960 c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG || c->std_error == EXEC_OUTPUT_JOURNAL ||
1961 c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) {
1962 char *fac_str, *lvl_str;
1965 r = log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
1969 r = log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
1974 "%sSyslogFacility: %s\n"
1975 "%sSyslogLevel: %s\n",
1976 prefix, strna(fac_str),
1977 prefix, strna(lvl_str));
1982 if (c->capabilities) {
1984 if ((t = cap_to_text(c->capabilities, NULL))) {
1985 fprintf(f, "%sCapabilities: %s\n",
1992 fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
1994 (c->secure_bits & 1<<SECURE_KEEP_CAPS) ? " keep-caps" : "",
1995 (c->secure_bits & 1<<SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
1996 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
1997 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
1998 (c->secure_bits & 1<<SECURE_NOROOT) ? " noroot" : "",
1999 (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
2001 if (c->capability_bounding_set_drop) {
2003 fprintf(f, "%sCapabilityBoundingSet:", prefix);
2005 for (l = 0; l <= cap_last_cap(); l++)
2006 if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) {
2009 if ((t = cap_to_name(l))) {
2010 fprintf(f, " %s", t);
2019 fprintf(f, "%sUser: %s\n", prefix, c->user);
2021 fprintf(f, "%sGroup: %s\n", prefix, c->group);
2023 if (strv_length(c->supplementary_groups) > 0) {
2024 fprintf(f, "%sSupplementaryGroups:", prefix);
2025 strv_fprintf(f, c->supplementary_groups);
2030 fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
2032 if (strv_length(c->read_write_dirs) > 0) {
2033 fprintf(f, "%sReadWriteDirs:", prefix);
2034 strv_fprintf(f, c->read_write_dirs);
2038 if (strv_length(c->read_only_dirs) > 0) {
2039 fprintf(f, "%sReadOnlyDirs:", prefix);
2040 strv_fprintf(f, c->read_only_dirs);
2044 if (strv_length(c->inaccessible_dirs) > 0) {
2045 fprintf(f, "%sInaccessibleDirs:", prefix);
2046 strv_fprintf(f, c->inaccessible_dirs);
2052 "%sUtmpIdentifier: %s\n",
2053 prefix, c->utmp_id);
2056 void exec_status_start(ExecStatus *s, pid_t pid) {
2061 dual_timestamp_get(&s->start_timestamp);
2064 void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
2067 if (s->pid && s->pid != pid)
2071 dual_timestamp_get(&s->exit_timestamp);
2077 if (context->utmp_id)
2078 utmp_put_dead_process(context->utmp_id, pid, code, status);
2080 exec_context_tty_reset(context);
2084 void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
2085 char buf[FORMAT_TIMESTAMP_MAX];
2098 prefix, (unsigned long) s->pid);
2100 if (s->start_timestamp.realtime > 0)
2102 "%sStart Timestamp: %s\n",
2103 prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
2105 if (s->exit_timestamp.realtime > 0)
2107 "%sExit Timestamp: %s\n"
2109 "%sExit Status: %i\n",
2110 prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
2111 prefix, sigchld_code_to_string(s->code),
2115 char *exec_command_line(char **argv) {
2123 STRV_FOREACH(a, argv)
2126 if (!(n = new(char, k)))
2130 STRV_FOREACH(a, argv) {
2137 if (strpbrk(*a, WHITESPACE)) {
2148 /* FIXME: this doesn't really handle arguments that have
2149 * spaces and ticks in them */
2154 void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
2156 const char *prefix2;
2165 p2 = strappend(prefix, "\t");
2166 prefix2 = p2 ? p2 : prefix;
2168 cmd = exec_command_line(c->argv);
2171 "%sCommand Line: %s\n",
2172 prefix, cmd ? cmd : strerror(ENOMEM));
2176 exec_status_dump(&c->exec_status, f, prefix2);
2181 void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
2187 LIST_FOREACH(command, c, c)
2188 exec_command_dump(c, f, prefix);
2191 void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
2198 /* It's kind of important, that we keep the order here */
2199 LIST_FIND_TAIL(ExecCommand, command, *l, end);
2200 LIST_INSERT_AFTER(ExecCommand, command, *l, end, e);
2205 int exec_command_set(ExecCommand *c, const char *path, ...) {
2213 l = strv_new_ap(path, ap);
2219 if (!(p = strdup(path))) {
2233 static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
2234 [EXEC_INPUT_NULL] = "null",
2235 [EXEC_INPUT_TTY] = "tty",
2236 [EXEC_INPUT_TTY_FORCE] = "tty-force",
2237 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
2238 [EXEC_INPUT_SOCKET] = "socket"
2241 DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
2243 static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
2244 [EXEC_OUTPUT_INHERIT] = "inherit",
2245 [EXEC_OUTPUT_NULL] = "null",
2246 [EXEC_OUTPUT_TTY] = "tty",
2247 [EXEC_OUTPUT_SYSLOG] = "syslog",
2248 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
2249 [EXEC_OUTPUT_KMSG] = "kmsg",
2250 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
2251 [EXEC_OUTPUT_JOURNAL] = "journal",
2252 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
2253 [EXEC_OUTPUT_SOCKET] = "socket"
2256 DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);