#!/usr/bin/env bash

#  filename: install-postfix
#  author: G. D. LaBossiere, Xview Solutions Inc. <code@xviewsolutions.com>
#  last modified: 2017-04-03
#  license: GNU GPL v. 3
#  comments: install, configure and (re)start Postfix MTA/MDA

[[ -f /etc/redhat-release ]] || {
  printf "%s\n" "For Redhat-compatible distros only."
  exit 1
}


[[ $(id -u) -eq 0 ]] || {
  printf "%s\n" "Requires administrative privileges. Use sudo or run this script as root."
  exit 1
}

#  look for processes listening on port 25 at any address
myMTA=( $(netstat -ltnp | grep ':25' | cut -d'/' -f2) )
[[ -n $myMTA && ! $myMTA =~ ^master$ ]] && {
  printf "%s\n" "Detected another mail server listening on port 25. Remove or disable it before installing Postfix."
  exit 1
}


#  only install Postfix if not already installed
if [[ $(type -p postfix) ]]; then
    printf "%s\n" "Postfix is already installed."
  else
    printf "%s\n" "Installing Postfix mail server and any dependencies..."
    yum -y install postfix.$(uname -i)
    [[ $? -eq 0 ]] || {
      printf "%s\n" "Installation attempt failed. Investigate and resolve."
      exit 1
    }
fi

#  ip binary not in user $PATH for old RHEL/CentOS versions
[[ -x $(type -p ip) ]] || {
  ipBin="$(whereis -b ip | tr -d [:blank:] | cut -d':' -f2)"
  [[ -x $ipBin ]] || {
    printf "%s\n" "Cannot find 'ip' utility. Investigate and resolve."
    exit 1
  }
  alias ip="$ipBin"
}

printf "%s\n" "Checking which internet protocols to enable for Postfix."
[[ -n $(ip -f inet addr show) ]] && inetProto=( ipv4 )
[[ -n $(ip -f inet6 addr show) ]] && inetProto=( ${inetProto[@]} ipv6 )

#  determine correct postfix config value
[[ ${inetProto[@]} =~ ipv4 && ${inetProto[@]} =~ ipv6 ]] && newCfg="inet_protocols = all"
[[ ${inetProto[@]} =~ ipv4 && ! ${inetProto[@]} =~ ipv6 ]] && newCfg="inet_protocols = ipv4"
[[ ! ${inetProto[@]} =~ ipv4 && ${inetProto[@]} =~ ipv6 ]] && newCfg="inet_protocols = ipv6"

#  get existing postfix config
configFile="/etc/postfix/main.cf"
[[ -w $configFile ]] || {
  printf "%s\n" "Cannot write to $configFile Investigate and resolve."
  exit 1
}
oldCfg="$(grep -E '^[[:blank:]]*inet_protocols[[:blank:]]*=[[:blank:]]*[0-9a-z].+$' $configFile)"

#  only change config value if necessary
[[ "$newCfg" == "$oldCfg" ]] && {
  printf "%s\n" "Param '$oldCfg' was already correct in $configFile"
  printf "%s\n" "All done. No errors."
  exit 0
}
sed -i "s/$oldCfg/$newCfg/g" "$configFile" 2> /dev/null
[[ $? -ne 0 ]] && {
  printf "%s\n" "Failed to change '$oldCfg' to '$newCfg' in $configFile Investigate and resolve."
  exit 1
}
printf "%s\n" "Changed '$oldCfg' to '$newCfg' in $configFile"

#  enable and (re)start postfix service on old RHEL/CentOS versions without systemd
[[ -x $(type -p systemctl) ]] || {
  svcMgr="$(whereis -b chkconfig | tr -d [:blank:] | cut -d':' -f2)"
  [[ -x $svcMgr ]] || {
    printf "%s\n" "Cannot find 'chkconfig' utility. Investigate and resolve."
    exit 1
  }
  $svcMgr --level 2345 postfix on
  [[ $? -ne 0 ]] && {
    printf "%s\n" "Failed to enable postfix service. Investigate and resolve."
    exit 1
  }
  svcCtl="$(whereis -b service | tr -d [:blank:] | cut -d':' -f2)"
  [[ -x $svcCtl ]] || {
    printf "%s\n" "Cannot find 'service' utility. Investigate and resolve."
    exit 1
  }
  $svcCtl postfix restart
  [[ $? -ne 0 ]] && {
    printf "%s\n" "Failed to (re)start postfix service. Investigate and resolve."
    exit 1
  }
  printf "%s\n" "All done. No errors."
  exit 0
}

#  enable and (re)start postfix service on RHEL/CentOS 7+
systemctl enable postfix.service
[[ $? -ne 0 ]] && {
  printf "%s\n" "Failed to enable postfix service. Investigate and resolve."
  exit 1
}
systemctl restart postfix.service
[[ $? -ne 0 ]] && {
  printf "%s\n" "Failed to (re)start postfix service. Investigate and resolve."
  exit 1
}
printf "%s\n" "All done. No errors."

