From b9dc975777f9f84dff20c5a79915d380e6aaaf0f Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 5 Mar 2019 20:08:14 +0200 Subject: [PATCH] domainlevel-get: fix various issues when running as non-admin Use proper filter that is caught up by the ACI for 'permission:System: Read Domain Level' to allow any authenticated user to see the domain level. If the server doesn't have domain level set, callers in replica installer expect errors.NotFound but never get it. Return the right exception here and change the other caller to follow the same convention. Inability to retrieve ipaDomainLevel attribute due to a filter mismatch casues ipa-replica-install to fail if run as a replica host principal. Use DOMAIN_LEVEL_0 constant instead of 0 as used by the rest of the code. Fixes: https://pagure.io/freeipa/issue/7876 Reviewed-By: Christian Heimes --- ipaserver/plugins/domainlevel.py | 21 +++++++++++++++------ ipaserver/plugins/topology.py | 8 ++++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/ipaserver/plugins/domainlevel.py b/ipaserver/plugins/domainlevel.py index c901833a6..e87e05e46 100644 --- a/ipaserver/plugins/domainlevel.py +++ b/ipaserver/plugins/domainlevel.py @@ -10,6 +10,7 @@ from ipalib import errors from ipalib import output from ipalib.parameters import Int from ipalib.plugable import Registry +from ipalib.constants import DOMAIN_LEVEL_0, MIN_DOMAIN_LEVEL from ipapython.dn import DN @@ -45,7 +46,7 @@ def get_domainlevel_range(master_entry): int(master_entry['ipaMaxDomainLevel'][0]) ) except KeyError: - return DomainLevelRange(0, 0) + return DomainLevelRange(DOMAIN_LEVEL_0, DOMAIN_LEVEL_0) def check_conflict_entries(ldap, api, desired_value): @@ -102,12 +103,20 @@ class domainlevel_get(Command): def execute(self, *args, **options): ldap = self.api.Backend.ldap2 - entry = ldap.get_entry( + entry = ldap.get_entries( get_domainlevel_dn(self.api), - ['ipaDomainLevel'] - ) + scope=ldap.SCOPE_BASE, + filter='(objectclass=ipadomainlevelconfig)', + attrs_list=['ipaDomainLevel'] + )[0] - return {'result': int(entry.single_value['ipaDomainLevel'])} + try: + value = int(entry.single_value['ipaDomainLevel']) + return {'result': value} + except KeyError: + raise errors.NotFound( + reason=_( + 'Server does not support domain level functionality')) @register() @@ -120,7 +129,7 @@ class domainlevel_set(Command): Int('ipadomainlevel', cli_name='level', label=_('Domain Level'), - minvalue=0, + minvalue=MIN_DOMAIN_LEVEL, ), ) diff --git a/ipaserver/plugins/topology.py b/ipaserver/plugins/topology.py index af86b7338..ef21e43c3 100644 --- a/ipaserver/plugins/topology.py +++ b/ipaserver/plugins/topology.py @@ -12,7 +12,7 @@ from .baseldap import ( LDAPRetrieve) from ipalib import _, ngettext from ipalib import output -from ipalib.constants import DOMAIN_LEVEL_1 +from ipalib.constants import MIN_DOMAIN_LEVEL, DOMAIN_LEVEL_1 from ipaserver.topology import ( create_topology_graph, get_topology_connection_errors, map_masters_to_suffixes) @@ -82,7 +82,11 @@ register = Registry() def validate_domain_level(api): - current = int(api.Command.domainlevel_get()['result']) + try: + current = int(api.Command.domainlevel_get()['result']) + except errors.NotFound: + current = MIN_DOMAIN_LEVEL + if current < DOMAIN_LEVEL_1: raise errors.InvalidDomainLevelError( reason=_('Topology management requires minimum domain level {0} '