postfix/sent_userinfo_postfix.sh

520 lines
14 KiB
Bash
Executable File

#!/usr/bin/env bash
script_name="$(basename $(realpath $0))"
working_dir="$(dirname $(realpath $0))"
file_dir="${working_dir}/files"
conf_dir="${working_dir}/conf"
log_dir="${working_dir}/log"
conf_file="${conf_dir}/sent_userinfo_postfix.conf"
logfile="${working_dir}/log/sent_userinfo_postfix.$(date +%Y-%m-%d-%H%M).log"
LOCK_DIR="/tmp/$(basename $0).$$.LOCK"
#---------------------------------------
#-----------------------------
# Setting Defaults
#-----------------------------
#---------------------------------------
DEFAULT_message_body_file="${file_dir}/sent_userinfo_postfix.message"
DEFAULT_db_type="pgsql"
DEFAULT_db_name="postfix"
DEFAULT_mail_user="vmail"
DEFAULT_mail_group="vmail"
if [[ -f "${file_dir}/sent_userinfo_postfix.subject" ]]; then
DEFAULT_email_subject="$(cat "${file_dir}/sent_userinfo_postfix.subject" | head -1)"
fi
#---------------------------------------
#-----------------------------
# Base Function(s)
#-----------------------------
#---------------------------------------
clean_up() {
# Perform program exit housekeeping
rm -rf $LOCK_DIR
exit $1
}
echononl(){
echo X\\c > /tmp/shprompt$$
if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then
echo "$*\\c" 1>&2
else
echo -e -n "$*" 1>&2
fi
rm /tmp/shprompt$$
}
warn (){
echo ""
echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*"
echo ""
}
fatal(){
echo ""
echo -e "[ \033[31m\033[1mFehler\033[m ]: $*"
echo -e "\n Script was interupted!\n"
echo
clean_up 1
}
echo_ok() {
echo -e "\033[75G[ \033[32mok\033[m ]"
}
echo_done() {
echo -e "\033[75G[ \033[32mdone\033[m ]"
}
echo_failed() {
echo -e "\033[75G[ \033[1;31mfailed\033[m ]"
}
echo_skipped() {
echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]"
}
# ----------
# - Jobhandling
# ----------
# - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM
# -
trap clean_up SIGHUP SIGINT SIGTERM
# - Create lock directory '$LOCK_DIR"
#
mkdir "$LOCK_DIR"
# ----------
# - Main part of script
# ----------
clear
echo ""
echo ""
echo -e "\033[1m----------\033[m"
echo -e "\033[32m\033[1mRunning script \033[m\033[1m$script_name\033[32m .. \033[m"
echo -e "\033[1m----------\033[m"
echo ""
# ----------
# - Read Configuration file
# ----------
echo ""
echo ""
echononl " Loading default Configuration values from $(basename ${conf_file}).."
if [[ ! -f "$conf_file" ]]; then
echo_skipped
else
source "${conf_file}" > /dev/null 2>&1
if [[ $? -eq 0 ]]; then
echo_ok
else
echo_failed
fi
fi
if [[ -n "$email_from" ]] ; then
DEFAULT_email_from="$email_from"
fi
if [[ -n "$email_from_org" ]] ; then
DEFAULT_email_from_org="$email_from_org"
fi
if [[ -n "$message_body_file" ]] ; then
$DEFAULT_message_body_file="$message_body_file"
fi
[[ -n "$db_type" ]] || db_type="$DEFAULT_db_type"
if [[ "$db_type" != "pgsql" ]] && [[ "$db_type" != "mysql" ]]; then
fatal "Unknown Database Type '$db_type' for Password Database (Parameter db_type)"
fi
[[ -n "$db_name" ]] || db_name="$DEFAULT_db_name"
if [[ "$db_type" = "mysql" ]]; then
if [[ -z "$mysql_credential_args" ]]; then
if [[ -f "/etc/mysql/debian.cnf" ]]; then
mysql_credential_args="--defaults-file=/etc/mysql/debian.cnf"
elif [[ -f "/usr/local/mysql/sys-maint.cnf" ]] ; then
mysql_credential_args="--defaults-file=/usr/local/mysql/sys-maint.cnf"
else
fatal "No credentials for access to MySQL is given!"
fi
fi
fi
[[ -n "$mail_user" ]] || mail_user="$DEFAULT_mail_user"
[[ -n "$mail_group" ]] || mail_group="$DEFAULT_mail_group"
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo "Is this a tset-run, sending the user info to only one given address?"
echo ""
echo ""
_TEST_RUN=
while [ "$_TEST_RUN" != "yes" -o "$_TEST_RUN" != "no" ] ; do
echononl "\033[1mTest run? [yes/no]:\033[m "
read _TEST_RUN
# - To lower case
_TEST_RUN=${_TEST_RUN,,}
if [ "X$_TEST_RUN" = "X" ]; then
echo -e "\n\t\033[33m\033[1mAn entry is required! Type 'yes' or 'no'\033[m.\n"
_TEST_RUN=""
continue
fi
if [ "$_TEST_RUN" = "yes" -o "$_TEST_RUN" = "no" ] ; then
break
fi
echo -e "\n\t\033[33m\033[1mWrong entry! Type 'yes' or 'no'.\033[m\n"
done
if [[ "$_TEST_RUN" = "yes" ]]; then
TEST_RUN=true
else
TEST_RUN=false
fi
if $TEST_RUN ; then
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo "Give the recipient address for the test run."
echo ""
echo ""
test_email=""
while [[ "X$test_email" = "X" ]] ; do
echononl "\033[1mRecipient address for test run:\033[m "
read test_email
if [[ "X$test_email" = "X" ]] ; then
echo -e "\n\t\033[33m\033[1mAn entry is required!\033[m"
fi
done
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo "Give the Sender E-Mail for the user info."
echo ""
echo ""
email_from=""
if [[ -n "$DEFAULT_email_from" ]]; then
echononl "Sender E-Mail [$DEFAULT_email_from]: "
read email_from
# - To lower case
email_from=${email_from,,}
if [[ "X$email_from" = "X" ]] ; then
email_from="$DEFAULT_email_from"
fi
else
while [ "X$email_from" = "X" ]; do
echononl "Sender E-Mail: "
read email_from
# - To lower case
email_from=${email_from,,}
if [ "X$email_from" = "X" ]; then
echo ""
echo -e "\n\t\033[33m\033[1m'Sender E-Mail' is required!\033[m\n"
continue
fi
done
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo "Give the Sender Organisation or the Sender Name."
echo ""
echo ""
email_from_org=""
if [[ -n "$DEFAULT_email_from_org" ]]; then
echononl "Sender Organisation/Name [$DEFAULT_email_from_org]: "
read email_from_org
if [[ "X$email_from_org" = "X" ]] ; then
email_from_org="$DEFAULT_email_from_org"
fi
else
while [ "X$email_from_org" = "X" ]; do
echononl "Sender Organisation/Name: "
read email_from_org
if [ "X$email_from_org" = "X" ]; then
echo ""
echo -e "\n\t\033[33m\033[1m'Sender Organisation/Name' is required!\033[m\n"
continue
fi
done
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo "Give the Subject of the user info e-mail."
echo ""
echo ""
email_subject=""
if [[ -n "$DEFAULT_email_subject" ]]; then
echononl "Subject [$DEFAULT_email_subject]: "
read email_subject
if [[ "X$email_subject" = "X" ]] ; then
email_subject="$DEFAULT_email_subject"
fi
else
while [ "X$email_subject" = "X" ]; do
echononl "Subject: "
read email_subject
if [ "X$email_subject" = "X" ]; then
echo ""
echo -e "\n\t\033[33m\033[1m'Subject' is required!\033[m\n"
continue
fi
done
fi
echo ""
echo -e "\033[32m--\033[m"
echo ""
echo "Give the path to the file containing message (body) of the info e-mail."
echo ""
echo ""
message_body_file=""
if [[ -n "$DEFAULT_message_body_file" ]]; then
echononl "Path to message file [$DEFAULT_message_body_file]: "
read message_body_file
if [[ "X$message_body_file" = "X" ]] ; then
message_body_file="$DEFAULT_message_body_file"
fi
else
while [ "X$message_body_file" = "X" ]; do
echononl "Path to message file: "
read message_body_file
if [ "X$message_body_file" = "X" ]; then
echo ""
echo -e "\n\t\033[33m\033[1m'Path to message file' is required!\033[m\n"
continue
fi
done
fi
if [[ -z "$email_from" ]] ; then
fatal "Missing Mail Sender Address (parameter 'email_from')."
fi
if [[ -z "$email_from_org" ]] ; then
fatal "Missing Mail Sender Organisation (parameter 'email_from_org')."
fi
if [[ -z "$email_subject" ]] ; then
fatal "Missing Subject (parameter 'email_subject')."
fi
if [[ ! -f $message_body_file ]];then
fatal "User Info-file to send '$message_body_file' does not exist !!"
fi
echo ""
echo ""
echo -e "\033[32mSettings for script \033[37m\033[1msent_userinfo_postfix.sh\033[m"
echo ""
echo " File containing the mail-body.........: $message_body_file"
echo ""
if [[ "$db_type" = "pgsql" ]] ; then
echo " Type of postfix databae...............: PostgreSQL ($db_type)"
echo " Name of Postfix Database..............: $db_name"
elif [[ "$db_type" = "mysql" ]] ; then
echo " Type of postfix databae...............: MySQL ($db_type)"
echo " Name of Postfix Database..............: $db_name"
echo " MySQL credential args.................: $mysql_credential_args"
fi
echo ""
echo " Mail Sender Address...................: $email_from"
echo " Mail Sender Organisation..............: $email_from_org"
echo " Subject of the userinfo e-mail........: $email_subject"
echo ""
echo " Mail User.............................: $mail_user"
echo " Mail Group............................: $mail_group"
echo ""
echo " Test Run..............................: $TEST_RUN"
if $TEST_RUN ; then
echo " Recipient address for test run........: $test_email"
fi
echo ""
if ! $TEST_RUN ; then
warn "This is \033[1mNOT\033[m a test run. All local mailboxes will receive the user info e-mail."
fi
echo ""
OK=
while [ "$OK" != "yes" -o "$OK" != "no" ] ; do
echononl "\033[1mParameters ok? [yes/no]:\033[m "
read OK
## - To lower case
OK=${OK,,}
if [ "X$OK" = "X" ]; then
echo -e "\n\t\033[33m\033[1mAn entry is required!\033[m\n"
OK=""
continue
fi
if [ "$OK" != "yes" -o "$OK" != "no" ] ; then
break
fi
echo -e "\n\t\033[33m\033[1mWrong entry!\033[m\n"
done
[[ $OK = "yes" ]] || fatal "Repeat execution with different parameters."
echo ""
echononl " Create log directory '$(dirname "$logfile")'.."
if [[ ! -d "$(dirname "$logfile")" ]] ; then
mkdir "$(dirname "$logfile")"
if [[ $? -eq 0 ]]; then
echo_ok
else
echo_failed
fi
else
echo_skipped
fi
> $logfile
curdir=`pwd`
if [ ! -f $message_body_file ]; then
fatal "File containing User Info not found!"
fi
pwd=`pwd`
cd /tmp
echo ""
echo -e "\n\t --- Prepare Info E-Mail --\n" | tee -a $logfile
cp "$message_body_file" "${LOCK_DIR}/message_tmp.txt"
echo "$email_subject" > ${LOCK_DIR}/subject_tmp.txt
# - Convert to UTF-8
# -
iconv -t UTF8 -o "${LOCK_DIR}/message_tmp_UTF8.txt" "${LOCK_DIR}/message_tmp.txt"
iconv -t UTF8 -o "${LOCK_DIR}/subject_tmp_UTF8.txt" "${LOCK_DIR}/subject_tmp.txt"
# - encode base64
# --
ENCODED_SUBJECT="=?utf-8?B?$(cat ${LOCK_DIR}/subject_tmp_UTF8.txt | base64 --wrap=0)?="
ENCODED_MESSAGE="$(cat ${LOCK_DIR}/message_tmp_UTF8.txt | base64)"
content_type='Content-Type: text/plain;\n charset="utf-8"'
transfer_encoding='Content-Transfer-Encoding: base64'
content_disposition='Content-Disposition: inline'
echo ""
echo -e "\n\t --- Sending userinfo into all local virtual mailboxes --\n" | tee -a $logfile
## - list of local virtual domains
## -
if $TEST_RUN ; then
if [[ ! "${test_email}" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]] ; then
fatal "The given recipient address (${test_email}) for test run does not look like a correct e-mail address!"
fi
domains="${test_email##*@}"
elif [[ "$db_type" = "pgsql" ]] ; then
domains=`su postgres -c"psql -At -F ' ' $db_name -c\"SELECT domain FROM domain WHERE domain != 'ALL' ORDER BY domain\""`
elif [[ "$db_type" = "mysql" ]] ; then
domains="$(mysql "$mysql_credential_args" "$db_name" \
-N -s -e"SELECT domain FROM domain WHERE domain != 'ALL' ORDER BY domain")"
fi
if [[ -z "$domains" ]] ; then
fatal "No mail domains found!"
fi
declare -i num_dom=0;
declare -i num_mbox_failed=0;
declare -i num_mbox=0;
# - Escape '@' sign for use in perl regex
# -
email_from_regex="$(echo ${email_from//\@/\\@})"
for domain in $domains ;do
echo -e "\nDOMAIN: $domain\n" | tee -a $logfile
if $TEST_RUN ; then
local_parts="${test_email%%@*}"
elif [[ "$db_type" = "pgsql" ]] ; then
local_parts=`su postgres -c"psql -At -F ' ' postfix -c\"SELECT local_part FROM mailbox WHERE domain = '$domain'\""`
elif [[ "$db_type" = "mysql" ]] ; then
local_parts="$(mysql "$mysql_credential_args" "$db_name" \
-N -s -e"SELECT local_part FROM mailbox WHERE domain = '$domain'")"
fi
if [[ -z "$local_parts" ]] ; then
warn "No mailbox found for domain '$domain'!"
echo " [ WARNING ]: No mailbox found for domain '$domain'" >> $logfile
continue
fi
for local_part in $local_parts ; do
echononl "\tSend userinfo to $local_part@$domain.."
echo -e "From: ${email_from_org} <${email_from}>
To: $local_part@$domain
Subject: ${ENCODED_SUBJECT}
${content_type}
${transfer_encoding}
${content_disposition}
$ENCODED_MESSAGE
" | /usr/sbin/sendmail -F "$email_from_org" -f $email_from -t
if [ "$?" = "0" ]; then
num_mbox=num_mbox+1
echo_done
echo " [ OK ]: Send userinfo to $local_part@$domain" >> $logfile
else
echo_failed
echo " [ ERROR ]: Cannot sent userinfo to \"$local_part\@$domain\"!" >> $logfile
num_mbox_failed=num_mbox_failed+1
fi
done
num_dom=num_dom+1
done
#if ! $TEST_RUN ; then
mv "$message_body_file" "${message_body_file}.SENT.$(date +%Y-%m-%d)"
if [[ -f "${file_dir}/sent_userinfo_postfix.subject" ]]; then
mv "${file_dir}/sent_userinfo_postfix.subject" "${file_dir}/sent_userinfo_postfix.subject.SENT.$(date +%Y-%m-%d)"
else
echo "$email_subject" > "${file_dir}/sent_userinfo_postfix.subject.SENT.$(date +%Y-%m-%d)"
fi
#fi
echo -e "\n\n----- Statistics -----\n\n\tSent mail to $num_mbox mailboxe(s) of $num_dom domain(s)" | tee -a $logfile
if [ $num_mbox_failed -gt 0 ];then
echo -e "\n\tFailed sending mail to $num_mbox_failed mailboxe(s)" >> $logfile
echo -e "\n\t\033[31m\033[1mFailed sending mail to $num_mbox_failed mailboxe(s)\033[m\033[m"
echo -e "\n\n-- See $logfile for details\n" | tee -a $logfile
fi
echo
cd $pwd
clean_up 0