chiark / gitweb /
manager: only serialize the timestamps for the initramfs if in_initrd()
[elogind.git] / src / core / execute.c
index 99a7881f1cbbc81c03d2af9fe36ca5dfe87e7ec1..4d4091940f9e13018940d2beaf1bcb59116563f6 100644 (file)
@@ -59,6 +59,7 @@
 #include "utmp-wtmp.h"
 #include "def.h"
 #include "loopback-setup.h"
+#include "path-util.h"
 
 /* This assumes there is a 'tty' group */
 #define TTY_MODE 0620
@@ -702,6 +703,7 @@ static int null_conv(
 static int setup_pam(
                 const char *name,
                 const char *user,
+                uid_t uid,
                 const char *tty,
                 char ***pam_env,
                 int fds[], unsigned n_fds) {
@@ -780,10 +782,17 @@ static int setup_pam(
                 open here that have been opened by PAM. */
                 close_many(fds, n_fds);
 
-                /* Wait until our parent died. This will most likely
-                 * not work since the kernel does not allow
-                 * unprivileged parents kill their privileged children
-                 * this way. We rely on the control groups kill logic
+                /* Drop privileges - we don't need any to pam_close_session
+                 * and this will make PR_SET_PDEATHSIG work in most cases.
+                 * If this fails, ignore the error - but expect sd-pam threads
+                 * to fail to exit normally */
+                if (setresuid(uid, uid, uid) < 0)
+                        log_error("Error: Failed to setresuid() in sd-pam: %s", strerror(-r));
+
+                /* Wait until our parent died. This will only work if
+                 * the above setresuid() succeeds, otherwise the kernel
+                 * will not allow unprivileged parents kill their privileged
+                 * children this way. We rely on the control groups kill logic
                  * to do the rest for us. */
                 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
                         goto child_finish;
@@ -929,7 +938,7 @@ static void rename_process_from_path(const char *path) {
         /* This resulting string must fit in 10 chars (i.e. the length
          * of "/sbin/init") to look pretty in /bin/ps */
 
-        p = file_name_from_path(path);
+        p = path_get_file_name(path);
         if (isempty(p)) {
                 rename_process("(...)");
                 return;
@@ -1152,14 +1161,14 @@ int exec_spawn(ExecCommand *command,
                 }
 
                 if (!keep_stdout) {
-                        err = setup_output(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin);
+                        err = setup_output(context, socket_fd, path_get_file_name(command->path), apply_tty_stdin);
                         if (err < 0) {
                                 r = EXIT_STDOUT;
                                 goto fail_child;
                         }
                 }
 
-                err = setup_error(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin);
+                err = setup_error(context, socket_fd, path_get_file_name(command->path), apply_tty_stdin);
                 if (err < 0) {
                         r = EXIT_STDERR;
                         goto fail_child;
@@ -1293,7 +1302,7 @@ int exec_spawn(ExecCommand *command,
 
 #ifdef HAVE_PAM
                 if (context->pam_name && username) {
-                        err = setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds);
+                        err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
                         if (err < 0) {
                                 r = EXIT_PAM;
                                 goto fail_child;