home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume5
/
vipw
< prev
next >
Wrap
Internet Message Format
|
1989-02-03
|
6KB
Path: xanth!nic.MR.NET!hal!ncoast!allbery
From: greywolf@unisoft.UUCP (The Grey Wolf)
Newsgroups: comp.sources.misc
Subject: v05i017: portable (mostly, if not completely) vipw shell script.
Keywords: vipw with no proprietary code.
Message-ID: <1308@unisoft.UUCP>
Date: 28 Oct 88 02:58:57 GMT
Sender: allbery@ncoast.UUCP
Reply-To: greywolf@unisoft.UUCP (The Grey Wolf)
Lines: 187
Approved: allbery@ncoast.UUCP
Posting-number: Volume 5, Issue 17
Submitted-by: "The Grey Wolf" <greywolf@unisoft.UUCP>
Archive-name: vipw
[Some comments:
(1) some shells break or slow down when the leading character on lines in
a here document is the same as the leading character of the "EOF word".
This has got that bug! (I fixed it, just in case.)
(2) The code is in "debug mode"; rearrange the comments a bit to make a
working version.
(3) I hate to tell you, greywolf, but this thing is just as useful under
Xenix or System V; neither of which are guaranteed to mount /usr.
Stupid parochialisms are why this critter's needed in the first place!
++bsa]
After seeing the questions on comp.unix.questions about a vipw program,
I thought I would submit one. It seems to me to be completely portable;
if not, the tweaks required are likely minimal. It includes sanity
checking for a uid 0 entry (verification of shell, home directory, password);
and produces appropriate messages explaining what happened.
Enjoy. Comments? Flames? -> ...!{sun,ucbvax,well,uunet}!unisoft!greywolf
-----cut here----------cut here----------cut here----------cut here-----
#!/bin/sh -
# This is a shell archive, meaning:
# 1: delete everything above the #! /bin/sh - line.
# 2: use sh (NOT csh) to unpack the archive.
#
# This file contains:
# vipw.sh (3832 bytes)
#
# Packed by greywolf@unisoft.UniSoft (The Grey Wolf) 30 September 1988
sed 's/^FOO_//g' << '_BAR_' > vipw.sh
FOO_#! /bin/sh -
FOO_# vipw: edit passwd file with locking.
FOO_# unicom!greywolf
FOO_
FOO_# PATH and IFS are here for paranoia's sake
FOO_# The path may be modified as necessary.
FOO_IFS='
FOO_'
FOO_PATH=/etc:/bin:/usr/bin:/usr/ucb:/usr/etc:/usr/local/bin export PATH IFS
FOO_
FOO_EDITOR=${EDITOR-vi}
FOO_
FOO_# PASSWD=/etc/passwd PTMP=/etc/ptmp
FOO_PASSWD=./passwd PTMP=./ptmp
FOO_
FOO_# if the temp file exists, tell 'em to come back later.
FOO_
FOO_if [ -f $PTMP ]
FOO_then echo "vipw: temp file busy, try again later."
FOO_ exit 0
FOO_fi
FOO_
FOO_# simplify cleanup
FOO_trap "/bin/rm -f $PTMP ; exit 0" 0 1 2 3 15
FOO_
FOO_cp $PASSWD $PTMP # so we don't have the real thing.
FOO_if chmod 600 $PTMP # This could be something like 644...
FOO_then :
FOO_else exit $?
FOO_fi
FOO_
FOO_# check if /usr is mounted; if we're single-user, it likely isn't, at least
FOO_# on any SANE implementation of a hierarchy. (Sun 4.0 is not a sane hier-
FOO_# archy in my opinion.)
FOO_
FOO_if mount | grep "/usr " > /dev/null
FOO_then mount=0
FOO_else mount=1 # set a flag to umount /usr later
FOO_ if mount /usr
FOO_ then :
FOO_ else echo "mounting /usr failed"
FOO_ exit $? # if it failed, we have problems -- better leave
FOO_ fi
FOO_fi
FOO_
FOO_# edit the thing.
FOO_
FOO_$EDITOR $PTMP
FOO_
FOO_# was it changed? don't shuffle files unnecessarily.
FOO_
FOO_if cmp -s $PTMP $PASSWD
FOO_then echo "No changes appear to have been made."
FOO_ exit 0
FOO_fi
FOO_
FOO_#
FOO_# check the super-user password entry. There MUST be at least one user with
FOO_# uid 0. If not, then we exit. If the password is not of the 13 char
FOO_# length, then it cannot be decrypted, so we exit. If the password has an
FOO_# asterisk in it, it cannot be decrypted, so we exit. If the ptmp file gets
FOO_# deleted/trashed, we don't even bother moving it. If root's login shell is
FOO_# not executable, then we don't allow it, and we exit. If root's passwd is
FOO_# zero-length, then we issue a warning only.
FOO_# Replacing root's (bad) shell with /bin/sh is tricky without another tmp
FOO_# file, and that's getting sloppy.
FOO_
FOO_# we don't demand "root" as the first uid 0 entry. I use "wizard" on some
FOO_# machines.
FOO_
FOO_echo "verifying superuser password entry..."
FOO_
FOO_# length of a minimal superuser password entry when echoed portably is
FOO_# 14 chars:
FOO_# "root::0:0::/:" + the newline that echo prints.
FOO_
FOO_if [ `cat $PTMP | wc -c` -lt 14 ]
FOO_then echo "panic: zero-length file!
FOO_passwd file unchanged."
FOO_ exit 1
FOO_fi
FOO_
FOO_# look for a uid 0 entry -- this MUST be first on the line or this will fail.
FOO_if pwd=`head -1 $PTMP | egrep '^[^:]*:[^:]*:0:[0-9^:]*:[^:]*:[^:]*:.*[^:]$'`
FOO_then pwd="`echo $pwd |
FOO_ sed -e 's/::/:NULL:/g' \
FOO_ -e 's/:.*\*[^:]*:/:STAR:/g' -e 's,:$,:/bin/sh,'`"
FOO_else echo "panic: basic super-user entry missing
FOO_passwd file unchanged."
FOO_ exit 1
FOO_fi
FOO_
FOO_# split the root entry for easy access
FOO_set `echo "$pwd" |
FOO_ awk -F: '{ printf "%s %s %d %d %s %s",$1,$2,$3,$4,$6,$7 }'`
FOO_
FOO_pw_name="$1" pw_passwd="$2" pw_uid="$3" pw_gid="$4"
FOO_pw_dir="$5" pw_shell="$6"
FOO_
FOO_
FOO_not_ok=0 # everything is ok until we find otherwise
FOO_
FOO_# The length of a password will be 13 chars; when echoed portably it will be
FOO_# 14 chars due to the newline returned by echo
FOO_
FOO_if [ `echo "$pw_passwd" | wc -c` -lt 14 ]
FOO_then if [ "$pw_passwd" = "NULL" ]
FOO_ then echo "warning: null super-user passwd."
FOO_ not_ok=1
FOO_ else
FOO_ echo "panic: impossible super-user password.
FOO_passwd file unchanged."
FOO_ exit 1
FOO_ fi
FOO_fi
FOO_
FOO_# root MUST log into / as home directory. Why? Enforcement of convention.
FOO_# if you don't like it, change it.
FOO_
FOO_if [ ! "$pw_dir" = "/" ]
FOO_then echo "panic: bad super-user directory.
FOO_passwd file unchanged."
FOO_ exit 1
FOO_fi
FOO_
FOO_# We have to have an existing executable shell, or else root's login/su
FOO_# attempts will fail miserably.
FOO_# Why doesn't test have a -x option?!?
FOO_
FOO_if [ ! -f "$pw_shell" ]
FOO_then echo "panic: can't find shell $pw_shell!
FOO_passwd file unchanged."
FOO_ exit 1
FOO_fi
FOO_
FOO_if [ $not_ok -eq 0 ]
FOO_then echo ok.
FOO_fi
FOO_
FOO_# make passwd file read-only to discourage direct use of an editor on the
FOO_# file.
FOO_chmod 444 $PTMP
FOO_mv -f $PTMP $PASSWD
FOO_echo done.
FOO_exit 0
_BAR_
if [ `cat vipw.sh` -ne 3832 ]
then
echo "vipw.sh unpacked with wrong size -- should be 3832 bytes
fi
# end of shar file.