SteveM has asked for the wisdom of the Perl Monks concerning the following question:

Greetings fellow Monks. I've created a list of valid passwords for users and would like to update the shadow file with the encrypted version of the new password. Is there a way to do this without using Expect to force "passwd" to do this (I'm having problems installing Pty.pm). Cheers!

Replies are listed 'Best First'.
Re: shadow passwd
by cianoz (Friar) on Oct 26, 2000 at 14:56 UTC
    first of all check if your system is using crypt() or MD5 passwords (RedHat 6..7 uses MD5) if your system uses MD5 passwords then you have to encrypt them with something like that:
    use Crypt::PasswdMD5; sub my_md5_crypt { my $salt; for(0..7) { $salt .= ('.', '/', 0..9, 'A'..'Z','a'..'z')[rand 64]; } my $pass = shift; #clear text password return unix_md5_crypt($pass, '$1$' . $salt . '$'); }
    in any case you should build a file in this format:
    USERNAME:ENCRYPTEDPASSWORD USERNAME2:ENCRYPTEDPASSWORD2 ...
    and then
    cat THATFILE | /usr/sbin/chpasswd -e
    Note: if you have normal crypt passwords just build a file like that:
    USERNAME1:CLEARTEXTPASS_1 ...
    and then "/usr/sbin/chpasswd < THATFILE"
      Thanks for that speedy response. Fantastic! I hope I may be able to return the help one day :-) Steve
RE: shadow passwd
by dempa (Friar) on Oct 26, 2000 at 13:10 UTC
    Semi-untested code follows:
    my $plaintext = "tstpw82!"; srand(time() ^ ($$ + ($$ << 15))); my @chars = ('0'..'9','a'..'z','A'..'Z','!','+'); my $salt = $chars[int(rand(scalar @chars))] . $chars[int(rand(scalar @ +chars))]; print crypt($plaintext,$salt) . "\n";
    This is just for generating the encrypted version of the plaintext password. Maybe you already knew that, but here it is anyway.

    To update shadow is a mission of it's own. Most of the time when I've done it in scripts, I use the following method:

    • Create backup of shadow file (IMPORTANT!)
    • Read shadow file into memory
    • Do substitutions or additions
    • Write new shadow file

    Something like that... I'm sure some people will have plenty of stuff to say about this approach, but it works for me and I manage over 8000 user accounts. :)

    ... and no! That's not my real password in $plaintext! :)

    update: In light of what cianoz wrote below, I must say that I was a bit one-track minded there. My post is valid for Solaris systems. :) I don't know if it's possible to implement MD5 passwords with some sort of PAM, and there's no such commmand as chpassword (I think).

      Thanks for this. I'm using Linux RH 6.2 which uses Crypt. I've been told we would use MD5 but some of our old Irix machines won't with it, so Crypt it is. Thanks again!