FS#31831 - [util-linux] /etc/profile is not read when running bash from su interactive login

Attached to Project: Arch Linux
Opened by Anton (zhuravlik) - Sunday, 07 October 2012, 15:32 GMT
Last edited by Allan McRae (Allan) - Friday, 16 November 2012, 13:18 GMT
Task Type Bug Report
Category Packages: Core
Status Closed
Assigned To Allan McRae (Allan)
Dave Reisner (falconindy)
Architecture All
Severity Medium
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

Description:
With one of updates my rc-script for teamcity (https://aur.archlinux.org/packages.php?ID=61147) stopped working.
It still does not work.

I decided to investigate why, and found the reason behind it.
Bash does not execute /etc/profile if started from su with interactive login.
But if I try the same with Zsh, /etc/profile is executed.

root@zhuravlik /home/anton # su - -c env --shell /bin/sh tmpuser
SHELL=/bin/sh
TERM=xterm
USER=tmpuser
PATH=/bin:/usr/bin
PWD=/usr/share/tmpuser
SHLVL=1
HOME=/usr/share/tmpuser
LOGNAME=tmpuser
_=/usr/bin/env

root@zhuravlik /home/anton # su - -c env --shell /bin/zsh tmpuser
TERM=xterm
HOME=/usr/share/tmpuser
SHELL=/bin/zsh
USER=tmpuser
LOGNAME=tmpuser
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/fantom/bin:/opt/java/bin:/opt/java/db/bin:/opt/java/jre/bin:/opt/opennebula/bin:/usr/bin/core_perl
SHLVL=0
PWD=/usr/share/tmpuser
OLDPWD=/usr/share/tmpuser
ANT_HOME=/usr/share/apache-ant
FAN_HOME=/opt/fantom
G_BROKEN_FILENAMES=1
J2SDKDIR=/opt/java
JAVA_HOME=/opt/java
DERBY_HOME=/opt/java/db
J2REDIR=/opt/java/jre
LANG=C
MAVEN_OPTS=-Xmx512m
HG=/usr/bin/hg
MOZ_PLUGIN_PATH=/usr/lib/mozilla/plugins
ONE_LOCATION=/opt/opennebula
XDG_DATA_HOME=/usr/share/tmpuser/.local/share
XDG_CONFIG_HOME=/usr/share/tmpuser/.config
XDG_CACHE_HOME=/usr/share/tmpuser/.cache
XDG_DATA_DIRS=/usr/local/share/:/usr/share/
XDG_CONFIG_DIRS=/etc/xdg
_=/usr/bin/env

Seems that it is not the issue of Bash, but the issue of it's configuration in Arch Linux.
I asked some users of other distributions, and they answer that with 4.2.36(1) and 4.2.37(1) /etc/profile is read by bash.
Also, another Arch user also commented that this problem exists for him.
(http://www.linux.org.ru/forum/general/8312534, warning: Russian language)

Additional info:
* local/bash 4.2.037-1 (base), untouched package from core repo

Steps to reproduce:
1) Run
su - -c env --shell /bin/sh tmpuser
or
su - -c env --shell /bin/bash tmpuser
and see that /etc/profile is not read.
2) Run
su - -c env --shell /bin/zsh tmpuser
and see that /etc/profile is read.
tmpuser should exist, and should not be logged in currently (for currently logged in users all works fine).
This task depends upon

Closed by  Allan McRae (Allan)
Friday, 16 November 2012, 13:18 GMT
Reason for closing:  Upstream
Additional comments about closing:  Appears very old bash behavior. Report there is considered an issue.
Comment by Allan McRae (Allan) - Sunday, 07 October 2012, 20:37 GMT
Looks like documented behavior to me...

man bash:

INVOCATION
A login shell is one whose first character of argument zero is a -, or
one started with the --login option.

...

--noprofile
Do not read either the system-wide startup file /etc/profile or
any of the personal initialization files ~/.bash_profile,
~/.bash_login, or ~/.profile. By default, bash reads these
files when it is invoked as a login shell (see INVOCATION
below).
Comment by Dave Reisner (falconindy) - Sunday, 07 October 2012, 20:48 GMT
> root@zhuravlik /home/anton # su - -c env --shell /bin/sh tmpuser

This does not start bash. It starts bash in POSIX compatibility mode. They are NOT the same.
Comment by Anton (zhuravlik) - Monday, 08 October 2012, 19:24 GMT
@Allan:

Thanks. But according to the documentation for "su" utility:
man su
-, -l, --login
Starts the shell as login shell with an environment similar to a real login:

o clears all environment variables except for TERM

o initializes the environment variables HOME, SHELL, USER, LOGNAME, PATH

o changes to the target user's home directory

o sets argv[0] of the shell to '-' in order to make the shell a login shell

I invoke it as "su -", so the expected behaviour for bash is to start as login shell.
But something prevents bash from it.


@Dave:
I know it. But the problem is here if I call bash as /bin/bash, too. And if I do not specify --shell argument at all, too (because /bin/bash is default shell for tmpuser).
And there is no such problem for all the other shells.

