Skip to content

Instantly share code, notes, and snippets.

@marcetcheverry
Created March 6, 2016 02:30
Show Gist options
  • Save marcetcheverry/46cfff92f02dfdaf100d to your computer and use it in GitHub Desktop.
Save marcetcheverry/46cfff92f02dfdaf100d to your computer and use it in GitHub Desktop.
beas.sh - Bash Email Admin Script updated for Debian Jessie 8
#!/bin/bash
#####
# beas.sh - Bash Email Admin Script
# Version 0.3 (Jessie edition)
# (c) 2015 Emmanuel Revah - manu-at-manurevah.com
# (c) 2015 Marc - marc@taplightsoftware.com
# This script is made to go with the tutorial found here
# http://workaround.org/ispmail/lenny
# You should inspect it before using it (test it on a test server
# or test database)
# This 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 3 of the License, or
# (at your option) any later version.
#
# DISS 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.
#
# You should have received a copy of the GNU General Public License
# along with DISS. If not, see <http://www.gnu.org/licenses/>.
#####
# This function can be used with MySQL and the Roundcube Password plugin
# http://trac.roundcube.net/browser/github/plugins/password
#
# DELIMITER //
# CREATE FUNCTION `update_password` (old_plain_text_pass text, new_plain_text_pass text, user_email text) RETURNS text CHARSET utf8
# MODIFIES SQL DATA
# BEGIN
# DECLARE error text;
# SET error = "Incorrect current password";
# SELECT '' INTO error FROM virtual_users WHERE email=user_email AND password=CONCAT('{PLAIN-MD5}', MD5(old_plain_text_pass)) LIMIT 1;
# UPDATE virtual_users SET password=CONCAT('{PLAIN-MD5}', MD5(new_plain_text_pass)) WHERE email=user_email AND password=CONCAT('{PLAIN-MD5}', MD5(old_plain_text_pass)) LIMIT 1;
# RETURN error;
# END //
# DELIMITER ;
#####
##!! Configuration !!##
# User and Password for MYSQL
SQLUSER="vmail"
SQLPASS="PASSWORD"
DATABASE="mail"
HOST="127.0.0.1"
DBCON="mysql -u${SQLUSER} -p${SQLPASS} -h${HOST} -ss -e"
# Mail Location - (Old tutorial used to be /home/vmail)
VMAIL="/var/vmail"
# Min and Max chars for usernames
MINMAIL="1"
MAXMAIL="23"
# Min chars for passwords
MINPW="6"
##!! End of configuration !!##
doTheMath () {
COUNTER=1
unset DB
for i in ${QUERY}; do
DB[$COUNTER]=$i
COUNTER=`expr $COUNTER + 1`
done
height=${#DB[@]}
for i in $(seq 1 $height); do
if [ -n "${DB[$i]}" ]; then
echo "$i. ${DB[$i]}"
fi
done
}
doTheMath2 () {
COUNTER=1
unset DB
for i in ${QUERY}; do
DB[$COUNTER]=$i
COUNTER=`expr $COUNTER + 1`
done
COUNTER=1
for i in ${QUERY2}; do
DB2[$COUNTER]=$i
COUNTER=`expr $COUNTER + 1`
done
height=${#DB[@]}
for i in $(seq 1 $height); do
if [ -n "${DB[$i]}" ]; then
echo "$i. ${DB[$i]} => ${DB2[$i]}"
fi
done
}
confirmORdie () {
COUNTER=0
while [ $COUNTER != 2 ]; do
echo -n "Should we continue ? (y/N): "
read GO
if [ -n "${GO}" ]; then break; fi
COUNTER="`expr $COUNTER + 1`"
done
if [ "${GO}" = "y" ] || [ "${GO}" = "Y" ]; then
echo "Continuing..."
else
echo "Going back to main menu... (press enter to proceed)"
read
pickAdomain
fi
}
pressEnter () {
echo ""
echo "Press enter to continue"
read
}
getInput () {
COUNTER=0
if [ "${2}" = "user" ]; then REGEX="^([0-9a-z\.-]{${MINMAIL},${MAXMAIL}})$"; fi
if [ "${2}" = "pw" ]; then REGEX="^.{${MINPW},}$"; fi
if [ "${2}" = "domain" ]; then REGEX="^[a-z0-9\.\-]+$"; fi
if [ "${2}" = "email" ]; then REGEX="^[a-z@0-9\.\-]+$"; fi
echo -n "${1} "
while read ANSWER; do
if [[ "${ANSWER}" =~ ${REGEX} ]] && [ -n "${ANSWER}" ]; then
break
fi
if [ "${COUNTER}" = "0" ]; then
echo "Answer contains forbidden characters,"
echo "you must use:"
if [ "${2}" = "user" ]; then
echo ""
echo "- lower case letters"
echo "- numbers (0-9)"
echo "- between ${MINMAIL} and ${MAXMAIL} characters"
elif [ "${2}" = "pw" ]; then
echo ""
echo "- at least ${MINPW} characters"
elif [ "${2}" = "domain" ]; then
echo ""
echo "- lower case letters"
echo "- numbers"
echo "- \". -\""
elif [ "${2}" = "email" ]; then
echo ""
echo "- lower case letters"
echo "- numbers"
echo "- \".\" and/or \"-\" and/or \"@\""
fi
echo ""
echo -n "${1} "
COUNTER="`expr $COUNTER + 1`"
else
echo " Bad answer please try again"
echo -n "${1} "
fi
done
}
getListInput () {
while read DBNO; do
if [ "${DBNO}" = "q" ] || [ "${DBNO}" = "Q" ]; then exit;
elif [ "${DBNO}" = "a" ] || [ "${DBNO}" = "A" ]; then add${THING}
elif [ "${DBNO}" = "h" ] || [ "${DBNO}" = "H" ]; then pickAdomain
fi
if [ "${THING}" = "Email" ]; then
if [ "${DBNO}" = "l" ] || [ "${DBNO}" = "L" ]; then pickAlias;
elif [ "${DBNO}" = "m" ] || [ "${DBNO}" = "M" ]; then modDomain;
elif [ "${DBNO}" = "d" ] || [ "${DBNO}" = "D" ]; then delDomain;
fi
fi
if [ -n "${DBNO}" ] && [ "${DBNO}" -eq "${DBNO}" > /dev/null 2>&1 ] && (("${DBNO}" >= "1")) && (("${DBNO}" <= $height)); then
break
fi
echo "Bad input, please try again"
echo -n " => "
done
}
genericMenuAddon () {
echo "H. Main menu"
echo "Q. Quit"
echo ""
echo -n " => "
getListInput
}
pickAdomain () {
THING="Domain"
echo ""
echo "+---------------------------+"
echo "| Listing all email domains |"
echo "+---------------------------+"
echo ""
QUERY=`${DBCON} "SELECT name FROM ${DATABASE}.virtual_domains;"|sort`
doTheMath
echo " "
echo "A. Add domain"
genericMenuAddon
DOMAIN="${DB[$DBNO]}"
pickAmail
}
pickAmail () {
THING="Email"
echo ""
echo "+----------------------------------+"
echo "| Listing all accounts from domain | => ${DOMAIN}"
echo "+----------------------------------+"
echo ""
QUERY=`${DBCON} "USE ${DATABASE}; SELECT email FROM virtual_users WHERE email LIKE '%@${DB[$DBNO]}';"`
doTheMath
echo " "
echo "A. Add Email"
echo "L. List Aliases from Domain ${DOMAIN}"
echo "M. Modify Domain ${DOMAIN}"
echo "D. Delete Domain ${DOMAIN}"
genericMenuAddon
EMAIL="${DB[$DBNO]}"
EMAILID=`${DBCON} "USE ${DATABASE}; SELECT id FROM virtual_users WHERE email = '${EMAIL}';"`
showMail
}
pickAlias () {
THING="Alias"
echo ""
echo "+---------------------------------+"
echo "| Listing all aliases from domain | ${DOMAIN}"
echo "+---------------------------------+"
echo ""
QUERY=`${DBCON} "USE ${DATABASE}; select source FROM virtual_aliases WHERE source LIKE '%@${DOMAIN}';"`
QUERY2=`${DBCON} "USE ${DATABASE}; select destination FROM virtual_aliases WHERE source LIKE '%@${DOMAIN}';"`
echo " source => destination"
echo "-------------------------------------------"
doTheMath2
echo " "
echo "A. Add Alias"
genericMenuAddon
ALIAS="${DB[$DBNO]}"
DESTINATION="${DB2[$DBNO]}"
showAlias
}
addDomain () {
getInput "Enter domain to add: " domain
NEWDOMAIN="${ANSWER}"
${DBCON} "USE ${DATABASE}; INSERT INTO virtual_domains ( id , name ) VALUES ( NULL , '${NEWDOMAIN}' );"
echo ""
echo "Domain ${NEWDOMAIN} added."
pressEnter
pickAdomain
}
addEmail () {
getInput "Enter email prefix (without \"@${DOMAIN}\"): " user
NEWMAIL="${ANSWER}"
getInput "Enter password for ${NEWMAIL}@${DOMAIN} : " pw
MAILPASS="${ANSWER}"
echo "creating ${NEWMAIL}@${DOMAIN} pass: ${MAILPASS}"
DOMAINID=`${DBCON} "USE ${DATABASE}; SELECT id FROM virtual_domains WHERE name = '${DOMAIN}';"`
${DBCON} "USE ${DATABASE}; INSERT INTO virtual_users ( id , domain_id , email, password ) VALUES ( NULL , '${DOMAINID}' , '${NEWMAIL}@${DOMAIN}' , CONCAT('{PLAIN-MD5}', MD5('${MAILPASS}')) )";
echo "Done"
echo ""
echo " Acount info:"
echo " user: ${NEWMAIL}@${DOMAIN}"
echo " password: ${MAILPASS}"
pressEnter
pickAdomain
}
addAlias () {
getInput "Enter Alias to add (without \"@${DOMAIN}\"): " user
NEWALIAS="${ANSWER}"
getInput "Enter destination (full email address): " email
NEWDESTINATION="${ANSWER}"
DOMAINID=`${DBCON} "USE ${DATABASE}; SELECT id FROM virtual_domains WHERE name = '${DOMAIN}';"`
${DBCON} "USE ${DATABASE}; INSERT INTO ${DATABASE}.virtual_aliases ( id , domain_id , source , destination ) VALUES (NULL , '${DOMAINID}', '${NEWALIAS}@${DOMAIN}', '${NEWDESTINATION}');"
echo ""
echo "New alias ${NEWALIAS}@${DOMAIN} => ${NEWDESTINATION} added"
pressEnter
pickAdomain
}
showMail () {
echo ""
echo "What do you want to do with ${EMAIL} ?"
echo ""
echo "M. Modify address"
echo "C. Change password"
echo "D. Delete mailbox"
echo "Q. Quit"
echo ""
echo -n "=> "
read ANS
if [ "${ANS}" = "m" ] || [ "${ANS}" = "M" ]; then modEmail;
elif [ "${ANS}" = "c" ] || [ "${ANS}" = "C" ]; then modPass;
elif [ "${ANS}" = "d" ] || [ "${ANS}" = "D" ]; then delEmail;
elif [ "${ANS}" = "q" ] || [ "${ANS}" = "Q" ]; then exit;
fi
pickAdomain
}
showAlias () {
echo ""
echo "What do you want to do with ${ALIAS} => ${DESTINATION} ?"
echo ""
echo "M. Modify Alias"
echo "D. Delete Alias"
echo "Q. Quit"
echo ""
echo -n "=> "
read ANS
DOMAINID=`${DBCON} "USE ${DATABASE}; SELECT id FROM virtual_domains WHERE name = '${DOMAIN}';"`
ALIASID=`${DBCON} "USE ${DATABASE}; SELECT id FROM virtual_aliases WHERE source = '${ALIAS}' AND domain_id = '${DOMAINID}';"`
if [ "${ANS}" = "m" ] || [ "${ANS}" = "M" ]; then modAlias;
elif [ "${ANS}" = "d" ] || [ "${ANS}" = "D" ]; then delAlias;
elif [ "${ANS}" = "q" ] || [ "${ANS}" = "Q" ]; then exit;
fi
pickAdomain
}
delDomain () {
echo ""
echo "WARNING !! This will delete:"
echo ""
echo " - The domain ${DOMAIN}"
echo " - All email accounts on ${DOMAIN}"
echo " - All aliases for ${DOMAIN}"
echo " - All emails in ${VMAIL}/${DOMAIN}"
echo ""
confirmORdie
${DBCON} "USE ${DATABASE}; DELETE FROM virtual_domains WHERE virtual_domains.name = '${DOMAIN}';"
if [ -d "${VMAIL}/${DOMAIN}" ]; then rm -rf ${VMAIL}/${DOMAIN}; fi
echo ""
echo "Domain ${DOMAIN} deleted"
echo ""
pressEnter
pickAdomain
}
delEmail () {
USER=`echo ${EMAIL}|cut -d "@" -f 1`
echo ""
echo "WARNING !! This will delete:"
echo ""
echo " - The email account ${EMAIL}"
echo " - ALL emails in ${VMAIL}/${DOMAIN}/${USER}"
echo ""
confirmORdie
${DBCON} "USE ${DATABASE}; DELETE FROM virtual_users WHERE virtual_users.id = '${EMAILID}';"
if [ -d "${VMAIL}/${DOMAIN}/${USER}" ]; then rm -rf ${VMAIL}/${DOMAIN}/${USER}; fi
echo ""
echo "Account deleted !"
pressEnter
pickAdomain
}
delAlias () {
echo ""
echo "Do you really want to delete the alias ${ALIAS} => ${DESTINATION} ?"
confirmORdie
${DBCON} "USE ${DATABASE}; DELETE FROM virtual_aliases WHERE virtual_aliases.id = '${ALIASID}';"
echo ""
echo "Alias deleted !"
pressEnter
pickAdomain
}
modDomain () {
echo ""
echo "This option changes the domain name and hence will impact all accounts attached to this domain."
echo "Beware that EMAIL ACCOUNTS and ALIASES will NOT be updated from this script."
echo ""
getInput "Enter replacement name for domain ${DOMAIN} : " domain
NEWDOMAIN="${ANSWER}"
DOMAINID=`${DBCON} "SELECT id FROM ${DATABASE}.virtual_domains WHERE name = '${DOMAIN}';"`
${DBCON} "USE ${DATABASE}; UPDATE virtual_domains SET name = '${NEWDOMAIN}' WHERE virtual_domains.id = '${DOMAINID}';"
echo ""
echo "The domain ${DOMAIN} is now ${NEWDOMAIN}."
pressEnter
pickAdomain
}
modEmail () {
echo ""
echo "Modifying email ${EMAIL}. (you should be aware that aliases will not be updated automatically)"
getInput "Enter replacement name (the part before the @ sign): " user
NEWMAIL="${ANSWER}"
DOMAINID=`${DBCON} "SELECT id FROM ${DATABASE}.virtual_users WHERE email = '${EMAIL}';"`
${DBCON} "USE ${DATABASE}; UPDATE virtual_users SET email = '${NEWMAIL}@${DOMAIN}' WHERE virtual_users.id = '${DOMAINID}';"
echo ""
echo "The email address ${EMAIL} is now ${NEWMAIL}@${DOMAIN}"
pressEnter
pickAdomain
}
modPass () {
echo ""
echo "Modifying email ${EMAIL}."
getInput "Enter new password: " pw
NEWPASS="${ANSWER}"
DOMAINID=`${DBCON} "SELECT id FROM ${DATABASE}.virtual_users WHERE email = '${EMAIL}';"`
${DBCON} "USE ${DATABASE}; UPDATE virtual_users SET password = CONCAT('{PLAIN-MD5}', MD5('${NEWPASS}')) WHERE virtual_users.id = '${DOMAINID}';"
echo ""
echo "Password for account ${EMAIL} modified"
pressEnter
pickAdomain
}
modAlias () {
echo ""
echo "Modifying Alias ${ALIAS} => ${DESTINATION}. with id ${ALIASID}"
echo ""
SHORTALIAS=`echo ${ALIAS}|cut -d "@" -f 1`
getInput "Enter new Alias source (without \"@${DOMAIN}\") (was: ${SHORTALIAS}) : " user
NEWALIAS="${ANSWER}@${DOMAIN}"
getInput "Enter new Destination (Complete email address where emails should be sent to): " email
NEWDESTINATION="${ANSWER}"
${DBCON} "USE ${DATABASE}; UPDATE virtual_aliases SET source = '${NEWALIAS}', destination = '${NEWDESTINATION}' WHERE virtual_aliases.id = '${ALIASID}' ;"
echo ""
echo " Old Alias: ${ALIAS} => ${DESTINATION}"
echo " is now"
echo " ${NEWALIAS}@${DOMAIN} => ${NEWDESTINATION}"
pressEnter
pickAdomain
}
echo "
+---------------------------+
| |
| Bash Email Admin Script |
| v. 0.3 |
+---------------------------+"
pickAdomain
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment