Tải bản đầy đủ (.pdf) (4 trang)

A Pseudo–shadow File

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (56.96 KB, 4 trang )

241
■ ■ ■
CHAPTER 37
A Pseudo–shadow File
S
ome environments do not use a shadow file for maintaining passwords. These envi-
ronments keep encrypted passwords in either a local passwd file or one that is handled
through NIS. I have seen this mode of operation in several versions of HP-UX and NIS.
NIS can support using a shadow file, but not all NIS clients have this capability.
The script in this chapter, which is intended to be run daily, creates and maintains a
pseudo–shadow file to track the age of user passwords and their change history. The script
does not, however, remove the encrypted password from the already-existing passwd file.
I intend this contrived shadow-file generator to be run in conjunction with the password-
aging script in Chapter 36. The script in that chapter relies on information contained in a
shadow file to determine the date of the last password change.
The first section of the script sets up several environment variables to be used later. The
variables originally were taken from a separate configuration file, but for the sake of sim-
plicity I have included them at the beginning of the script.
#!/bin/ksh
HOME=/usr/local/pass_aging
ARCHIVE=$HOME/archive
BIN="$HOME/bin"
DEBUG=duh
shad=/usr/local/pass_aging/bin/shadow_nis
pswd=/var/yp/src/passwd
PERL=/usr/bin/perl
ED=ed.script
The only interesting variables being set here are the debug flag and the variables stor-
ing the locations of the passwd and shadow files. The DEBUG variable just needs to be set to
anything non-null to generate some debugging output while the script is running, so that
you can see what it is doing when you are testing.


The shad variable holds the location of the shadow file. Since the shadow file is a regular
file that the system itself doesn’t actually use, you can call it anything you want. The
pswd file definition is the real master passwd file that the machine relies on. This script
only ever has read access to that file, so there is no danger in possibly modifying the live
file even when testing. If your anxiety level is high, you could copy the original and run
the script against the copy.
242
CHAPTER 37

A PSEUDO–SHADOW FILE
In the following code we determine the number of days since 1/1/1970, the start of the
UNIX epoch. The number in the third field of a shadow-file entry represents the date that
the password for that account was last changed, expressed as a number of days since the
beginning of the epoch. This value can be determined in a number of ways. Please refer to
Chapter 3 for more discussion on this topic.
seconds_since_epoch=`$PERL -e 'print time'`
seconds_per_day=$((60*60*24))
days_since_epoch=$(($seconds_since_epoch/$seconds_per_day))
If this is the first time the script is run and there is no existing shadow file, the script will
create one based on the specified passwd file. Since the age of the password was probably
not tracked before the first time this script is run, the script assumes that today is the day
the password was last changed, and enters that value in the new shadow file. This gives
users the benefit of the doubt.
if [ ! -f $shad ]
then
test "$DEBUG" != "" && echo DEBUG: $shad does not exist, creating
cat $pswd | awk -v days=$days_since_epoch -F: \
'{print $1 ":" $2 ":" days ":0:90:7:::"}' > $shad
fi
Even though this file isn’t used by any system process, we want to back it up to be able

to retrace our steps in case something goes wrong. I have used saved files many times to
restore account information without having to use a system backup. We also want to be
able to remove the older files in the backup directory.
backdate=`date +%m%d%y%H%M`
test "$DEBUG" != "" && echo DEBUG: Backing up $shad to $ARCHIVE/nis_shadow.$backdate
cp -p $shad $ARCHIVE/nis_shadow.$backdate
find $ARCHIVE -mtime +7 -exec rm {} \;
Like the script in Chapter 36, this script will construct and run an ed script, which
allows us to edit the shadow file in place when changes need to be made. This is discussed
in more detail in Chapter 25. First we have to remove any previously created ed script files
that may be lying around.
if [ -f $HOME/bin/$ED ]
then
test "$DEBUG" != "" && echo DEBUG: Cleaning up old ed.script
rm $HOME/bin/$ED
fi
Now we’re in the core of the program. The loop iterates through the current passwd file
and updates the corresponding entries in the new shadow file.
for user in `cut -d: -f1 $pswd`
do
CHAPTER 37

A PSEUDO–SHADOW FILE
243
First you have to determine whether the user’s name appears in the shadow file. If he
has a new account, he may not have been entered into it yet. If this is so, you have to create
an entry in the shadow file.
user_exist=`grep "^${user}:" $shad | cut -d: -f1`
if [ "$user_exist" = "" ]
then

