# Install Sendmail packages.
#
class sendmail::common {

    if !$mail_domain and $domain {
        $mail_domain = $domain
    }

    if $::operatingsystem != "OpenBSD" {
        package { "sendmail":
            ensure => installed,
            name   => [ "sendmail", "sendmail-cf", ],
            before => File["/etc/mail/certs"],
        }
        service { "sendmail":
            ensure  => running,
            enable  => true,
            require => Package["sendmail"],
        }
    }

    case $::operatingsystem {
        "centos","redhat","fedora": {
            file { "/etc/sysconfig/sendmail":
                ensure  => present,
                content => "DAEMON=no\nQUEUE=1h\n",
                owner   => "root",
                group   => "root",
                mode    => "0644",
                notify  => Service["sendmail"],
            }
            $ostype = "linux"
            $cabundle = "/etc/pki/tls/certs/ca-bundle.crt"
        }
        "ubuntu","debian": {
            $ostype = "linux"
            $cabundle = "/etc/ssl/certs/ca-certificates.crt"
        }
        "openbsd": {
            $ostype = "openbsd"
            $cabundle = "/etc/ssl/cert.pem"
        }
        default: {
            fail("sendmail module not supported on ${::operatingsystem}")
        }
    }

    file { "/etc/mail/certs":
        ensure  => directory,
        mode    => "0755",
        owner   => "root",
        group   => $::operatingsystem ? {
            "openbsd" => "wheel",
            default   => "root",
        },
    }
    exec { "populate-etc-mail-certs":
        path    => "/bin:/usr/bin:/sbin:/usr/sbin",
        command => "csplit -k ${cabundle} '/BEGIN/' '{1000}' ; sh -c 'for i in x* ; do name=`openssl x509 -hash -noout -in \$i`.0 ; openssl x509 -hash -in \$i -out \$name ; done' && rm -f x* .0",
        cwd     => "/etc/mail/certs",
        onlyif  => "find /etc/mail/certs ! -newer ${cabundle} | egrep '.*' || [ -z \"`ls /etc/mail/certs`\" ]",
        require => File["/etc/mail/certs"],
    }

}


# Configure Sendmail submission.
#
# === Global variables
#
#   $mail_server:
#       Hostname of mail server.
#
class sendmail::client inherits sendmail::common {

    if !$mail_server {
        $mail_server = "127.0.0.1"
    }

    file { "/etc/mail/submit.mc":
        path    => $::operatingsystem ? {
            "openbsd" => "/usr/share/sendmail/cf/submit.mc",
            default   => "/etc/mail/submit.mc",
        },
        ensure  => present,
        content => template("sendmail/submit.mc.erb", "sendmail/submit.mc.msp.erb"),
        owner   => "root",
        group   => $::operatingsystem ? {
            "openbsd" => "bin",
            default   => "root",
        },
        mode    => "0644",
        notify  => Exec["make submit.cf"],
        require => $::operatingsystem ? {
            "openbsd" => undef,
            default   => Package["sendmail"],
        },
    }

    exec { "make submit.cf":
        path        => "/bin:/usr/bin:/sbin:/usr/sbin:/etc/mail",
        cwd         => $::operatingsystem ? {
            "openbsd" => "/usr/share/sendmail/cf",
            default   => "/etc/mail",
        },
        refreshonly => true,
        notify      => $::operatingsystem ? {
            "openbsd" => undef,
            default   => Service["sendmail"],
        },
    }

    file { "/etc/mail/submit.cf":
        ensure  => present,
        owner   => "root",
        group   => $::operatingsystem ? {
            "openbsd" => "wheel",
            "ubuntu"  => "smmsp",
            default   => "root",
        },
        mode    => "0644",
        source  => $::operatingsystem ? {
            "openbsd" => "/usr/share/sendmail/cf/submit.cf",
            default   => undef,
        },
        require => Exec["make submit.cf"],
    }

    case $::operatingsystem {
        "centos","redhat","fedora": {
            case $mail_server {
                "127.0.0.1","localhost": {
                    File["/etc/sysconfig/sendmail"] {
                        content => "DAEMON=yes\nQUEUE=1h\n",
                    }
                }
            }
        }
    }

}


# Configure Sendmail submission using port 587.
#
class sendmail::client::msa inherits sendmail::client {

    File["/etc/mail/submit.mc"] {
        content => template("sendmail/submit.mc.erb", "sendmail/submit.mc.msa.erb"),
    }

}


# Configure Sendmail server.
#
#   $mail_domain:
#       SMTP domain name.
#
#   $masquerade_exception:
#       Everything is masqueraded to $mail_domain except these hosts.
#
#   $sendmail_auth_mech:
#       List of authentication mechanisms to use. Defaults to PLAIN and LOGIN.
#
#   $sendmail_ssl_key:
#
#   $sendmail_ssl_cert:
#
class sendmail::server inherits sendmail::common {

    include procmail

    if !$sendmail_auth_mech {
        $sendmail_auth_mech = [ "PLAIN", "LOGIN", ]
    }

    if !$masquerade_exception {
        $masquerade_exception = []
    }

    $ssl_key = basename($sendmail_ssl_key)
    $ssl_cert = basename($sendmail_ssl_cert)
    if $sendmail_ssl_chain {
        $ssl_chain = basename($sendmail_ssl_chain)
    }

