as my related question doesn't seem to get much love, here another one: What's the proper way to authenticate a user via username/password prompt in Linux nowadays?

In principle, I suppose I would have to obtain username and password, read salt and hash of the corresponding user from /etc/shadow. I would then calculate the hash of the given password and the stored salt and check if the result matches the hash stored in /etc/shadow.

Normally, I could simply authenticate via PAM (e.g. pam_unix) which does all this already but my application is a custom PAM module and I found no method to call one PAM module from another. If this is possible somehow, I'd gladly go for this solution.

As of now, I found this really dated tutorial http://www.tldp.org/HOWTO/Shadow-Password-HOWTO-8.html from 1996 when, apparently, shadow support was not yet built into libc. It mentions pw_auth and valid as helper functions for authentication. I tried implanting these into my code and linking against libshadow.a of the shadow-tools but I get 'unresolved external reference' errors for pw_auth and valid. The code looks something like this:

if ((pw->pw_passwd && pw->pw_passwd[0] == '@'
     && pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL))
    || !valid (passwd, pw)) {
    return (UPAP_AUTHNAK);

I haven't checked this further but anyway this is not a preferred solution as I'd have to update my code every time shadow-utils are updated.

I'd much rather link to a library (that isn't PAM) that provides authentication against /etc/shadow. Is there such thing and I didn't find it yet? Or some other solution?

  • The normal way to do what you describe would be to leave username/password authentication out of your module, and stack it after pam_unix (and pam_ldap). – Gilles Nov 14 '14 at 22:28
  • I still want to be able to execute commands after the user has successfully authenticated themself. At first start, my module should detect that the user has not logged in previously, require an authentication and create my custom token afterwards. From the second login on I would not require pam_unix anymore (except when my module fails). – Sonny O'Rullivan Nov 22 '14 at 13:10

You fear of an update of shadow-utils is IMO unwarranted. The routines described in that HOWTO are available on my Ubuntu 12.04 and Mint 17 systems without installing anything special.

The structure to read /etc/shadow information in a C program can be found in /usr/include/shadow.h and with man 5 shadow and the functions that you would need to find e.g. a shadow password entry by name as defined in /usr/include/shadow.h is getspnam and that will get you a man page as well (man getspnam) describing that and all related functions.

Based on that you should be able to get the hashed password entry for any given name. The hashed password should have multiple '$' tokens, cut of everything after and including the last '$' from the hashed password and present that as salt to crypt(), the glibc version (according to man 3 crypt) should be able to handle the "extended" salts that indicate SHA512 entries as are more common nowadays.

  • Ok, so doing the authentication myself via crypt() and getspnam should be doable. Are pw_auth and valid also available in your installation? Because I can't find them on my Ubuntu 14.04 (only when installing shadow-tools from source and linking to the library and even then it does not work) They don't do very much actually and I could replace them with my own code of course - I am just curious as to why they have been dropped. – Sonny O'Rullivan Nov 14 '14 at 14:50
  • Another thing that came to mind: What method should be used to prompt the user for a password? Is there an availabe function/library that does this for me (providing the standard system password entry prompt)? – Sonny O'Rullivan Nov 14 '14 at 15:13
  • @SonnyO'Rullivan No pwauth.h is not installed. You should just compare the output from crypt with the shadow entry (not sure if you have to prepend the salt yourself). For the password prompt I would look at what login does, IIRC it just switches of echoing, but it has been a long time since I looked at that. – Anthon Nov 14 '14 at 15:44
  • Thanks, tried crypt() after obtaining salt and hash type and it worked nicely. Easier than I had thought and I don't even need pwauth.h etc. The login part should not be too much effort then as well. – Sonny O'Rullivan Nov 14 '14 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.