irods / irods_auth_plugin_pam_interactive

BSD 3-Clause "New" or "Revised" License
2 stars 5 forks source link

Using the `irods` PAM stack does not work with `pam_interactive` #29

Closed alanking closed 3 months ago

alanking commented 3 months ago

What I tried to do

I wanted to make pam_interactive look and behave a lot like pam_password just by using PAM modules. Or at least see whether it is possible with little or no changes to the existing plugin.

I created the irods PAM stack as described in our documentation here: https://docs.irods.org/4.3.2/plugins/pluggable_authentication/#pam-pluggable-authentication-module

$ cat /etc/pam.d/irods
auth        required      pam_env.so
auth        sufficient    pam_unix.so
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so

pam_interactive uses the irods PAM stack, so it should be using it here. After disabling the SSL checks (see #16), I was seeing some promising prompts, but I was getting the following error when I tried to authenticate as the iRODS user alan using the PAM user alan's credentials:

$ iinit
Enter your iRODS user name: alan
Password:  
Level 0: Error occurred while authenticating user [alan] [CAT_INVALID_AUTHENTICATION: authentication flow completed without success

] [ec=-826000]

I then tailed /var/log/auth.log and saw the following messages:

Jul 19 19:01:32 7fc9a462d7bf unix_chkpwd[89224]: check pass; user unknown
Jul 19 19:01:32 7fc9a462d7bf unix_chkpwd[89224]: password check failed for user (alan)
Jul 19 19:01:32 7fc9a462d7bf --bin: pam_unix(irods:auth): authentication failure; logname= uid=999 euid=999 tty= ruser= rhost=  user=alan

Finding some success

After some searching around, I ran across somebody who had a similar problem in their own application and asked about it in a linux-pam/linux-pam GitHub issue. The response from the one of the maintainers shed some light on to what was happening: https://github.com/linux-pam/linux-pam/issues/112#issuecomment-491171684

It seems that the auth checking executable leveraged by the PamHandshake session was not able to authenticate the user alan because it is being run as the iRODS service account user irods. You can see this is the case from the auth.log error message above which says "uid=999", and we have this in /etc/passwd:

$ cat /etc/passwd
<snip>
irods:x:999:999:iRODS Administrator:/var/lib/irods:/bin/bash
alan:x:1000:1000::/home/alan:/bin/bash
bobby:x:1001:1001::/home/bobby:/bin/sh

Following the clues in the linux-pam issue above, I set /etc/shadow to be world readable, and the authentication worked because the irods user was now able to check the entered password against the password database. Obviously, this is not a viable solution because /etc/shadow is not supposed to be readable by everybody. We could put irods in the shadow group, or make some other group-based solution for this, but that would require additional administrative changes, so I took another look around for solutions.

Comparing with pam_password

I wanted to understand how pam_password is able to use the same PAM stack (irods) and see success while pam_interactive got an error. This led me eventually to take a look at the executable installed by this plugin's packages:

$ ls -l /usr/lib/irods/plugins/auth/pam_handshake_auth_check
-rwxr-xr-x 1 root root 102184 Jul 18 19:16 /usr/lib/irods/plugins/auth/pam_handshake_auth_check

I compared the equivalent authentication check program shipped with the pam_password plugin:

$ ls -l /usr/sbin/irodsPamAuthCheck 
-rwsr-xr-x 1 root root 22176 Jul 17 16:02 /usr/sbin/irodsPamAuthCheck

The setuid bit is set for the u field on irodsPamAuthCheck, but not on pam_handshake_auth_check. I tried changing the setuid bit to match and everything started working as expected. Here is the command that I ran to get the permissions to match irodsPamAuthCheck:

chmod u+s /usr/lib/irods/plugins/auth/pam_handshake_auth_check

After that, the authentication succeeded using alan's PAM credentials.

So, I think we should set setuid on the pam_handshake_auth_check executable like we do for irodsPamAuthCheck here: https://github.com/irods/irods/blob/7b8b97a1966bce4f18bd863997ca977a07485e5b/server/auth/CMakeLists.txt#L21-L28

Bonus Question

Notice the prompt that I shared above when attempting to authenticate with the irods PAM stack:

$ iinit
Enter your iRODS user name: alan
Password: 

The pam_password prompt instead says:

$ iinit
Enter your iRODS user name: alan
Enter your current PAM password:

I don't think this is an issue because the prompt in the case of pam_password is being fed directly from the plugin whereas the prompt for pam_interactive is coming from the PAM module itself. But if we wanted an exact drop-in replacement for pam_password, we might have to consider a module which displays the "Enter your current PAM password:" prompt instead of just "Password: ".