From 70558ba1bec7a35d8a26165cd3028a3c84647940 Mon Sep 17 00:00:00 2001 From: Jan Veen Date: Thu, 5 Mar 2020 15:41:41 +0100 Subject: [PATCH 1/7] Fix setup instructions Remove hardcoded service instance name Remove double quotes --- tasks/389-setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/389-setup.yml b/tasks/389-setup.yml index 23997f8..17af0de 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 From ee87824b2a1b824fad78051d1c47351e021ee2da Mon Sep 17 00:00:00 2001 From: Jan Veen Date: Thu, 5 Mar 2020 15:43:25 +0100 Subject: [PATCH 2/7] Use FQDN instead of inventory hostname The FQDN might in fact be different from the inventory name and is more appropriate for connecting. --- templates/haproxy-dropin.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/haproxy-dropin.conf.j2 b/templates/haproxy-dropin.conf.j2 index 7f3f1af..d2e5046 100644 --- a/templates/haproxy-dropin.conf.j2 +++ b/templates/haproxy-dropin.conf.j2 @@ -9,7 +9,7 @@ frontend {{ item }}-ldap-front backend {{ item }}-ldap-back mode tcp option ldap-check - server remote {{ item }}:60389 ssl crt /etc/dirsrv/client.pem ca-file /etc/dirsrv/ca.pem verify required check check-ssl + server remote {{ hostvars[item]['ansible_fqdn'] }}:60389 ssl crt /etc/dirsrv/client.pem ca-file /etc/dirsrv/ca.pem verify required check check-ssl {% endif %} {% endfor %} From e69b5a94898a4fa5e57374dbc6a5f6b9e3ca13cd Mon Sep 17 00:00:00 2001 From: Jan Veen Date: Fri, 6 Mar 2020 14:45:14 +0100 Subject: [PATCH 3/7] Allow setting arbitary domains for replication --- defaults/main.yml | 5 +++++ templates/haproxy-dropin.conf.j2 | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/defaults/main.yml b/defaults/main.yml index a51a055..3cba65a 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 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 %} From 951c9a4031b8f36bcb25075a803c1b1bbd836f11 Mon Sep 17 00:00:00 2001 From: Lukas Reichart Date: Tue, 17 Sep 2019 13:48:54 +0200 Subject: [PATCH 4/7] Added configuration of memberOf plugin. --- README.md | 1 + defaults/main.yml | 3 +++ tasks/389-replication.yml | 1 + tasks/389-setup.yml | 14 ++++++++++++++ 4 files changed, 19 insertions(+) diff --git a/README.md b/README.md index b90b798..bab4ec2 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 | +| `uth_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: ``` diff --git a/defaults/main.yml b/defaults/main.yml index a51a055..fdd0dfb 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -124,3 +124,6 @@ auth_ldap_system_users: # 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 \ No newline at end of file diff --git a/tasks/389-replication.yml b/tasks/389-replication.yml index 918bfea..be76caf 100644 --- a/tasks/389-replication.yml +++ b/tasks/389-replication.yml @@ -69,6 +69,7 @@ nsds5replicaroot: "{{ auth_ldap_domain_ldap }}" description: "agreement to replicate {{ item[1] }} to {{ item[0] }}" nsds5replicacredentials: "{{ auth_ldap_sync_pwd }}" + nsds5replicatedattributelist: "{% if auth_ldap_use_memberof_plugin %}(objectclass=*) $ EXCLUDE memberof{% else %}(objectclass=*){% endif %}" when: (item[0] != item[1]) and (item[1] == ansible_fqdn) with_cartesian: - "{{ groups[auth_ldap_group] }}" diff --git a/tasks/389-setup.yml b/tasks/389-setup.yml index 23997f8..fd927b5 100644 --- a/tasks/389-setup.yml +++ b/tasks/389-setup.yml @@ -292,5 +292,19 @@ nsslapd-exclude-suffix: 'cn=config' notify: restart dirsrv + - name: Enable Memberof Plugin + when: auth_ldap_use_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: 'on' + notify: restart dirsrv + # If we changed the haproxy config, this will restart the server and activate it - meta: flush_handlers From 10a1679e65d52ea89f6a9b30ecaf67e82bd5b105 Mon Sep 17 00:00:00 2001 From: Lukas Reichart Date: Tue, 17 Sep 2019 17:02:30 +0200 Subject: [PATCH 5/7] Fixed memberof configuratin for fractional replication. --- README.md | 10 +++++++++- tasks/389-replication.yml | 18 +++++++++++++++++- tasks/389-setup.yml | 5 ++--- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bab4ec2..f14c234 100644 --- a/README.md +++ b/README.md @@ -33,7 +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 | -| `uth_ldap_use_memberof_plugin` | `False` | Whether to enable the `memberOf` LDAP plugin. | +| `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: ``` @@ -48,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` `inetperson` set. More information about `inetperson` 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/tasks/389-replication.yml b/tasks/389-replication.yml index be76caf..8e43afe 100644 --- a/tasks/389-replication.yml +++ b/tasks/389-replication.yml @@ -69,7 +69,6 @@ nsds5replicaroot: "{{ auth_ldap_domain_ldap }}" description: "agreement to replicate {{ item[1] }} to {{ item[0] }}" nsds5replicacredentials: "{{ auth_ldap_sync_pwd }}" - nsds5replicatedattributelist: "{% if auth_ldap_use_memberof_plugin %}(objectclass=*) $ EXCLUDE memberof{% else %}(objectclass=*){% endif %}" when: (item[0] != item[1]) and (item[1] == ansible_fqdn) with_cartesian: - "{{ groups[auth_ldap_group] }}" @@ -129,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 fd927b5..7441e6c 100644 --- a/tasks/389-setup.yml +++ b/tasks/389-setup.yml @@ -292,8 +292,7 @@ nsslapd-exclude-suffix: 'cn=config' notify: restart dirsrv - - name: Enable Memberof Plugin - when: auth_ldap_use_memberof_plugin + - name: Enable or disable Memberof Plugin ldap_attr: dn: "cn=MemberOf Plugin,cn=plugins,cn=config" server_uri: "{{ auth_ldap_ansible_url }}" @@ -303,7 +302,7 @@ name: "{{ item.key }}" values: "{{ item.value }}" with_dict: - nsslapd-pluginEnabled: 'on' + 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 From f68f3e9f2884b633f82f11b08dfa2ed550b6bade Mon Sep 17 00:00:00 2001 From: Lukas Reichart Date: Sat, 28 Sep 2019 15:42:03 +0200 Subject: [PATCH 6/7] Add memberOf to the noncritical ldap attributes. --- defaults/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index fdd0dfb..9f010fe 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -85,7 +85,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 }}" @@ -126,4 +126,4 @@ auth_ldap_system_users: auth_ldap_store_pam: True # Whether to enable the memberOf plugin -auth_ldap_use_memberof_plugin: False \ No newline at end of file +auth_ldap_use_memberof_plugin: False From e0f4320c9687a1d8972af948bc4ef874e78694ef Mon Sep 17 00:00:00 2001 From: Jan Veen Date: Thu, 5 Mar 2020 16:00:12 +0100 Subject: [PATCH 7/7] Add inetUser objectClass to system users --- README.md | 2 +- defaults/main.yml | 5 +++++ tasks/389-acl.yml | 5 +---- tasks/content.yml | 5 +---- tasks/main.yml | 4 ++++ tasks/variable-initialisation.yml | 5 +++++ 6 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 tasks/variable-initialisation.yml diff --git a/README.md b/README.md index f14c234..5f1baad 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ After running the playbook, use `kadmin.local` on one of the servers and do `cpw ### 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` `inetperson` set. More information about `inetperson` 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.). +* 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 diff --git a/defaults/main.yml b/defaults/main.yml index 9f010fe..f50859e 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -122,6 +122,11 @@ 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 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/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'] }}"