[Pkg-shadow-devel] Bug#276419: su appends the positional args to the command line

Helmut Waitzmann (Debian Bug Tracking System) "Helmut Waitzmann" (Debian Bug Tracking System) <Helmut.Waitzmann@web.de>, 276419@bugs.debian.org
Mon, 11 Jul 2005 17:44:01 +0200


Nicolas Fran=C3=A7ois <nicolas.francois@centraliens.net> writes:

>a patch was included in the 4.0.3-36 release, but this one breaks some
>scripts (see #317264).

which are broken and need to be fixed.  See below.

>Thus, I'm considering to revert this patch and fix your bug by documenting
>the su behavior in its man page.
>
>Here are some details on the issues introduced by the patch:
>
> * arguments are no more concatenated to provide only one string to the -c
>   option of the shell:
>   if some arguments are provided after the command provided by -c, these
>   arguments are provided to the shell that interprets the command, not to
>   the command itself.
>   For example:
>     $ bash -c 'echo $@' a b c
>   will print "b c"
>   but:
>     $ bash -c echo a b c
>   will only display an empty line

This behavior corresponds to the Debian manual page, the Linux Standard
Base and concurres with the behavior of Fedora Linux' and HPUX's su (and
if I remember correctly, solaris' su, too) and is correct behavior.

Passing additional arguments to su and banking on concatenation to the
command line is broken usage of su:  Neither Debian's nor Fedora's nor
HPUX's su's manual page nor the Linux Standard Base supports this.  The
rule is simple:  If you want su to pass a command line with concatenated
additional args, then simply concatenate them to the command line before
passing it to su.

> * -c is no more provided to the shell when it is not provided to su:
>   This break invocation of su like:
>     $ su $LOGNAME bash
>     /bin/bash: /bin/bash: cannot execute binary file

The same is true here.

Passing a command line to su without a preceding "-c" is broken usage of
su:  Neither Debian's nor Fedora's nor HPUX's su's manual page nor the
Linux Standard Base supports this.  The rule is simple:  If you want su to
provide a "-c" option to the shell, then simply provide it to su.

>As the old behaviors are assumed by some packages (at least pbuilder,
>and probably others),=20

Those packages are broken and should be fixed:

1. If there is a command line to be passed, precede it with "-c".

2. If there are additional arguments to be concatenated to the command
   line, concatenate them to the command line.

Then those packages will work both with old and new su and there will be
no need to

>revert the patch, and just document the fact that -c is always provided
>to the invoked shell (if there are additional arguments), and that the
>arguments are provided in a concatenated form to the -c flag.

>Do you agree with this?

As it breaks the specifications of Linux Standard Base, I don't.  Please,
don't revert to a broken su.  That would make Debian's su different from
any other su in UNIX-like operating systems and restrict it to a very
small subset of invocations it will serve.

On the other hand, the invocation

$ su - someone -c 'for arg; do process "$arg"; done' *

, which meets the specifications, will fail with old su, as it will be
treated like

$ (set x *
   shift
   exec su - someone -c 'for arg; do process "$arg"; done '"$*"
   )

, which will not have the intended behavior as long as at least one
additional argument is supplied.  And there is no remedy, no matter how
many levels of escape are applied.

What do you think about creating a su-old-behavior package, which depends
on su (and will work with both old and new su) and contains a wrapper
executable (shell script, perl script or binary) called e.g. old-su, to
provide the old behavior of su using new (or old) su?

Then all fixing to be done to packages assuming the old behavior of su
would be to substitute all calls to su with calls to old-su and making a
dependency to the su-old-behavior package.

Do you think it is worth while doing that?

>To fix your issues, there will still be the solutions of:

>  * use su -- - "$LOGNAME" bash -x
>    instead of su -- - "$LOGNAME" -x

This is not a solution.  Using new su:

$ su -- - "$LOGNAME" -x

will start a login shell in debug mode, whereas using old su

$ su -- - "$LOGNAME" bash -x

will start a login shell which will start a bash in debug mode.  It will
not help me debugging my login shell, especially when I want to pass
positional arguments to an interactive login shell (to be used in
"$HOME"/.profile).

>PS: I'm BCC'ing you to your address without nospam, sorry if you receive
>this mail twice)

As long as 276419-submitter@bugs.debian.org is included in the list of
recipients or

Helmut Waitzmann (Debian Bug Tracking System) <Helmut.Waitzmann@web.de>

is included in the revealed list of recipients (i.e. BCC will not
work), I'll receive that mail.

Best regards,

Helmut
--=20
Wenn Sie mir E-Mail schreiben, stellen |  When writing me e-mail, please
Sie bitte vor meine E-Mail-Adresse     |  precede my e-mail address with
meinen Vor- und Nachnamen, etwa so:    |  my full name, like
Helmut Waitzmann <xxx@example.net>, (Helmut Waitzmann) xxx@example.net