
# Install and configure ldap authentication
#
# === Global variables
#
#   $ldap_server:
#       Array containing LDAP server URI's.
#
#   $ldap_basedn:
#       LDAP base DN.
#
#   $ldap_login_umask:
#       Default umask for LDAP users in OpenBSD, defaults to 077.
#
class ldap::auth inherits ldap::client {

    $ldap_uri = inline_template('<%= ldap_server.join(" ") -%>')

    case $operatingsystem {
        CentOS: {
            package { "nss_ldap":
                ensure => installed,
            }
            exec { "authconfig --enableldap --enableldapauth --enableldapssl --ldapserver='${ldap_uri}' --ldapbasedn='${ldap_basedn}' --update":
                path    => "/bin:/usr/bin:/sbin:/usr/sbin",
                unless  => 'cat /etc/sysconfig/authconfig | egrep "^USELDAPAUTH=yes$|^USELDAP=yes$" | wc -l | egrep "^2$"',
                before  => [ Augeas["pam-ldap-conf"],
                             File["/etc/openldap/ldap.conf"], ],
                require => Package["nss_ldap"],
            }
            augeas { "pam-ldap-conf":
                context  => "/files/etc/ldap.conf",
                changes  => [ "set nss_paged_results yes",
                              "set pam_password exop",
                              "set ssl on", ],
                onlyif   => [ "get nss_paged_results != yes",
                              "get pam_password != exop",
                              "get ssl != on", ],
            }
        }
	Ubuntu: {
            package { "ldap-auth-client":
                ensure => installed,
            }
            exec { "auth-client-config -t nss -p lac_ldap":
                path    => "/bin:/usr/bin:/sbin:/usr/sbin",
                unless  => "auth-client-config -t nss -p lac_ldap -s",
                require => Package["ldap-auth-client"],
                before  => Augeas["pam-ldap-conf"],
                notify  => Exec["nssldap-update-ignoreusers"],
            }
            exec { "nssldap-update-ignoreusers":
                path        => "/bin:/usr/bin:/sbin:/usr/sbin",
                refreshonly => true,
            }
            augeas { "pam-ldap-conf":
                context => "/files/etc/ldap.conf",
                changes => [ "set uri '${ldap_uri}'",
                             "set base ${ldap_basedn}",
                             "set nss_paged_results yes",
                             "set pam_password exop",
			     "rm rootbinddn",
                             "set ssl on", ],
                onlyif  => [ "get uri != '${ldap_uri}'",
                             "get base != ${ldap_basedn}",
                             "get nss_paged_results != yes",
                             "get pam_password != exop",
			     "get rootbinddn == 'cn=manager,dc=example,dc=net'",
                             "get ssl != on", ],
            }
        }
	Debian: {
            package {[ "libnss-ldap",
		       "libpam-ldap" ]:
                ensure => installed,
            }
## Debian lacks some lenses. nss-ldap-conf and pam_ldap-conf needs corresponding files
## to /usr/share/augeas/lenses/dist/spacevars.aug. More info at: 
## https://github.com/jwm/augeas/commit/8f768f45779048cbd95b5b7d71682b808d41bfd3
## There isn't lens for nsswitch.conf either. nss-ldap-conf and pam_ldap-conf are tested, nsswitch isn't.
#            augeas { "nss-ldap-conf":
#                context => "/files/etc/libnss-ldap.conf",
#                changes => [ "set uri '${ldap_uri}'",
#                             "set base ${ldap_basedn}",
#                             "set nss_paged_results yes",
#                             "set pam_password exop",
#                             "rm rootbinddn",
#                             "set ssl on", ],
#                onlyif  => [ "get uri != '${ldap_uri}'",
#                             "get base != ${ldap_basedn}",
#                             "get nss_paged_results != yes",
#                             "get pam_password != exop",
#                             "get rootbinddn == 'cn=manager,dc=example,dc=net'",
#                             "get ssl != on", ],
#		require => Package["libnss-ldap"],
#            }
#            augeas { "pam_ldap-conf":
#                context => "/files/etc/pam_ldap.conf",
#                changes => [ "set uri '${ldap_uri}'",
#                             "set base ${ldap_basedn}",
#                             "set nss_paged_results yes",
#                             "set pam_password exop",
#                             "rm rootbinddn",
#                             "set ssl on", ],
#                onlyif  => [ "get uri != '${ldap_uri}'",
#                             "get base != ${ldap_basedn}",
#                             "get nss_paged_results != yes",
#                             "get pam_password != exop",
#                             "get rootbinddn == 'cn=manager,dc=example,dc=net'",
#                             "get ssl != on", ],
#		require => Package["libpam-ldap"],
#            }
#            augeas { "nsswitch-conf":
#                context => "/files/etc/nsswitch.conf",
#                changes => [ "set passwd: 'files ldap'",
#                             "set group: 'files ldap'",
#                             "set shadow: 'files ldap'", ],
#                onlyif  => [ "get passwd: != 'files ldap'",
#                             "get group: != 'files ldap'",
#                             "get shadow: != 'files ldap'", ],
#		require => [ Augeas["pam_ldap-conf"],
#                             Augeas["nss-ldap-conf"], ],
#            }
        }
        OpenBSD: {
            if ! $ldap_login_umask {
                $ldap_login_umask = "077"
            }
            package { "login_ldap":
                ensure => installed,
            }
            file { "/etc/login.conf":
                ensure  => present,
                content => template("ldap/login.conf.erb"),
                mode    => 0644,
                owner   => root,
                group   => wheel,
                require => [ File["/etc/openldap/ldap.conf"],
                             Package["login_ldap"], ]
            }
        }
        default: {
            fail("ldap::auth not supported on ${operatingsystem}")
        }
    }

}

