views:

368

answers:

3

I have written a cgi-bin application in C that runs in a browser and allows the user to open an interactive shell and view & edit files on a Linux machine. It runs as the standard apache "www-data" user. I just added a login screen to it where the user types in their name and password (in a form) but I cannot authenticate the user using getspnam since this function only works when running as root.

What options do I have to check the login credentials of a user when not running as root?

PS: In my interactive shell I can type "su root" and then type in my password and it does elevate to root fine so it obviously can be done interactively.

+1  A: 

With regard to your PS: Well, when you do a su root you're switching to the root user. So yes, of course, root can read the shadow file, you all ready said that.

With regard to your problem: Can't you have your apache processes temporarily elevate to root (by calling setuid or similar) to perform the authentication?

Good luck!

mrduclaw
it should be noted that this only works because `su` is suid root. If it wasn't, it would have the same issues no matter which user you are attempting to switch to.
Evan Teran
I'm not sure I understand what you're saying @Evan Teran. He's doing a `su root` to switch to the root user. If he did a `su randomUser` then he would not be able to read root's files as a `randomUser` unless `root` had given `randomUser` permission to do so. Isn't that a given? Or did I misunderstand you?
mrduclaw
Using SetUID solved my problem. I was not aware of this functionality before as I am a Linux newbie. thanks!
KPexEA
@mrduclaw: the issue is reading `/etc/shadow` which is only readable by `root`. `su` is a suid root program which means when you run it, no matter which user executes it, it runs as root. **This** is what allows su to do the authentication and switch the users. If `su` were not suid root, it couldn't read `/etc/shadow` and wouldn't be able to do anything.
Evan Teran
@Evan Teran, I understand that. I guess I'm just failing to see where what you're saying contradicts what I'm saying. @KPexEA, Glad it worked. Cheers!
mrduclaw
@msduclaw: you said this "Well, when you do a su root you're switching to the root user. So yes, of course, root can read the shadow file, you all ready said that." which is fairly meaningless because it doesn't matter which user you are switching to. It is `su` which is reading `/etc/shadow` not the user you are switching to.
Evan Teran
to follow up, your first reply seems to imply that you think i'm talking about reading some random files owned by root. I am not, I am specifically talking about accessing `/etc/shadow` which is the issue relevant to the OP.
Evan Teran
Finally for example, if I do: `su eteran`, the `su` binary will run as root because it is suid root and still will read `/etc/shadow` to verify my credentials, then it will switch my user id to `eteran`. Basically, the first paragraph in your original answer doesn't say anything meaningful.
Evan Teran
Ah, I get what you're saying. With that paragraph, I was referring to his ability to interactively, as the `root` user, to read the `/etc/shadow` file. I wasn't referring to how `su` takes care of authenticating the user (since I didn't think he could use `su` to solve his problem). My intension was to attempt to solve his issue in the simplest way, and I thought that by effectively changing his euid would do so (thus the 2nd paragraph), and apparently that was the case. I'm sorry if my first paragraph confused you. And thanks for calling me Ms, that was real sweet of you.
mrduclaw
Also, with regard to your example, after authenticating at the `eteran` user, you would not be able to read the `/etc/shadow` file interactively unless the permissions on `/etc/shadow` were set to allow that. But since he's authenticating as the `root` user, he's able to. It doesn't matter if `su` can read the `/etc/shadow` file or not, we want his interactive user to be able to read the `/etc/shadow` file so he can authenticate someone, right?
mrduclaw
+2  A: 

I think you want to take a look at Pluggable authentication modules. AFAIK, PAM handles all the messy stuff for you and you just need to do a few function calls to authenticate the user on whatever the backend to authenticate users on the Linux host is (be it shadow passwords, nis, ldap, whatever)

Here's a short guide about integrating your C code with them.

Kimvais
A: 

As suggested, I think PAM is the modern way to do this. But if you want to go old school, you need to create a setuid-root program (not a script) to do your authentication.

There are lots of gotchas with setuid-root programs, which is why PAM is likely better.

Here's a link to some good papers on safely writing setuid-root programs.

Lee-Man
I just realized you could also use 'sudo' to change your user id to root. This is just a setuid-root program that already has security built in. Be careful how you set this up, or, like roll-your-own setuid-root programs, you'll leave your system vulnerable.
Lee-Man