chiark / gitweb /
strv: introduce new strv_from_stdarg_alloca() macro to generate a string array from...
[elogind.git] / src / core / execute.c
index a53ef48ef83305ce231e4112574ea4c5922a63e0..3ae28ee080af0531863c13da866d393c826f1474 100644 (file)
@@ -317,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) {
@@ -511,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;
 
@@ -748,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);
@@ -760,6 +761,9 @@ 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 (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;
@@ -772,11 +776,11 @@ static int setup_pam(
                         goto fail;
         }
 
-        pam_code = pam_acct_mgmt(handle, PAM_SILENT);
+        pam_code = pam_acct_mgmt(handle, flags);
         if (pam_code != PAM_SUCCESS)
                 goto fail;
 
-        pam_code = pam_open_session(handle, PAM_SILENT);
+        pam_code = pam_open_session(handle, flags);
         if (pam_code != PAM_SUCCESS)
                 goto fail;
 
@@ -850,7 +854,7 @@ static int setup_pam(
 
                 /* If our parent died we'll end the session */
                 if (getppid() != parent_pid) {
-                        pam_code = pam_close_session(handle, PAM_DATA_SILENT);
+                        pam_code = pam_close_session(handle, flags);
                         if (pam_code != PAM_SUCCESS)
                                 goto child_finish;
                 }
@@ -858,7 +862,7 @@ static int setup_pam(
                 r = 0;
 
         child_finish:
-                pam_end(handle, pam_code | PAM_DATA_SILENT);
+                pam_end(handle, pam_code | flags);
                 _exit(r);
         }
 
@@ -880,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);
@@ -1082,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;
         }
@@ -1094,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,
@@ -1277,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;
@@ -1462,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,
@@ -1717,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);
         }
@@ -2205,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;
 }
@@ -2225,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;
         }