237 lines
6.6 KiB
Bash
Executable File
237 lines
6.6 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# vmail-stack
|
|
# https://git.stack-source.com/msb/vmail-stack
|
|
# Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
#
|
|
# vmail include file, used by other vmail bash scripts
|
|
|
|
# constants
|
|
readonly VMAIL_DIR=/var/vmail
|
|
readonly MYSQL_CONNECTION_INFO_FILE=$VMAIL_DIR/.my.cnf
|
|
|
|
# switch to required user
|
|
if [[ $(basename $0) == "vmail-domains-arc.sh" ]] || [[ $(basename $0) == "vmail-domains-del.sh" ]] || [[ $(basename $0) == "vmail-domains-exp.sh" ]] || [[ $(basename $0) == "vmail-domains-imp.sh" ]] || [[ $(basename $0) == "vmail-dovecot-"* ]]; then
|
|
if [[ "$USER" != "root" ]]; then
|
|
exec sudo -u root $0 "$@"
|
|
fi
|
|
elif [[ $(basename $0) == "vmail-dkim-"* ]]; then
|
|
if [[ "$USER" != "Debian-exim" ]]; then
|
|
exec sudo -u Debian-exim -g ssl-cert $0 "$@"
|
|
fi
|
|
elif [[ $(basename $0) == "vmail-purge-spool.sh" ]]; then
|
|
if [[ "$USER" != "Debian-exim" ]]; then
|
|
exec sudo -u Debian-exim $0 "$@"
|
|
fi
|
|
else
|
|
if [[ "$USER" != "vmail" ]]; then
|
|
exec sudo -u vmail $0 "$@"
|
|
else
|
|
# check that MYSQL_CONNECTION_INFO_FILE exists and is readable
|
|
if [ ! -f "$MYSQL_CONNECTION_INFO_FILE" ]; then
|
|
echo "ERROR: MySQL connection info file ($MYSQL_CONNECTION_INFO_FILE) does not exist or is not readable."
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# functions
|
|
|
|
# crude but good enough domain name format validation
|
|
function vmail::validate_domain () {
|
|
local my_domain=$1
|
|
if [[ $my_domain =~ ^(([a-zA-Z0-9](-?[a-zA-Z0-9])*)\.)+[a-zA-Z]{2,}$ ]] ; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# yesno prompt
|
|
#
|
|
# Examples:
|
|
# loop until y or n: if vmail::yesno "Continue?"; then
|
|
# default y: if vmail::yesno "Continue?" Y; then
|
|
# default n: if vmail::yesno "Continue?" N; then
|
|
function vmail::yesno() {
|
|
|
|
local prompt default reply
|
|
|
|
if [ "${2:-}" = "Y" ]; then
|
|
prompt="Y/n"
|
|
default=Y
|
|
elif [ "${2:-}" = "N" ]; then
|
|
prompt="y/N"
|
|
default=N
|
|
else
|
|
prompt="y/n"
|
|
default=
|
|
fi
|
|
|
|
while true; do
|
|
|
|
read -p "$1 [$prompt] " -n 1 -r reply
|
|
|
|
# Default?
|
|
if [ -z "$reply" ]; then
|
|
reply=$default
|
|
fi
|
|
|
|
# Check if the reply is valid
|
|
case "$reply" in
|
|
Y*|y*) return 0 ;;
|
|
N*|n*) return 1 ;;
|
|
esac
|
|
|
|
done
|
|
|
|
}
|
|
|
|
function vmail:getoptions () {
|
|
local OPTIND
|
|
while getopts "ha:b:d:e:f:gj:cp:q:r:s:tk:gl:m:o:u:vx" opt ; do
|
|
case "${opt}" in
|
|
h ) # display help and exit
|
|
help
|
|
exit
|
|
;;
|
|
a ) # alias
|
|
alias=${OPTARG,,}
|
|
if [[ $alias =~ "@" ]] ; then
|
|
domain=${alias##*@}
|
|
if vmail::validate_domain $domain; then
|
|
alias=${alias%@*}
|
|
else
|
|
echo "ERROR: $domain is not a valid domain name."
|
|
exit 1
|
|
fi
|
|
fi
|
|
;;
|
|
b ) # body - Body for Autoresponder emails
|
|
body="${OPTARG}"
|
|
;;
|
|
c ) # cvs - output in cvs format
|
|
cvs="| sed 's/\t/,/g'"
|
|
;;
|
|
d ) # domain name (virtualhost) to act on
|
|
domain=${OPTARG,,}
|
|
if ! vmail::validate_domain $domain; then
|
|
echo "ERROR: $domain is not a valid domain name."
|
|
exit 1
|
|
fi
|
|
;;
|
|
e ) # email address
|
|
email=${OPTARG,,}
|
|
if [[ $email =~ "@" ]] ; then
|
|
mbox=${email%@*}
|
|
domain=${email##*@}
|
|
if [ -z $mbox ] ; then
|
|
echo "ERROR: No local part in $email."
|
|
exit 1
|
|
elif [ -z $domain ] ; then
|
|
echo "ERROR: No domain in $email."
|
|
exit 1
|
|
elif ! vmail::validate_domain $domain; then
|
|
echo "ERROR: $domain is not a valid domain name."
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "ERROR: $email is not a valid email."
|
|
exit 1
|
|
fi
|
|
;;
|
|
f ) # forward to email address
|
|
forward=${OPTARG,,}
|
|
if [[ $forward =~ "@" ]] ; then
|
|
forward_mbox=${forward%@*}
|
|
forward_domain=${forward##*@}
|
|
if [ -z $forward_mbox ] ; then
|
|
echo "ERROR: No local part in $forward."
|
|
exit 1
|
|
elif [ -z $forward_domain ] ; then
|
|
echo "ERROR: No domain in $forward."
|
|
exit 1
|
|
elif ! vmail::validate_domain $forward_domain; then
|
|
echo "ERROR: $forward_domain is not a valid domain name."
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "ERROR: $forward is not a valid email."
|
|
exit 1
|
|
fi
|
|
;;
|
|
g ) # glob (wildcard) search
|
|
glob=${OPTARG,,}
|
|
;;
|
|
j ) # Filter Junk
|
|
filter=${OPTARG}
|
|
;;
|
|
k ) # keep
|
|
keep=${OPTARG}
|
|
if [[ $keep != "0" ]] && [[ $keep != "1" ]]; then
|
|
echo "ERROR: Invalid save keep setting: -k $keep."
|
|
exit 1
|
|
fi
|
|
;;
|
|
l ) # limit
|
|
limit=${OPTARG}
|
|
;;
|
|
m ) # mbox
|
|
mbox=${OPTARG}
|
|
;;
|
|
p ) # password
|
|
password=${OPTARG}
|
|
;;
|
|
o ) # mode for autoresponder - must be Vacation or Autoresponder
|
|
mode=${OPTARG,,} # first force lower case
|
|
mode=${mode^} # then capitlize first letter
|
|
if [[ $mode != "Vacation" ]] && [[ $mode != "Autoresponder" ]]; then
|
|
echo "ERROR: Invalid mode setting: -o $mode. Must be either Vacation or Autoresponder"
|
|
exit 1
|
|
fi
|
|
;;
|
|
q ) # quota
|
|
quota=${OPTARG}
|
|
;;
|
|
r ) # ratelimit - hourly limit for sending, multiplied by 10 for daily limit
|
|
ratelimit=${OPTARG}
|
|
;;
|
|
s ) # status - 0 or 1 or 2
|
|
status=${OPTARG}
|
|
if [[ $status != "0" ]] && [[ $status != "1" ]] && [[ $status != "2" ]]; then
|
|
echo "ERROR: Invalid status setting: -s $status"
|
|
exit 1
|
|
fi
|
|
;;
|
|
t ) # tab - Use tabs instead of tables for output, do not display column headers
|
|
tab=true
|
|
;;
|
|
u ) # subject - Subject for Autoresponder emails
|
|
subject="${OPTARG}"
|
|
;;
|
|
n ) # dry-run
|
|
dryrun=true
|
|
;;
|
|
v ) # verbose
|
|
verbose=true
|
|
;;
|
|
w ) # write - store data in file
|
|
write=true
|
|
;;
|
|
x ) # eXecute - don't prompt for confirmation
|
|
execute=true
|
|
;;
|
|
\? )
|
|
echo "Invalid option: $OPTARG"
|
|
exit 1
|
|
;;
|
|
: )
|
|
echo "Invalid option: $OPTARG requires an argument"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND-1))
|
|
}
|