515 lines
13 KiB
Bash
Executable File
515 lines
13 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)"
|
|
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
|