BryanDavis has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/277702

Change subject: [WIP] Add LdapAuthentication role
......................................................................

[WIP] Add LdapAuthentication role

Add a role to provision an openldap server and "ldapauth" wiki.

Bug: T128501
Change-Id: I11eb9e8ae9dc26ba9ea52219b770d9736cb914b3
---
M puppet/hieradata/common.yaml
A puppet/modules/openldap/files/rfc2307bis.schema
A puppet/modules/openldap/manifests/init.pp
A puppet/modules/openldap/templates/base-acls.erb
A puppet/modules/openldap/templates/base-indices.erb
A puppet/modules/openldap/templates/default.erb
A puppet/modules/openldap/templates/ldap.conf.erb
A puppet/modules/openldap/templates/slapd.erb
A puppet/modules/role/manifests/ldapauth.pp
A puppet/modules/role/templates/ldapauth/LdapAuthentication.php.erb
A puppet/modules/role/templates/ldapauth/check_db.erb
A puppet/modules/role/templates/ldapauth/create_db.erb
12 files changed, 782 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/vagrant 
refs/changes/02/277702/1

diff --git a/puppet/hieradata/common.yaml b/puppet/hieradata/common.yaml
index 30c5b2e..48e5167 100644
--- a/puppet/hieradata/common.yaml
+++ b/puppet/hieradata/common.yaml
@@ -279,6 +279,10 @@
 payments::branch: fundraising/REL1_25
 payments::dir: /vagrant/mediawiki-fr
 
+role::ldapauth::proxy_agent_password: vagrant_agent
+role::ldapauth::writer_password: vagrant_writer
+role::ldapauth::admin_password: vagrant_admin
+
 role::mediawiki::hostname: "dev%{hiera('mediawiki::multiwiki::base_domain')}"
 
 role::quips::vhost_name: "quips%{hiera('mwv::tld')}%{::port_fragment}"
diff --git a/puppet/modules/openldap/files/rfc2307bis.schema 
b/puppet/modules/openldap/files/rfc2307bis.schema
new file mode 100644
index 0000000..db34365
--- /dev/null
+++ b/puppet/modules/openldap/files/rfc2307bis.schema
@@ -0,0 +1,288 @@
+# builtin
+#
+#attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'
+#  DESC 'An integer uniquely identifying a user in an administrative domain'
+#  EQUALITY integerMatch
+#  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+#  SINGLE-VALUE )
+
+# builtin
+#
+#attributetype ( 1.3.6.1.1.1.1.1 NAME 'gidNumber'
+#  DESC 'An integer uniquely identifying a group in an
+#        administrative domain'
+#  EQUALITY integerMatch
+#  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+#  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.2 NAME 'gecos'
+  DESC 'The GECOS field; the common name'
+  EQUALITY caseIgnoreIA5Match
+  SUBSTR caseIgnoreIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.3 NAME 'homeDirectory'
+  DESC 'The absolute path to the home directory'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.4 NAME 'loginShell'
+  DESC 'The path to the login shell'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.6 NAME 'shadowMin'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.7 NAME 'shadowMax'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.8 NAME 'shadowWarning'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.9 NAME 'shadowInactive'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.10 NAME 'shadowExpire'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.11 NAME 'shadowFlag'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.12 NAME 'memberUid'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
+  DESC 'Netgroup triple'
+  EQUALITY caseIgnoreIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.15 NAME 'ipServicePort'
+  DESC 'Service port number'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol'
+  DESC 'Service protocol name'
+  SUP name )
+
+attributetype ( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber'
+  DESC 'IP protocol number'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber'
+  DESC 'ONC RPC number'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE )
+attributetype ( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber'
+  DESC 'IPv4 addresses as a dotted decimal omitting leading
+        zeros or IPv6 addresses as defined in RFC2373'
+  SUP name )
+
+attributetype ( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber'
+  DESC 'IP network as a dotted decimal, eg. 192.168,
+        omitting leading zeros'
+  SUP name
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber'
+  DESC 'IP netmask as a dotted decimal, eg. 255.255.255.0,
+        omitting leading zeros'
+  EQUALITY caseIgnoreIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.22 NAME 'macAddress'
+  DESC 'MAC address in maximal, colon separated hex
+        notation, eg. 00:00:92:90:ee:e2'
+  EQUALITY caseIgnoreIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.23 NAME 'bootParameter'
+  DESC 'rpc.bootparamd parameter'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.24 NAME 'bootFile'
+  DESC 'Boot image name'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetype ( 1.3.6.1.1.1.1.26 NAME 'nisMapName'
+  DESC 'Name of a A generic NIS map'
+  SUP name )
+
+attributetype ( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry'
+  DESC 'A generic NIS entry'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.28 NAME 'nisPublicKey'
+  DESC 'NIS public key'
+  EQUALITY octetStringMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.29 NAME 'nisSecretKey'
+  DESC 'NIS secret key'
+  EQUALITY octetStringMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.30 NAME 'nisDomain'
+  DESC 'NIS domain'
+  EQUALITY caseIgnoreIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
+
+attributetype ( 1.3.6.1.1.1.1.31 NAME 'automountMapName'
+  DESC 'automount Map Name'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.32 NAME 'automountKey'
+  DESC 'Automount Key value'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.1.1.1.33 NAME 'automountInformation'
+  DESC 'Automount information'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY
+  DESC 'Abstraction of an account with POSIX attributes'
+  MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
+  MAY ( userPassword $ loginShell $ gecos $
+        description ) )
+
+objectclass ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' SUP top AUXILIARY
+  DESC 'Additional attributes for shadow passwords'
+  MUST uid
+  MAY ( userPassword $ description $
+        shadowLastChange $ shadowMin $ shadowMax $
+        shadowWarning $ shadowInactive $
+        shadowExpire $ shadowFlag ) )
+
+objectclass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' SUP top AUXILIARY
+  DESC 'Abstraction of a group of accounts'
+  MUST gidNumber
+  MAY ( userPassword $ memberUid $
+        description ) )
+
+objectclass ( 1.3.6.1.1.1.2.3 NAME 'ipService' SUP top STRUCTURAL
+  DESC 'Abstraction an Internet Protocol service.
+        Maps an IP port and protocol (such as tcp or udp)
+        to one or more names; the distinguished value of
+        the cn attribute denotes the services canonical
+        name'
+  MUST ( cn $ ipServicePort $ ipServiceProtocol )
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' SUP top STRUCTURAL
+  DESC 'Abstraction of an IP protocol. Maps a protocol number
+        to one or more names. The distinguished value of the cn
+        attribute denotes the protocols canonical name'
+  MUST ( cn $ ipProtocolNumber )
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.5 NAME 'oncRpc' SUP top STRUCTURAL
+  DESC 'Abstraction of an Open Network Computing (ONC)
+       [RFC1057] Remote Procedure Call (RPC) binding.
+       This class maps an ONC RPC number to a name.
+       The distinguished value of the cn attribute denotes
+       the RPC services canonical name'
+  MUST ( cn $ oncRpcNumber )
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.6 NAME 'ipHost' SUP top AUXILIARY
+  DESC 'Abstraction of a host, an IP device. The distinguished
+        value of the cn attribute denotes the hosts canonical
+        name. Device SHOULD be used as a structural class'
+  MUST ( cn $ ipHostNumber )
+  MAY ( userPassword $ l $ description $ manager ) )
+
+objectclass ( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' SUP top STRUCTURAL
+  DESC 'Abstraction of a network. The distinguished value of
+        the cn attribute denotes the networks canonical name'
+  MUST ipNetworkNumber
+  MAY ( cn $ ipNetmaskNumber $ l $ description $ manager ) )
+
+objectclass ( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL
+  DESC 'Abstraction of a netgroup. May refer to other netgroups'
+  MUST cn
+  MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) )
+
+objectclass ( 1.3.6.1.1.1.2.9 NAME 'nisMap' SUP top STRUCTURAL
+  DESC 'A generic abstraction of a NIS map'
+  MUST nisMapName
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.10 NAME 'nisObject' SUP top STRUCTURAL
+  DESC 'An entry in a NIS map'
+  MUST ( cn $ nisMapEntry $ nisMapName )
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' SUP top AUXILIARY
+  DESC 'A device with a MAC address; device SHOULD be
+        used as a structural class'
+  MAY macAddress )
+
+objectclass ( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' SUP top AUXILIARY
+  DESC 'A device with boot parameters; device SHOULD be
+        used as a structural class'
+  MAY ( bootFile $ bootParameter ) )
+
+objectclass ( 1.3.6.1.1.1.2.14 NAME 'nisKeyObject' SUP top AUXILIARY
+  DESC 'An object with a public and secret key'
+  MUST ( cn $ nisPublicKey $ nisSecretKey )
+  MAY ( uidNumber $ description ) )
+
+objectclass ( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' SUP top AUXILIARY
+  DESC 'Associates a NIS domain with a naming context'
+  MUST nisDomain )
+
+objectclass ( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL
+  MUST ( automountMapName )
+  MAY description )
+
+objectclass ( 1.3.6.1.1.1.2.17 NAME 'automount' SUP top STRUCTURAL
+  DESC 'Automount information'
+  MUST ( automountKey $ automountInformation )
+  MAY description )
+## namedObject is needed for groups without members
+objectclass ( 1.3.6.1.4.1.5322.13.1.1 NAME 'namedObject' SUP top
+       STRUCTURAL MAY cn )
+
diff --git a/puppet/modules/openldap/manifests/init.pp 
b/puppet/modules/openldap/manifests/init.pp
new file mode 100644
index 0000000..3439ebd
--- /dev/null
+++ b/puppet/modules/openldap/manifests/init.pp
@@ -0,0 +1,119 @@
+# == Class: openldap
+#
+# This class installs slapd and configures it with a single suffix hdb
+# database. Based on the openldap class from
+# https://phabricator.wikimedia.org/diffusion/OPUP/
+#
+# === Parameters
+#
+# [*suffix*]
+#   Distinguished name of the root of the subtree managed by this server.
+#
+# [*datadir*]
+#   The datadir this suffix will be installed, e.g. "/var/lib/ldap"
+#
+# [*admin_dn*]
+#   Distinguished name of admin user.
+#
+# [*admin_password*]
+#   Password for admin user.
+#
+# [*logging*]
+#   Specify the kind of logging desired. Defaults to "sync stats" And it is
+#   not named loglevel cause that's a puppet metaparameter
+#
+class openldap(
+    $suffix,
+    $datadir,
+    $admin_dn,
+    $admin_password,
+    $logging = 'sync stats',
+) {
+    require_package('slapd', 'ldap-utils', 'python-ldap')
+
+    service { 'slapd':
+        ensure     => running,
+        hasstatus  => true,
+        hasrestart => true,
+        require    => [
+            Exec['rm_slapd.d'],
+            File[$datadir],
+            File['/etc/ldap/ldap.conf'],
+        ]
+    }
+
+    file { $datadir:
+        ensure  => directory,
+        recurse => false,
+        owner   => 'openldap',
+        group   => 'openldap',
+        mode    => '0750',
+        force   => true,
+        require => Package['slapd'],
+    }
+
+    file { '/etc/ldap/slapd.conf' :
+        ensure  => present,
+        owner   => 'openldap',
+        group   => 'openldap',
+        mode    => '0440',
+        content => template('openldap/slapd.erb'),
+        require => Package['slapd'],
+        notify  => Service['slapd']
+    }
+
+    file { '/etc/default/slapd' :
+        ensure  => present,
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0444',
+        content => template('openldap/default.erb'),
+        require => Package['slapd'],
+        notify  => Service['slapd']
+    }
+
+    file { '/etc/ldap/schema/rfc2307bis.schema' :
+        ensure  => present,
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0444',
+        source  => 'puppet:///modules/openldap/rfc2307bis.schema',
+        require => Package['slapd'],
+        notify  => Service['slapd']
+    }
+
+    file { '/etc/ldap/acls.conf' :
+        ensure  => present,
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0444',
+        content => template('openldap/base-acls.erb'),
+        require => Package['slapd'],
+        notify  => Service['slapd']
+    }
+
+    file { '/etc/ldap/indices.conf' :
+        ensure  => present,
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0444',
+        content => template('openldap/base-indices.erb'),
+        require => Package['slapd'],
+        notify  => Service['slapd']
+    }
+
+    exec { 'rm_slapd.d':
+        onlyif  => '/usr/bin/test -d /etc/ldap/slapd.d',
+        command => '/bin/rm -rf /etc/ldap/slapd.d',
+        require => Package['slapd'],
+    }
+
+    file { '/etc/ldap/ldap.conf':
+        ensure  => present,
+        owner   => 'root',
+        group   => 'root',
+        mode    => '0444',
+        content => template('openldap/ldap.conf.erb'),
+        require => Package['slapd'],
+    }
+}
diff --git a/puppet/modules/openldap/templates/base-acls.erb 
b/puppet/modules/openldap/templates/base-acls.erb
new file mode 100644
index 0000000..f62dc90
--- /dev/null
+++ b/puppet/modules/openldap/templates/base-acls.erb
@@ -0,0 +1,30 @@
+#######################################################################
+## Access lists
+
+# The userPassword by default can be changed
+# by the entry owning it if they are authenticated.
+# Others should not be able to see it, except the
+# admin entry below
+# These access lines apply to database #1 only
+access to attrs=userPassword,shadowLastChange
+       by dn="cn=admin,<%= @suffix %>" write
+       by anonymous auth
+       by self write
+       by * none
+
+# Ensure read access to the base for things like
+# supportedSASLMechanisms.  Without this you may
+# have problems with SASL not knowing what
+# mechanisms are available and the like.
+# Note that this is covered by the 'access to *'
+# ACL below too but if you change that as people
+# are wont to do you'll still need this if you
+# want SASL (and possible other things) to work
+# happily.
+access to dn.base="" by * read
+
+# everyone can read everything else not already defined
+# in above rules and write self
+access to *
+       by self write
+       by * read
diff --git a/puppet/modules/openldap/templates/base-indices.erb 
b/puppet/modules/openldap/templates/base-indices.erb
new file mode 100644
index 0000000..6deed87
--- /dev/null
+++ b/puppet/modules/openldap/templates/base-indices.erb
@@ -0,0 +1,25 @@
+index  default                 pres,eq
+index  objectClass             eq
+index  entryCSN                eq
+index  entryUUID               eq
+index  automountkey            pres,eq
+index  businessCategory        pres,eq
+index   cn                     eq,sub
+index  gidNumber               pres,eq
+index  givenName               eq,sub
+index  initials                pres,eq
+index  ipHostNumber            pres,sub
+index  ipnetworkNumber         pres,eq
+index  mail                    eq,sub
+index  member                  eq
+index  membernisnetgroup       pres,sub
+index  nisnetgrouptriple       pres
+index  oncRpcNumber            pres,eq
+index  sn                      eq,sub
+index  telephoneNumber         eq,sub
+index   uid                    eq
+index  uidNumber               pres,eq
+index  uniqueMember            eq
+index  x121address             pres,eq
+index  memberOf                eq
+index  memberUid               eq
diff --git a/puppet/modules/openldap/templates/default.erb 
b/puppet/modules/openldap/templates/default.erb
new file mode 100644
index 0000000..ec6e8d4
--- /dev/null
+++ b/puppet/modules/openldap/templates/default.erb
@@ -0,0 +1,53 @@
+#####################################################################
+### THIS FILE IS MANAGED BY PUPPET
+### puppet:///modules/openldap/templates/default.erb
+###################################################################
+
+# Bump the fd limit, otherwise we max out LDAP connections at around 1000
+ulimit -n 8192
+
+# Default location of the slapd.conf file or slapd.d cn=config directory. If
+# empty, use the compiled-in default (/etc/ldap/slapd.d with a fallback to
+# /etc/ldap/slapd.conf).
+SLAPD_CONF=
+
+# System account to run the slapd server under. If empty the server
+# will run as root.
+SLAPD_USER="openldap"
+
+# System group to run the slapd server under. If empty the server will
+# run in the primary group of its user.
+SLAPD_GROUP="openldap"
+
+# Path to the pid file of the slapd server. If not set the init.d script
+# will try to figure it out from $SLAPD_CONF (/etc/ldap/slapd.d by
+# default)
+SLAPD_PIDFILE=
+
+# slapd normally serves ldap only on all TCP-ports 389. slapd can also
+# service requests on TCP-port 636 (ldaps) and requests via unix
+# sockets.
+# Example usage:
+# SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
+SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"
+
+# If SLAPD_NO_START is set, the init script will not start or restart
+# slapd (but stop will still work).  Uncomment this if you are
+# starting slapd via some other means or if you don't want slapd normally
+# started at boot.
+#SLAPD_NO_START=1
+
+# If SLAPD_SENTINEL_FILE is set to path to a file and that file exists,
+# the init script will not start or restart slapd (but stop will still
+# work).  Use this for temporarily disabling startup of slapd (when doing
+# maintenance, for example, or through a configuration management system)
+# when you don't want to edit a configuration file.
+SLAPD_SENTINEL_FILE=/etc/ldap/noslapd
+
+# For Kerberos authentication (via SASL), slapd by default uses the system
+# keytab file (/etc/krb5.keytab).  To use a different keytab file,
+# uncomment this line and change the path.
+#export KRB5_KTNAME=/etc/krb5.keytab
+
+# Additional options to pass to slapd
+SLAPD_OPTIONS=""
diff --git a/puppet/modules/openldap/templates/ldap.conf.erb 
b/puppet/modules/openldap/templates/ldap.conf.erb
new file mode 100644
index 0000000..88cfab2
--- /dev/null
+++ b/puppet/modules/openldap/templates/ldap.conf.erb
@@ -0,0 +1,13 @@
+#####################################################################
+### THIS FILE IS MANAGED BY PUPPET
+### puppet:///modules/openldap/templates/ldap.conf.erb
+###################################################################
+
+# See ldap.conf(5) for details
+# This file should be world readable but not world writable.
+
+BASE   <%= @suffix %>
+URI    ldap://127.0.0.1
+
+# Do not derefernce aliases
+DEREF  never
diff --git a/puppet/modules/openldap/templates/slapd.erb 
b/puppet/modules/openldap/templates/slapd.erb
new file mode 100644
index 0000000..271ca2f
--- /dev/null
+++ b/puppet/modules/openldap/templates/slapd.erb
@@ -0,0 +1,103 @@
+#####################################################################
+### THIS FILE IS MANAGED BY PUPPET
+### puppet:///modules/openldap/templates/slapd.erb
+#####################################################################
+
+# Only allow v3 bindings
+#allow bind_v2
+
+# Schema and objectClass definitions
+include         /etc/ldap/schema/core.schema
+include         /etc/ldap/schema/cosine.schema
+include         /etc/ldap/schema/rfc2307bis.schema
+include         /etc/ldap/schema/inetorgperson.schema
+include         /etc/ldap/schema/dyngroup.schema
+include         /etc/ldap/schema/ppolicy.schema
+
+# Where the pid file is put. The init.d script
+# will not stop the server if you change this.
+pidfile         /var/run/slapd/slapd.pid
+
+# List of arguments that were passed to the server
+argsfile        /var/run/slapd/slapd.args
+
+# Read slapd.conf(5) for possible values
+loglevel        <%= @logging %>
+
+# Where the dynamically loaded modules are stored
+modulepath  /usr/lib/ldap
+moduleload  back_hdb
+moduleload  back_monitor
+moduleload  memberof
+moduleload  syncprov
+moduleload  auditlog
+moduleload  ppolicy
+moduleload  deref
+moduleload  unique
+
+# Maximum number of entries that is returned for a search operation
+sizelimit 2048
+
+# 10 minute idle timeout for ill-behaved clients
+idletimeout 600
+writetimeout 30
+
+# Limit amount of cpu's that is used for indexing.
+tool-threads 1
+
+#######################################################################
+## Databases
+
+database        monitor
+rootdn          "<%= @admin_dn %>"
+
+access to dn.subtree="cn=monitor"
+       by dn="<%= @admin_dn %>" write
+       by dn="cn=monitor,<%= @suffix %>" read
+       by self write
+       by * none
+
+database            hdb
+suffix              <%= @suffix %>
+directory           <%= @datadir %>
+rootdn              "<%= @admin_dn %>"
+rootpw              <%= @admin_password %>
+
+overlay auditlog
+auditlog /var/lib/ldap/slapd-audit.log
+
+overlay deref
+
+#######################################################################
+## Replication
+
+# Unique ID
+ServerID 1
+
+overlay syncprov
+syncprov-checkpoint 100 5
+syncprov-sessionlog 100
+syncprov-reloadhint TRUE
+
+overlay unique
+unique_uri ldap:///?uidNumber?sub?(objectClass=posixaccount)
+unique_uri ldap:///?gidNumber?sub?(objectClass=posixgroup)
+
+#######################################################################
+## General parameters and indexes
+
+dbconfig set_cachesize 0 2097152 0
+dbconfig set_lk_max_objects 1500
+dbconfig set_lk_max_locks 1500
+dbconfig set_lk_max_lockers 1500
+dbconfig set_lg_regionmax 262144
+dbconfig set_lg_bsize 2097152
+
+# LDAP indices
+include /etc/ldap/indices.conf
+
+lastmod         on
+checkpoint      512 30
+
+# ACLs
+include /etc/ldap/acls.conf
diff --git a/puppet/modules/role/manifests/ldapauth.pp 
b/puppet/modules/role/manifests/ldapauth.pp
new file mode 100644
index 0000000..52fcde2
--- /dev/null
+++ b/puppet/modules/role/manifests/ldapauth.pp
@@ -0,0 +1,57 @@
+# == Class: role::ldapauth
+# Provisions and LDAP server and the LdapAuthentication extension for use by
+# a wiki named ldapauth.wiki.local.wmftest.net.
+#
+# === Parameters
+# [*proxy_agent_password*]
+#   Password for proxy agent account
+#
+# [*writer_password*]
+#   Password for account with write access
+#
+# [*admin_password*]
+#   Password for LDAP admin account
+#
+class role::ldapauth(
+    $proxy_agent_password,
+    $writer_password,
+    $admin_password,
+) {
+    # Needed if the VM is using role::zend
+    require_package('php5-ldap')
+
+    # This is a lazy short cut so we don't have to pass a bazillion options to
+    # create the initial LDIF data.
+    $base_dn = 'dc=wmftest,dc=net'
+    $admin_dn = "cn=admin,${base_dn}"
+    $user_base_dn = "ou=people,${base_dn}"
+    $proxy_agent_dn = "cn=proxyagent,ou=profile,${base_dn}"
+    $writer_dn = "cn=writer,ou=profile,${base_dn}"
+
+    class { '::openldap':
+        suffix         => $base_dn,
+        datadir        => '/var/lib/ldap',
+        admin_dn       => $admin_dn,
+        admin_password => $admin_password,
+    }
+
+    exec { 'Create basic LDAP entries':
+        command => template('role/ldapauth/create_db.erb'),
+        unless  => template('role/ldapauth/check_db.erb'),
+        require => Class['::openldap'],
+    }
+
+    mediawiki::wiki { 'ldapauth':
+        wgconf => {
+            'wmvExtensions' => {
+                  'CentralAuth' => false,
+            },
+        },
+    }
+
+    mediawiki::extension { 'LdapAuthentication':
+        needs_update => true,
+        settings     => template('role/ldapauth/LdapAuthentication.php.erb'),
+        wiki         => 'ldapauth',
+    }
+}
diff --git a/puppet/modules/role/templates/ldapauth/LdapAuthentication.php.erb 
b/puppet/modules/role/templates/ldapauth/LdapAuthentication.php.erb
new file mode 100644
index 0000000..ec541ed
--- /dev/null
+++ b/puppet/modules/role/templates/ldapauth/LdapAuthentication.php.erb
@@ -0,0 +1,37 @@
+//<?php
+$wgAuth = new LdapAuthenticationPlugin();
+
+$wgLDAPDomainNames = array( 'ldap' );
+$wgLDAPServerNames = array( 'ldap' => '127.0.0.1' );
+$wgLDAPEncryptionType = array( 'ldap' => 'clear' );
+
+$wgLDAPProxyAgent =  array( 'ldap' => '<%= @proxy_agent_dn %>' );
+$wgLDAPProxyAgentPassword =  array( 'ldap' => '<%= @proxy_agent_password %>' );
+
+$wgLDAPSearchAttributes = array( 'ldap' => 'cn' );
+$wgLDAPBaseDNs = array( 'ldap' => '<%= @base_dn %>' );
+$wgLDAPUserBaseDNs = array( 'ldap' => '<%= @user_base_dn %>' );
+
+$wgLDAPWriterDN = array( 'ldap' => '<%= @writer_dn %>' );
+$wgLDAPWriterPassword = array( 'ldap' => '<%= @writer_password %>' );
+
+$wgLDAPWriteLocation = array( 'ldap' => '<%= @user_base_dn %>' );
+$wgLDAPAddLDAPUsers = array( 'ldap' => true );
+$wgLDAPUpdateLDAP = array( 'ldap' => true );
+$wgLDAPPasswordHash = array( 'ldap' => 'clear' );
+// 'invaliddomain' is set to true so that mail password options
+// will be available on user creation and password mailing
+$wgLDAPMailPassword = array( 'ldap' => true, 'invaliddomain' => true );
+$wgLDAPPreferences = array( 'ldap' => array( 'email' => 'mail' ) );
+$wgLDAPUseFetchedUsername = array( 'ldap' => true );
+$wgLDAPLowerCaseUsernameScheme = array( 'ldap' => false, 'invaliddomain' => 
false );
+$wgLDAPLowerCaseUsername = array( 'ldap' => false, 'invaliddomain' => false );
+
+//$wgLDAPUseLocal = true;
+
+// Shortest password a user is allowed to login using. Notice that 1 is the
+// minimum so that when using a local domain, local users cannot login as
+// domain users (as domain user's passwords are not stored)
+$wgMinimalPasswordLength = 1;
+
+$wgLDAPDebug = 5;
diff --git a/puppet/modules/role/templates/ldapauth/check_db.erb 
b/puppet/modules/role/templates/ldapauth/check_db.erb
new file mode 100644
index 0000000..85f07c4
--- /dev/null
+++ b/puppet/modules/role/templates/ldapauth/check_db.erb
@@ -0,0 +1 @@
+/usr/bin/ldapsearch -x -D '<%= @admin_dn %>' -w '<%= @admin_password %>' -b 
'<%= @base_dn %>' '(cn=writer)'
diff --git a/puppet/modules/role/templates/ldapauth/create_db.erb 
b/puppet/modules/role/templates/ldapauth/create_db.erb
new file mode 100755
index 0000000..f63f6ae
--- /dev/null
+++ b/puppet/modules/role/templates/ldapauth/create_db.erb
@@ -0,0 +1,52 @@
+/usr/bin/ldapadd -x -D "<%= @admin_dn %>" -w "<%= @admin_password %>" <<LIDF
+dn: <%= @base_dn %>
+objectclass: dcObject
+objectclass: organization
+objectClass: top
+dc: wmftest
+o: wmftest
+
+dn: <%= @admin_dn %>
+objectClass: organizationalRole
+cn: admin
+
+dn: ou=profile,<%= @base_dn %>
+objectclass: organizationalUnit
+objectclass: top
+ou: profile
+
+dn: <%= @user_base_dn %>
+objectclass: organizationalUnit
+objectclass: top
+ou: people
+
+dn: <%= @proxy_agent_dn %>
+objectclass: organizationalRole
+objectClass: simpleSecurityObject
+cn: proxyagent
+userPassword: <%= @proxy_agent_password %>
+
+dn: <%= @writer_dn %>
+objectclass: organizationalRole
+objectClass: simpleSecurityObject
+cn: writer
+userPassword: <%= @writer_password %>
+
+oclAccess: to dn.subtree="<%= @user_base_dn %>"
+    by dn.base="<%= @admin_dn %>" manage
+    by dn.base="<%= @writer_dn %>" manage
+    by users read
+    by * none
+
+oclAccess: to attr=userPassword
+    by dn.base="<%= @admin_dn %>" write
+    by dn.base="<%= @writer_dn %>" write
+    by self =xw
+    by anonymous auth
+    by * none
+
+oclAccess: to *
+    by self write
+    by users read
+    by * search
+LIDF

-- 
To view, visit https://gerrit.wikimedia.org/r/277702
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I11eb9e8ae9dc26ba9ea52219b770d9736cb914b3
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/vagrant
Gerrit-Branch: master
Gerrit-Owner: BryanDavis <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to