diff options
author | Nalin Dahyabhai <nalin@dahyabhai.net> | 2011-06-08 11:09:28 -0400 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2011-06-14 02:03:21 -0400 |
commit | df0b927bfb2ad0f6cb15e5c69270d03668a2177c (patch) | |
tree | 2863ff97d86ac6ff36ffd136616f5b6811a54589 /ipaserver | |
parent | 6e5885d109a6aa303b62706bd571dc076491fab4 (diff) | |
download | freeipa.git-df0b927bfb2ad0f6cb15e5c69270d03668a2177c.tar.gz freeipa.git-df0b927bfb2ad0f6cb15e5c69270d03668a2177c.tar.xz freeipa.git-df0b927bfb2ad0f6cb15e5c69270d03668a2177c.zip |
Select a server with a CA on it when submitting signing requests.
When the RA is about to submit a signing request to a CA, check
if the ca_host is actually a CA. If it isn't, and it isn't the
local host, check if the local host is a CA. If that doesn't
work, try to select a CA host at random. If there aren't any,
just give up and pretend the ca_host is a CA so that we can fail
to connect to it, as we would have before.
Ticket #1252.
Diffstat (limited to 'ipaserver')
-rw-r--r-- | ipaserver/plugins/dogtag.py | 68 |
1 files changed, 65 insertions, 3 deletions
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py index 8563848b..d1234a0d 100644 --- a/ipaserver/plugins/dogtag.py +++ b/ipaserver/plugins/dogtag.py @@ -1196,7 +1196,7 @@ from ipalib import api, SkipPluginModule if api.env.ra_plugin != 'dogtag': # In this case, abort loading this plugin module... raise SkipPluginModule(reason='dogtag not selected as RA plugin') -import os +import os, random, ldap from ipaserver.plugins import rabase from ipalib.errors import NetworkError, CertificateOperationError from ipalib.constants import TYPE_ERROR @@ -1218,6 +1218,7 @@ class ra(rabase.rabase): self.ipa_key_size = "2048" self.ipa_certificate_nickname = "ipaCert" self.ca_certificate_nickname = "caCert" + self.ca_host = None try: f = open(self.pwd_file, "r") self.password = f.readline().strip() @@ -1226,6 +1227,63 @@ class ra(rabase.rabase): self.password = '' super(ra, self).__init__() + def _host_has_service(self, host, service='CA'): + """ + :param host: A host which might be a master for a service. + :param service: The service for which the host might be a master. + :return: (true, false) + + Check if a specified host is a master for a specified service. + """ + base_dn = 'cn=%s,cn=masters,cn=ipa,cn=etc,%s' % (host, api.env.basedn) + filter = '(&(objectClass=ipaConfigObject)(cn=%s)(ipaConfigString=enabledService))' % service + try: + ldap2 = self.api.Backend.ldap2 + ent,trunc = ldap2.find_entries(filter=filter, base_dn=base_dn) + if len(ent): + return True + except Exception, e: + pass + return False + + def _select_any_master(self, service='CA'): + """ + :param service: The service for which we're looking for a master. + :return: host + as str + + Select any host which is a master for a specified service. + """ + base_dn = 'cn=masters,cn=ipa,cn=etc,%s' % api.env.basedn + filter = '(&(objectClass=ipaConfigObject)(cn=%s)(ipaConfigString=enabledService))' % service + try: + ldap2 = self.api.Backend.ldap2 + ent,trunc = ldap2.find_entries(filter=filter, base_dn=base_dn) + if len(ent): + entry = random.choice(ent) + return ldap.explode_dn(dn=entry[0],notypes=True)[1] + except Exception, e: + pass + return None + + def _select_ca(self): + """ + :return: host + as str + + Select our CA host. + """ + if self._host_has_service(host=api.env.ca_host): + return api.env.ca_host + if api.env.host != api.env.ca_host: + if self._host_has_service(host=api.env.host): + return api.env.host + host = self._select_any_master() + if host: + return host + else: + return api.env.ca_host + def _request(self, url, port, **kw): """ :param url: The URL to post to. @@ -1235,7 +1293,9 @@ class ra(rabase.rabase): Perform an HTTP request. """ - return dogtag.http_request(self.env.ca_host, port, url, **kw) + if self.ca_host == None: + self.ca_host = self._select_ca() + return dogtag.http_request(self.ca_host, port, url, **kw) def _sslget(self, url, port, **kw): """ @@ -1247,7 +1307,9 @@ class ra(rabase.rabase): Perform an HTTPS request """ - return dogtag.https_request(self.env.ca_host, port, url, self.sec_dir, self.password, self.ipa_certificate_nickname, **kw) + if self.ca_host == None: + self.ca_host = self._select_ca() + return dogtag.https_request(self.ca_host, port, url, self.sec_dir, self.password, self.ipa_certificate_nickname, **kw) def get_parse_result_xml(self, xml_text, parse_func): ''' |