# Install and configure ldap client
#
# === Global variables
#
#   $ldap_server:
#       Array containing LDAP server URI's.
#
#   $ldap_basedn:
#       LDAP base DN.
#
class ldap::client {

    package { "openldap-client":
        name   => $operatingsystem ? {
            "debian"  => "ldap-utils",
            "ubuntu"  => "ldap-utils",
            "openbsd" => "openldap-client",
            default => "openldap-clients",
        },
        ensure => $operatingsystem ? {
            darwin  => absent,
            default => installed,
        },
    }

    file { "/etc/openldap/ldap.conf":
        ensure  => present,
        content => template("ldap/ldap.conf.erb"),
        path    => $operatingsystem ? {
            "debian"  => "/etc/ldap/ldap.conf",
            "ubuntu"  => "/etc/ldap/ldap.conf",
            default => "/etc/openldap/ldap.conf",
        },
        mode    => 0644,
        owner   => root,
        group   => $operatingsystem ? {
            "darwin"  => wheel,
            "openbsd" => wheel,
            default => root,
        },
        require => Package["openldap-client"],
    }

}


# Install python ldap bindings.
#
class ldap::client::python {

    package { "python-ldap":
        name   => $operatingsystem ? {
            openbsd => "py-ldap",
            default => "python-ldap",
        },
        ensure => installed,
    }

}


# Install Ruby ldap bindings.
#
class ldap::client::ruby {

    case $operatingsystem {
        "ubuntu","debian": {
            $pkgname = regsubst($rubyversion, '^([0-9]+\.[0-9]+)\..*', 'libldap-ruby\1')
        }
        default: {
            $pkgname = "ruby-ldap"
        }
    }

    package { "ruby-ldap":
        name   => $pkgname,
        ensure => installed,
    }

}

# Install OpenLDAP server.
#
#   $ldap_datadir:
#       Directory for LDAP databases. Defaults to /srv/ldap.
#
class ldap::server {

    case $operatingsystem {
        "debian","ubuntu": {
            $user = "openldap"
            $group = "openldap"
            $package_name = "slapd"
            $service_name = "slapd"
        }
        "fedora": {
            $user = "ldap"
            $group = "ldap"
            $package_name = "openldap-servers"
            $service_name = "slapd"
        }
        "centos": {
            $user = "ldap"
            $group = "ldap"
            $package_name = $operatingsystemrelease ? {
                /^5/ => [ "openldap-servers", "openldap-servers-overlays" ],
                /^6/ => "openldap-servers",
            }
            $service_name = $operatingsystemrelease ? {
                /^5/ => "ldap",
                /^6/ => "slapd",
            }
        }
    }

    if $ldap_datadir {
        file { "${ldap_datadir}":
            ensure  => directory,
            mode    => 0700,
            owner   => $user,
            group   => $group,
            require => Package["openldap-server"],
        }
        file { "/srv/ldap":
            ensure  => link,
            target  => "${ldap_datadir}",
            require => File["${ldap_datadir}"],
        }
    } else {
        file { "/srv/ldap":
            ensure  => directory,
            mode    => 0700,
            owner   => $user,
            group   => $group,
            require => Package["openldap-server"],
        }
    }

    package { "openldap-server":
        name   => $package_name,
        ensure => installed,
    }

    service { "slapd":
        name    => $service_name,
        ensure  => running,
        enable  => true,
        require => Package ["openldap-server"]
    }

    file { "slapd.conf":
	path => $operatingsystem ? {
		"ubuntu" => "/etc/ldap/slapd.conf",
		"debian" => "/etc/ldap/slapd.conf",
		"centos" => "/etc/openldap/slapd.conf",
		"fedora" => "/etc/openldap/slapd.conf",
	},
        ensure  => present,
        source  => [ "puppet:///files/ldap/slapd.conf.${fqdn}",
                     "puppet:///files/ldap/slapd.conf", ],
        mode    => 0640,
        owner   => root,
        group   => $group,
        notify  => Service["slapd"],
        require => Package["openldap-server"],
    }

    file { "/srv/ldap/DB_CONFIG":
        ensure  => present,
        source  => [ "puppet:///files/ldap/DB_CONFIG.${fqdn}",
                     "puppet:///files/ldap/DB_CONFIG",
                     "puppet:///modules/ldap/DB_CONFIG", ],
        mode    => 0644,
        owner   => root,
        group   => root,
        require => Package["openldap-server"],
    }

    ldap::server::schema { "apple-auth": }
    ldap::server::schema { "apple": }
    ldap::server::schema { "autofs": }
    ldap::server::schema { "dnszone": }
    ldap::server::schema { "hdb": }
    ldap::server::schema { "openssh-lpk": }
    ldap::server::schema { "rfc2307bis": }
    ldap::server::schema { "samba": }

}


# Install custom schema to OpenLDAP.
#
# === Parameters
#
#   $name:
#       Schema name.
#
# === Sample usage
#
# ldap::server::schema { "samba": }
#
define ldap::server::schema() {

    include ldap::server

    file { "${name}.schema":
	path => $operatingsystem ? {
                "ubuntu" => "/etc/ldap/schema/${name}.schema",
                "debian" => "/etc/ldap/schema/${name}.schema",
                "centos" => "/etc/openldap/schema/${name}.schema",
		"fedora" => "/etc/openldap/schema/${name}.schema",
	},
        ensure  => present,
        source  => [ "puppet:///files/ldap/${name}.schema",
                     "puppet:///modules/ldap/${name}.schema", ],
        mode    => 0644,
        owner   => root,
        group   => root,
        require => Package["openldap-server"],
    }
}

