X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fexecute.c;h=3ae28ee080af0531863c13da866d393c826f1474;hb=eb9da376d76b48585b3b63b4f91903b54f7abd36;hp=43b571e043ad0b7231311e748e68b9875e8c353e;hpb=31a7eb86f18b0466681d6fbe80c148f96c551c80;p=elogind.git diff --git a/src/core/execute.c b/src/core/execute.c index 43b571e04..3ae28ee08 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -67,6 +67,7 @@ #include "env-util.h" #include "fileio.h" #include "unit.h" +#include "async.h" #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC) #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC) @@ -316,12 +317,12 @@ static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty case EXEC_INPUT_TTY_FAIL: { int fd, r; - if ((fd = acquire_terminal( - tty_path(context), - i == EXEC_INPUT_TTY_FAIL, - i == EXEC_INPUT_TTY_FORCE, - false, - (usec_t) -1)) < 0) + fd = acquire_terminal(tty_path(context), + i == EXEC_INPUT_TTY_FAIL, + i == EXEC_INPUT_TTY_FORCE, + false, + (usec_t) -1); + if (fd < 0) return fd; if (fd != STDIN_FILENO) { @@ -510,7 +511,7 @@ fail: return r; } -_printf_attr_(1, 2) static int write_confirm_message(const char *format, ...) { +_printf_(1, 2) static int write_confirm_message(const char *format, ...) { int fd; va_list ap; @@ -747,6 +748,7 @@ static int setup_pam( char **e = NULL; bool close_session = false; pid_t pam_pid = 0, parent_pid; + int flags = 0; assert(name); assert(user); @@ -759,24 +761,33 @@ static int setup_pam( * daemon. We do things this way to ensure that the main PID * of the daemon is the one we initially fork()ed. */ - if ((pam_code = pam_start(name, user, &conv, &handle)) != PAM_SUCCESS) { + if (log_get_max_level() < LOG_PRI(LOG_DEBUG)) + flags |= PAM_SILENT; + + pam_code = pam_start(name, user, &conv, &handle); + if (pam_code != PAM_SUCCESS) { handle = NULL; goto fail; } - if (tty) - if ((pam_code = pam_set_item(handle, PAM_TTY, tty)) != PAM_SUCCESS) + if (tty) { + pam_code = pam_set_item(handle, PAM_TTY, tty); + if (pam_code != PAM_SUCCESS) goto fail; + } - if ((pam_code = pam_acct_mgmt(handle, PAM_SILENT)) != PAM_SUCCESS) + pam_code = pam_acct_mgmt(handle, flags); + if (pam_code != PAM_SUCCESS) goto fail; - if ((pam_code = pam_open_session(handle, PAM_SILENT)) != PAM_SUCCESS) + pam_code = pam_open_session(handle, flags); + if (pam_code != PAM_SUCCESS) goto fail; close_session = true; - if ((!(e = pam_getenvlist(handle)))) { + e = pam_getenvlist(handle); + if (!e) { pam_code = PAM_BUF_ERR; goto fail; } @@ -790,7 +801,8 @@ static int setup_pam( parent_pid = getpid(); - if ((pam_pid = fork()) < 0) + pam_pid = fork(); + if (pam_pid < 0) goto fail; if (pam_pid == 0) { @@ -841,14 +853,16 @@ static int setup_pam( } /* If our parent died we'll end the session */ - if (getppid() != parent_pid) - if ((pam_code = pam_close_session(handle, PAM_DATA_SILENT)) != PAM_SUCCESS) + if (getppid() != parent_pid) { + pam_code = pam_close_session(handle, flags); + if (pam_code != PAM_SUCCESS) goto child_finish; + } r = 0; child_finish: - pam_end(handle, pam_code | PAM_DATA_SILENT); + pam_end(handle, pam_code | flags); _exit(r); } @@ -870,16 +884,19 @@ static int setup_pam( return 0; fail: - if (pam_code != PAM_SUCCESS) + if (pam_code != PAM_SUCCESS) { + log_error("PAM failed: %s", pam_strerror(handle, pam_code)); err = -EPERM; /* PAM errors do not map to errno */ - else + } else { + log_error("PAM failed: %m"); err = -errno; + } if (handle) { if (close_session) - pam_code = pam_close_session(handle, PAM_DATA_SILENT); + pam_code = pam_close_session(handle, flags); - pam_end(handle, pam_code | PAM_DATA_SILENT); + pam_end(handle, pam_code | flags); } strv_free(e); @@ -1016,7 +1033,7 @@ int exec_spawn(ExecCommand *command, bool apply_chroot, bool apply_tty_stdin, bool confirm_spawn, - CGroupControllerMask cgroup_mask, + CGroupControllerMask cgroup_supported, const char *cgroup_path, const char *unit_id, int idle_pipe[4], @@ -1072,7 +1089,7 @@ int exec_spawn(ExecCommand *command, free(line); if (context->private_tmp && !context->tmp_dir && !context->var_tmp_dir) { - r = setup_tmpdirs(&context->tmp_dir, &context->var_tmp_dir); + r = setup_tmpdirs(unit_id, &context->tmp_dir, &context->var_tmp_dir); if (r < 0) return r; } @@ -1084,7 +1101,7 @@ int exec_spawn(ExecCommand *command, if (pid == 0) { int i, err; sigset_t ss; - const char *username = NULL, *home = NULL; + const char *username = NULL, *home = NULL, *shell = NULL; uid_t uid = (uid_t) -1; gid_t gid = (gid_t) -1; _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, @@ -1197,7 +1214,7 @@ int exec_spawn(ExecCommand *command, } if (cgroup_path) { - err = cg_attach_with_mask(cgroup_mask, cgroup_path, 0); + err = cg_attach_everywhere(cgroup_supported, cgroup_path, 0); if (err < 0) { r = EXIT_CGROUP; goto fail_child; @@ -1267,7 +1284,7 @@ int exec_spawn(ExecCommand *command, if (context->user) { username = context->user; - err = get_user_creds(&username, &uid, &gid, &home, NULL); + err = get_user_creds(&username, &uid, &gid, &home, &shell); if (err < 0) { r = EXIT_USER; goto fail_child; @@ -1452,46 +1469,28 @@ int exec_spawn(ExecCommand *command, } } - our_env = new0(char*, 7); - if (!our_env) { + our_env = new(char*, 8); + if (!our_env || + (n_fds > 0 && ( + asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 || + asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0)) || + (home && asprintf(our_env + n_env++, "HOME=%s", home) < 0) || + (username && ( + asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 || + asprintf(our_env + n_env++, "USER=%s", username) < 0)) || + (shell && asprintf(our_env + n_env++, "SHELL=%s", shell) < 0) || + ((is_terminal_input(context->std_input) || + context->std_output == EXEC_OUTPUT_TTY || + context->std_error == EXEC_OUTPUT_TTY) && ( + !(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))))) { + err = -ENOMEM; r = EXIT_MEMORY; goto fail_child; } - if (n_fds > 0) - if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 || - asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) { - err = -ENOMEM; - r = EXIT_MEMORY; - goto fail_child; - } - - if (home) - if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) { - err = -ENOMEM; - r = EXIT_MEMORY; - goto fail_child; - } - - if (username) - if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 || - asprintf(our_env + n_env++, "USER=%s", username) < 0) { - err = -ENOMEM; - r = EXIT_MEMORY; - goto fail_child; - } - - if (is_terminal_input(context->std_input) || - context->std_output == EXEC_OUTPUT_TTY || - context->std_error == EXEC_OUTPUT_TTY) - if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) { - err = -ENOMEM; - r = EXIT_MEMORY; - goto fail_child; - } - - assert(n_env <= 7); + our_env[n_env++] = NULL; + assert(n_env <= 8); final_env = strv_env_merge(5, environment, @@ -1581,6 +1580,28 @@ void exec_context_init(ExecContext *c) { c->timer_slack_nsec = (nsec_t) -1; } +static void *remove_tmpdir_thread(void *p) { + int r; + _cleanup_free_ char *dirp = p; + char *dir; + + assert(dirp); + + r = rm_rf_dangerous(dirp, false, true, false); + dir = dirname(dirp); + if (r < 0) + log_warning("Failed to remove content of temporary directory %s: %s", + dir, strerror(-r)); + else { + r = rmdir(dir); + if (r < 0) + log_warning("Failed to remove temporary directory %s: %s", + dir, strerror(-r)); + } + + return NULL; +} + void exec_context_tmp_dirs_done(ExecContext *c) { char* dirs[] = {c->tmp_dir ? c->tmp_dir : c->var_tmp_dir, c->tmp_dir ? c->var_tmp_dir : NULL, @@ -1588,22 +1609,8 @@ void exec_context_tmp_dirs_done(ExecContext *c) { char **dirp; for(dirp = dirs; *dirp; dirp++) { - char *dir; - int r; - - r = rm_rf_dangerous(*dirp, false, true, false); - dir = dirname(*dirp); - if (r < 0) - log_warning("Failed to remove content of temporary directory %s: %s", - dir, strerror(-r)); - else { - r = rmdir(dir); - if (r < 0) - log_warning("Failed to remove temporary directory %s: %s", - dir, strerror(-r)); - } - - free(*dirp); + log_debug("Spawning thread to nuke %s", *dirp); + asynchronous_job(remove_tmpdir_thread, *dirp); } c->tmp_dir = c->var_tmp_dir = NULL; @@ -1699,7 +1706,7 @@ void exec_command_free_list(ExecCommand *c) { ExecCommand *i; while ((i = c)) { - LIST_REMOVE(ExecCommand, command, c, i); + LIST_REMOVE(command, c, i); exec_command_done(i); free(i); } @@ -2187,8 +2194,8 @@ void exec_command_append_list(ExecCommand **l, ExecCommand *e) { if (*l) { /* It's kind of important, that we keep the order here */ - LIST_FIND_TAIL(ExecCommand, command, *l, end); - LIST_INSERT_AFTER(ExecCommand, command, *l, end, e); + LIST_FIND_TAIL(command, *l, end); + LIST_INSERT_AFTER(command, *l, end, e); } else *l = e; } @@ -2207,7 +2214,8 @@ int exec_command_set(ExecCommand *c, const char *path, ...) { if (!l) return -ENOMEM; - if (!(p = strdup(path))) { + p = strdup(path); + if (!p) { strv_free(l); return -ENOMEM; }