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

1

8

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
Proem answered 13/8, 2020 at 17:1 Comment(5)
Stack Overflow is for programming questions, not questions about using or configuring Unix and its utilities. Unix & Linux or Super User would be better places for questions like this.Plutonian
This is a programming question, I am coding a PAM and NSS modules, and if I go with the setuid shell, this will be a binary I will code.Proem
Then you need to post the code that you need help with. This isn't the place to discuss designs, but solve specific problems in your code.Plutonian
@Plutonian From what I read in the help center, source code is not required as long as it talks about a specific programming problem like this question is doing: "We feel the best Stack Overflow questions have a bit of source code in them, but if your question generally covers a specific programming problem... then you’re in the right place". In this circumstance, I don't think there's any specific code that can be added that would make the question any more clear.Legitimatize
You need something vaguely code-like so someone can see what you're trying to do and explain how to do it correctly. As far as I can tell, you're just looking for general design ideas, not a specific programming solution.Plutonian
P
2

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

Proem answered 28/8, 2020 at 12:58 Comment(2)
Hey could you please explain more ? Did you do this on application level ? I mean post authentication and allocation of shell. Does your shell talks to radius server and then drop privileges ?Sodomy
Basically I changed the user shell from something like /bin/bash to /bin/mywrapper and the wrapper change to root user, talk with radius then change to the user returned by radius. You can check the source code github.com/kuon/radius-auth-virtual/blob/master/shell_wrapper/…Proem

© 2022 - 2024 — McMap. All rights reserved.