Skip to content
Snippets Groups Projects
workgroup.pp 7.15 KiB
Newer Older
Adam Lewenberg's avatar
Adam Lewenberg committed
# Configure PAM to allow the control of access to a system using
# Stanford Workgroups.  This module installs a local LDAP proxy
# server that uses a Kerberos bind to the central service and
# allows anonymous local access to the directory information.
#
# There are two steps require to implement Workgroup control:
#
#   1. Request access to the directory data using the form at
#      http://tools.stanford.edu/dataowner.  The request is
#      for access to the suPrivilegGroup attribute.  The request
#      description should be similar to:
#
#         The XYZ department would like to use Workgroup membership to
#         control access to a set of Linux systems and requests access
#         to the suPrivilegeGroup attribute for users in the ABC
#         Workgroup stem.
#
#      The default principal name used to access the LDAP directory is
#      the host principal.
#
#   2. Configure any hosts that need the access control with either:
#      1) ldap proxy server and pam/nss ldap packages or 2) pam/nss
#      ldap packages that support kerberos binds to the directory.
#      This module will perform the required tasks.  In general,
#      systems should use kerberos bind packages where they are
#      available which current means newer debian or ubuntu systems.
#      RedHat systems require a slapd proxy.
#
# Examples:
#
#   To restrict access to a single Workgoup specify an LDAP filter
#   that selects the current suPrivilegeGroups.
#
#      base::pam::workgroup { 'anesthesia':
#        ensure      => 'present',
#        ldap_filter => '(suPrivilegeGroup=stanford:staff)',
#      }
#
#   To allow anyone in the workgroup stem access an LDAP filter does
#   not need to be specified.
#
#      base::pam::workgroup { 'anesthesia': ensure => 'present' }
#
# Testing:
#
#   To make sure that the correct account information is being
#   return the getent command can be used.  For example:
#
#     % getent passwd whm
#
#   On systems that have an ldap proxy installed a simple ldapsearch
#   can be used to verify anonymous directory connectivity.  For
#   example:
#
#     % ldapsearch -x
#
#   should return all of the posixAccount entries for the choosen
#   Workgroup stem.

define base::pam::workgroup (
  $ensure         = 'present',
  $ldap_host      = 'ldap.stanford.edu',
  $ldap_filter    = '(objectclass=posixAccount)',
  $ldap_proxy     = 'NONE',
  $ldap_base      = 'cn=Accounts,dc=stanford,dc=edu',
  $principal      = 'HOST',
  $workgroup_stem = 'NONE'
) {

  # Nice default for the stem
  case $workgroup_stem {
    'NONE':  { $stem = $name           }
    default: { $stem = $workgroup_stem }
  }

  # When the nslcd.conf file changes reload the changes.
  exec {'nslcd refresh':
    command     => '/etc/init.d/nslcd force-reload',
    path        => ['/bin','/usr/sbin'],
    refreshonly => true,
    require     => File['/etc/nslcd.conf'],
    returns     => 0,
    logoutput   => true,
  }

  case $ensure {

    'absent': {

      # Remove the packages and the configuration files directly
      # supporting the packages, but don't change nsswitch.conf.
      # That will need to be handled manually.
      file { '/etc/nslcd.conf': ensure => absent }
      case $::operatingsystem {
        'RedHat': {
          file { '/etc/pam_ldap.conf': ensure => absent }
          package {
            'nss-pam-ldapd': ensure => absent;
            'pam_ldap':      ensure => absent;
          }
        }
        'Debian', 'Ubuntu': {
          package {
            'libpam-ldapd': ensure => absent;
            'libnss-ldapd': ensure => absent;
          }
        }
        default: { fail('unrecognized operating system') }
      }
    }

    default: {

      # Turn off user management
      include user::managed::disabled
      # Add packages and configuration files.
      file { '/etc/nsswitch.conf':
        source => 'puppet:///modules/base/pam/etc/nsswitch.conf';
      }

      case $::operatingsystem {
        # RedHat requires a proxy server because the pam/nss support
        # available with RHEL does not support kerberos binds to the
        # directory.
        'RedHat': {
          $thisUID = 'nslcd'
          $thisGID = 'ldap'
          # Create a slapd proxy to allow anonymous local searches.
          $useProxy = true
          slapd_proxy::new {$::hostname:
            ensure       => present,
            principal    => $principal,
            ldapHost     => $ldap_host,
            ldapConfBase => $ldap_base
          }
          include base::pam::workgroup_redhat
          package {
            'nss-pam-ldapd': ensure => present;
            'pam_ldap':      ensure => present;
          }
          file { '/etc/pam_ldap.conf':
            content => template('base/pam/etc/pam_ldap.conf.erb'),
            require => Package['pam_ldap'],
          }
          file { '/etc/nslcd.conf':
            content => template('base/pam/etc/nslcd.conf.erb'),
            notify  => Exec['nslcd refresh'],
            require => Package['nss-pam-ldapd'],
          }
        }
        # Later versions of debian and ubuntu support pam/nss kerberos
        # binds to the directory which obviates the need for a slapd
        # proxy server.  Once can be used it desired, but recommended
        # practice is to not use a proxy.
        'Debian', 'Ubuntu': {
          $thisUID = 'nslcd'
          $thisGID = 'nslcd'
          package {
            'libpam-ldapd': ensure => present;
            'libnss-ldapd': ensure => present;
          }
          if $ldap_proxy == 'NONE' {
            $useProxy = false
            $ldapConfBase = $ldap_base
            file {
              '/etc/ldap':
                ensure => directory,
                mode   => 755;
              '/etc/ldap/ldap.conf':
                mode    => 644,
                content => template('base/pam/etc/ldap/ldap.conf.erb'),
                require => File['/etc/ldap'];
              '/var/run/nslcd':
                ensure  => directory,
                mode    => 755,
                owner   => $thisUID,
                group   => $thisGID,
                require => Package['libpam-ldapd','libnss-ldapd'];
            }
            package {
              'libsasl2-modules-gssapi-mit':
                ensure  => installed;
              'ldap-utils':
                ensure  => installed,
                require => File['/etc/ldap'];
            }
          } else {
            $useProxy = true
            slapd_proxy::new {$::hostname:
              ensure       => present,
              principal    => $principal,
              ldapHost     => $ldap_host,
              ldapConfBase => $ldap_base
            }
          }
          file { '/etc/nslcd.conf':
            content => template('base/pam/etc/nslcd.conf.erb'),
            notify  => Exec['nslcd refresh'],
            require => Package['libnss-ldapd'],
          }
        }
        default: { fail('unrecognized operating system') }
      }
    }
  }
}

# Over ride pam configuration on redhat systems

class base::pam::workgroup_redhat inherits base::pam::redhat {
  File['/etc/pam.d/system-auth'] { target => '/etc/pam.d/system-auth-ldap' }
  file {
    '/etc/pam.d/system-auth-ldap':
      mode   => 644,
      source => 'puppet:///modules/base/pam/etc/pam.d/system-auth-ldap',
  }
}