#!/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