You might be interested in this also:
#!/bin/bash
#
#'usercreate' script version 0.5 by Ben Tisdall.
#
# Incorporates password generator code by Antoni Sawicki <tenox@tenox.tc>
#
http://www.tenox.tc/
# This script attempts to create UNIX, Samba & Scalix accounts
# for a single user in one step based on interactively-supplied
# information. It does its best to validate the user input & should
# not get as far as attempting to create a UNIX or Scalix user with
# an ID that already exists. It also tries not to leave a mess for the
# Sysadmin by trying to clean after itself in the event
# that, say, the UNIX user creation step succeeds but the
# Scalix user creation step fails.
# REQUIREMENTS
#
# BASH & standard UNIX utils.
#
# Tested using bash on FC-4 & Centos 4.
# Set the config file
#
CONFFILE=/etc/usercreate.conf
#######################################
# #
# UTILITY FUNCTIONS UTILITY FUNCTIONS #
# #
#######################################
# Validate boolean config opts
#
function check_bopts () {
for opt in $GENPASSWD $SETUNIXPASSWD $MAILACC; do
case ${opt%$opt=} in
0 | 1 );;
* ) echo -e "\nInvalid value found in Section 1 of $CONFFILE."
quit
exit 1
esac
done
}
# Confirm answers to questions
#
function confirm () {
REPLY=""
while [ -z $REPLY ]; do
echo -e ":\c"
read
case $REPLY in
[yY] ) YES=Y;;
[nN] ) YES="";;
* ) echo -e "\nPlease enter Y (Yes) or N (No)."; REPLY="";;
esac
done
}
# Transpose a text string to propercase
#
function propercase () {
echo $(echo ${1:0:1} | tr [[:lower:]] [[:upper:]])$(echo ${1:1} | tr [[:upper:]] [[:lower:]])
}
# Transpose a text string to uppercase
#
function upcase () {
tr [[:lower:]] [[:upper:]]
}
# Transpose a text string to lowercase
#
function downcase () {
tr [[:upper:]] [[:lower:]]
}
# Check an ID generated/gathered here against the UNIX password database & the Scalix directory.
#
function check_id () {
CHECKID=$1
if id $CHECKID > /dev/null 2>&1 || $SXBINDIR/omshowu $CHECKID >/dev/null 2>&1; then
return 0
else
return 1
fi
}
# See how many Enterprise users we have on the system (thanks Dave!)
#
function countfullusers () {
$SXBINDIR/omsearch -d USERLIST -t H -s -e ul-class=full | wc -l
}
# Can we create another Enterprise user?
#
function checkfullusers () {
if [ $(countfullusers) -ge $ALLOWEDFULLUSERS ]; then
return 0
else
return 1
fi
}
# Random password generator for GNU BASH 2.0x,
# Copyright (c) 2002 by Antoni Sawicki <tenox@tenox.tc>
#
http://www.tenox.tc/
function passgen () {
PASSWD=''
echo -e "\nGenerating password..."
M="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
L="8"
while [ $L -gt 0 ]; do
PASSWD="$PASSWD${M:$(($RANDOM%${#M})):1}"
let L-=1
done
return 0
}
function errorlevel () {
let ERRLEVEL+=$1
}
# Important functions increment the error level by 1000 if they fail.
# Check the error level and if > 1000 clean up and exit.
#
function errorcheck () {
if [ $ERRLEVEL -ge 1000 ]; then
bailout
return 1
else
return 0
fi
}
function quit () {
echo -e "\nQuitting...\n"
sleep 1
}
#######################################################
# #
# INPUT GATHERING FUNCTIONS INPUT GATHERING FUNCTIONS #
# #
#######################################################
# Obtain the new user's real name
#
function get_realname () {
local MAINLOOP=""
while [ -z $MAINLOOP ]; do
FIRSTN=""
while [ -z $FIRSTN ]; do
echo -e "\nEnter firstname\n:\c"
read FIRSTN
if
echo "$FIRSTN" | grep -qv "$LEGALNAME"; then
echo -e "\nSorry, firstnames must consist of between 2-16 letters only."
FIRSTN=""
fi
done
FIRSTN=$(propercase $FIRSTN)
local LOOP1=""
while [ -z $LOOP1 ]; do
echo -e "\nEnter middle initial or leave blank\n:\c"
read MIDIN
if echo "$MIDIN" | grep -qv "$LEGALINIT"; then
echo -e "\nSorry, middle initial should either be blank or a single letter only."
LOOP1=""
else
LOOP1=1
fi
done
MIDIN=$(propercase $MIDIN)
SURN=""
while [ -z $SURN ]; do
echo -e "\nEnter surname\n:\c"
read SURN
if echo "$SURN" | grep -qv "$LEGALNAME"; then
echo -e "\nSorry, surnames must consist of between 2-16 letters only."
SURN=""
fi
done
SURN=$(propercase $SURN)
echo -e "\nYou've entered: $FIRSTN ${MIDIN:+$MIDIN }$SURN"
echo -e "\nIs this correct? [Y/N]"
confirm; [ $YES ] && MAINLOOP=1
done
autogen_id
return 0
}
# Have a simple-minded attempt at generating a user ID based on the real name
#
function autogen_id () {
IDA=$(echo $FIRSTN.$SURN | downcase)
IDB=$(echo $FIRSTN$MIDIN.$SURN | downcase)
echo -e "\nAttempting to automatically generate a user ID based on name..."
sleep 0.3
if check_id $IDA && [ -z $MIDIN ]; then
echo -e "\nSorry, ID $IDA is already in use."; get_id
elif
check_id $IDA && check_id $IDB; then
echo -e "\nSorry, IDs $IDA & $IDB are already in use."; get_id
elif
check_id $IDA; then
echo -e "\nUser $IDA is already in use, would you like to use $IDB as the username? [Y/N]\n"
confirm
if [ $YES ]; then
ID=$IDB
echo -e "\nUser ID set to \"$ID\"."
else
get_id
fi
else
ID=$IDA
echo -e "\nUser ID set to \"$ID\"."
fi
return 0
}
# Get the user ID from user input
# Modify the '$LEGALID' variable at the top of the script if you need to.
#
function get_id () {
sleep 0.3
ID=""
while [ -z "$ID" ]; do
echo -e "\nPlease enter a user ID in the form of 2-16 letters or numbers,\na dot, followed by 2-16 more letters or numbers."
echo -e "\ne.g. lara.bloggs\n:\c"
read ID
if echo "$ID" | grep -qv "$LEGALID"; then
sleep 0.3
echo -e "\nSorry, that ID is not allowed."
ID=""
fi
if [ $ID ]; then
echo -e "\nYou've chosen $ID, is this correct? [Y/N]"
confirm
[ $YES ] && check_id $ID && echo -e "\nSorry, username $ID is already in use." && ID=""
fi
done
ID=$(echo $ID | downcase)
return 0
}
# Get the password
# Modify the '$LEGALPASSWD' variable at the top of the script if you need to
#
function get_passwd () {
PASSWD=""
while [ -z $PASSWD ]; do
PASSWDA=""
while [ -z $PASSWDA ]; do
echo -e "\nPlease enter a password of at least 8 characters.\n:\c"
read -s PASSWDA
if echo "$PASSWDA" | grep -qv "$LEGALPASSWD"; then
echo -e "\nSorry, the password you entered isn't long enough."
PASSWDA=""
fi
done
echo -e "\n\nPlease re-enter the password.\n:\c"
read -s PASSWDB
if [ "$PASSWDA" != "$PASSWDB" ]; then
echo -e "\n\nSorry, the passwords you entered don't match."
PASSWD=""
else
PASSWD=$PASSWDA
fi
done
echo -e ""
}
# Set user class, i.e. 'Enterprise' (can use Scalix Connect/Outlook)
# or 'Community' (SWA/IMAP/POP3 only).
#
function get_class () {
echo -e "\n***INFO***: This section sets Outlook capability for the user."
if checkfullusers; then
echo -e "\nThe maximum number of Outlook users ($ALLOWEDFULLUSERS) already exists."
echo -e "\nThis user will be only able to access mail via SWA (webmail) or $ALTCLIENTS."
echo -e "\nPlease contact the System Administrator to enable Outlook access for this user."
CLASS=limited; OL=NO
else
echo -e "\nThere are currently $(countfullusers) Outlook users out of a possible $ALLOWEDFULLUSERS on this system."
sleep 0.3
echo -e "\nDoes the user require Outlook access? [Y/N]"
confirm
if [ $YES ]; then
CLASS=full; OL=YES
else
CLASS=limited; OL=NO
fi
fi
}
# Build a comma-separated list of UNIX groups the user will belong to
# derived from the "$GRPS" variable set at the top of the script.
#
function get_unixgroups () {
echo -e "\n***INFO***: GROUP MEMBERSHIPS give read &/or write access to different document folders."
echo -e "\nFor example all members of the \"staff\" Group can read & write in the \"staff\" folder."
sleep 0.3
SELGRPS="$DEFAULTGRPS"
for grp in $GRPS; do
echo -e "\nMake user a member of the \"${grp%,}\" group? [Y/N]"
confirm
[ $YES ] && SELGRPS="${SELGRPS:+$SELGRPS, }${grp%,}"
done
return 0
}
# Build a comma-separated list of Scalix DLs that the user will belong to
# derived from the "$DLS" variable set at the top of the script.
#
function get_scalixdls () {
echo -e "\n***INFO***: DISTRIBUTION LISTS manage groups of users on the email system."
echo -e "\nFor example all members of the \"Staff\" Distribution List get email addressed to \"staff@$MAILDOMAIN\"."
sleep 0.3
SELDLS=""
for list in $DLS; do
echo -e "\nMake user a member of the \"${list%,}\" Distribution list? [Y/N]"
confirm
[ $YES ] && SELDLS="${SELDLS:+$SELDLS, }${list%,}"
done
return 0
}
# Do all the input gathering functions
#
function get_all () {
if [ $GENPASSWD -eq 0 ]; then
SETPASSWD=passgen
PASSWDOPT=Generate
else
SETPASSWD=get_passwd
PASSWDOPT=Choose
fi
GATHERFUNCS="get_realname get_class get_scalixdls get_unixgroups $SETPASSWD"
for function in $GATHERFUNCS; do
$function
done
}
#####################################
# #
# DISPLAY/OPTION FUNCTIONS #
# #
#####################################
# Opening titles.
#
function intro () {
echo -e "\n"
echo -e "*******************************************"
echo -e "* *"
echo -e "* USERCREATE SCRIPT BY BEN TISDALL 2006 *"
echo -e "* *"
echo -e "*******************************************"
echo -e "\nThis script will gather the information required &"
echo -e "perform the steps necessary to create a system user."
sleep 0.3
}
# Display the information gathered
#
function display_all () {
sleep 0.3
echo -e "\n\n***********************"
echo -e "* INFORMATION SUMMARY *"
echo -e "***********************\n"
echo -e "Name: $FIRSTN $SURN"
echo -e "Scalix & Windows user ID: $ID"
echo -e "Email: $ID@$MAILDOMAIN (this is automatically set from the user ID)"
echo -e "Password: $PASSWD"
echo -e "Outlook: $OL"
echo -e "Scalix distribution lists: ${SELDLS:-NONE}."
echo -e "Groups for document access: ${SELGRPS:-MINIMUM ACCESS ONLY}."
}
# A menu to access the individual gathering functions discretely
#
function option_menu () {
display_all
sleep 0.3
echo -e "\n\nNOW PLEASE ENTER ONE OF THE FOLLOWING OPTIONS:\n"
echo -e "[C] Create the user account."
echo -e "[S] Start over."
echo -e "[1] Re-enter name."
echo -e "[2] Choose a new user ID."
echo -e "[3] Select Outlook ON/OFF."
echo -e "[4] Select Scalix distribution lists."
echo -e "[5] Select groups for document access."
echo -e "[6] $PASSWDOPT a new password."
echo -e "[Q] Quit without doing anything."
echo -e "\n:\c"
read OPTREPLY
case $OPTREPLY in
1 ) get_realname && option_menu;;
2 ) get_id && option_menu;;
3 ) get_class && option_menu;;
4 ) get_scalixdls && option_menu;;
5 ) get_unixgroups && option_menu;;
6 ) $SETPASSWD && option_menu;;
[cC] ) create_accs;;
[sS] ) get_all && option_menu;;
[qQ] ) quit; exit 0;;
* ) echo -e "\nSorry, that selection is invalid." && sleep 0.3 && option_menu;;
esac
}
#######################################
# #
# ACTUALLY DO THINGS TO THE SYSTEM!!! #
# #
#######################################
# Create a UNIX account for the new user
#
function add_unixuser () {
echo -e "\nCreating UNIX user \"$ID\"... \c"
sleep 0.3
for grp in $SELGRPS; do
USEGRPS=${USEGRPS:+$USEGRPS,}${grp%,}
done
if /usr/sbin/useradd $ID -G "$USEGRPS" > /dev/null 2>> $ERRORLOG; then
UNDOLIST="add_unixuser${UNDOLIST:+ $UNDOLIST}"
else
errorlevel 1000
fi
return 0
}
# Delete the UNIX user if 'backtrack' is invoked.
#
function undo_add_unixuser () {
userdel -r $ID
}
function set_smbpasswd () {
echo -e "\nCreating Windows user \"$ID\"... \c"
if (echo "$PASSWD"; echo "$PASSWD") | smbpasswd -as "$ID" > /dev/null 2>> $ERRORLOG; then
#echo -e "DONE."
UNDOLIST="set_smbpasswd${UNDOLIST:+ $UNDOLIST}"
else
errorlevel 1000
fi
}
# Delete the Samba user if 'backtrack' is invoked.
#
function undo_set_smbpasswd () {
smbpasswd -x $ID
}
function set_unixpasswd () {
echo -e "\nSetting UNIX password for user \"$ID\"... \c"
echo "$ID:$PASSWD" | chpasswd > /dev/null 2>> $ERRORLOG || errorlevel 1000
}
# Create a Scalix account for the user
#
function add_sxuser () {
echo -e "\nCreating Scalix user \"$ID\"... \c"
sleep 0.3
if $SXBINDIR/omaddu -n "$FIRSTN $SURN/$MAILNODE/IA=$ID@$MAILDOMAIN" -u $ID -p $PASSWD --class $CLASS $ID > /dev/null 2>> $ERRORLOG; then
#echo -e "DONE."
UNDOLIST="add_sxuser${UNDOLIST:+ $UNDOLIST}"
else
errorlevel 1000
fi
}
# Delete the Scalix user if 'backtrack' is invoked.
#
function undo_add_sxuser () {
$SXBINDIR/omdelu $ID
}
# Add the user to the chosen PDLs
#
function add_sxpdls () {
echo -e "\nAdding \"$ID\" to the selected Scalix PDLs... \c"
for list in $SELDLS; do
$SXBINDIR/omaddpdln -l ${list%,} -n "$FIRSTN $SURN/$MAILNODE" > /dev/null 2>> $ERRORLOG
done
if ! [ $? -eq 0 ]; then
echo -e "\n\n(There was a problem adding the user to some Scalix PDLs but the account is functional).\n"
errorlevel 1
fi
}
# Mail the account details.
#
function mailacc () {
echo -e "\nMailing the account details to the Admin list... \c"
umask 0077
cat > $MAILOK <<-EOF
This is the "$(basename $0)" script at $HOSTNAME.
A new system user was created with the following details:
Name: $FIRSTN ${MIDIN:+$MIDIN }$SURN
Email address: $ID@$MAILDOMAIN
Scalix & Windows ID: $ID
Scalix, Windows${UNIXOPT:+, $UNIXOPT} password: $PASSWD
Outlook capability: $OL
Mailserver name for setting up Outlook: $MAILHOST
Scalix Distribution Lists: ${SELDLS:-NONE}.
Groups for document access: ${SELGRPS:-MINIMUM ACCESS ONLY}.
The user can change their Scalix password by visiting: $SXPASSWDURL
To change the Windows password they can press CTRL-ALT-DEL after logging in & click 'Change Password'.
Please be aware that this Scalix version allows $ALLOWEDFULLUSERS users with Outlook capability & there are currently $(countfullusers) such users on the system.
EOF
if [ $ERRLEVEL -gt 0 ]; then
cat >> $MAILOK <<-EOF
Some minor errors occurred, but the accounts were created anyway & should be functional.
The errors were:
EOF
cat $ERRORLOG >> $MAILOK
fi
mail -s "New user $ID created" $ADMINLIST < $MAILOK && echo -e "DONE."
rm $MAILOK
}
# Invoked when something important didn't succeed.
#
function bailout () {
sleep 0.3
echo -e "\nSorry, the script was not able to create the requested accounts."
echo -e "\nPlease contact the System Administrator."
backtrack # Try to clear up.
mailerrs # Mail the bad news.
quit
exit 1
}
# Try to clear up if we didn't completely succeed.
#
function backtrack () {
echo -e "\nCleaning up..."
sleep 0.3
for function in $UNDOLIST; do
undo_$function > /dev/null 2>>$ERRORLOG
done
}
#Account creation control function
#
#
function create_accs () {
if [ $SETUNIXPASSWD -eq 0 ]; then
setunixpw=set_unixpasswd
UNIXOPT=UNIX
fi
CREATEFUNCS="add_unixuser $setunixpw set_smbpasswd add_sxuser add_sxpdls"
sleep 0.3
let ERRLEVEL=0
for function in $CREATEFUNCS; do
$function
if errorcheck; then
sleep 0.3
echo -e "DONE."
fi
done
end_success
}
# Mail the new account details to the operator, else just quit.
#
function end_success () {
sleep 0.3
echo -e "\nAll accounts successfully created."
if [ $MAILACC -eq 0 ]; then
echo -e "\nMail the details of the new accounts to the Admin List? [Y/N]"
confirm
[ $YES ] && mailacc
fi
quit
return 0
}
# If there's a problem then mail the details.
#
function mailerrs () {
sleep 0.3
echo -e "\nMailing the errors the Admin list..."
cat > $MAILERR <<-EOF
This is the "$(basename $0)" script at $HOSTNAME.
The requested accounts for $ID could not be created.
Please contact the system administrator.
Errors:
EOF
cat $ERRORLOG >> $MAILERR
mail -s "Errors creating new user $ID" $ADMINLIST < $MAILERR
rm $MAILERR
}
#################################
# #
# FIRST RUN FISRT RUN FIRST RUN #
# #
#################################
#
# We must be root
#
if [ $UID -ne 0 ]; then
echo -e "\nSorry, you must be root to run this script"
quit
exit 1
fi
# Read config file & terminate if we don't find it.
#
if [ -r $CONFFILE ]; then
. $CONFFILE
else
echo -e "\nUnable to find configuration file"
quit
exit 1
fi
check_bopts
[ -d $ERRORLOGDIR ] || mkdir -p $ERRORLOGDIR
# Off we go...
#
intro && \
get_all && \
option_menu