views:

534

answers:

7

I know about passwd(1) and crypt(3). What I'm looking for is a C API to call which will set the user's password in the passwd/shadow files, without having to programatically walk the files and overwrite the entry for the user in question. Application runs as root.

Does such an API exist?

EDIT: Guess I should specify, the password is being synced between different systems, so we cannot simply call system("passwd") and allow the user to enter whatever password they want when passwd prompts them. We need to know the password so we can programatically update the other systems with the same password.

A: 

The best bet is to exec the passwd command with the appropriate arguments and let it worry about the file handling, crypt, and file locking issues. At some level, something is going to have to "programmatically walk the files" no matter what. Unless you really have a big performance problem with this, you're better off relying on the existing code and experience rather than trying to duplicate the existing code.

Shannon Nelson
Passwd command does not allow password to be specified as a command-line argument.
Stéphane
Could pipe commands to passwd.
Joey Robert
A: 

Perhaps you want PAM? Not sure, but most distributions use it...

Added: It looks like Mac OS X uses openssl to manage it's password hashing. It may be possible to do something similar under linux, but for your needs you have to be compatible with the authentication layer used by the OS.

dmckee
A: 

You could have a look at passwd source, but I'd first try an easier and lazier way: I'd just strace passwd and see what happens.

Anonymous
strace wouldn't help too much, it is too low level. At best it would show open on both /etc/shadow and /etc/passwd and write being called on those file handles.
Evan Teran
+2  A: 

Using /etc/passwd and /etc/shadow for password storage? Are the UIDs in sync between systems? You could simply copy/overwrite the line in the /etc/shadow file for the particular user.

And the "don't do it" answer would be to use a NIS server and change the password only once.

hometoast
+1  A: 

Maybe the putpwent call is what you are looking for. Try man putpwent. On a quicks search I find a page with some examples. It might help.

http://linux.omnipotent.net/article.php?article_id=10935

Check getpwnam for looking up than changing the entry and utilizing putpwent.

Norbert Hartl
+4  A: 

This would most likely vary depending on what mechanism the system in question uses...

...which brings me to another suggestion, use existing tools to have the different systems authenticate users against a common store instead - like LDAP or whatever directory or master system is available at your site. Or set one up. Preferably not NIS+ ^^

Do not reinvent the wheel, as they supposedly say.

Where would you get the clear text password from to begin with? If it's out there, why even bother having passwords? (Yeah, I know I'm a prick when it comes to these things, sorry - let the downvotes begin ;)

Oskar Duveborn
A: 

As 8jean commented above, looks like /usr/sbin/chpasswd might be the easiest way. Otherwise I'd have gone with noha's comment of using functions like fgetpwent() -- or fgetspent() for dealing with the shadow file -- to walk the list of users and modify the record(s) I need to change. Thanks, everyone!

Stéphane