Skip to content
Advertisement

How to tell SSH to setuid after PAM and not before to remap users

I am working on a radius authentication solution composed of a PAM module and an NSS module.

The flow is like this:

  • user ben login (via the login command)
  • the user enters the username: ben
  • my NSS module is queried with that username and returns a default non privileged user radius, same behavior as libnss-ato
  • the user types the password
  • my PAM module is called and will query the Radius server, if the auth is accepted, the PAM module will use Radius vendor attributes to pick a local username to map the Radius user to, this mapping is written to a database, for example ben -> admin
  • now, my NSS module will read that database and return the proper local username for the Radius user
  • with the login command, the user is logged at the proper mapped user admin

Now, my problem is as follow. OpenSSH server will read NSS before PAM.

This means the flow is like this:

  • user ben ssh in
  • SSH query NSS and map ben to the default account radius
  • the user is presented with a password prompt and enters the password
  • my PAM module is called and the mapping ben -> admin cached
  • SSH will spawn a session as radius instead of admin because it uses the value it got from NSS before PAM was called

Now this bug happens only on first login, because on second login the NSS will have cached data and return correct user on first call.

But it is still a problem, firstly because I don’t want the first login to fall to the wrong user each time, second if ben got admin rights dropped, his next login will still be mapped to admin by SSH because of NSS cache of my NSS module.

I cannot query the mapping on the first NSS call because querying mapping from radius requires a successful login.

I have a few leads, but I’d really love some insight on this issue.

My leads are:

  • have the radius user use a special root setuid shell, this shell would read the my NSS database and change user, then exec the real shell, the problem is that I need to know which radius user is logged in. I can write env var in my PAM module, but as the shell will be setuid, I need a security mechanism to ensure that var is trusted. Only thing I see is to have a crypto signature in the var, and have the setuid shell verify that with a private key in root 0600.
  • call setuid in the PAM module, but that’s sound fishy

Advertisement

Answer

I ended up changing the shell for the user to a setuid wrapper that drop privileges to the intended user.

Code is here: https://github.com/kuon/radius-auth-virtual

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement