saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Get access to the Salt software package repository here:
https://repo.saltproject.io/
Apache License 2.0
14.17k stars 5.48k forks source link

runsas broken on Fedora29 #51055

Open c-wicklein opened 5 years ago

c-wicklein commented 5 years ago

The runas option isn't effective on Fedora 29 with salt-2018.3.2-5.fc29.noarch because getpass.getuser() while running as root is returning the runas username. This affects cmd.run, git.latest, etc. I am running salt from an interactive shell as user me with sudo salt-call ... exclusively, so it might be specific to that use case.

I've fixed it for myself with this patch:

--- utils/user.py.orig  2018-06-27 11:04:57.000000000 -0500
+++ utils/user.py       2019-01-04 07:45:21.322476941 -0600
@@ -222,7 +222,9 @@
     Helper method for for subprocess.Popen to initialise uid/gid and umask
     for the new process.
     '''
-    if runas is not None and runas != getpass.getuser():
+#   if runas is not None and runas != getpass.getuser():
+    uinfo = pwd.getpwnam(runas)
+    if os.getuid() != uinfo.pw_uid:
         chugid(runas)
     if umask is not None:
         os.umask(umask)  # pylint: disable=blacklisted-function
c-wicklein commented 5 years ago

I wonder if this is related to or the same as #46417? FWIW, I didn't have this problem using 2018.3.2 on macOS.

c-wicklein commented 5 years ago

I can work around this problem without any patches by replacing sudo salt-call ... with sudo su --login -c "salt-call ..."

Ch3LL commented 5 years ago

can you clarify the entire command you are running to help replicate this issue?

c-wicklein commented 5 years ago

I'm currently running this script without arguments:

#!/bin/bash

ORIGIN="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
"$ORIGIN"/_salt.sh state.apply

...which in turn runs this script:

#!/bin/bash

sudo su --login -c "salt-call \
  --local \
  --file-root=$HOME/salt/salt \
  --pillar-root=$HOME/salt/pillar \
  --module-dirs=$HOME/salt/modules \
  --log-level=warning \
  --state-output=changes \
  $@"

But, I think the key is whether you run sudo salt-call... (which breaks runas) or sudo su --login -c "salt-call..." (which makes deficiencies in the in environment provided by sudo irrelevant by running salt-call from a root login shell.)

cdalvaro commented 5 years ago

This must be related with #51008

Ch3LL commented 5 years ago

thanks for pointing that out @cdalvaro @c-wicklein does that look like a duplicate of your issue? If so i'll close here and we can monitor in the other issue.

c-wicklein commented 5 years ago

Both issues are related to problems with runas and how Salt manages user substitution, but the issues are not the same. #51008 can be summarized as, "running su -l within Salt does a better job of getting the environment right than su, but it results in a change of directory which Salt doesn't manage". #51055 can be summarized as, "Salt doesn't check which user it's running as properly (because getpass.getuser isn't suitable), thinks its running as the runas user, doesn't change from root to the runas user, and makes a mess." The apparent similarity comes from my work-around of running sudo su -l to start salt to ensure salt isn't running UID 0 with USER still set to my personal user.

The patch offered for #51008 is a darwin-specific fix; my patch above addresses the UID checking problem on all? platforms.

Ch3LL commented 5 years ago

thank for clearing that up for me. mind submitting your change up as a PR and we can get more eyes on the fix. I imagine we will still want to check if runas is not None as well.

sastorsl commented 5 years ago

We're getting same/similar issues.

$ salt-call --out=txt -l error cmd.run "readlink -f /proc/$(pgrep -u postfix pickup)/exe"
local: /usr/libexec/postfix/pickup

$ salt-call --out=txt -l error cmd.run "readlink -f /proc/$(pgrep -u postfix pickup)/exe" runas=postfix
[ERROR   ] Command 'readlink -f /proc/17262/exe' failed with return code: 1
[ERROR   ] retcode: 1
[ERROR   ] Command 'readlink -f /proc/17262/exe' failed with return code: 1
[ERROR   ] output: 

Version:

Salt Version:
           Salt: 2019.2.0

Dependency Versions:
           cffi: Not Installed
       cherrypy: Not Installed
       dateutil: 1.5
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
          ioflo: Not Installed
         Jinja2: 2.7.2
        libgit2: Not Installed
        libnacl: Not Installed
       M2Crypto: 0.31.0
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.5.6
   mysql-python: Not Installed
      pycparser: Not Installed
       pycrypto: 2.6.1
   pycryptodome: Not Installed
         pygit2: Not Installed
         Python: 2.7.5 (default, Mar 26 2019, 22:13:06)
   python-gnupg: Not Installed
         PyYAML: 3.11
          PyZMQ: 15.3.0
           RAET: Not Installed
          smmap: Not Installed
        timelib: Not Installed
        Tornado: 4.2.1
            ZMQ: 4.1.4

System Versions:
           dist: redhat 7.6 Maipo
         locale: UTF-8
        machine: x86_64
        release: 3.10.0-957.12.2.el7.x86_64
         system: Linux
        version: Red Hat Enterprise Linux Server 7.6 Maipo
sastorsl commented 5 years ago

Still present in salt-2019.2.1

# salt-call -V
Salt Version:
           Salt: 2019.2.1

Dependency Versions:
           cffi: Not Installed
       cherrypy: Not Installed
       dateutil: 1.5
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
          ioflo: Not Installed
         Jinja2: 2.7.2
        libgit2: Not Installed
        libnacl: Not Installed
       M2Crypto: 0.31.0
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.5.6
   mysql-python: Not Installed
      pycparser: Not Installed
       pycrypto: 2.6.1
   pycryptodome: Not Installed
         pygit2: Not Installed
         Python: 2.7.5 (default, Jun 11 2019, 14:33:56)
   python-gnupg: Not Installed
         PyYAML: 3.11
          PyZMQ: 15.3.0
           RAET: Not Installed
          smmap: Not Installed
        timelib: Not Installed
        Tornado: 4.2.1
            ZMQ: 4.1.4

System Versions:
           dist: redhat 7.7 Maipo
         locale: UTF-8
        machine: x86_64
        release: 3.10.0-1062.1.1.el7.x86_64
         system: Linux
        version: Red Hat Enterprise Linux Server 7.7 Maipo
sastorsl commented 4 years ago

Any traction on this?

luxi2001 commented 4 years ago

Works if you set the group parameter to the cmd module, ie:

[root@app01 /]# su - eosd1 -c 'ls -l /proc/316/exe'
lrwxrwxrwx 1 eosd1 eosd1 0 Nov  5 13:42 /proc/316/exe -> /eos/jdk1.8.0_102/bin/java

Without group:

[root@app01 /]# salt-call -l info cmd.shell cmd='readlink -f /proc/316/exe' runas='eosd1'
[INFO    ] Executing command 'readlink -f /proc/316/exe' as user 'eosd1' in directory '/eos/d1'
[ERROR   ] Command 'readlink -f /proc/316/exe' failed with return code: 1
[ERROR   ] retcode: 1
[ERROR   ] Command 'readlink -f /proc/316/exe' failed with return code: 1
[ERROR   ] output: 
local:

With group:

[root@app01 /]# salt-call -l info cmd.shell cmd='readlink -f /proc/316/exe' runas='eosd1' group='eosd1'
[INFO    ] Executing command 'readlink -f /proc/316/exe' as user 'eosd1' in group 'eosd1' in directory '/eos/d1'
local:
    /eos/jdk1.8.0_102/bin/java
stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

If this issue is closed prematurely, please leave a comment and we will gladly reopen the issue.

sastorsl commented 4 years ago

.

stale[bot] commented 4 years ago

Thank you for updating this issue. It is no longer marked as stale.

c-wicklein commented 4 years ago

Works if you set the group parameter to the cmd module, ie:

[root@app01 /]# salt-call -l info cmd.shell cmd='readlink -f /proc/316/exe' runas='eosd1' group='eosd1'
[INFO    ] Executing command 'readlink -f /proc/316/exe' as user 'eosd1' in group 'eosd1' in directory '/eos/d1'
local:
    /eos/jdk1.8.0_102/bin/java

@luxi2001 Which version of Salt are you using? I encountered this problem running 2018.3.2 on Fedora 29. I'm now running 2019.2.1 on CentOS 8.

This is the relevant code in master as of today, and it appears to have the same fundamental problem (using getpass.getuser.) I wonder if you're working around a special case.

luxi2001 commented 4 years ago

@c-wicklein We're running 2019.2.0 on CentOS 7.4 and RHEL 7.7. We had to add the group parameter to all our cmdcalls where we use runas. I see You maybe have a different problem, although i suspect the root cause is the same.

mariushoch commented 3 years ago

Still a problem on Fedora 33, probably for the same reason (both ran as root):

LOGNAME=root python3 -c 'import getpass; print(getpass.getuser())'
root
LOGNAME=marius python3 -c 'import getpass; print(getpass.getuser())'
marius

Worked around by using alias salt-call='LOGNAME=root salt-call'.