URL: https://github.com/freeipa/freeipa/pull/5325 Author: tiran Title: #5325: LDAP autobind authenticateAsDN for BIND named Action: opened
PR body: """ Use new nsslapd-ldapiautoauthdnattr feature to switch BIND named from GSSAPI bind to EXTERNAL LDAPI bind. Requires 389-DS build https://copr.fedorainfracloud.org/coprs/build/1811023 - [ ] Requires new build of 389-DS - [ ] Add new OIDs to FreeIPA's OID registry Fixes: https://pagure.io/freeipa/issue/8544 See: https://github.com/389ds/389-ds-base/issues/4381 Signed-off-by: Christian Heimes <chei...@redhat.com> """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/5325/head:pr5325 git checkout pr5325
From 95281b18d8912cdd18769b5c5b9e8049ba36df9e Mon Sep 17 00:00:00 2001 From: Christian Heimes <chei...@redhat.com> Date: Fri, 4 Dec 2020 12:18:22 +0100 Subject: [PATCH] LDAP autobind authenticateAsDN for BIND named Use new nsslapd-ldapiautoauthdnattr feature to switch BIND named from GSSAPI bind to EXTERNAL LDAPI bind. Requires 389-DS build https://copr.fedorainfracloud.org/coprs/build/1811023 Fixes: https://pagure.io/freeipa/issue/8544 See: https://github.com/389ds/389-ds-base/issues/4381 Signed-off-by: Christian Heimes <chei...@redhat.com> --- freeipa.spec.in | 11 +++---- install/share/60basev3.ldif | 2 ++ install/share/bind.named.conf.template | 3 +- install/updates/20-autobind.update | 8 +++++ install/updates/49-autobind-services.update | 6 ++++ install/updates/Makefile.am | 1 + ipapython/ipaldap.py | 2 ++ ipaserver/install/bindinstance.py | 10 ++++++- ipaserver/install/ipa_restore.py | 8 ++++- ipaserver/install/ldapupdate.py | 3 ++ ipaserver/install/server/upgrade.py | 7 +++++ ipaserver/install/service.py | 33 ++++++++++++++++++--- 12 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 install/updates/49-autobind-services.update diff --git a/freeipa.spec.in b/freeipa.spec.in index c0c82be2aa8..be177eef0a5 100755 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -73,10 +73,8 @@ %global selinux_policy_version 3.14.3-52 %global slapi_nis_version 0.56.4 %global python_ldap_version 3.1.0-1 -# python3-lib389 -# Fix for "Installation fails: Replica Busy" -# https://pagure.io/389-ds-base/issue/49818 -%global ds_version 1.4.2.4-6 +# authenticate as DN feature +%global ds_version 2.0.1-20201203 # Fix for TLS 1.3 PHA, RHBZ#1775158 %global httpd_version 2.4.37-21 %global bind_version 9.11.20-6 @@ -101,9 +99,8 @@ # fix for segfault in python3-ldap, https://pagure.io/freeipa/issue/7324 %global python_ldap_version 3.1.0-1 -# 1.4.3 moved nsslapd-db-locks to cn=bdb sub-entry -# https://pagure.io/freeipa/issue/8515 -%global ds_version 1.4.3 +# authenticat as DN feature +%global ds_version 2.0.1-20201203 # Fix for TLS 1.3 PHA, RHBZ#1775146 %global httpd_version 2.4.41-9 diff --git a/install/share/60basev3.ldif b/install/share/60basev3.ldif index efc6c8afb60..f1b909bcc11 100644 --- a/install/share/60basev3.ldif +++ b/install/share/60basev3.ldif @@ -58,6 +58,7 @@ attributeTypes: (2.16.840.1.113730.3.8.11.70 NAME 'ipaPermTargetTo' DESC 'Destin attributeTypes: (2.16.840.1.113730.3.8.11.71 NAME 'ipaPermTargetFrom' DESC 'Source location from where moving an entry IPA permission ACI' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'IPA v4.0' ) attributeTypes: ( 2.16.840.1.113730.3.8.11.75 NAME 'ipaNTAdditionalSuffixes' DESC 'Suffix for the user principal name associated with the domain' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15) attributeTypes: (2.16.840.1.113730.3.8.11.77 NAME 'ipaDomainResolutionOrder' DESC 'List of domains used to resolve a short name' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'IPA v4.5') +attributeTypes: (2.16.840.1.113730.3.8.11.78 NAME 'ipaAuthenticateAsDN' DESC 'LDAPI autobind as DN' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'IPA v4.10' ) attributeTypes: (2.16.840.1.113730.3.8.18.2.1 NAME 'ipaVaultType' DESC 'IPA vault type' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v4.2') attributeTypes: (2.16.840.1.113730.3.8.18.2.2 NAME 'ipaVaultSalt' DESC 'IPA vault salt' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2' ) # FIXME: https://bugzilla.redhat.com/show_bug.cgi?id=1267782 @@ -86,5 +87,6 @@ objectClasses: (2.16.840.1.113730.3.8.12.25 NAME 'ipaPrivateKeyObject' DESC 'Wra objectClasses: (2.16.840.1.113730.3.8.12.26 NAME 'ipaSecretKeyObject' DESC 'Wrapped secret keys' SUP top AUXILIARY MUST ( ipaSecretKey $ ipaWrappingKey $ ipaWrappingMech ) X-ORIGIN 'IPA v4.1' ) objectClasses: (2.16.840.1.113730.3.8.12.34 NAME 'ipaSecretKeyRefObject' DESC 'Indirect storage for encoded key material' SUP top AUXILIARY MUST ( ipaSecretKeyRef ) X-ORIGIN 'IPA v4.1' ) objectClasses: (2.16.840.1.113730.3.8.12.39 NAME 'ipaNameResolutionData' DESC 'Data used to resolve short names to fully-qualified form' SUP top AUXILIARY MAY ( ipaDomainResolutionOrder ) X-ORIGIN 'IPA v4.5') +objectClasses: (2.16.840.1.113730.3.8.12.40 NAME 'ipaAutobind' DESC 'LDAPI autobind by uid+gid entry' SUP top STRUCTURAL MUST ( cn $ uidNumber $ gidNumber $ ipaAuthenticateAsDN ) MAY ( description ) X-ORIGIN 'IPA v4.10') objectClasses: (2.16.840.1.113730.3.8.18.1.1 NAME 'ipaVault' DESC 'IPA vault' SUP top STRUCTURAL MUST ( cn ) MAY ( description $ ipaVaultType $ ipaVaultSalt $ ipaVaultPublicKey $ owner $ member ) X-ORIGIN 'IPA v4.2' ) objectClasses: (2.16.840.1.113730.3.8.18.1.2 NAME 'ipaVaultContainer' DESC 'IPA vault container' SUP top STRUCTURAL MUST ( cn ) MAY ( description $ owner ) X-ORIGIN 'IPA v4.2' ) diff --git a/install/share/bind.named.conf.template b/install/share/bind.named.conf.template index 55e8142ebc2..1cdf5d0d6fa 100644 --- a/install/share/bind.named.conf.template +++ b/install/share/bind.named.conf.template @@ -55,6 +55,5 @@ dyndb "ipa" "$BIND_LDAP_SO" { base "cn=dns,$SUFFIX"; server_id "$FQDN"; auth_method "sasl"; - sasl_mech "GSSAPI"; - sasl_user "DNS/$FQDN"; + sasl_mech "EXTERNAL"; }; diff --git a/install/updates/20-autobind.update b/install/updates/20-autobind.update index 3a06f84b9a3..f9a3c6d48e5 100644 --- a/install/updates/20-autobind.update +++ b/install/updates/20-autobind.update @@ -1,6 +1,14 @@ +# countainer for autobind +dn: cn=autobind,cn=config +default: objectClass: nsContainer +default: objectClass: top +default: cn: autobind + # map LDAPI autobind uid/gid to user entries (not used by root autobind) dn: cn=config only: nsslapd-ldapimaptoentries: on +only: nsslapd-ldapientrysearchbase: cn=autobind,cn=config +only: nsslapd-ldapiautoauthdnattr: ipaAuthenticateAsDN # lib389 configures 389-DS for root-autobind. This entry is no longer needed. dn: cn=root-autobind,cn=config diff --git a/install/updates/49-autobind-services.update b/install/updates/49-autobind-services.update new file mode 100644 index 00000000000..a5d6c491ccb --- /dev/null +++ b/install/updates/49-autobind-services.update @@ -0,0 +1,6 @@ +# create / update LDAPI autobind rules for services +# also used by ipa-restore to ensure correct mappings + +dn: cn=named,cn=autobind,cn=config +onlyifexist: uidNumber: $NAMED_UID +onlyifexist: gidNumber: $NAMED_GID diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am index 5741805a65a..1f3a9caf1f5 100644 --- a/install/updates/Makefile.am +++ b/install/updates/Makefile.am @@ -45,6 +45,7 @@ app_DATA = \ 41-caacl.update \ 41-lightweight-cas.update \ 45-roles.update \ + 49-autobind-services.update \ 50-7_bit_check.update \ 50-dogtag10-migration.update \ 50-groupuuid.update \ diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py index 394cd92e431..d2248f903ea 100644 --- a/ipapython/ipaldap.py +++ b/ipapython/ipaldap.py @@ -761,6 +761,8 @@ class LDAPClient: 'nsslapd-enable-upgrade-hash': True, 'nsslapd-db-locks': True, 'nsslapd-logging-hr-timestamps-enabled': True, + 'nsslapd-ldapientrysearchbase': True, + 'nsslapd-ldapiautoauthdnattr': True, }) time_limit = -1.0 # unlimited diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index 3b446ce765c..b75c8f32034 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -760,8 +760,11 @@ def create_instance(self): self.step("setting up records for other masters", self.__add_others) # all zones must be created before this step self.step("adding NS record to the zones", self.__add_self_ns) - + # The service entry is used for LDAPI autobind. The keytab is no + # longer used to authenticate the server. The server still needs + # the keytab to handle incoming nsupdate requests with TSIG. self.step("setting up kerberos principal", self.__setup_principal) + self.step("setting up LDAPI autobind", self.setup_autobind) self.step("setting up named.conf", self.setup_named_conf) self.step("setting up server configuration", self.__setup_server_configuration) @@ -1028,6 +1031,11 @@ def __setup_principal(self): dns_principal, str(e)) raise + def setup_autobind(self): + self.add_autobind_entry( + constants.NAMED_USER, constants.NAMED_GROUP, self.principal + ) + def setup_named_conf(self, backup=False): """Create, update, or migrate named configuration files diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py index 02550e04320..726f9f1ce50 100644 --- a/ipaserver/install/ipa_restore.py +++ b/ipaserver/install/ipa_restore.py @@ -40,7 +40,7 @@ from ipapython.dn import DN from ipaserver.install.replication import (wait_for_task, ReplicationManager, get_cs_replication_manager) -from ipaserver.install import installutils +from ipaserver.install import installutils, ldapupdate from ipaserver.install import dsinstance, httpinstance, cainstance, krbinstance from ipaserver.masters import get_masters from ipapython import ipaldap @@ -467,6 +467,12 @@ def run(self): oddjobd.enable() oddjobd.start() http.remove_httpd_ccaches() + # update autobind configuration in case uid/gid have changed + ld = ldapupdate.LDAPUpdate(api=api) + autobind_update = os.path.join( + paths.UPDATES_DIR, "49-autobind-services.update" + ) + ld.update([autobind_update]) # have the daemons pick up their restored configs tasks.systemd_daemon_reload() # Restart IPA a final time. diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py index 15c0ccb5082..c2859ea9bae 100644 --- a/ipaserver/install/ldapupdate.py +++ b/ipaserver/install/ldapupdate.py @@ -296,6 +296,9 @@ def __init__(self, dm_password=_sentinel, sub_dict=None, SELINUX_USERMAP_DEFAULT=platformconstants.SELINUX_USERMAP_DEFAULT, SELINUX_USERMAP_ORDER=platformconstants.SELINUX_USERMAP_ORDER, FIPS="#" if tasks.is_fips_enabled() else "", + # uid / gid for autobind + NAMED_UID=platformconstants.NAMED_USER.uid, + NAMED_GID=platformconstants.NAMED_GROUP.gid, ) for k, v in default_sub.items(): self.sub_dict.setdefault(k, v) diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py index 18891d53c7d..46211cba02b 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -1453,6 +1453,13 @@ def upgrade_bind(fstore): else: bind_started = False + try: + bind.setup_autobind() + except ipalib.errors.DuplicateEntry: + logger.debug("Autobind entry for named service exists.") + else: + logger.info("Added autobind entry for named service") + try: changed = bind.setup_named_conf(backup=True) if changed: diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py index 2afb251fc10..ea0953f66c8 100644 --- a/ipaserver/install/service.py +++ b/ipaserver/install/service.py @@ -326,6 +326,15 @@ def principal(self): kerberos.Principal( (self.service_prefix, self.fqdn), realm=self.realm)) + def get_principal_dn(self, principal=None): + if principal is None: + principal = self.principal + return DN( + ('krbprincipalname', principal), + self.api.env.container_service, + self.suffix + ) + def _ldap_update(self, filenames, *, basedir=paths.UPDATES_DIR): """Apply update ldif files @@ -413,7 +422,7 @@ def move_service(self, principal): # This can happen when installing a replica return None entry.pop('krbpwdpolicyreference', None) # don't copy virtual attr - newdn = DN(('krbprincipalname', principal), ('cn', 'services'), ('cn', 'accounts'), self.suffix) + newdn = self.get_principal_dn(principal) hostdn = DN(('fqdn', self.fqdn), ('cn', 'computers'), ('cn', 'accounts'), self.suffix) api.Backend.ldap2.delete_entry(entry) entry.dn = newdn @@ -431,7 +440,7 @@ def add_simple_service(self, principal): The principal needs to be fully-formed: service/host@REALM """ - dn = DN(('krbprincipalname', principal), ('cn', 'services'), ('cn', 'accounts'), self.suffix) + dn = self.get_principal_dn(principal) hostdn = DN(('fqdn', self.fqdn), ('cn', 'computers'), ('cn', 'accounts'), self.suffix) entry = api.Backend.ldap2.make_entry( dn, @@ -445,6 +454,23 @@ def add_simple_service(self, principal): api.Backend.ldap2.add_entry(entry) return dn + def add_autobind_entry(self, user, group, principal): + authdn = self.get_principal_dn(principal) + dn = DN( + ('cn', self.service_name), ('cn', 'autobind'), ('cn', 'config') + ) + ldap2 = self.api.Backend.ldap2 + entry = ldap2.make_entry( + dn, + objectclass=['ipaAutobind'], + cn=[self.service_name], + uidNumber=[user.uid], + gidNumber=[group.gid], + ipaAuthenticateAsDN=[authdn] + ) + ldap2.add_entry(entry) + return dn + def add_cert_to_service(self): """ Add a certificate to a service @@ -453,8 +479,7 @@ def add_cert_to_service(self): """ if self.cert is None: raise ValueError("{} has no cert".format(self.service_name)) - dn = DN(('krbprincipalname', self.principal), ('cn', 'services'), - ('cn', 'accounts'), self.suffix) + dn = self.get_principal_dn() entry = api.Backend.ldap2.get_entry(dn) entry.setdefault('userCertificate', []).append(self.cert) try:
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org