From 0ea8c3b56e0b04448fee8a8d0a47afb5126ae9f2 Mon Sep 17 00:00:00 2001 From: Christoph Date: Mon, 14 Oct 2019 00:22:45 +0200 Subject: [PATCH] Add script 'install_vacation.sh'. --- install_vacation.sh | 575 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 575 insertions(+) create mode 100755 install_vacation.sh diff --git a/install_vacation.sh b/install_vacation.sh new file mode 100755 index 0000000..4b4ff22 --- /dev/null +++ b/install_vacation.sh @@ -0,0 +1,575 @@ +#!/usr/bin/env bash +clear +echo -e "\n\t\033[32mStart script for installation of vacation script (from postfixadmin) ..\033[m" + +## =================================================================== +## - Install Postfixadmin +## =================================================================== + +## ----------------------------------------------------------------- +## ---------------------------------------------------------------- +## --- +## --- For configurations see file conf/install_postfixadmin.conf +## --- +## --- Dont make changes here! +## --- +## ----------------------------------------------------------------- +## ----------------------------------------------------------------- + +# ------------- +# - Settings +# ------------- + +_src_base_dir="$(realpath $(dirname $0))" +conf_file="${_src_base_dir}/conf/install_postfixadmin.conf" + +log_file="$(mktemp)" +backup_date="$(date +%Y-%m-%d-%H%M)" + +declare -A check_entry_main_cf_arr + +# ------------- +# - Functions +# ------------- + +clean_up() { + + # Perform program exit housekeeping + rm -f "$log_file" + 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$$ +} + +fatal(){ + echo "" + echo -e "\t[ \033[31m\033[1mFatal\033[m ]: $*" + echo "" + echo -e "\t\033[31m\033[1mInstalllation wird abgebrochen\033[m\033[m" + echo "" + clean_up 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\033[m ]: $*" + echo "" +} + +warn (){ + echo "" + echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" + echo "" +} +info (){ + echo "" + echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*" + echo "" +} +# - remove leading/trailling whitespaces +# - +trim() { + local var="$*" + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" +} + +echo_ok() { + echo -e "\033[75G[ \033[32mok\033[m ]" + ## echo -e " [ ok ]" +} +echo_failed(){ + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" + ## echo -e " [ failed ]" +} +echo_skipped() { + echo -e "\033[75G[ \033[30m\033[1mskipped\033[m ]" +} + + +if [ "$POSTFIX_DB_TYPE" = "postgres" -o "$POSTFIX_DB_TYPE" = "postgresql" -o "$POSTFIX_DB_TYPE" = "pgsql" -o "$POSTFIX_DB_TYPE" = "psql" ];then + POSTFIX_DB_TYPE=pgsql +fi + +echo +echononl "\tInclude Configuration file.." +if [[ ! -f $conf_file ]]; then + echo_failed + fatal "Missing configuration file '$conf_file'" +else + source $conf_file + echo_ok +fi + +echo -e "\033[32m--\033[m" +echo "" +echo "Version of the EXISTING Postfixadmin installation" +echo "" +echo "" +PF_ADMIN_VERSION= +while [ "X$PF_ADMIN_VERSION" = "X" ] +do + echononl "Postfixadmin Version: " + read PF_ADMIN_VERSION + if [ "X$PF_ADMIN_VERSION" = "X" ]; then + echo -e "\n\t\033[33m\033[1mA version number is required!\033[m\n" + fi +done +echo "" +echo -e "\033[32m--\033[m" +echo "" + +_vacation_script="$(find ${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION} -type f -name vacation.pl -print 2>/dev/null)" + +if [[ ! -d "${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION}" ]]; then + fatal "Postfix Admin source directory (${_src_base_dir}/postfixadmin-${PF_ADMIN_VERSION}) not found" +fi +if [[ -z "$(trim "$_vacation_script")" ]]; then + fatal "No vacation script found!" +fi + + + +# - Default values +# - +DEFAULT_WEBSITE_BASEDIR="/var/www/${WEBSITE_NAME}" + +DEFAULT_VACATION_USER="vacation" +DEFAULT_VACATION_GROUP="vacation" + +DEFAULT_POSTFIX_DB_NAME="postfix" +DEFAULT_POSTFIX_DB_USER="postfix" + +DEFAULT_POSTFIX_DB_HOST_MYSQL="unix:/tmp/mysql.sock" + + +[[ -n "$PF_ADMIN_VERSION" ]] || fatal "Version of Postfix Admin to install (PF_ADMIN_VERSION) not present!" +[[ -n "$WEBSITE_NAME" ]] || fatal "Website's name (WEBSITE_NAME) not present!" + +TLD=${WEBSITE_NAME##*.} +_tmp_string=${WEBSITE_NAME%.*} +MAIN_DOMAIN=${_tmp_string##*.} + +[[ -n "$AUTOREPLY_HOSTNAME" ]] || AUTOREPLY_HOSTNAME=autoreply.${MAIN_DOMAIN}.$TLD + +[[ -n "$POSTFIX_DB_HOST_MYSQL" ]] || POSTFIX_DB_HOST_MYSQL="$DEFAULT_POSTFIX_DB_HOST_MYSQL" + +if [[ "$POSTFIX_DB_HOST_MYSQL" =~ sock$ ]] || [[ "$POSTFIX_DB_HOST_MYSQL" =~ localhost ]]; then + VACATION_DB_HOST_MYSQL="127.0.0.1" +else + VACATION_DB_HOST_MYSQL="$POSTFIX_DB_HOST_MYSQL" +fi + +[[ -n "$POSTFIX_DB_TYPE" ]] || fatal "Database Type of Postfix Database (POSTFIX_DB_TYPE) not present!" +[[ -n "$POSTFIX_DB_NAME" ]] || POSTFIX_DB_NAME="$DEFAULT_POSTFIX_DB_NAME" +[[ -n "$POSTFIX_DB_USER" ]] || POSTFIX_DB_USER="$DEFAULT_POSTFIX_DB_USER" +[[ -n "$POSTFIX_DB_PASS" ]] || fatal "Password of Postfix Database (POSTFIX_DB_PASS) not given!" + +# - Vacation +# - + +[[ -n "$VACATION_USER" ]] || VACATION_USER=$DEFAULT_VACATION_USER +[[ -n "$VACATION_GROUP" ]] || VACATION_GROUP=$DEFAULT_VACATION_GROUP + + +echo "" +echo "" +echo -e "\033[1;32mSettings for installation of \033[1;37mPostfix Admin / Vacation\033[m" +echo "" +echo -e "\tPostfix Admin Version................: $PF_ADMIN_VERSION" +echo "" +echo -e "\tHostname for Vacation Messages.......: $AUTOREPLY_HOSTNAME" +echo -e "\tUser of vacation script..............: $VACATION_USER" +echo -e "\tGroup of vacation script.............: $VACATION_GROUP" +echo "" +echo -e "\tName of Postfix Database.............: $POSTFIX_DB_NAME" +echo -e "\tUser of Postfix Database.............: $POSTFIX_DB_USER" +echo -e "\tPassword of Postfix Database.........: $POSTFIX_DB_PASS" +echo "" +echo "" + +echo "" +echo -n "Type upper case 'YES' to continue executing with this parameters: " +read OK +if [[ "$OK" = "YES" ]] ; then + echo "" + echo "" + echo -e "\t\033[1;32mGoing to install Postfix Admin / Vacation \033[1;37m\033[m" +else + fatal "Abort by user request - Answer as not 'YES'" +fi + + + + +echo -e "\n\n\t\033[37m\033[1mInstall Vacation\033[m\n" + +echononl "\tInstall database related CPAN Modules" +_failed=false +> $log_file +_needed_cpan_modules=" + CPAN + DBI + Mail::Sender" +if [[ "$POSTFIX_DB_TYPE" = "pgsql" ]] ; then + _needed_cpan_modules="$_needed_cpan_modules + DBD::Pg" +else + _needed_cpan_modules="$_needed_cpan_modules + DBD::mysql" +fi +for _module in $_needed_cpan_modules ; do + cpanm -q --skip-installed $_module >> "$log_file" 2>&1 + if [[ "$?" -ne 0 ]] ; then + error "$(cat $tmp_err_msg)" + fi +done +if $_failed ; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +echo "" + +echononl "\tCreate system group '$VACATION_GROUP'" +if ! grep -q "$VACATION_GROUP" /etc/group > /dev/null 2>&1 ; then + addgroup --system --gid 65501 $VACATION_GROUP > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + +echononl "\tCreate system user '$VACATION_USER'" +if ! grep -q "$VACATION_USER" /etc/passwd > /dev/null 2>&1 ; then + adduser --system --home /var/spool/vacation --no-create-home --uid 65501 --gid 65501 --shell /usr/sbin/nologin $VACATION_USER > "$log_file" 2>&1 + + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + +echononl "\tCreate directory '/var/spool/vacation'" +if [[ ! -d "/var/spool/vacation" ]]; then + mkdir /var/spool/vacation > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + +echononl "\tSet Permissions on directoy '/var/spool/vacation'" +chown -R ${VACATION_USER}:$VACATION_GROUP /var/spool/vacation > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +echononl "\tBackup existing script 'vacation.pl'" +if [[ -f "/var/spool/vacation/vacation.pl" ]] ; then + mv /var/spool/vacation/vacation.pl /var/spool/vacation/vacation.pl.${backup_date} > "$log_file" 2>&1 + if [[ $? -ne 0 ]]; then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + + +echononl "\tCopy vacation script to '/var/spool/vacation/vacation.pl'" +if [[ -n "$(trim "$_vacation_script")" ]] ; then + cp -a ${_vacation_script} /var/spool/vacation/ > "$log_file" 2>&1 + if [[ $? -eq 0 ]];then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + error "Vacation script not found!" +fi + + +# - Encoding does not work as exspected. +# - +# - NOTE: +# - this IS NOT a fix, but a workaround +# - +echononl "\tWorkaround, because encoding does not work as exspected." +# - Vacation script changed. Since Version 3.2 we need another perl regexp. +# - The old one was: +# - perl -i -n -p -e "s/(\s*\'ctype\'\s* =>\s*)\'text\/plain.*$/\1\'text\/plain; charset=iso-8859-1\',/" \ +# - +perl -i -n -p -e "s/(\s*\'Content-Type\'\s* =>\s*)\"text\/plain.*$/\1\"text\/plain; charset=iso-8859-1\",/" \ + /var/spool/vacation/vacation.pl > "$log_file" 2>&1 +if [[ $? -eq 0 ]];then + echo_ok + info "This IS NOT a fix, but a workaround." +else + echo_failed + error "$(cat $log_file)" +fi + +echononl "\tSet Permission on vacation script" +_failed=false +chown ${VACATION_USER}:$VACATION_GROUP /var/spool/vacation/vacation.pl > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + _failed=true +fi +chmod 700 /var/spool/vacation/vacation.pl > "$log_file" 2>&1 +if [[ $? -ne 0 ]]; then + _failed=true +fi +if $_failed ;then + echo_failed + error "$(cat $log_file)" +else + echo_ok +fi + +# - Script vacation.pl tries to reads setting from +# - +# - /etc/mail/postfixadmin/vacation.conf +# - /etc/postfixadmin/vacation.conf +# - +# - Instead of changing this script, we put the needed entries +# - to file /etc/postfixadmin/vacation.conf: +# - +echononl "\tCreate directory '/etc/postfixadmin' " +if [[ ! -d "/etc/postfixadmin" ]]; then + mkdir /etc/postfixadmin > "$log_file" 2>&1 + if [[ $? -eq 0 ]];then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tBackup existing file '/etc/postfixadmin/vacation.conf'" +if [[ -f "/etc/postfixadmin/vacation.conf" ]]; then + mv /etc/postfixadmin/vacation.conf /etc/postfixadmin/vacation.conf.${backup_date} > "$log_file" 2>&1 + if [[ $? -eq 0 ]];then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +# - Create configuration file '/etc/postfixadmin/vacation.conf' +# - +echononl "\tCreate configuration file '/etc/postfixadmin/vacation.conf'" +if [[ "$POSTFIX_DB_TYPE" = "pgsql" ]]; then + _db_type="Pg" +else + _db_type="mysql" +fi + +cat < /etc/postfixadmin/vacation.conf 2> "$log_file" +\$db_type = '$_db_type'; +\$db_username = '${POSTFIX_DB_USER}'; +\$db_password = '${POSTFIX_DB_PASS}'; +\$db_name = '${POSTFIX_DB_NAME}'; +EOF +if [[ "$POSTFIX_DB_TYPE" = "mysql" ]]; then + cat <> /etc/postfixadmin/vacation.conf 2> "$log_file" +\$db_host = '$VACATION_DB_HOST_MYSQL'; +EOF +fi +cat <> /etc/postfixadmin/vacation.conf 2> "$log_file" +\$vacation_domain = '${AUTOREPLY_HOSTNAME}'; +\$syslog = 0; +\$log_to_file = 1; +\$logfile = '/var/log/vacation.log'; +\$log_level = 1; +\$interval = 60*60*24; +\$smtp_ssl = '0'; +1; # required final line - keeps perl happy. +EOF +if [[ $? -eq 0 ]];then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +echononl "\tCreate logfile /var/log/vacation.log" +touch /var/log/vacation.log > "$log_file" 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi +echononl "\tSet permissions on /var/log/vacation.log" +chown ${VACATION_USER}:$VACATION_GROUP /var/log/vacation.log > "$log_file" 2>&1 +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi +echononl "\tConfigure logrotation for '/var/log/vacation.log'" +cat < /etc/logrotate.d/vacation 2> "$log_file" +/var/log/vacation.log { + daily + start 0 + rotate 7 + missingok + compress + delaycompress + notifempty + create 640 vacation vacation + copytruncate +} +EOF +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + + +# - Create an entry in /etc/hosts for the (non-existant domain) +# - $AUTOREPLY_HOSTNAME +# - +# - add: +# - +# - 127.0.0.1 $AUTOREPLY_HOSTNAME +# - +echononl "\tCreate entry in /etc/hosts for '$AUTOREPLY_HOSTNAME'" +if ! grep -q "$AUTOREPLY_HOSTNAME" /etc/hosts > $log_file 2>&1 ; then + perl -i -n -p -e"s#(^\s*127.0.0.1\s+localhost.*)#\1\n\n127.0.0.1 ${AUTOREPLY_HOSTNAME}#" /etc/hosts > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +# - Define the transport type in the Postfix master file +# - /etc/postfix/master.cf +# - +# - vacation unix - n n - - pipe +# - flags=Rq user=vacation argv=/var/spool/vacation/vacation.pl -f ${sender} -- ${recipient} +# - +echononl "\tDefine transport for vacation in /etc/postfix/master.cf" +if ! grep -q -E "^\s*vacation\s+unix" /etc/postfix/master.cf > $log_file 2>&1 ; then + cat <> /etc/postfix/master.cf + +vacation unix - n n - - pipe + flags=Rq user=vacation argv=/var/spool/vacation/vacation.pl -f \${sender} -- \${recipient} +EOF + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +# - Setup the transport maps file /etc/postfix/transport +# - +# - add line: +# - +# - $AUTOREPLY_HOSTNAME vacation: +# - +echononl "\tSetup the transport maps for vacation domain in '/etc/postfix/transport'" +if ! grep -q -E "^\s*$AUTOREPLY_HOSTNAME\s+vacation:" /etc/postfix/transport > $log_file 2>&1 ; then + _failed=false + echo "$AUTOREPLY_HOSTNAME vacation:" >> /etc/postfix/transport 2> $log_file + if [[ $? -ne 0 ]] ; then + _failed=true + fi + postmap btree:/etc/postfix/transport > $log_file 2>&1 + if [[ $? -ne 0 ]] ; then + _failed=true + fi + if [[ $? -ne 0 ]]; then + _failed=true + fi + if $_failed ;then + echo_failed + error "$(cat $log_file)" + else + echo_ok + fi +else + echo_skipped +fi + +check_entry_main_cf_arr["transport_maps"]="btree:/etc/postfix/transport" +# - Add 'btree:/etc/postfix/transport' ton parameter transport_maps in /etc/postfix/main.cf +# - +# - take care the entry for transport_maps in /etc/postfix/main.cf +# - contains "btree:/etc/postfix/transport" +# - +echononl "\tAdd 'btree:/etc/postfix/transport' to parameter transport_maps" +if ! grep -q "btree:/etc/postfix/transport" /etc/postfix/main.cf > $log_file 2>&1 ; then + perl -i -n -p -e "s#(^transport_maps\s+=.*)#\1\n btree:/etc/postfix/transport#" /etc/postfix/main.cf > $log_file 2>&1 + if [[ $? -eq 0 ]] ; then + echo_ok + else + echo_failed + error "$(cat $log_file)" + fi +else + echo_skipped +fi + +echononl "\tReload/Restart postfix" +if $systemd_supported ; then + systemctl reload postfix > $log_file 2>&1 +else + /etc/init.d/postfix reload > $log_file 2>&1 +fi +if [[ $? -eq 0 ]] ; then + echo_ok +else + echo_failed + error "$(cat $log_file)" +fi + +echo "" +clean_up 0