summaryrefslogtreecommitdiff
path: root/localadduser
blob: 88f424a5bfc4aeecbd45cccd2f44c2e621f95824 (plain)
  1. #!/bin/sh
  2. #
  3. # /usr/local/bin/localadduser
  4. # Copyright 2003-2006 Jonas Smedegaard <dr@jones.dk>
  5. #
  6. # $Id: localadduser,v 1.5 2006-08-31 22:51:54 jonas Exp $
  7. #
  8. # Execute adduser noninteractively through sudo
  9. #
  10. # TODO: Check for bad arguments
  11. # TODO: Implement --help option
  12. # TODO: Support overriding options in /etc/local file
  13. # TODO: Check gecos field length
  14. # TODO: Check password strength of autogenerated password (and pick another if needed)
  15. # TODO: Deal with non-ASCII chars (transliterate or silence chfn warnings)
  16. # TODO: quiten output: only emit password line by default
  17. # TODO: support reading from file or stdin
  18. # TODO: Implement --update option: apply missing data to existing account
  19. #
  20. set -e
  21. PRG=$(basename "$0")
  22. TEMP="`getopt -s sh -o vqin -l verbose,quiet,interactive,noninteractive,dry-run -n "$PRG" -- "$@"`"
  23. if [ $? != 0 ] ; then echo >&2 "ERROR: Internal getopt error." ; exit 1 ; fi
  24. eval set -- "$TEMP"
  25. verbose=1
  26. interactive=0
  27. while true ; do
  28. case "$1" in
  29. -v|--verbose) verbose=1; shift ;;
  30. -q|--quiet) verbose=0; shift ;;
  31. -i|--interactive) interactive=1; shift ;;
  32. -n|--noninteractive) interactive=0; shift ;;
  33. --dry-run) simulate=true; shift ;;
  34. --) shift ; break ;;
  35. *) echo >&2 "ERROR: Internal error resolving options." ; exit 1 ;;
  36. esac
  37. done
  38. # echo something, but only if in verbose mode
  39. vecho() {
  40. test -n "$verbose" && echo "$@" >&2
  41. }
  42. exit1() {
  43. response="${1:+Error: }${1:-Internal error!}"
  44. echo "$response"
  45. exit 1
  46. }
  47. u=$1
  48. shift
  49. for chunk in $@; do
  50. case $chunk in
  51. @*)
  52. groupchunks="${groupchunks:+$groupchunks }$chunk"
  53. ;;
  54. %*)
  55. officechunks="${officechunks:+$officechunks }$chunk"
  56. ;;
  57. *@*)
  58. other="${other:+$other }$chunk"
  59. ;;
  60. +*)
  61. phone_area="$chunk"
  62. ;;
  63. 0*|1*|2*|3*|4*|5*|6*|7*|8*|9*)
  64. if [ -z "$phone_area" ]; then
  65. exit1 "Phone number provided without leading area code!"
  66. fi
  67. if [ -n "$home_phone" ]; then
  68. exit1 "More than 2 phone numbers provided!"
  69. elif [ -n "$office_phone" ]; then
  70. office_phone="$phone_area $chunk"
  71. else
  72. home_phone="$phone_area $chunk"
  73. fi
  74. phone_area=""
  75. ;;
  76. *)
  77. fullname="${fullname:+$fullname }$chunk"
  78. ;;
  79. esac
  80. done
  81. if getent passwd "$u" | grep -q .; then
  82. exit1 "User \"$u\" already exists!"
  83. fi
  84. if [ -n "$phone_area" ]; then
  85. exit1 "Area code provided without trailing phonenumber!"
  86. fi
  87. for groupchunk in $groupchunks; do
  88. group="$(echo "$groupchunk" | perl -pe 's/^@//;')"
  89. if echo "$group" | perl -ne '/^[a-z][a-z0-9_-]*$/ and exit 1;'; then
  90. exit1 "Group \"$group\" contains illegal characters!"
  91. fi
  92. if ! members="$(getent group "$group")"; then
  93. exit1 "Group \"$group\" does not exist!"
  94. fi
  95. if echo "$members" | perl -pe 's/.*://; s/,/\n/g' | grep -Fxq "$u"; then
  96. exit1 "Group \"$group\" already contains user \"$u\"!"
  97. fi
  98. groups="${groups:+$groups }$group"
  99. done
  100. for officechunk in $officechunks; do
  101. office="${office:+$office }$(echo "$officechunk" | perl -pe 's/^%//;')"
  102. done
  103. if [ ! "$interactive" -gt 0 ]; then
  104. quiet="--quiet"
  105. fi
  106. if [ -n "$fullname$office$office_phone$home_phone$other" ]; then
  107. eval $simulate sudo "/usr/sbin/adduser $quiet --disabled-login --gecos \"$fullname,$office,$office_phone,$home_phone,$other\" \"$u\""
  108. else
  109. if [ ! "$interactive" -gt 0 ]; then
  110. exit1 "Not enough info provided to create account for \"$u\"!"
  111. fi
  112. eval $simulate sudo "/usr/sbin/adduser --disabled-login \"$u\""
  113. fi
  114. for group in $groups; do
  115. eval $simulate sudo "/usr/sbin/adduser $quiet \"$u\" \"$group\""
  116. done
  117. eval $simulate localresetpasswd "$u"
  118. #vecho "Account \"$u\" created succesfully! Password is $pass"