Return to BSD News archive
Newsgroups: comp.os.386bsd.questions
Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!bunyip.cc.uq.oz.au!munnari.oz.au!constellation!news.uoknor.edu!ns1.nodak.edu!netnews.nwnet.net!reuter.cse.ogi.edu!cs.uoregon.edu!usenet.ee.pdx.edu!fastrac.llnl.gov!lll-winken.llnl.gov!sol.ctr.columbia.edu!spool.mu.edu!cass.ma02.bull.com!as02.bull.oz.au!melb.bull.oz.au!zen!sjg
From: sjg@zen.void.oz.au (Simon J. Gerraty)
Subject: Re: ADD USER utility for BSDI
Message-ID: <1994Aug21.003437.12382@zen.void.oz.au>
Organization: Zen programming...
Date: Sun, 21 Aug 1994 00:34:37 GMT
References: <Brad-1808941518300001@btmedia.mankato.mn.us>
Lines: 336
Brad@BTMedia.Mankato.MN.US (Brad Theissen) writes:
>We are using the BSDI product, and are growing weary of the process of
>adding new users (editing pwrd file, making directories, changing
>ownership, etc.). We made a little mistake last night that forced us to
>rebuild the router from scratch!
I once wrote a mega complex adduser script, but these days I just use
this one. I've used it on NetBSD, SunOS, Solaris and HP-UX. You
should have little trouble on other *BSD flavours.
#!/bin/sh
# This is a shell archive.
# remove everything above the "#!/bin/sh" line
# and feed to /bin/sh
# Use -c option to overwrite existing files
#
# Contents:
# adduser.sh
#
# packed by: <sjg@zen.void.oz.au> on Sun Aug 21 10:25:30 EST 1994
#
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f adduser.sh -a x$1 != x-c ; then
echo shar: Will not over-write existing file \"adduser.sh\"
else
echo shar: Extracting \"adduser.sh\" \(6443 characters\)
sed 's/^X//' >adduser.sh << '!EOF'
X:
X#
X# NAME:
X# adduser.sh - portable add user script
X#
X# SYNOPSIS:
X#
X# adduser.sh [-G "Group"] [-H "Homes"] [-S "Shell"] [-u "uid"] \\
X# [-p "encrypted"] [-P "cleartext"] [-l]
X#
X# DESCRIPTION:
X# Simply adds users and their home directory. It prompts for a
X# "username" and "fullname" which become part of the passwd file
X# entry for the new user. It adds "username" to "Group"
X# (creating it if necessary) and uses "uid" or the 'gid' of
X# "Group" as a starting point for its search for an unused
X# 'uid'. By default it will prompt for a passwd after adding
X# each user, but '-p' can be used to set a pre-encrypted password
X# or '-P' can be used to give a clear text password which the
X# script will encrypt and then use for each new "username".
X#
X# Most of the variables used are obvious. "Homes" is the parent
X# directory of new users home directories.
X#
X# The '-l' option causes the script to show the default values
X# for the variables that it uses. Most if not all can be set on
X# a per machine basis by creating a file '.adduserrc' in the
X# super users home directory or in the directory where
X# 'adduser.sh' is found. If "Homes"/.adduserrc exists it will
X# be processed after any others, so can be used to set defaults
X# on a per project basis.
X#
X# NOTES:
X# The script handles shadow password files on Solaris 2.3, other
X# machines may break. It has been tested on NetBSD, SunOS,
X# Solaris and HP-UX.
X#
X# AUTHOR:
X# Simon J. Gerraty <sjg@zen.void.oz.au>
X#
X
X# RCSid:
X# $Id: adduser.sh,v 1.2 1994/05/08 22:54:04 sjg Exp sjg $
X#
X# @(#) Copyright (c) 1993 Simon J. Gerraty
X#
X# This file is provided in the hope that it will
X# be of use. There is absolutely NO WARRANTY.
X# Permission to copy, redistribute or otherwise
X# use this file is hereby granted provided that
X# the above copyright notice and this notice are
X# left intact.
X#
X# Please send copies of changes and bug-fixes to:
X# sjg@zen.void.oz.au
X#
X
XMyname=`basename $0 .sh`
XMydir=`dirname $0`
Xcase $Mydir in
X.) Mydir=`pwd`;;
Xesac
X
XETC=/etc
X# for testing only
X#ETC=/tmp
X#VIPW="ed $ETC/passwd"
X
X# thinks that the rc file may override.
Xhost=`hostname 2>/dev/null`
XHomes=/home/${host:-`uname -n`}
XShell=/bin/csh
X[ -x /bin/ksh ] && Shell=/bin/ksh
XGroup=users
XPasswd='**'
X
X# look for an rc file
Xfor d in $HOME $Mydir
Xdo
X [ -s $d/.${Myname}rc ] && { . $d/.${Myname}rc; break; }
Xdone
X
XEXF=/tmp/e$$
XTF=/tmp/u$$
XTF2=/tmp/uu$$
X
Xcase `echo -n .` in
X-n*) N=;C="\c";;
X*) N=-n;C=;;
Xesac
X
XOS=`uname -s`
X
Xadd_path () { [ -d $1 ] && eval ${2:-PATH}="\$${2:-PATH}:$1"; }
X
Xget_id()
X{
X file=$1
X name=$2
X min=${3:-1000}
X max=`expr $min + ${4:-999}`
X > $EXF
X
X id=`grep "^$name:" $file | cut -d: -f3`
X case "$id" in
X "")
X # missing, must add it
X i=$min
X while [ $i -lt $max ]
X do
X n=`cut -d: -f1,3 $file | grep ":$i\$"`
X case "$n" in
X "")
X # an empty slot - use it
X id=$i
X break;;
X esac
X i=`expr $i + 1`
X done
X ;;
X *)
X echo $id > $EXF;;
X esac
X echo $id
X}
X
Xmkdirs()
X{
X case $1 in
X /*) pp=/;;
X *) pp=;;
X esac
X for p in `echo $1 | tr / " "`
X do
X case "$pp" in
X "") pp=$p;;
X /) pp=/$p;;
X *) pp=$pp/$p;;
X esac
X [ -d $pp ] || mkdir $pp || exit 1
X done
X}
X
X
Xadd_group()
X{
X echo "adding $1:*:$2: to $ETC/group"
X echo "$1:*:$2:" >> $ETC/group
X}
X
Xupd_group()
X{
X [ "$mygroup" ] || mygroup=`grep "^$1:" /etc/group | cut -d: -f4`
X case ",$mygroup," in
X ",,") # empty
X add=$2;;
X *,$2,*) # already there
X add=;;
X *) # missing
X add=,$2;;
X esac
X [ "$add" ] && sed "/^$1:/s/\$/$add/" $ETC/group > $ETC/group.$$ &&
X mv $ETC/group.$$ $ETC/group
X}
X
Xupd_passwd()
X{
X EDITOR=ed
X VISUAL=ed
X export EDITOR VISUAL
X
X didit=
X
X echo "adding $1:$2:$3:$4:$5:$6:$7 to $ETC/passwd"
X case "$OS" in
X SunOS)
X if test -f /etc/shadow; then
X # we are assuming its Solaris
X echo "$1:x:$3:$4:$5:$6:$7" > $TF
X echo "$1:$2:6445::::::" > $TF2
X didit=yes
X fi
X ;;
X *BSD) # NetBSD at least
X echo "$1:$2:$3:$4::0:0:$5:$6:$7" > $TF
X didit=yes
X ;;
X esac
X # most OS's just want this.
X test "$didit" || echo "$1:$2:$3:$4:$5:$6:$7" > $TF
X
X line=`grep -n '^+:' $ETC/passwd | cut -d: -f1`
X ( sleep 1; echo ${line}-1r $TF; echo w; echo q;
X if test -f /etc/shadow && test "$OS" = SunOS
X then
X # this is a crok...
X sleep 5
X echo e
X sleep 5
X echo '$r' $TF2
X echo w
X echo q
X fi
X ) | ${VIPW:-vipw}
X}
X
Xadd_user()
X{
X group=$1; shift
X
X eval set -- `echo "'$*'" | sed "s/:/' '/g"`
X
X gid=`get_id $ETC/group $group $4 256`
X if [ "$gid" ]; then
X [ -s $EXF ] || add_group $group $gid
X uid=`get_id $ETC/passwd $1 $3 1024`
X if [ "$uid" ]; then
X [ -s $EXF ] || upd_passwd "$1" "$2" "$uid" "$gid" "$5" "$6" "$7"; upd_group $group $1
X [ -d $6 ] || { mkdirs $6 && chown $1 $6 && chgrp $group $6 && chmod 2775 $6; }
X else
X echo "can't add user $1" >&2; exit 1
X fi
X else
X echo "can't add group $group" >&2; exit 1
X fi
X}
X
Xrm_user()
X{
X ( echo /^$1:/d; echo w; echo q ) | ${VIPW:-vipw}
X}
X
X# needs perl
Xencrypt() {
X for d in /usr/libexec /usr/lib
X do
X [ -x $d/makekey ] && { makekey=$d/makekey; break; }
X done
X perl -e "print pack('a8a2', '$1', '${2:-$$}')" | ${makekey:-makekey}
X}
X
X# ok, time to get to work...
Xset -- `getopt H:S:G:u:p:P:l $*`
X
Xadd_path /sbin
Xadd_path /usr/sbin
Xadd_path /usr/ucb
Xadd_path /usr/etc
X
Xfor i in $*
Xdo
X case "$i" in
X --) shift; break;;
X -H) Homes=$2; shift 2;
X # pick up group defaults...
X test -s $Homes/.${Myname}rc && . $Homes/.${Myname}rc
X ;;
X -S) Shell=$2; shift 2;;
X -G) Group=$2; shift 2;;
X -u) uid=$2; shift 2;;
X -p) Passwd="$2"; shift 2;;
X -P) Passwd=`encrypt $2`; shift 2;;
X -l) list=yes;;
X esac
Xdone
X
Xgid=`get_id $ETC/group $Group 100 1000`
X[ "$uid" ] || uid=$gid
X
Xcase "$Passwd" in
X""|none) Passwd=;;
Xnologin) Passwd='*';;
Xesac
X
Xif [ "$list" = yes ]; then
X echo "Defaults:"
X for v in Group Homes Shell
X do
X eval echo "\ $v=\$$v"
X done
X [ "x$Passwd" = "x*" ] && echo " Passwd=prompt" || echo " Passwd=$Passwd"
X [ "$uid" ] && echo " Initial uid=$uid"
X echo
Xfi
Xecho Enter username and fullname - spaces in fullname are ok, no quotes needed.
Xecho An empty line terminates input.
Xecho
X
Xecho $N "username fullname: $C"
Xwhile read uname fname
Xdo
X [ "$uname" ] || exit 0
X add_user $Group "$uname:$Passwd:$uid:$gid:$fname:$Homes/$uname:$Shell"
X [ "x$Passwd" = "x**" ] && passwd $uname
X echo $N "username fullname: $C"
Xdone
!EOF
if test 6443 -ne `wc -c < adduser.sh`; then
echo shar: \"adduser.sh\" unpacked with wrong size!
fi
chmod +x adduser.sh
fi
exit 0
--
Simon J. Gerraty <sjg@zen.void.oz.au>
#include <disclaimer> /* imagine something _very_ witty here */