#!/bin/sh
##
## UNIX user account admin script to provide a common interface
## Copyright (c) 2008 SATOH Fumiyasu @ OSS Technology, Inc.
##               <http://www.osstech.co.jp/>
##
## Licese: GNU General Public License version 2
## Date: 2008-02-27, since 2008-02-25
##

## FIXME: Test on Solaris
## FIXME: Add support smbldap-tools?
## FIXME: `groupadd -K KEY=VALUE` is not supported on RHEL4

set -u
umask 0022

LC_ALL=C
PATH="/opt/osstech/bin:/opt/osstech/sbin:/usr/sbin:/usr/bin:/bin:/sbin"
export LC_ALL PATH

## Functions
## ======================================================================

pinfo()
{
  echo "$0: INFO: $1" 1>&2
}

pwarn()
{
  echo "$0: WARNING: $1" 1>&2
}

perr()
{
  echo "$0: ERROR: $1" 1>&2
}

pdie()
{
  perr "$1"
  exit ${2-1}
}

run()
{
  [ "$#" -gt 0 ] && [ -n "${flag_verbose-}" ] && pinfo "run: $*"
  [ -z "$flag_run" ] && return 0
  ${1+"$@"}
  return $?
}

run_or_die()
{
  run ${1+"$@"}
  _run_status="$?"
  [ "$_run_status" -ne 0 ] && pdie "command failed ($_run_status): $*"
}

## Options
## ======================================================================

flag_verbose=""
flag_run="yes"

login_new=""
password_hash=""
uid=""
uid_min=""
uid_max=""
group=""
groups=""
comment=""
home_dir=""
skeleton_dir=""
flag_create_home=""
flag_no_create_home="yes"
flag_remove_home=""
shell=""

case "`uname`" in
Linux)
  if [ -f /etc/debian_version ]; then
    useradd_no_create_home_opt=""
  else
    useradd_no_create_home_opt="-M"
  fi
  ;;
*)
  useradd_no_create_home_opt=""
  ;;
esac

cmd_usage="Usage: $0 OPERATION [OPTIONS] LOGIN"

## Command-line options
## ----------------------------------------------------------------------

if [ $# -lt 2 ]; then
  echo "$cmd_usage"
  exit 0
fi
op_name="$1"; shift

getopts_want_arg()
{
  if [ "$1" -eq 0 ]; then
    pdie "option requires an argument: $2" 1>&2
  fi
}

while test "$#" -gt 0; do
  opt="$1"; shift
  case "$opt" in
  -v|--verbose)
    flag_verbose="yes"
    ;;
  --no-run)
    flag_run=""
    ;;
  -l|--login)
    getopts_want_arg "$#" "$opt"
    login_new="$1"; shift
    ;;
  -p|--password)
    getopts_want_arg "$#" "$opt"
    password_hash="$1"; shift
    ;;
  -u|--uid)
    getopts_want_arg "$#" "$opt"
    uid="$1"; shift
    ;;
  --uid-min)
    getopts_want_arg "$#" "$opt"
    uid_min="$1"; shift
    ;;
  --uid-max)
    getopts_want_arg "$#" "$opt"
    uid_max="$1"; shift
    ;;
  -g|--group)
    getopts_want_arg "$#" "$opt"
    group="$1"; shift
    ;;
  -G|--groups)
    getopts_want_arg "$#" "$opt"
    groups="$1"; shift
    ;;
  -c|--comment)
    getopts_want_arg "$#" "$opt"
    comment="$1"; shift
    ;;
  -d|--home)
    getopts_want_arg "$#" "$opt"
    home_dir="$1"; shift
    ;;
  -k|--skeleton)
    getopts_want_arg "$#" "$opt"
    skeleton_dir="$1"; shift
    ;;
  -m|--create-home)
    flag_create_home="yes"
    flag_no_create_home=""
    ;;
  -M|--no-create-home)
    flag_create_home=""
    flag_no_create_home="yes"
    ;;
  -r|--remove-home)
    flag_remove_home="yes"
    ;;
  -s|--shell)
    getopts_want_arg "$#" "$opt"
    shell="$1"; shift
    ;;
  --)
    break
    ;;
  -*)
    pdie "invalid option: $opt" 1>&2
    exit 1
    ;;
  *)
    set -- "$opt" ${1+"$@"}
    break
    ;;
  esac
done

if [ $# -ne 1 ]; then
  echo "$cmd_usage"
  exit 0
fi
login="$1"; shift

case "$op_name" in
add)
  run_or_die /usr/sbin/useradd \
    ${password_hash:+-p "$password_hash"} \
    ${uid:+-u "$uid"} \
    ${uid_min:+-K UID_MIN="$uid_min"} \
    ${uid_max:+-K UID_MAX="$uid_max"} \
    ${group:+-g "$group"} \
    ${groups:+-G "$groups"} \
    ${comment:+-c "$comment"} \
    ${home_dir:+-d "$home_dir"} \
    ${skeleton_dir:+-k "$skeleton_dir"} \
    ${flag_create_home:+-m} \
    ${flag_no_create_home:+$useradd_no_create_home_opt} \
    ${shell:+-s "$shell"} \
    "$login"
  ;;
modify)
  run_or_die /usr/sbin/usermod \
    ${password_hash:+-p "$password_hash"} \
    ${login_new:+-l "$login_new"} \
    ${uid:+-u "$uid"} \
    ${group:+-g "$group"} \
    ${groups:+-G "$groups"} \
    ${comment:+-c "$comment"} \
    ${home_dir:+-d "$home_dir"} \
    ${flag_create_home:+-m} \
    ${shell:+-s "$shell"} \
    "$login"
  ;;
delete)
  run_or_die /usr/sbin/userdel \
    ${flag_remove_home:+-r} \
    "$login"
  ;;
*)
  pdie "invalid operation name: $op_name"
  ;;
esac

exit 0

