#!/bin/sh # Script origin: http://www.tuxcomputing.com/cookbook/mass_passwd # Original timestamp: 2004-12-15 23:36 ## Mass Password Change for Linux ## This requires the Shadow Suite utilities. ## Usage: ## mass_passwd username username ... ## mass_passwd -g groupname groupname ... ## mass_passwd -a ## ## This program is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License ## as published by the Free Software Foundation; either version 2 ## of the License, or (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## http://www.fsf.org/licenses/gpl.html ###################################################################### ## This is where the "username.passwd.txt" files will be dumped ## It will be created if it doesn't already exist text_file_dir=$HOME/mass_passwds log_file=mass_passwd.log ## Minimum userid considered a regular (human) user min_uid=1000 ## Length of generated passwords pass_len=8 ## Length of time, in days, before a password expires pass_expire=90 ###################################################################### ## Few user-serviceable parts inside. ## You may wish to edit the text between the two --------- lines, below. # Get the name of this program (probably "mass_passwd") prog=${0##*/} usage () { echo "usage: $prog [-v] [-n] username ..." echo " $prog [-v] [-n] [-g] groupname ..." echo " $prog [-v] [-n] [-a]" echo " -g change passwords of everyone in a group" echo " -a change everyone's password" echo " -v verbose" echo " -n don't do it, just simulate (implies -v)" exit 0 } short_usage () { echo >&2 "usage: $prog [-v] [-g] [-a] name..." echo >&2 " $prog -h for help" exit 1 } # echo something, but only if in verbose mode vecho () { test -n "$verbose" && echo "$@" } # Generate a random password. # # If pwgen is available, use that - that's what it's for, and it works well. # # If not, read /dev/urandom and filter out all non-alphanumeric characters # until we have enough for a password. The numbers in the "tr -d" are ASCII # values, in octal notation, of ranges of character values to delete. # # Using /dev/urandom like this is very inefficient, but who cares? randompass () { pwgen $pass_len 1 2>&- || tr -d '[\000-\057][\072-\100][\133-\140][\173-\377]' < /dev/urandom | dd bs=$pass_len count=1 2>&- } # Interpret usernames / groupnames / "-a" mode, and return a list of usernames get_users () { if [ -n "$all_mode" ]; then getent passwd | awk -F: '{if ($3 >= '$min_uid') {print $1}}' return fi if [ -z "$group_mode" ]; then echo "$@" return fi # ok, we're in group mode, must look up the users who belong to a group while [ -n "$1" ]; do g_ent=$(getent group "$1" 2>&-) if [ -z "$g_ent" ]; then echo >&2 "warning: $1: group not found" continue fi members=${g_ent##*:} gid=${g_ent%:*} gid=${gid##*:} echo "$members" | tr ',' ' ' getent passwd | awk -F: '{if ($4 == '$gid') { print $1 } }' shift done } ###################################################################### ## main body group_mode=; verbose=; all_mode=; simulate=; eol=; while [ -z "$eol" ]; do case "$1" in -g) group_mode=1; shift ;; -v) verbose=1; shift ;; -a) all_mode=1; shift ;; -n) simulate=true; verbose=1; shift ;; -M) mass_out=1; shift ;; # we're called from mass_useradd -h | -? | --help) usage ;; --) eol=1; shift ;; -*) short_usage ;; *) eol=1 ;; esac done # Set up a secure environment and the directory for printable text files PATH=/usr/sbin:/usr/bin:$PATH umask 077 mkdir -p $text_file_dir cd $text_file_dir processed=0 for u in $(get_users "$@"); do vecho -n "generating password for $u..." pass=$(randompass) echo "$u:$pass" | eval $simulate chpasswd vecho -n "." eval $simulate chage -M $pass_expire -d 2003-01-01 $u vecho -n "." rm -f $u.passwd.txt echo > $u.passwd.txt "\ ---------------------------------------------------------------------- Login name: $u Password: $pass Please log in and change your password; the system should prompt you to do this when you log in. You can change your password at any time with the 'passwd' command. Choose a strong password - everyday words, birthdays, names of people or animals, all these are too easy to guess. Also, DO NOT give your password to anyone, ever. The IT staff will never ask you for your password, and neither should anyone else. You will be held responsible for all activity done via your account. ----------------------------------------------------------------------" printf >> $log_file "$(date) %-12s %s\\n" $u $pass vecho "$pass" if [ -n "$mass_out" ]; then uid=$(getent passwd $u | cut -f3 -d:) /bin/echo -e "$u\\t$pass\\t$uid" fi processed=$(expr $processed + 1) done if [ $processed -gt 0 ]; then test -z "$mass_out" && echo >&2 "$processed password(s) reset - see $text_file_dir/$log_file" else echo >&2 "no users specified - see '$prog -h' for help" fi