# Install Postfix packages.
#
# === Global variables
#
#   $mail_domain:
#       SMTP domain name.
#
#   $mydestination:
#       Destinations we will accept and relay mail for.
#
#   $mail_server:
#       Optional smarthost used for sending mail.
#
#   $postfix_hostname:
#       Hostname of postfix server. Defaults to $fqdn.
#
#   $postfix_interfaces:
#       Interfaces to listen. Defaults to 'localhost'.
#
#   $postfix_networks:
#       Optional value for mynetworks variable.
#
#   $postfix_home_mailbox:
#       Optional value for home_mailbox variable.
#
#   $postfix_rbl:
#       List of RBL hosts to use.
#
#   $postfix_key:
#       Path to SSL private key. Defaults to puppet client key.
#
#   $postfix_cert:
#       Path to SSL certificate. Defaults to puppet client certificate.
#
#   $postfix_chain:
#       Path to intermediary CA cert.
#
#   $postgrey:
#       Whether to run postgrey or not.
#
#   $submission:
#       Whether to enable submission (and sasl::saslauthd).
#
#   $cyrus_lmtp:
#       Whether to enable cyrus-lmtp delivery.
class postfix {

    include ssl

    if !$postfix_key {
        $postfix_key = "${puppet_ssldir}/private_keys/${homename}.pem"
    }
    if !$postfix_cert {
        $postfix_cert = "${puppet_ssldir}/certs/${homename}.pem"
    }

    if !$mail_domain {
        if $domain {
            $mail_domain = $domain
        } else {
            fail("Failed to set \$mail_domain, missing \$domain")
        }
    }

    if !$postfix_hostname {
        if $fqdn {
            $postfix_hostname = $fqdn
        } else {
            fail("Failed to set \$postfix_hostname, missing \$fqdn")
        }
    }

    if !$postfix_interfaces {
        $postfix_interfaces = "localhost"
    }

    file { "${ssl::certs}/postfix.crt":
        ensure  => present,
        source  => $postfix_cert,
        mode    => "0644",
        owner   => "root",
        group   => "root",
        require => Package["postfix"],
        notify  => Service["postfix"],
    }

    if $postfix_chain {
        file { "${ssl::certs}/postfix-chain.crt":
            ensure  => present,
            source  => $postfix_chain,
            mode    => "0644",
            owner   => "root",
            group   => "root",
            require => Package["postfix"],
            notify  => Service["postfix"],
        }
    }

    file { "${ssl::private}/postfix.key":
        ensure  => present,
        source  => $postfix_key,
        mode    => "0640",
        owner   => "root",
        group   => "postfix",
        require => Package["postfix"],
        notify  => Service["postfix"],
    }
    
    exec { "usermod-postfix-ssl-cert":
        path    => "/bin:/usr/bin:/sbin:/usr/sbin",
        command => "usermod -a -G ssl-cert postfix",
        unless  => "id -n -G postfix | grep '\\bssl-cert\\b'",
        notify  => Service["postfix"],
    }

    if $postgrey {
        case $::operatingsystem {
            "debian","ubuntu": {
                package {"postgrey": ensure => installed,}
                exec { "usermod-postfix":
                    path    => "/bin:/usr/bin:/sbin:/usr/sbin",
                    command => "usermod -a -G mail postfix",
                    unless  => "id -n -G postfix | grep '\\bmail\\b'",
                }
            }
            default: {
                fail("Postgrey module not yet supported in ${::operatingsystem}.")
            }
        }
    }

    package { "postfix":
        ensure => installed,
    }

    service { "postfix":
        ensure  => running,
        enable  => true,
        require => Package["postfix"],
    }

    file { "/etc/postfix/main.cf":
        ensure  => present,
        mode    => "0644",
        owner   => "root",
        group   => "root",
        content => template("postfix/main.cf.erb"),
        notify  => Service["postfix"],
        require => Package["postfix"],
    }

    if $submission {
        include sasl::saslauthd
        file { "/var/spool/postfix/var":
            ensure => directory,
            mode => "0755",
            owner => "root",
            group => "root",
        }
        file { "/var/spool/postfix/var/run":
            ensure => directory,
            mode => "0755",
            owner => "root",
            group => "root",
        }
        file { "/var/spool/postfix/var/run/saslauthd":
            ensure => directory,
            mode => "0755",
            owner => "root",
            group => "root",
        }
        mount { "/var/spool/postfix/var/run/saslauthd":
            ensure  => mounted,
            atboot  => true,
            device => "/var/run/saslauthd",
            options => "bind,noauto",
            fstype => "bind",
            dump    => "0",
            pass    => "0",
        }
        file { "/etc/postfix/sasl/smtpd.conf":
            ensure  => present,
            mode    => "0644",
            owner   => "root",
            group   => "root",
            source => "puppet:///modules/postfix/smtpd.conf",
            notify  => Service["postfix"],
        }

    }

    file { "/etc/postfix/master.cf":
        ensure  => present,
        mode    => "0644",
        owner   => "root",
        group   => "root",
        content => template("postfix/master.cf.erb"),
        notify  => Service["postfix"],
        require => Package["postfix"],
    }

    file { "/etc/aliases":
        ensure  => present,
        source  => [
          "puppet:///files/mail/aliases.${homename}",
          "puppet:///files/mail/aliases",
          "puppet:///modules/postfix/aliases",
        ],
        mode    => "0644",
        owner   => "root",
        group   => "root",
        notify  => Exec["newaliases"],
    }
    exec { "newaliases":
        path        => "/bin:/usr/bin:/sbin:/usr/sbin",
        refreshonly => true,
    }

    file { "/etc/postfix/virtual":
        ensure  => present,
        source  => [
          "puppet:///files/mail/virtual.${homename}",
          "puppet:///files/mail/virtual",
          "puppet:///modules/postfix/empty",
        ],
        mode    => "0644",
        owner   => "root",
        group   => "root",
        notify  => Exec["postmap /etc/postfix/virtual"],
    }
    exec { "postmap /etc/postfix/virtual":
        path        => "/bin:/usr/bin:/sbin:/usr/sbin",
        refreshonly => true,
    }

}

