We have a client that likes to generate their own /etc/shadow password hashes and have us assign them to a bulk list of their userids. This enables them to not have to pass along a plain-text password to us, their hosting provider. We’re in the process of transitioning this client to our LDAP configuration, but until we get them converted it’s each individual machine and I wasn’t thrilled about having to spend an entire day to vi the shadow file on more than 50 servers for 17 userids on each server.
Prior to Solaris 10 this was easy enough to do via a script given the limited characters for password generation. I needed to figure out a way to script it out for Solaris 10 with the inclusion of $ and / into the password hashes. I finally got it working via command line and then had to slightly modify the way it was done via script. The only funkiness I noticed was the literal interpretation of $ when read in from a variable, so please note that the line in the script containing the password must include “\” prior to every occurance of $.
For example, if your password salt is “$1$aQmSf/ZM$CBSTF10TXrvpOe..OaCtH/” then you’ll need to set your salt into the script’s variable thusly:
PASSWD=”\$1\$aQmSf/ZM\$CBSTF10TXrvpOe..OaCtH/”
I added a few idiot checks around the script since wiping out your /etc/shadow file is never a fun thing to explain to the boss. Feel free to tweak this if you can think of any other ways to streamline it or any additional idiot checks. Please also note that while this script does clean up after itself in the /root/scripts working directory, it will leave a time-stamped copy of /etc/shadow in /etc in case you run into any need to rollback your changes.
#!/usr/bin/bash
# Check for userid
if [[ $1 = “” ]]
then
echo ” Usage: pwchange.sh <userid>”
exit
else
sleep 0
fiDATE=`date +%m%d%y%H%M%S`
USER=$1
OLDPW=`grep $USER /etc/shadow | cut -f 2 -d “:”`
USERCK=`grep $USER /etc/shadow | cut -f 2 -d “:” | wc -l`# Check if userid exists in /etc/shadow.
if [[ $USERCK -lt 1 ]]
then
echo “No users matching $USER”
exit
else
sleep 0
fi# Check if multiple userids exist. If there are, fail out.
if [[ $USERCK -gt 1 ]]
then
echo “Multiple users matching $USER”
exit
else
sleep 0
fiPASSWD=”\$1\$aQmSf/ZM\$CBSTF10TXrvpOe..OaCtH/”
# Check if password has already been set to salt.
if [[ $OLDPW = $PASSWD ]]
then
echo “Password already matches for $USER”
exit
else
sleep 1
fiecho “Setting password for $1”
/usr/bin/cp -rp /etc/shadow /etc/shadow.$DATE
/usr/bin/cp -rp /etc/shadow /root/scripts/shadow
/usr/bin/sed -e “/$USER/s|$OLDPW|$PASSWD|g” /root/scripts/shadow > /etc/shadow
/usr/bin/rm /root/scripts/shadow