summaryrefslogtreecommitdiff
path: root/mass_passwd
blob: 2eff7e7cd668dffbebfed3ae3fbd7bf799a4fbf0 (plain)
  1. #!/bin/sh
  2. # Script origin: http://www.tuxcomputing.com/cookbook/mass_passwd
  3. # Original timestamp: 2004-12-15 23:36
  4. ## Mass Password Change for Linux
  5. ## This requires the Shadow Suite utilities.
  6. ## Usage:
  7. ## mass_passwd username username ...
  8. ## mass_passwd -g groupname groupname ...
  9. ## mass_passwd -a
  10. ##
  11. ## This program is free software; you can redistribute it and/or
  12. ## modify it under the terms of the GNU General Public License
  13. ## as published by the Free Software Foundation; either version 2
  14. ## of the License, or (at your option) any later version.
  15. ##
  16. ## This program is distributed in the hope that it will be useful,
  17. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. ## GNU General Public License for more details.
  20. ## http://www.fsf.org/licenses/gpl.html
  21. ######################################################################
  22. ## This is where the "username.passwd.txt" files will be dumped
  23. ## It will be created if it doesn't already exist
  24. text_file_dir=$HOME/mass_passwds
  25. log_file=mass_passwd.log
  26. ## Minimum userid considered a regular (human) user
  27. min_uid=1000
  28. ## Length of generated passwords
  29. pass_len=8
  30. ## Length of time, in days, before a password expires
  31. pass_expire=90
  32. ######################################################################
  33. ## Few user-serviceable parts inside.
  34. ## You may wish to edit the text between the two --------- lines, below.
  35. # Get the name of this program (probably "mass_passwd")
  36. prog=${0##*/}
  37. usage () {
  38. echo "usage: $prog [-v] [-n] username ..."
  39. echo " $prog [-v] [-n] [-g] groupname ..."
  40. echo " $prog [-v] [-n] [-a]"
  41. echo " -g change passwords of everyone in a group"
  42. echo " -a change everyone's password"
  43. echo " -v verbose"
  44. echo " -n don't do it, just simulate (implies -v)"
  45. exit 0
  46. }
  47. short_usage () {
  48. echo >&2 "usage: $prog [-v] [-g] [-a] name..."
  49. echo >&2 " $prog -h for help"
  50. exit 1
  51. }
  52. # echo something, but only if in verbose mode
  53. vecho () {
  54. test -n "$verbose" && echo "$@"
  55. }
  56. # Generate a random password.
  57. #
  58. # If pwgen is available, use that - that's what it's for, and it works well.
  59. #
  60. # If not, read /dev/urandom and filter out all non-alphanumeric characters
  61. # until we have enough for a password. The numbers in the "tr -d" are ASCII
  62. # values, in octal notation, of ranges of character values to delete.
  63. #
  64. # Using /dev/urandom like this is very inefficient, but who cares?
  65. randompass () {
  66. pwgen $pass_len 1 2>&- ||
  67. tr -d '[\000-\057][\072-\100][\133-\140][\173-\377]' < /dev/urandom |
  68. dd bs=$pass_len count=1 2>&-
  69. }
  70. # Interpret usernames / groupnames / "-a" mode, and return a list of usernames
  71. get_users () {
  72. if [ -n "$all_mode" ]; then
  73. getent passwd | awk -F: '{if ($3 >= '$min_uid') {print $1}}'
  74. return
  75. fi
  76. if [ -z "$group_mode" ]; then
  77. echo "$@"
  78. return
  79. fi
  80. # ok, we're in group mode, must look up the users who belong to a group
  81. while [ -n "$1" ]; do
  82. g_ent=$(getent group "$1" 2>&-)
  83. if [ -z "$g_ent" ]; then
  84. echo >&2 "warning: $1: group not found"
  85. continue
  86. fi
  87. members=${g_ent##*:}
  88. gid=${g_ent%:*}
  89. gid=${gid##*:}
  90. echo "$members" | tr ',' ' '
  91. getent passwd | awk -F: '{if ($4 == '$gid') { print $1 } }'
  92. shift
  93. done
  94. }
  95. ######################################################################
  96. ## main body
  97. group_mode=; verbose=; all_mode=; simulate=; eol=;
  98. while [ -z "$eol" ]; do
  99. case "$1" in
  100. -g) group_mode=1; shift ;;
  101. -v) verbose=1; shift ;;
  102. -a) all_mode=1; shift ;;
  103. -n) simulate=true; verbose=1; shift ;;
  104. -M) mass_out=1; shift ;; # we're called from mass_useradd
  105. -h | -? | --help) usage ;;
  106. --) eol=1; shift ;;
  107. -*) short_usage ;;
  108. *) eol=1 ;;
  109. esac
  110. done
  111. # Set up a secure environment and the directory for printable text files
  112. PATH=/usr/sbin:/usr/bin:$PATH
  113. umask 077
  114. mkdir -p $text_file_dir
  115. cd $text_file_dir
  116. processed=0
  117. for u in $(get_users "$@"); do
  118. vecho -n "generating password for $u..."
  119. pass=$(randompass)
  120. echo "$u:$pass" | eval $simulate chpasswd
  121. vecho -n "."
  122. eval $simulate chage -M $pass_expire -d 2003-01-01 $u
  123. vecho -n "."
  124. rm -f $u.passwd.txt
  125. echo > $u.passwd.txt "\
  126. ----------------------------------------------------------------------
  127. Login name: $u
  128. Password: $pass
  129. Please log in and change your password; the system should
  130. prompt you to do this when you log in. You can change your
  131. password at any time with the 'passwd' command.
  132. Choose a strong password - everyday words, birthdays,
  133. names of people or animals, all these are too easy to guess.
  134. Also, DO NOT give your password to anyone, ever. The IT
  135. staff will never ask you for your password, and neither
  136. should anyone else. You will be held responsible for all
  137. activity done via your account.
  138. ----------------------------------------------------------------------"
  139. printf >> $log_file "$(date) %-12s %s\\n" $u $pass
  140. vecho "$pass"
  141. if [ -n "$mass_out" ]; then
  142. uid=$(getent passwd $u | cut -f3 -d:)
  143. /bin/echo -e "$u\\t$pass\\t$uid"
  144. fi
  145. processed=$(expr $processed + 1)
  146. done
  147. if [ $processed -gt 0 ]; then
  148. test -z "$mass_out" &&
  149. echo >&2 "$processed password(s) reset - see $text_file_dir/$log_file"
  150. else
  151. echo >&2 "no users specified - see '$prog -h' for help"
  152. fi