mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-07-29 15:55:47 -05:00
Fix race condition in get_locations_records()
The method IPASystemRecords.get_locations_records() has a race condition. The IPASystemRecords object creates a mapping of server names to server data. get_locations_records() uses server_find() again to get a list of servers, but then operates on the cached dict of server names. In parallel replication case, the second server_find() call in get_locations_records() can return additional servers. Since the rest of the code operates on the cached data, the method then fails with a KeyError. server_data is now an OrderedDict to keep same sorting as with server_find(). Fixes: https://pagure.io/freeipa/issue/7566 Signed-off-by: Christian Heimes <cheimes@redhat.com> Reviewed-By: Tibor Dudlak <tdudlak@redhat.com>
This commit is contained in:
@@ -8,7 +8,7 @@ import logging
|
|||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict, OrderedDict
|
||||||
from dns import (
|
from dns import (
|
||||||
rdata,
|
rdata,
|
||||||
rdataclass,
|
rdataclass,
|
||||||
@@ -71,7 +71,7 @@ class IPASystemRecords(object):
|
|||||||
def __init__(self, api_instance, all_servers=False):
|
def __init__(self, api_instance, all_servers=False):
|
||||||
self.api_instance = api_instance
|
self.api_instance = api_instance
|
||||||
self.domain_abs = DNSName(self.api_instance.env.domain).make_absolute()
|
self.domain_abs = DNSName(self.api_instance.env.domain).make_absolute()
|
||||||
self.servers_data = {}
|
self.servers_data = OrderedDict()
|
||||||
self.__init_data(all_servers=all_servers)
|
self.__init_data(all_servers=all_servers)
|
||||||
|
|
||||||
def reload_data(self):
|
def reload_data(self):
|
||||||
@@ -93,7 +93,7 @@ class IPASystemRecords(object):
|
|||||||
return location + DNSName('_locations') + self.domain_abs
|
return location + DNSName('_locations') + self.domain_abs
|
||||||
|
|
||||||
def __init_data(self, all_servers=False):
|
def __init_data(self, all_servers=False):
|
||||||
self.servers_data = {}
|
self.servers_data.clear()
|
||||||
|
|
||||||
kwargs = dict(no_members=False)
|
kwargs = dict(no_members=False)
|
||||||
if not all_servers:
|
if not all_servers:
|
||||||
@@ -328,7 +328,7 @@ class IPASystemRecords(object):
|
|||||||
|
|
||||||
zone_obj = zone.Zone(self.domain_abs, relativize=False)
|
zone_obj = zone.Zone(self.domain_abs, relativize=False)
|
||||||
if servers is None:
|
if servers is None:
|
||||||
servers = self.servers_data.keys()
|
servers = list(self.servers_data)
|
||||||
|
|
||||||
for server in servers:
|
for server in servers:
|
||||||
self._add_base_dns_records_for_server(zone_obj, server,
|
self._add_base_dns_records_for_server(zone_obj, server,
|
||||||
@@ -351,11 +351,7 @@ class IPASystemRecords(object):
|
|||||||
"""
|
"""
|
||||||
zone_obj = zone.Zone(self.domain_abs, relativize=False)
|
zone_obj = zone.Zone(self.domain_abs, relativize=False)
|
||||||
if servers is None:
|
if servers is None:
|
||||||
servers_result = self.api_instance.Command.server_find(
|
servers = list(self.servers_data)
|
||||||
pkey_only=True,
|
|
||||||
servrole=u"IPA master", # only fully installed masters
|
|
||||||
)['result']
|
|
||||||
servers = [s['cn'][0] for s in servers_result]
|
|
||||||
|
|
||||||
locations_result = self.api_instance.Command.location_find()['result']
|
locations_result = self.api_instance.Command.location_find()['result']
|
||||||
locations = [l['idnsname'][0] for l in locations_result]
|
locations = [l['idnsname'][0] for l in locations_result]
|
||||||
|
|||||||
Reference in New Issue
Block a user