echo "$user:$cur_pass_word:$days_since_epoch:0:90:7:::" >> $shad
test "$DEBUG" != "" && echo DEBUG: Missing $user, adding to $shad
fi
Now the script gathers the user’s encrypted password from the passwd file and its age
from the shadow file.
cur_pass_word=`grep "^${user}:" $pswd | cut -d: -f2`
old_pass_word=`grep "^${user}:" $shad | cut -d: -f2`
pass_days=`grep "^${user}:" $shad | cut -d: -f3`
test "$DEBUG" != "" && echo DEBUG: \
$user, $cur_pass_word, $old_pass_word, $pass_days
The shadow file is updated only when this script is run. If the password saved in the
shadow file isn’t the same as the current one in the passwd file, some updates need to be
made to the shadow file.
if [ "$old_pass_word" != "$cur_pass_word" ]
then
test "$DEBUG" != "" && echo DEBUG: $user password has changed,\
updating $shad
Now we have to make sure the encrypted passwords are handled correctly. These pass-
words contain special characters (., /, *, and $) that need to be escaped with a preceding
backslash where they appear in the ed script. This operation will ensure that the correct
password string is entered in the shadow file.
old_pass_word=`echo $old_pass_word | sed -e s/\\\./\\\\\\\\./g`
old_pass_word=`echo $old_pass_word | sed -e s/\\\*/\\\\\\\\*/g`
old_pass_word=`echo $old_pass_word | sed -e s/\\\$/\\\\\\\\$/g`
old_pass_word=`echo $old_pass_word | sed -e s/\\\\\//\\\\\\\\\\\//g`
cur_pass_word=`echo $cur_pass_word | sed -e s/\\\./\\\\\\\\./g`
cur_pass_word=`echo $cur_pass_word | sed -e s/\\\*/\\\\\\\\*/g`
cur_pass_word=`echo $cur_pass_word | sed -e s/\\\$/\\\\\\\\$/g`
cur_pass_word=`echo $cur_pass_word | sed -e s/\\\\\//\\\\\\\\\\\//g`
These sed commands look pretty ugly, but that’s because a lot of escape slashes have to

be evaluated and in turn the following escape slash needs to be escaped itself. For more
coverage of sed commands for updating encrypted password strings, refer to Chapter 36.
With all the characters being replaced, there is one character that gets escaped but
should not be part of the final password string. The special $ character is the “end of line”
244
CHAPTER 37

A PSEUDO–SHADOW FILE
character for all strings on UNIX and Linux systems, and normally is not visible. When
all the special characters were escaped in the previous sed commands, this trailing \$
became visible at the end of the string. It wasn’t part of the original encrypted password,
so the last two characters (\$) need to be removed from the string. This use of sed is dis-
cussed in more detail in Chapter 24.
old_pass_word=`echo $old_pass_word | sed 's/\(.*\)\(.\)\(.\)$/\1/'`
cur_pass_word=`echo $cur_pass_word | sed 's/\(.*\)\(.\)\(.\)$/\1/'`
Now we create an instruction in the ed script that will replace the old encrypted
password and its days since last change value with the new encrypted password and
the current days since epoch value. We do this by taking the new values from the current
passwd file. One such instruction is appended to the ed script using double greater-than
signs (>>) for each user account, and then all shadow-entry updates are made at once by
running the ed script.
test "$DEBUG" != "" && echo DEBUG: Creating ed file to change\
$old_pass_word:$pass_days to $cur_pass_word:$days_since_epoch
echo "g/$user:$old_pass_word/s/$old_pass_word:\
$pass_days/$cur_pass_word:$days_since_epoch/g" \
>> $HOME/bin/$ED
else
test "$DEBUG" != "" && echo DEBUG: No changes for $user
continue
fi

done
Now that the loop is complete for all the users, you should add the final two lines to the
ed script and process the shadow file with all its changes.
# Complete and process the file with the ed.script
echo "w" >> $HOME/bin/$ED
echo "q" >> $HOME/bin/$ED
test "$DEBUG" != "" && echo DEBUG: Running ed.script for $user on $shad
ed -s $shad < $HOME/bin/$ED > /dev/null
You might want to make one refinement: once the modifications are complete, you
could check the line counts of the passwd and shadow files to see whether they match. If they
don’t match, it is possible that an account has been removed and the account is not present
in the passwd file; the entry is still visible in the shadow file, though. The script should then
remove the old usernames from the shadow file to keep both files synchronized.

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×