root@zhuravlik /home/anton # su - tmpuser -c env --shell /bin/mksh
_=/usr/bin/env
USER=tmpuser
LANG=C
LOGNAME=tmpuser
XDG_DATA_DIRS=/usr/local/share/:/usr/share/
HG=/usr/bin/hg
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/fantom/bin:/opt/java/bin:/opt/java/db/bin:/opt/java/jre/bin:/opt/opennebula/bin:/usr/bin/core_perl
RANDOM=28649
MAVEN_OPTS=-Xmx512m
G_BROKEN_FILENAMES=1
ANT_HOME=/usr/share/apache-ant
FAN_HOME=/opt/fantom
XDG_CONFIG_DIRS=/etc/xdg
DERBY_HOME=/opt/java/db
JAVA_HOME=/opt/java
XDG_DATA_HOME=/usr/share/tmpuser/.local/share
TERM=xterm
J2REDIR=/opt/java/jre
J2SDKDIR=/opt/java
SHELL=/bin/mksh
XDG_CONFIG_HOME=/usr/share/tmpuser/.config
ONE_LOCATION=/opt/opennebula
XDG_CACHE_HOME=/usr/share/tmpuser/.cache
HOME=/usr/share/tmpuser
MOZ_PLUGIN_PATH=/usr/lib/mozilla/plugins

root@zhuravlik /home/anton # su - tmpuser -c env --shell /bin/csh
tee: /usr/share/tmpuser/.hushmotd: Permission denied
((( MOTD shown only once, unless it is changed )))
TERM=xterm
HOME=/usr/share/tmpuser
SHELL=/bin/tcsh
USER=tmpuser
LOGNAME=tmpuser
PATH=/bin:/usr/bin:/usr/local/bin:/opt/bin:/opt/java/bin:/opt/java/db/bin:/opt/java/jre/bin:/usr/bin/core_perl
HOSTTYPE=x86_64-linux
VENDOR=unknown
OSTYPE=linux
MACHTYPE=x86_64
SHLVL=1
PWD=/usr/share/tmpuser
GROUP=tmpuser
HOST=zhuravlik
ANT_HOME=/usr/share/apache-ant
G_BROKEN_FILENAMES=1
J2SDKDIR=/opt/java
JAVA_HOME=/opt/java/
DERBY_HOME=/opt/java/db
J2REDIR=/opt/java/jre
MOZ_PLUGIN_PATH=/usr/lib/mozilla/plugins
XDG_DATA_HOME=/usr/share/tmpuser/.local/share
XDG_CONFIG_HOME=/usr/share/tmpuser/.config
XDG_CACHE_HOME=/usr/share/tmpuser/.cache
XDG_DATA_DIRS=/usr/local/share/:/usr/share/
XDG_CONFIG_DIRS=/etc/xdg


Comment by Anton (zhuravlik) - Monday, 08 October 2012, 19:26 GMT
p.s.: This worked with bash, too, but was broken after one of updates. Unfortunately, I cannot remind after which update.
Comment by Dave Reisner (falconindy) - Monday, 08 October 2012, 19:30 GMT
You get a resounding "works for me".
Comment by Anton (zhuravlik) - Monday, 08 October 2012, 19:43 GMT
@Dave:

You mean that for you bash sources /etc/profile if started via
su - tmpuser -c env --shell /bin/bash
for user that is currently not logged in?

(If you tried with your personal user or root, which is currently logged in, it is not the same case, and in such case it works.)

I'll try to investigate the problem myself, of course. I'll downgrade bash several times until it works again, and then will comment here what caused this.
Just wanted to hear something helpful from developers.
Comment by Dave Reisner (falconindy) - Monday, 08 October 2012, 20:17 GMT
Sure.

# useradd -s /bin/bash -g users foo
# su - foo
su: warning: cannot change directory to /home/foo: No such file or directory
[foo@beatbox root]$ env
XDG_DATA_HOME=/home/foo/.local/share
SHELL=/bin/bash
TERM=linux
LC_NUMERIC=C
USER=foo
XDG_CONFIG_DIRS=/etc/xdg
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/bin/core_perl
LC_COLLATE=C
PWD=/root
LANG=en_US.UTF-8
SHLVL=1
HOME=/home/foo
XDG_CONFIG_HOME=/home/foo/.config
XDG_CACHE_HOME=/home/foo/.cache
LOGNAME=foo
XDG_DATA_DIRS=/usr/local/share/:/usr/share/
G_BROKEN_FILENAMES=1
_=/usr/bin/env
Comment by Anton (zhuravlik) - Monday, 08 October 2012, 20:40 GMT
@Dave:

You provided one more test case, but it is not the same as I described and it works even for me.
"su - foo, then env as foo" is not the same as "su - foo -c env". Though it should work in the same way, it does not.

Try "su - foo -c env", and you'll see.
Comment by Dave Reisner (falconindy) - Monday, 08 October 2012, 21:01 GMT
Seems like a bash bug that goes back at least to bash3. It doesn't appear to honor argv[0][0] == '-' when executing a command. The only thing that changed here is su, which we now take from util-linux. It's supposed to be the same code as what was in coreutils, but isn't quite the same due to licensing issues (coreutils su was GPLv3'd at some point). However, this part of the code in particular is identical.

I could propose a patch to su which would use the -l flag in addition to setting argv[0][0], but I'm not sure if that's portable across all shells. The POSIX standard mentions nothing of login shells, but dash does implement it.
Comment by Allan McRae (Allan) - Monday, 15 October 2012, 09:02 GMT
Assigning to Dave too because I have decided he will fix this...
Comment by Allan McRae (Allan) - Thursday, 25 October 2012, 03:39 GMT
Well... we are going to need much more information about when this occurred. I just tested with the repos from 2012/07/20 which is before su moved to util linux and it does not work then either.
Comment by Allan McRae (Allan) - Thursday, 25 October 2012, 04:10 GMT
Running "su - foo -c env" also does not source /etc/profile in an install from 2012/01/01.

Loading...