Change password through linux PAM without running application as root

not-root-userpamshadow

An application I'm writing will have some password change functionality. However I'm wondering if it is possible to not run the account management part of it as root.

Right now I'm running into the issue that if I'm running as the user that I'm trying to manage I can't change the password. I've verified that the password is correct by first authenticating with the given password. (separate call to another part of the auth module.) Only when I then make a call to chauthtok to change it for the user pamtest it results in this as my debug output for the conversation function:

START PAM CHANGE PASSWORD
PAM_CONV start [('Changing password for pamtest.', 4)]
PAM_CONV iter: Changing password for pamtest. 4
PAM_CONV end: [('', 0)]
PAM_CONV start [('(current) UNIX password: ', 1)]
PAM_CONV iter: (current) UNIX password:  1
PAM_CONV end: [(u'5ACN5pbmDFBVMHp', 0)]
PAM_CONV start [('Enter new UNIX password: ', 1)]
PAM_CONV iter: Enter new UNIX password:  1
PAM_CONV end: [(u'pdJb7ffsQTHWw4V', 0)]
PAM_CONV start [('Retype new UNIX password: ', 1)]
PAM_CONV iter: Retype new UNIX password:  1
PAM_CONV end: [(u'pdJb7ffsQTHWw4V', 0)]
Pass change failed for pamtest! '' (('Authentication token manipulation error', 20))
response:False

Where the debug flag for pam_unix.so gives this line twice in the rsyslog auth.log file:

<date> <time>   <system>    python  pam_unix(passwd:chauthtok): username [pamtest] obtained

This leads me to believe that there's an issue with writing the changed password to the shadow file. Which is probably due to root being the only one with write access. And the code does work when I run it as root.

Is this a correct assumption and if so, is this normally done by running the module as root? Or are there other options available like creating a specific user with only rights to write to the shadow file?

Best Answer

This leads me to believe that there's an issue with writing the changed password to the shadow file. Which is probably due to root being the only one with write access. And the code does work when I run it as root.

Is this a correct assumption

Yes. /etc/shadow is only writable by root, so your program will only work when it has root permissions.

Or are there other options available like creating a specific user with only rights to write to the shadow file?

Write a "setuid root" program. setuid means that the program always has root permissions, regardless of which user started it. Your program then has to ensure that

  • the calling user may only change his own password
  • the calling user has provided the correct old password
  • there's no way for the calling user to manipulate your program to do something else entirely, like starting a root shell

Of course, you have to be extremely careful when writing setuid progams. Your program now has more permissions then the calling user, so attackers will try to exploit bugs in your program to elevate their own permissions to root.

Related Question