    selinux::manage_fcontext { "/etc/smrsh(/.*)?":
        type => "sendmail_exec_t",
    }

    case $::operatingsystem {
        "centos","redhat","fedora": {
            File["/etc/sysconfig/sendmail"] {
                content => "DAEMON=yes\nQUEUE=1h\n",
            }
        }
        default: {
            fail("sendmail::server not supported in '${::operatingsystem}'")
        }
    }

    file { "/etc/pki/tls/private/${ssl_key}":
        ensure => present,
        source => $sendmail_ssl_key,
        mode   => "0600",
        owner  => "root",
        group  => "root",
        notify => Service["sendmail"],
    }
    file { "/etc/pki/tls/certs/${ssl_cert}":
        ensure => present,
        source => $sendmail_ssl_cert,
        mode   => "0644",
        owner  => "root",
        group  => "root",
        notify => Service["sendmail"],
    }
    if $ssl_chain {
        file { "/etc/pki/tls/certs/${ssl_chain}":
            ensure => present,
            source => $sendmail_ssl_chain,
            mode   => "0644",
            owner  => "root",
            group  => "root",
            notify => Service["sendmail"],
        }
    }

    file { "sendmail.mc":
        name    => $::operatingsystem ? {
            "openbsd" => "/usr/share/sendmail/cf/sendmail.mc",
            default   => "/etc/mail/sendmail.mc",
        },
        content => template("sendmail/sendmail.mc.erb"),
        owner   => "root",
        group   => "root",
        mode    => "0644",
        notify  => Exec["make sendmail.cf"],
    }
    exec { "make sendmail.cf":
        path        => "/bin:/usr/bin:/sbin:/usr/sbin:/etc/mail",
        cwd         => $::operatingsystem ? {
            "openbsd" => "/usr/share/sendmail/cf",
            default   => "/etc/mail",
        },
        require     => $::operatingsystem ? {
            "openbsd" => undef,
            default   => Package["sendmail"],
        },
        refreshonly => true,
    }
    file { "/etc/mail/sendmail.cf":
        ensure  => present,
        mode    => "0644",
        owner   => "root",
        group   => "root",
        source  => $::operatingsystem ? {
            "openbsd" => "/usr/share/sendmail/cf/sendmail.cf",
            default   => undef,
        },
        require => Exec["make sendmail.cf"],
        notify  => Service["sendmail"],
    }

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

    file { "/etc/mail/access":
        ensure => present,
        source => [
          "puppet:///files/mail/access.${fqdn}",
          "puppet:///files/mail/access",
          "puppet:///modules/sendmail/empty",
        ],
        mode   => "0644",
        owner  => "root",
        group  => "root",
        notify => Exec["make access.db"],
    }
    exec { "make access.db":
        path        => "/bin:/usr/bin:/sbin:/usr/sbin",
        command     => "makemap hash /etc/mail/access < /etc/mail/access",
        refreshonly => true,
        notify      => Service["sendmail"],
    }

    file { "/etc/mail/genericstable":
        ensure => present,
        source => [
          "puppet:///files/mail/genericstable.${fqdn}",
          "puppet:///files/mail/genericstable",
          "puppet:///modules/sendmail/empty",
        ],
        mode   => "0644",
        owner  => "root",
        group  => "root",
        notify => Exec["make genericstable.db"],
    }
    exec { "make genericstable.db":
        path        => "/bin:/usr/bin:/sbin:/usr/sbin",
        command     => "makemap hash /etc/mail/genericstable < /etc/mail/genericstable",
        refreshonly => true,
        notify      => Service["sendmail"],
    }

    file { "/etc/mail/mailertable":
        ensure => present,
        source => [
          "puppet:///files/mail/mailertable.${fqdn}",
          "puppet:///files/mail/mailertable",
          "puppet:///modules/sendmail/empty",
        ],
        mode   => "0644",
        owner  => "root",
        group  => "root",
        notify => Exec["make mailertable.db"],
    }
    exec { "make mailertable.db":
        path        => "/bin:/usr/bin:/sbin:/usr/sbin",
        command     => "makemap hash /etc/mail/mailertable < /etc/mail/mailertable",
        refreshonly => true,
        notify      => Service["sendmail"],
    }

    file { "/etc/mail/virtusertable":
        ensure => present,
        source => [
          "puppet:///files/mail/virtusertable.${fqdn}",
          "puppet:///files/mail/virtusertable",
          "puppet:///modules/sendmail/empty",
        ],
        mode   => "0644",
        owner  => "root",
        group  => "root",
        notify => Exec["make virtusertable.db"],
    }
    exec { "make virtusertable.db":
        path        => "/bin:/usr/bin:/sbin:/usr/sbin",
        command     => "makemap hash /etc/mail/virtusertable < /etc/mail/virtusertable",
        refreshonly => true,
        notify      => Service["sendmail"],
    }

    file { "/etc/mail/local-host-names":
        ensure => present,
        source => [
          "puppet:///files/mail/local-host-names.${fqdn}",
          "puppet:///files/mail/local-host-names",
          "puppet:///modules/sendmail/empty",
        ],
        mode   => "0644",
        owner  => "root",
        group  => "root",
        notify => Service["sendmail"],
    }

}
