]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
su-common: revert "su: pass arguments after <user> to shell"
authorChristian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Tue, 7 Apr 2026 14:25:17 +0000 (10:25 -0400)
committerChristian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Mon, 27 Apr 2026 13:29:44 +0000 (09:29 -0400)
This reverts commit ac0147fd14b348097c82c1c89a5417b582e26bad.

Commit ac0147f added '+' to the getopt(3) option string which
allowed the passing of all arguments after a non-option arg
to be passed to the invoked shell, in this case after <user>.
However, this introduced a regression in runuser(1) and su(1)
where options for both utilities are scattered before and after
the username. E.g.: "su <user> -c 'echo foo' -s /bin/bash" will
pass both -c and -s argument sets to the invoked shell instead
of simply passing -c 'echo foo'.

Note that this behavior is more common in BSD/macOS-style
implementations of su(1), in a future commit this behavior will
be added more sensibly and carefully.

Addresses: ac0147f
Signed-off-by: Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
login-utils/su-common.c

index 6f361e65a478da4f41715719d8a80491bd03661f..c4b30f39aa83f0b08e1195c2b844718f3c468193 100644 (file)
@@ -1045,7 +1045,7 @@ int su_main(int argc, char **argv, int mode)
        su->conv.appdata_ptr = (void *) su;
 
        while ((optc =
-               getopt_long(argc, argv, "+c:fg:G:lmpPTs:u:hVw:", longopts,
+               getopt_long(argc, argv, "c:fg:G:lmpPTs:u:hVw:", longopts,
                            NULL)) != -1) {
 
                err_exclusive_options(optc, longopts, excl, excl_st);
@@ -1153,7 +1153,7 @@ int su_main(int argc, char **argv, int mode)
                }
                FALLTHROUGH;
        case SU_MODE:
-               if (optind < argc && *argv[optind] != '-')
+               if (optind < argc)
                        su->new_user = argv[optind++];
                break;
        }