X-Git-Url: https://git.cameronkatri.com/pw-darwin.git/blobdiff_plain/28bed408771188366358723714f5f1509e46bbf7..bc3a83e68decbe1477319e15f3bb05b6362f86cf:/adduser/adduser.sh diff --git a/adduser/adduser.sh b/adduser/adduser.sh index 3b843c6..a8622b9 100644 --- a/adduser/adduser.sh +++ b/adduser/adduser.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2002, 2003 Michael Telahun Makonnen. All rights reserved. +# Copyright (c) 2002-2004 Michael Telahun Makonnen. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -22,7 +22,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# Email: Mike Makonnen +# Email: Mike Makonnen # # $FreeBSD$ # @@ -77,12 +77,15 @@ show_usage() { echo "usage: ${THISCMD} [options]" echo " options may include:" echo " -C save to the configuration file only" + echo " -D do not attempt to create the home directory" echo " -E disable this account after creation" echo " -G additional groups to add accounts to" echo " -L login class of the user" echo " -N do not read configuration file" + echo " -S a nonexistent shell is not an error" echo " -d home directory" echo " -f file from which input will be received" + echo " -g default login group" echo " -h display this usage message" echo " -k path to skeleton home directory" echo " -m user welcome message file" @@ -109,32 +112,74 @@ valid_shells() { ;; esac done + + # /usr/sbin/nologin is a special case + [ -x "${NOLOGIN_PATH}" ] && echo -n " ${NOLOGIN}" } # fullpath_from_shell shell -# Given $shell, the basename component of a valid shell, get the +# Given $shell, which is either the full path to a shell or +# the basename component of a valid shell, get the # full path to the shell from the /etc/shells file. # fullpath_from_shell() { _shell=$1 [ -z "$_shell" ] && return 1 + # /usr/sbin/nologin is a special case; it needs to be handled + # before the cat | while loop, since a 'return' from within + # a subshell will not terminate the function's execution, and + # the path to the nologin shell might be printed out twice. + # + if [ "$_shell" = "${NOLOGIN}" -o \ + "$_shell" = "${NOLOGIN_PATH}" ]; then + echo ${NOLOGIN_PATH} + return 0; + fi + cat ${ETCSHELLS} | while read _path _junk ; do case "$_path" in \#*|'') ;; *) - if [ "`basename $_path`" = "$_shell" ]; then + if [ "$_path" = "$_shell" -o \ + "`basename $_path`" = "$_shell" ]; then echo $_path return 0 fi ;; esac done + return 1 } +# shell_exists shell +# If the given shell is listed in ${ETCSHELLS} or it is +# the nologin shell this function will return 0. +# Otherwise, it will return 1. If shell is valid but +# the path is invalid or it is not executable it +# will emit an informational message saying so. +# +shell_exists() +{ + _sh="$1" + _shellchk="${GREPCMD} '^$_sh$' ${ETCSHELLS} > /dev/null 2>&1" + + if ! eval $_shellchk; then + # The nologin shell is not listed in /etc/shells. + if [ "$_sh" != "${NOLOGIN_PATH}" ]; then + err "Invalid shell ($_sh) for user $username." + return 1 + fi + fi + ! [ -x "$_sh" ] && + info "The shell ($_sh) does not exist or is not executable." + + return 0 +} + # save_config # Save some variables to a configuration file. # Note: not all script variables are saved, only those that @@ -145,6 +190,7 @@ save_config() { echo "# NOTE: only *some* variables are saved." >> ${ADDUSERCONF} echo "# Last Modified on `${DATECMD}`." >> ${ADDUSERCONF} echo '' >> ${ADDUSERCONF} + echo "defaultLgroup=$ulogingroup" >> ${ADDUSERCONF} echo "defaultclass=$uclass" >> ${ADDUSERCONF} echo "defaultgroups=$ugroups" >> ${ADDUSERCONF} echo "passwdtype=$passwdtype" >> ${ADDUSERCONF} @@ -189,12 +235,22 @@ add_user() { [ -n "$ulogingroup" ] && _group='-g "$ulogingroup"' [ -n "$ugroups" ] && _grouplist='-G "$ugroups"' [ -n "$ushell" ] && _shell='-s "$ushell"' - [ -n "$uhome" ] && _home='-m -d "$uhome"' [ -n "$uclass" ] && _class='-L "$uclass"' [ -n "$ugecos" ] && _comment='-c "$ugecos"' [ -n "$udotdir" ] && _dotdir='-k "$udotdir"' [ -n "$uexpire" ] && _expire='-e "$uexpire"' [ -n "$upwexpire" ] && _pwexpire='-p "$upwexpire"' + if [ -z "$Dflag" -a -n "$uhome" ]; then + # The /nonexistent home directory is special. It + # means the user has no home directory. + if [ "$uhome" = "$NOHOME" ]; then + _home='-d "$uhome"' + else + _home='-m -d "$uhome"' + fi + elif [ -n "$Dflag" -a -n "$uhome" ]; then + _home='-d "$uhome"' + fi case $passwdtype in no) _passwdmethod="-w no" @@ -323,7 +379,7 @@ get_gecos() { # get_shell # Get the account's shell. Works in interactive and batch mode. It -# accepts only the base name of the shell, NOT the full path. +# accepts either the base name of the shell or the full path. # If an invalid shell is entered it will simply use the default shell. # get_shell() { @@ -332,11 +388,12 @@ get_shell() { ushell="$defaultshell" # Make sure the current value of the shell is a valid one - _shellchk="${GREPCMD} '^$ushell$' ${ETCSHELLS} > /dev/null 2>&1" - eval $_shellchk || { - err "Invalid shell ($ushell). Using default shell ${defaultshell}." - ushell="$defaultshell" - } + if [ -z "$Sflag" ]; then + if ! shell_exists $ushell ; then + info "Using default shell ${defaultshell}." + ushell="$defaultshell" + fi + fi if [ -z "$fflag" ]; then echo -n "Shell ($shells) [`basename $ushell`]: " @@ -345,12 +402,17 @@ get_shell() { _input="`echo "$fileline" | cut -f9 -d:`" fi if [ -n "$_input" ]; then - _fullpath=`fullpath_from_shell $_input` - if [ -n "$_fullpath" ]; then - ushell="$_fullpath" + if [ -n "$Sflag" ]; then + ushell="$_input" else - err "Invalid shell selection. Using default shell ${defaultshell}." - ushell="$defaultshell" + _fullpath=`fullpath_from_shell $_input` + if [ -n "$_fullpath" ]; then + ushell="$_fullpath" + else + err "Invalid shell ($_input) for user $username." + info "Using default shell ${defaultshell}." + ushell="$defaultshell" + fi fi fi } @@ -430,25 +492,23 @@ get_class() { # get_logingroup # Reads user's login group. Can be used in both interactive and batch # modes. The specified value can be a group name or its numeric id. -# This routine leaves the field blank if nothing is provided. The pw(8) -# command will then provide a login group with the same name as the username. +# This routine leaves the field blank if nothing is provided and +# a default login group has not been set. The pw(8) command +# will then provide a login group with the same name as the username. # get_logingroup() { - ulogingroup= + ulogingroup="$defaultLgroup" _input= - # No need to take down a login group for a configuration saving run. - [ -n "$configflag" ] && return - if [ -z "$fflag" ]; then - echo -n "Login group [$username]: " + echo -n "Login group [${ulogingroup:-$username}]: " read _input else _input="`echo "$fileline" | cut -f3 -d:`" fi # Pw(8) will use the username as login group if it's left empty - [ -n "$_input" ] && ulogingroup="$_input" || ulogingroup= + [ -n "$_input" ] && ulogingroup="$_input" } # get_groups @@ -528,7 +588,6 @@ input_from_file() { while read -r fileline ; do case "$fileline" in \#*|'') - return 0 ;; esac @@ -558,6 +617,8 @@ input_interactive() { _random="no" _emptypass="no" _usepass="yes" + _logingroup_ok="no" + _groups_ok="no" case $passwdtype in none) _emptypass="yes" @@ -629,14 +690,14 @@ input_interactive() { ;; esac passwdtype="yes" - [ -n "$configrun" ] && break + [ -n "$configflag" ] && break trap 'stty echo; exit' 0 1 2 3 15 stty -echo echo -n "Enter password: " read -r upass echo'' echo -n "Enter password again: " - read _passconfirm + read -r _passconfirm echo '' stty echo # if user entered a blank password @@ -711,7 +772,7 @@ input_interactive() { [ -z "$configflag" ] && printf "%-10s : %s\n" "Full Name" "$ugecos" [ -z "$configflag" ] && printf "%-10s : %s\n" "Uid" "$uuid" printf "%-10s : %s\n" "Class" "$uclass" - [ -z "$configflag" ] && printf "%-10s : %s %s\n" "Groups" "${ulogingroup:-$username}" "$ugroups" + printf "%-10s : %s %s\n" "Groups" "${ulogingroup:-$username}" "$ugroups" printf "%-10s : %s\n" "Home" "$uhome" printf "%-10s : %s\n" "Shell" "$ushell" printf "%-10s : %s\n" "Locked" "$_disable" @@ -734,7 +795,7 @@ input_interactive() { return 0 } -#### END SUBROUTINE DEFENITION #### +#### END SUBROUTINE DEFINITION #### THISCMD=`/usr/bin/basename $0` DEFAULTSHELL=/bin/sh @@ -742,6 +803,9 @@ ADDUSERCONF="${ADDUSERCONF:-/etc/adduser.conf}" PWCMD="${PWCMD:-/usr/sbin/pw}" MAILCMD="${MAILCMD:-mail}" ETCSHELLS="${ETCSHELLS:-/etc/shells}" +NOHOME="/nonexistent" +NOLOGIN="nologin" +NOLOGIN_PATH="/usr/sbin/nologin" GREPCMD="/usr/bin/grep" DATECMD="/bin/date" @@ -769,13 +833,16 @@ configflag= fflag= infile= disableflag= +Dflag= +Sflag= readconfig="yes" homeprefix="/home" randompass= fileline= savedpwtype= defaultclass= -defaultgoups= +defaultLgroup= +defaultgroups= defaultshell="${DEFAULTSHELL}" # Make sure the user running this program is root. This isn't a security @@ -820,6 +887,10 @@ for _switch ; do configflag=yes shift ;; + -D) + Dflag=yes + shift + ;; -E) disableflag=yes shift @@ -833,6 +904,10 @@ for _switch ; do fflag=yes shift; shift ;; + -g) + defaultLgroup="$2" + shift; shift + ;; -G) defaultgroups="$2" shift; shift @@ -881,6 +956,10 @@ for _switch ; do defaultshell="`fullpath_from_shell $2`" shift; shift ;; + -S) + Sflag=yes + shift + ;; -u) uidstart=$2 shift; shift @@ -904,7 +983,11 @@ if [ -n "$fflag" ]; then else input_interactive while : ; do - echo -n "Add another user? (yes/no): " + if [ -z "$configflag" ]; then + echo -n "Add another user? (yes/no): " + else + echo -n "Re-edit the default configuration? (yes/no): " + fi read _input case $_input in [Yy][Ee][Ss]|[Yy][Ee]|[Yy])