Postfix Dovecot User Admin Script

While working on a postfix/dovecot non-mysql virtual domain configuration, I needed a simple admin script to add new users. The script below is what I came up with after about 30 minutes.

I was unable to find something that met my needs on the interweb, so I hope this post finds someone else in need!

Please submit bugs/suggestions to: nick.wilkens@mnxsolutions.com


[code]
#!/bin/bash
# bugs/suggestions to: nick.wilkens@mnxsolutions.com
# 1/29/2012

USERSFILE=/etc/dovecot/users
POSTFIXVIRTUAL_MAILBOX=/etc/postfix/virtual_mailbox_maps
POSTFIXVIRTUAL_DOMAINS=/etc/postfix/virtual_domains

function validate_username() {
username=$1
echo $username| egrep -iq ‘([[:alnum:]_.]+@[[:alnum:]_]+?.[[:alpha:].]{2,6})’; RC=$?
if [ ${RC} -ne 0 ]
then
echo "Invalid username, please ensure user@domain.tld format ($RC)"
exit 1
fi
}

function get_username() {
echo -n "Username <user@domain.com>: "
read username
validate_username ${username}
}

function get_password() {
randpw=$(mkpasswd -l 15 -d 3 -C 5)
echo
echo "Password suggestion: ${randpw}"
echo
echo -n "Password: "
read password1
echo -n "Password (again): "
read password2

if [ "${password1}" != "${password2}" ]
then
echo "Passwords miss-match, retry"
get_password
fi
}

function gen_ssha512() {
local password=$1
doveadm pw -s SSHA512 -p "$password"
}

function check_dovecot_user() {
grep -iq $username $USERSFILE; RC=$?
if [ "${RC}" -eq 0 ]
then
echo "User already exists in $USERSFILE, please check."
echo "For reference, or manual editing here was the computed string to use"
echo "${username}:${password}"
exit 1
fi
}

function check_postfix_maps() {
grep -iq $username $POSTFIXVIRTUAL_MAILBOX; RC=$?
if [ "${RC}" -eq 0 ]
then
echo "User already exists in $POSTFIXVIRTUAL_MAILBOX, please check."
echo "For reference, or manual editing here was the computed string to use"
echo
echo "${username} OK"
echo
echo "You will also need to run ‘postmap hash:$POSTFIXVIRTUAL_MAILBOX’ if you edit this file directly"
exit 1
fi
}

function update_postfix_virtual() {
local domain=`echo $username|cut -d@ -f2`
grep -iq $domain $POSTFIXVIRTUAL_DOMAINS; RC=$?

# Add the domain if we don’t find it in grep
if [ "${RC}" -ne 0 ]
then
echo "${domain}" >> $POSTFIXVIRTUAL_DOMAINS
fi
}

get_username
get_password
password=$(gen_ssha512)
check_dovecot_user
check_postfix_maps
update_postfix_virtual

echo "${username}:${password}" >> $USERSFILE
echo "${username} OK" >> $POSTFIXVIRTUAL_MAILBOX

postmap hash:$POSTFIXVIRTUAL_MAILBOX

service postfix reload

echo "Done"
[/code]