Ondřej Vašík 917089
diff -urNp coreutils-8.6-orig/src/su.c coreutils-8.6/src/su.c
Ondřej Vašík 917089
--- coreutils-8.6-orig/src/su.c	2010-11-03 13:56:11.679069689 +0100
Ondřej Vašík 917089
+++ coreutils-8.6/src/su.c	2010-11-03 13:56:45.304325661 +0100
Ondřej Vašík 917089
@@ -153,6 +153,9 @@ static bool simulate_login;
Tim Waugh 9f2386
 /* If true, change some environment vars to indicate the user su'd to.  */
Tim Waugh 9f2386
 static bool change_environment;
Tim Waugh 9f2386
 
Tim Waugh 9f2386
+/* If true, then don't call setsid() with a command. */
Tim Waugh 9f2386
+int same_session = 0;
Tim Waugh 9f2386
+
Ondřej Vašík 917089
 #ifdef USE_PAM
Ondřej Vašík 917089
 static bool _pam_session_opened;
Ondřej Vašík 917089
 static bool _pam_cred_established;
Ondřej Vašík 917089
@@ -161,6 +164,7 @@ static bool _pam_cred_established;
Tim Waugh 9f2386
 static struct option const longopts[] =
Tim Waugh 9f2386
 {
Tim Waugh 9f2386
   {"command", required_argument, NULL, 'c'},
Tim Waugh 9f2386
+  {"session-command", required_argument, NULL, 'C'},
Tim Waugh 9f2386
   {"fast", no_argument, NULL, 'f'},
Tim Waugh 9f2386
   {"login", no_argument, NULL, 'l'},
Tim Waugh 9f2386
   {"preserve-environment", no_argument, NULL, 'p'},
Ondřej Vašík 917089
@@ -335,14 +339,27 @@ create_watching_parent (void)
Ondřej Vašík 917089
       sigemptyset (&action.sa_mask);
Ondřej Vašík 917089
       action.sa_flags = 0;
Ondřej Vašík 917089
       sigemptyset (&ourset);
Ondřej Vašík 917089
-      if (sigaddset (&ourset, SIGTERM)
Ondřej Vašík 917089
-	  || sigaddset (&ourset, SIGALRM)
Ondřej Vašík 917089
-	  || sigaction (SIGTERM, &action, NULL)
Ondřej Vašík 917089
-	  || sigprocmask (SIG_UNBLOCK, &ourset, NULL))
Ondřej Vašík 917089
-	{
Tim Waugh 9f2386
+    if (!same_session)
Tim Waugh eb20fc
+      {
Ondrej Vasik 250517
+        if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT))
Ondrej Vasik 250517
+          {
Ondřej Vašík 917089
+            error (0, errno, _("cannot set signal handler"));
Ondřej Vašík 917089
+            caught_signal = true;
Ondrej Vasik 250517
+          }
Tim Waugh eb20fc
+      }
Ondřej Vašík 917089
+    if (!caught_signal && (sigaddset(&ourset, SIGTERM)
Ondrej Vasik 250517
+                    || sigaddset(&ourset, SIGALRM)
Ondrej Vasik 250517
+                    || sigaction(SIGTERM, &action, NULL)
Ondrej Vasik 250517
+                    || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) {
Ondřej Vašík 917089
 	  error (0, errno, _("cannot set signal handler"));
Ondřej Vašík 917089
 	  caught_signal = true;
Ondřej Vašík 917089
 	}
Ondřej Vašík 917089
+    if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL)
Ondrej Vasik 250517
+                                     || sigaction(SIGQUIT, &action, NULL)))
Tim Waugh eb20fc
+      {
Ondřej Vašík 917089
+        error (0, errno, _("cannot set signal handler"));
Ondřej Vašík 917089
+        caught_signal = true;
Tim Waugh eb20fc
+      }
Ondřej Vašík 917089
     }
Ondřej Vašík 917089
   if (!caught_signal)
Ondřej Vašík 917089
     {
Ondřej Vašík 917089
@@ -627,6 +644,8 @@ Change the effective user id and group i
Tim Waugh 9f2386
 \n\
Tim Waugh 9f2386
   -, -l, --login               make the shell a login shell\n\
Tim Waugh d66c4d
   -c, --command=COMMAND        pass a single COMMAND to the shell with -c\n\
Tim Waugh 9f2386
+  --session-command=COMMAND    pass a single COMMAND to the shell with -c\n\
Tim Waugh 9f2386
+                               and do not create a new session\n\
Tim Waugh 9f2386
   -f, --fast                   pass -f to the shell (for csh or tcsh)\n\
Tim Waugh 9f2386
   -m, --preserve-environment   do not reset environment variables\n\
Tim Waugh 9f2386
   -p                           same as -m\n\
Ondřej Vašík 917089
@@ -649,6 +668,7 @@ main (int argc, char **argv)
Tim Waugh 9f2386
   int optc;
Tim Waugh 9f2386
   const char *new_user = DEFAULT_USER;
Tim Waugh 9f2386
   char *command = NULL;
Tim Waugh 9f2386
+  int request_same_session = 0;
Tim Waugh 9f2386
   char *shell = NULL;
Tim Waugh 9f2386
   struct passwd *pw;
Tim Waugh 9f2386
   struct passwd pw_copy;
Ondřej Vašík 917089
@@ -674,6 +694,11 @@ main (int argc, char **argv)
Ondrej Vasik 250517
           command = optarg;
Ondrej Vasik 250517
           break;
Tim Waugh 9f2386
 
Ondrej Vasik 250517
+        case 'C':
Ondrej Vasik 250517
+          command = optarg;
Ondrej Vasik 250517
+          request_same_session = 1;
Ondrej Vasik 250517
+          break;
Tim Waugh 9f2386
+
Ondrej Vasik 250517
         case 'f':
Ondrej Vasik 250517
           fast_startup = true;
Ondrej Vasik 250517
           break;
Ondřej Vašík 917089
@@ -743,6 +768,9 @@ main (int argc, char **argv)
Tim Waugh 9f2386
     }
Tim Waugh 9f2386
 #endif
Tim Waugh 9f2386
 
Tim Waugh 9f2386
+  if (request_same_session || !command || !pw->pw_uid)
Tim Waugh 9f2386
+    same_session = 1;
Tim Waugh 9f2386
+
Tim Waugh 9f2386
   if (!shell && !change_environment)
Tim Waugh 9f2386
     shell = getenv ("SHELL");
Tim Waugh 9f2386
   if (shell && getuid () != 0 && restricted_shell (pw->pw_shell))
Ondřej Vašík 917089
@@ -764,6 +792,8 @@ main (int argc, char **argv)
Ondřej Vašík 917089
 #endif
Ondřej Vašík 917089
 
Ondřej Vašík 917089
   change_identity (pw);
Ondřej Vašík 917089
+  if (!same_session)
Ondřej Vašík 917089
+    setsid ();
Ondřej Vašík 917089
 
Ondřej Vašík 917089
   /* Set environment after pam_open_session, which may put KRB5CCNAME
Ondřej Vašík 917089
      into the pam_env, etc.  */