blob: 576714b41543548ff4663bb03a1262dceceae489 (
plain)
- #!/bin/sh
- #
- # /usr/local/bin/localadduser
- # Copyright 2003-2006 Jonas Smedegaard <dr@jones.dk>
- #
- # $Id: localadduser,v 1.5 2006-08-31 22:51:54 jonas Exp $
- #
- # Execute adduser noninteractively through sudo
- #
- # TODO: Check for bad arguments
- # TODO: Implement --help option
- # TODO: Support overriding options in /etc/local file
- # TODO: Check gecos field length
- # TODO: Check password strength of autogenerated password (and pick another if needed)
- # TODO: Deal with non-ASCII chars (transliterate or silence chfn warnings)
- # TODO: quiten output: only emit password line by default
- # TODO: support reading from file or stdin
- # TODO: Implement --update option: apply missing data to existing account
- #
- set -e
- PRG=$(basename "$0")
- TEMP="`getopt -s sh -o vqin -l verbose,quiet,interactive,noninteractive,dry-run -n "$PRG" -- "$@"`"
- if [ $? != 0 ] ; then echo >&2 "ERROR: Internal getopt error." ; exit 1 ; fi
- eval set -- "$TEMP"
- verbose=1
- interactive=0
- while true ; do
- case "$1" in
- -v|--verbose) verbose=1; shift ;;
- -q|--quiet) verbose=0; shift ;;
- -i|--interactive) interactive=1; shift ;;
- -n|--noninteractive) interactive=0; shift ;;
- --dry-run) simulate=true; shift ;;
- --) shift ; break ;;
- *) echo >&2 "ERROR: Internal error resolving options." ; exit 1 ;;
- esac
- done
- # echo something, but only if in verbose mode
- vecho() {
- test -n "$verbose" && echo "$@" >&2
- }
- exit1() {
- response="${1:+Error: }${1:-Internal error!}"
- echo "$response"
- exit 1
- }
- u=$1
- shift
- for chunk in $@; do
- case $chunk in
- @*)
- groupchunks="${groupchunks:+$groupchunks }$chunk"
- ;;
- %*)
- officechunks="${officechunks:+$officechunks }$chunk"
- ;;
- *@*)
- other="${other:+$other }$chunk"
- ;;
- +*)
- phone_area="$chunk"
- ;;
- 0*|1*|2*|3*|4*|5*|6*|7*|8*|9*)
- if [ -z "$phone_area" ]; then
- exit1 "Phone number provided without leading area code!"
- fi
- if [ -n "$home_phone" ]; then
- exit1 "More than 2 phone numbers provided!"
- elif [ -n "$office_phone" ]; then
- office_phone="$phone_area $chunk"
- else
- home_phone="$phone_area $chunk"
- fi
- phone_area=""
- ;;
- *)
- fullname="${fullname:+$fullname }$chunk"
- ;;
- esac
- done
- if getent passwd "$u" | grep -q .; then
- exit1 "User \"$u\" already exists!"
- fi
- if getent group "$u" | grep -q .; then
- exit1 "Group \"$u\" already exists!"
- fi
- if [ -n "$phone_area" ]; then
- exit1 "Area code provided without trailing phonenumber!"
- fi
- for groupchunk in $groupchunks; do
- group="$(echo "$groupchunk" | perl -pe 's/^@//;')"
- if echo "$group" | perl -ne '/^[a-z][a-z0-9_-]*$/ and exit 1;'; then
- exit1 "Group \"$group\" contains illegal characters!"
- fi
- if ! members="$(getent group "$group")"; then
- exit1 "Group \"$group\" does not exist!"
- fi
- if echo "$members" | perl -pe 's/.*://; s/,/\n/g' | grep -Fxq "$u"; then
- exit1 "Group \"$group\" already contains user \"$u\"!"
- fi
- groups="${groups:+$groups }$group"
- done
- for officechunk in $officechunks; do
- office="${office:+$office }$(echo "$officechunk" | perl -pe 's/^%//;')"
- done
- if [ ! "$interactive" -gt 0 ]; then
- quiet="--quiet"
- fi
- sudo=sudo
- [ "$(id -u)" -ne 0 ] || sudo=
- # adduser is too pessimistic on --gecos size
- eval $simulate $sudo "/usr/sbin/adduser $quiet --disabled-login --gecos \"\" \"$u\""
- eval $simulate $sudo "/usr/sbin/usermod -c \"$fullname,$office,$office_phone,$home_phone,$other\" \"$u\""
- for group in $groups; do
- eval $simulate $sudo "/usr/sbin/adduser $quiet \"$u\" \"$group\""
- done
- eval $simulate localresetpasswd "$u"
- #vecho "Account \"$u\" created succesfully! Password is $pass"
|