]> granicus.if.org Git - shadow/commitdiff
su.c: be more predictable
authorHarm te Hennepe <harm@tehennepe.org>
Mon, 26 Mar 2018 22:45:03 +0000 (00:45 +0200)
committerHarm te Hennepe <harm@tehennepe.org>
Mon, 26 Mar 2018 22:57:21 +0000 (00:57 +0200)
Always parse first non-option as username.

man/su.1.xml
src/su.c

index 24143c3878edfff12574b5c494465b6e0bf46903..4b413fc8a5a362b3614361a69f57d3f5e342a847 100644 (file)
     <cmdsynopsis>
       <command>su</command>
       <arg choice='opt'>
-       <replaceable>options</replaceable>
+          <replaceable>options</replaceable>
       </arg>
       <arg choice='opt'>
-       <arg choice='plain'>
-         <replaceable>username</replaceable>
-       </arg>
+          <replaceable>-</replaceable>
+      </arg>
+      <arg choice='opt'>
+          <replaceable>username</replaceable>
+          <arg choice='opt'>
+              <replaceable>args</replaceable>
+          </arg>
       </arg>
     </cmdsynopsis>
   </refsynopsisdiv>
   <refsect1 id='description'>
     <title>DESCRIPTION</title>
     <para>
-      The <command>su</command> command is used to become another user during
-      a login session. Invoked without a <option>username</option>, 
-      <command>su</command> defaults to
-      becoming the superuser. The optional argument <option>-</option> may
-      be used to provide an environment similar to what the user would
-      expect had the user logged in directly.
-    </para>
-
-    <para>
-      Additional arguments may be provided after the username, in which case
-      they are supplied to the user's login shell. In particular, an
-      argument of <option>-c</option> will cause the next argument to be
-      treated as a command by most command interpreters. The command will be
-      executed by the shell specified in <filename>/etc/passwd</filename>
-      for the target user.
+      The <command>su</command> command is used to become another user during a
+      login session. Invoked without a <option>username</option>,
+      <command>su</command> defaults to becoming the superuser. The
+      <option>-</option> option may be used to provide an environment similar
+      to what the user would expect had the user logged in directly. The
+      <option>-c</option> option may be used to treat the next argument as a
+      command by most shells.
     </para>
 
     <para>
-      You can use the <option>--</option> argument to separate
-      <command>su</command> options from the arguments supplied to the shell.
+      Options are recognized everywhere in the argument list. You can use the
+      <option>--</option> argument to stop option parsing. The
+      <option>-</option> option is special: it is also recognized after
+      <option>--</option>, but has to be placed before
+      <option>username</option>.
     </para>
 
     <para>The user will be prompted for a password, if appropriate. Invalid
index 974048e9fccc0e2e898fa338b61197db9076a667..8a5371f7cd7d246b1a44fd321e5742cd116a1344 100644 (file)
--- a/src/su.c
+++ b/src/su.c
@@ -436,7 +436,7 @@ static void prepare_pam_close_session (void)
 static void usage (int status)
 {
        (void)
-       fputs (_("Usage: su [options] [LOGIN]\n"
+       fputs (_("Usage: su [options] [-] [username [args]]\n"
                 "\n"
                 "Options:\n"
                 "  -c, --command COMMAND         pass COMMAND to the invoked shell\n"
@@ -446,7 +446,8 @@ static void usage (int status)
                 "  --preserve-environment        do not reset environment variables, and\n"
                 "                                keep the same shell\n"
                 "  -s, --shell SHELL             use SHELL instead of the default in passwd\n"
-                "\n"), (E_SUCCESS != status) ? stderr : stdout);
+                "\n"
+                "If no username is given, assume root.\n"), (E_SUCCESS != status) ? stderr : stdout);
        exit (status);
 }
 
@@ -815,13 +816,7 @@ static void process_flags (int argc, char **argv)
                }
        }
 
-       /*
-        * The next argument must be either a user ID, or some flag to a
-        * subshell. Pretty sticky since you can't have an argument which
-        * doesn't start with a "-" unless you specify the new user name.
-        * Any remaining arguments will be passed to the user's login shell.
-        */
-       if ((optind < argc) && ('-' != argv[optind][0])) {
+       if (optind < argc) {
                STRFCPY (name, argv[optind++]); /* use this login id */
                if ((optind < argc) && (strcmp (argv[optind], "--") == 0)) {
                        optind++;