75

I need to allow user martin to switch to user martin-test without password

su - martin-test

I think this can be configured in /etc/pam.d/su. There are already some lines in that file which can be uncommented. However, I don't like the idea of adding user martin to group wheel. I don't want to give martin any more privileges than to be able to switch to martin-test. I also do not want to use sudo.

What would be the best way to do it, while keeping the privileges of user martin minimal?

9
  • 3
    This is easier to do with sudo eg sudo -u martin-test -i. Is there a reason you are asking specifically about su?
    – jordanm
    Feb 5, 2014 at 22:24
  • I don't want to install sudo just because of this (I don't normally use sudo and I don't particularly like it). And I think using pam is cleaner and more transparent way to do it. Feb 5, 2014 at 22:28
  • 3
    @MartinVegter As you can see from the script answer, doing this through some sort of pam mechanism is very ugly. Really this is exactly what sudo was meant for. Aside from not normally using it, what are the objections?
    – phemmer
    Feb 12, 2014 at 22:32
  • 1
    If a clean solution is possible with pam, I would prefer that over sudo. If sudo is the only possibility, than that is fine as well. My objections to sudo are mostly ideological: I don't like the idea of user doing administration with sudo foo. When I need to do administration, I log in as root. Otherwise I log in as user, These two distinct roles should not be mixed. Also, I already have pam infrastructure installed. I don't want to install another setuid program which can possibly introduce security bugs. Feb 13, 2014 at 10:47
  • 6
    @MartinVegter You don't have to do sudo foo for specific commands. Sudo has sudo -s which will launch a shell. sudo is a very common utility meaning it's security has been thoroughly vetted, far more than some pam trickery will be. I would also argue that getting a root shell for tasks is much more insecure than launching specific commands. When you launch a shell, you run everything as root. If any one of those things (such as a simple ls) has a security vulnerability, then you've just opened a security hole.
    – phemmer
    Feb 13, 2014 at 13:47

5 Answers 5

91
+25

Add the following lines underneath the pam_rootok.so line in your /etc/pam.d/su:

auth  [success=ignore default=1] pam_succeed_if.so user = martin-test
auth  sufficient                 pam_succeed_if.so use_uid user = martin

These lines perform checks using the pam_succeed_if.so module. See also the Linux-PAM configuration file syntax to learn more about the auth lines.

  • The first line checks whether the target user is martin-test. If it is nothing happens (success=ignore) and we can continue on the next line to check the current user. If it is not, the next line will be skipped (default=1) and we can continue on subsequent lines with the usual authentication steps.
  • The second line checks whether the current user is martin or not, if it is then the system considers the authentication process as successful and returns (sufficient), if it is not, nothing happens and we continue on subsequent lines with the usual authentication steps.

You can also restrict su to a group, here the group allowedpeople can su without a password:

auth sufficient pam_succeed_if.so use_uid user ingroup allowedpeople
9
  • 1
    If you want to authorize if they are in a certain group: auth sufficient pam_succeed_if.so user ingroup GROUP Aug 25, 2015 at 21:08
  • @gnp Super Thanks!! Working on iCinga with nrpe, have to execute some command as different user!! Helped lot!!!!!! Thanks!!!!! May 26, 2016 at 15:57
  • @GnP Please help me on askubuntu.com/questions/821793/… Sep 6, 2016 at 18:19
  • It would be nice to add info on how to apply the changes as well.
    – Kyslik
    Nov 14, 2017 at 13:33
  • @Kyslik what do you mean? The instructions on how to edit the necessary files are in the answer ...
    – GnP
    Nov 14, 2017 at 17:10
14

If you don't want to change groups or use sudo, use a pam module called pam_exec to execute external scripts in a pam stage.

Add a line in your /etc/pam.d/su after the pam_rootok.so line:

auth       sufficient pam_exec.so quiet /path/to/script

/path/to/script has the permissions 755 (rwxr-xr-x) and the following content:

#!/bin/bash
if [ "$PAM_TYPE" == "auth" ] && \
[ "$PAM_USER" == "martin-test" ] && \
[ "$PAM_RUSER" == "martin" ]; then
  exit 0
else
  exit 1
fi

So this script exits with success if su:

  • is called in context of authentication,
  • the calling user is martin and
  • the user to authenticate is martin-test.

See:

martin@host:~$ su - martin-test
martin-test@host:~$ exit
martin@host:~$ su - otheruser
Password: ****
otheruser@host:~$ 
4
  • 1
    pam_access can be used to provide similar functionality, without relying on a script. (this is what pam_access was made to do)
    – jsbillings
    Feb 6, 2014 at 1:37
  • 1
    @jsbillings Would you make that (with some details) another answer? Feb 6, 2014 at 6:06
  • 1
    how would I need to modify my /etc/pam.d/su to make use of pam_access for my situation? Feb 6, 2014 at 9:18
  • 3
    @jsbillings Actually pam_access can't do this. When su is going through the pam stack, it's doing so as the user you're changing to, not the user you're changing from. So if you add a rule such as + : martin : ALL, it will allow anyone changing to martin. Even if you change martin to martin-test, it will still let anyone do it. You need to analyze both the user you're coming from, and the user you're changing to. Really, this is exactly what sudo is for...
    – phemmer
    Feb 12, 2014 at 22:28
9

This might be the possible best way.

su is not meant to do that -- sudo is.

Open /etc/sudoers.d/custom and write the following:

user-a ALL=(user-b:user-b) NOPASSWD:ALL

This means: whenever user-a executes sudo -u user-b, let him go without asking for the password.

Another way

youruserid ALL = (username) NOPASSWD: ALL

with visudo and then sudo -u username bash is like su - username

1
  • What if you don't have root access? I want to change from my user to another non-root user. Feb 26, 2020 at 19:59
1

If you don't have access to the root account, but have the password of the user you want to use to run a command, you can do the following.

  • This will ask you the toto's password : su - toto -c whoami
  • This will not : ssh toto@localhost whoami

Just install your public key in authorized_keys of toto

1
  • Thoughtful answer.. However, the command someone wanna try running is already on the machine. So there is no point ssh'ing to the same server. Aug 12, 2015 at 11:31
-1

My simple solution is:

sudo login -f martin-test

If you want to avoid sudo at all cost, I think it should be possible to put this in a script:

  1. owned by root and with root privileges (using the setuid flag)
  2. executable by everybody, also without any sudo.

However, I can't figure out the chown root and chmod +s ToTest.sh bits, to make this actually work:

#!/usr/bin/env bash
echo howdy, I am $(whoami)
sudo login -f martin-test

I still runs as my normal user, as the echo tells me. And it still requires sudo password. If it was running as root, one could do away with the sudo in the last line...

2
  • The setuid flag on a shell (or any other script) script won't work in Linux and for good reasons. Notice that the above script with a working suid flag would immediately be a trap: It engages bash via "env" (quite self-defeatingly, because if you assume you don't know where bash is, why do you assume you know where env is or whether it even exists?). But in the end, you don't know what bash this will be exactly. It could come from the invoking user's directory and have been compiled a minute earlier from his source code. You see where I'm going? Or the user could override whoami... Jan 26, 2019 at 13:31
  • My brain is currently too far away from these issues to fully grasp, but still thanx for the detailed explanations.
    – Frank N
    Jan 28, 2019 at 11:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .