diff --git a/README.md b/README.md index b90b798..5f1baad 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ This role sets up 389ds in multi-master mode. | `auth_kerberos_admin_privs` | `[]` | Kerberos principals to grant administrative permissions to (see defaults/main.yml for format) | | `auth_ldap_store_pam` | `True` | Whether to actually store the generated 389ds PAM config. Useful if you want to customize it using another role | |`auth_kerberos_curves` | `edwards25519` | Curves to use for kerberos SPAKE | +| `auth_ldap_use_memberof_plugin` | `False` | Whether to enable the `memberOf` LDAP plugin. | Users can be created by putting them into `auth_ldap_users` as a dict with the following format: ``` @@ -47,6 +48,14 @@ auth_ldap_users: ``` After running the playbook, use `kadmin.local` on one of the servers and do `cpw foobar` to set a password. +## FAQ + +### Enabling memberOf plugin +If you enable the memberOf plugin by setting the `auth_ldap_user_memberof_plugin` variable to true, you need to pay attention to a few points: + +* The user objects that should have the memberOf need to have the `objectClass` `inetUser` set. More information about `inetUser` can be found [here](https://msg.wikidoc.info/index.php/InetUser_LDAP_Object_Class#targetText=InetUser%20LDAP%20Object%20Class&targetText=For%20Mail%3A,for%20creating%20a%20mail%20account.&targetText=Group%20entries%20may%20be%20extended%20with%20this%20class.). +* If you're enabling memberOf on an existing database you will have to do an initial sync of the memberOf field, as described in section 5 [here](https://access.redhat.com/solutions/28282). + ## License Apache 2.0, except for the included LDAP schemas: * `files/kerberos.ldif` is `CoPyRiGhT=(c) Copyright 2006, Novell, Inc. All rights reserved` and has been extracted from the freely available openLDAP source. diff --git a/defaults/main.yml b/defaults/main.yml index a51a055..7ba325e 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -6,6 +6,11 @@ auth_ldap_domain_suffix: None # If you have subdomains with hosts, you might want to add them here auth_ldap_domain_subdomains: [] +# If your LDAP servers are not mutually reachable via their FQDN, set this for +# replication +auth_ldap_use_external_domain: False +auth_ldap_external_domain: None + # LDAP admin credentials (you need to change these) auth_ldap_admin_pwd: None auth_ldap_sync_pwd: None @@ -85,7 +90,7 @@ auth_ldap_service_accounts: ktmode: "0640" # Permissions. This should give you a sensible default, tweak as needed -auth_ldap_noncritical_filter: "dn || krbLastSuccessfulAuth || krbLastPwdChange || krbPasswordExpiration || krbLoginFailedCount || uid || objectClass || uidNumber || gidNumber || sn || homeDirectory || mail || givenName || cn || sendAlias || alias || mailboxTransport || canReceiveExternally || canSendExternally || mailboxQuota || primaryMail" +auth_ldap_noncritical_filter: "dn || krbLastSuccessfulAuth || krbLastPwdChange || krbPasswordExpiration || krbLoginFailedCount || uid || objectClass || uidNumber || gidNumber || sn || homeDirectory || mail || givenName || cn || sendAlias || alias || mailboxTransport || canReceiveExternally || canSendExternally || mailboxQuota || primaryMail || memberOf" auth_ldap_noncritical_group_filter: "dn || objectClass || cn || member || memberUid || description || uniqueMember || alias || sendAlias" auth_ldap_permissions: - target: "{{ auth_ldap_domain_ldap }}" @@ -122,5 +127,13 @@ auth_ldap_system_users: gid: 1000 initialPassword: "{{ auth_kerberos_ldap_password }}" +auth_ldap_user_objectclasses: + - posixAccount + - top + - inetOrgPerson + # Whether to actually store the pam kerberos passthrough config auth_ldap_store_pam: True + +# Whether to enable the memberOf plugin +auth_ldap_use_memberof_plugin: False diff --git a/tasks/389-acl.yml b/tasks/389-acl.yml index 7e8ed9b..72bf98f 100644 --- a/tasks/389-acl.yml +++ b/tasks/389-acl.yml @@ -17,10 +17,7 @@ ldap_entry: dn: "cn={{ item.name }},ou=TechnicalUsers,{{ auth_ldap_domain_ldap }}" server_uri: "{{ auth_ldap_ansible_url }}" - objectClass: - - posixAccount - - top - - inetOrgPerson + objectClass: "{{ auth_ldap_user_objectclasses }}" bind_dn: "cn=Directory Manager" bind_pw: "{{ auth_ldap_admin_pwd }}" state: present diff --git a/tasks/389-replication.yml b/tasks/389-replication.yml index 918bfea..8e43afe 100644 --- a/tasks/389-replication.yml +++ b/tasks/389-replication.yml @@ -128,3 +128,20 @@ with_dict: nsslapd-pluginEnabled: 'on' notify: restart dirsrv + +# Disable replication of the memberOf field in multi master setup +# this should be done according to the documentation [here](https://access.redhat.com/solutions/28282) + - name: Configure replication for memberOf plugin + ldap_attr: + dn: "cn={{ item[0] }}-to-{{ item[1] }},cn=replica,cn={{ auth_ldap_domain_ldap | replace(\"=\", \"\\=\") | replace(\",\", \"\\,\")}},cn=mapping tree,cn=config" + server_uri: "{{ auth_ldap_ansible_url }}" + bind_dn: "cn=Directory Manager" + bind_pw: "{{ auth_ldap_admin_pwd }}" + state: exact + name: "nsds5replicatedattributelist" + values: (objectclass=*) $ EXCLUDE memberof + when: (item[0] != item[1]) and (item[1] == ansible_fqdn) + with_cartesian: + - "{{ groups[auth_ldap_group] }}" + - "{{ groups[auth_ldap_group] }}" + notify: restart dirsrv diff --git a/tasks/389-setup.yml b/tasks/389-setup.yml index 23997f8..bb13fd0 100644 --- a/tasks/389-setup.yml +++ b/tasks/389-setup.yml @@ -22,7 +22,7 @@ - name: Check whether server cert is installed become: True - shell: certutil -d "/etc/dirsrv/slapd-{{ auth_ldap_shortname }}" -L | grep -E ''{{ ansible_fqdn }}|Server-Cert'' + shell: certutil -d "/etc/dirsrv/slapd-{{ auth_ldap_shortname }}" -L | grep -E '{{ ansible_fqdn }}|Server-Cert' register: certsrvout failed_when: False changed_when: False @@ -60,7 +60,7 @@ - name: Rename the server certificate in case pk12util decided to ignore it's arguments again become: True when: certsrvout.rc == 1 - command: 'certutil --rename -d/etc/dirsrv/slapd-core-fal -n "{{ ansible_fqdn }}" --new-n Server-Cert' + command: 'certutil --rename -d/etc/dirsrv/slapd-{{ auth_ldap_shortname }} -n "{{ ansible_fqdn }}" --new-n Server-Cert' args: chdir: /etc/dirsrv notify: restart dirsrv @@ -292,5 +292,18 @@ nsslapd-exclude-suffix: 'cn=config' notify: restart dirsrv + - name: Enable or disable Memberof Plugin + ldap_attr: + dn: "cn=MemberOf Plugin,cn=plugins,cn=config" + server_uri: "{{ auth_ldap_ansible_url }}" + bind_dn: "cn=Directory Manager" + bind_pw: "{{ auth_ldap_admin_pwd }}" + state: exact + name: "{{ item.key }}" + values: "{{ item.value }}" + with_dict: + nsslapd-pluginEnabled: "{% if auth_ldap_use_memberof_plugin %}on{% else %}off{% endif %}" + notify: restart dirsrv + # If we changed the haproxy config, this will restart the server and activate it - meta: flush_handlers diff --git a/tasks/content.yml b/tasks/content.yml index 91e3742..920ffba 100644 --- a/tasks/content.yml +++ b/tasks/content.yml @@ -4,10 +4,7 @@ ldap_entry: dn: "uid={{ item.id }},ou=Users,{{ auth_ldap_domain_ldap }}" server_uri: "{{ auth_ldap_ansible_url }}" - objectClass: - - posixAccount - - top - - inetOrgPerson + objectClass: "{{ auth_ldap_user_objectclasses }}" bind_dn: "cn=Directory Manager" bind_pw: "{{ auth_ldap_admin_pwd }}" state: present diff --git a/tasks/main.yml b/tasks/main.yml index d49261c..9069879 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -22,6 +22,10 @@ - ldap - kerberos + - import_tasks: variable-initialisation.yml + tags: + - ldap + - import_tasks: 389-setup.yml tags: - ldap diff --git a/tasks/variable-initialisation.yml b/tasks/variable-initialisation.yml new file mode 100644 index 0000000..482b2aa --- /dev/null +++ b/tasks/variable-initialisation.yml @@ -0,0 +1,5 @@ +--- + + - name: Add inetUser to system users + set_fact: + auth_ldap_user_objectclasses: "{{ auth_ldap_user_objectclasses + ['inetUser'] }}" diff --git a/templates/haproxy-dropin.conf.j2 b/templates/haproxy-dropin.conf.j2 index 7f3f1af..d2eec37 100644 --- a/templates/haproxy-dropin.conf.j2 +++ b/templates/haproxy-dropin.conf.j2 @@ -9,7 +9,11 @@ frontend {{ item }}-ldap-front backend {{ item }}-ldap-back mode tcp option ldap-check +{% if auth_ldap_use_external_domain %} + server remote {{ hostvars[item]['auth_ldap_external_domain'] }}:60389 ssl crt /etc/dirsrv/client.pem ca-file /etc/dirsrv/ca.pem verify required check check-ssl +{% else %} server remote {{ item }}:60389 ssl crt /etc/dirsrv/client.pem ca-file /etc/dirsrv/ca.pem verify required check check-ssl +{% endif %} {% endif %} {% endfor %}