home *** CD-ROM | disk | FTP | other *** search
- From decwrl!labrea!rutgers!ukma!cwjcc!hal!ncoast!allbery Sun Oct 30 15:06:46 PST 1988
- Article 694 of comp.sources.misc:
- Path: granite!decwrl!labrea!rutgers!ukma!cwjcc!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.
-
-
-