diff options
-rw-r--r-- | API.txt | 6 | ||||
-rw-r--r-- | VERSION | 4 | ||||
-rwxr-xr-x | install/tools/ipa-ca-install | 6 | ||||
-rwxr-xr-x | install/tools/ipa-replica-install | 3 | ||||
-rwxr-xr-x | install/tools/ipa-server-install | 6 | ||||
-rw-r--r-- | install/tools/ipa-upgradeconfig | 27 | ||||
-rwxr-xr-x | ipa-client/ipa-install/ipa-client-install | 33 | ||||
-rw-r--r-- | ipa-client/ipaclient/ipa_certupdate.py | 20 | ||||
-rw-r--r-- | ipalib/plugins/cert.py | 38 | ||||
-rw-r--r-- | ipalib/plugins/host.py | 6 | ||||
-rw-r--r-- | ipalib/plugins/service.py | 4 | ||||
-rw-r--r-- | ipalib/x509.py | 2 | ||||
-rw-r--r-- | ipaserver/install/httpinstance.py | 12 | ||||
-rw-r--r-- | ipaserver/install/ipa_replica_prepare.py | 15 | ||||
-rw-r--r-- | ipaserver/install/ipa_server_certinstall.py | 20 | ||||
-rw-r--r-- | ipaserver/install/plugins/upload_cacrt.py | 7 |
16 files changed, 144 insertions, 65 deletions
@@ -450,6 +450,12 @@ arg: Any('methods*') option: Str('version?', exclude='webui') output: Output('count', <type 'int'>, None) output: Output('results', (<type 'list'>, <type 'tuple'>), None) +command: ca_is_enabled +args: 0,1,3 +option: Str('version?', exclude='webui') +output: Output('result', <type 'bool'>, None) +output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None) +output: PrimaryKey('value', None, None) command: cert_find args: 0,17,4 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') @@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000 # # ######################################################## IPA_API_VERSION_MAJOR=2 -IPA_API_VERSION_MINOR=106 -# Last change: npmccallum - Remove token vendor, model, serial defaults +IPA_API_VERSION_MINOR=107 +# Last change: jcholast - add ca_is_enabled diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install index 0ea8cf24d..3934b0372 100755 --- a/install/tools/ipa-ca-install +++ b/install/tools/ipa-ca-install @@ -234,9 +234,6 @@ def install_master(safe_options, options): api.bootstrap(in_server=True) api.finalize() - if api.env.enable_ra: - sys.exit("CA is already installed.\n") - dm_password = options.password if not dm_password: if options.unattended: @@ -251,6 +248,9 @@ def install_master(safe_options, options): api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dm_password) + if api.Command.ca_is_enabled()['result']: + sys.exit("CA is already installed.\n") + config = api.Command['config_show']()['result'] subject_base = config['ipacertificatesubjectbase'][0] diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install index 0e0fa1788..df0e5d565 100755 --- a/install/tools/ipa-replica-install +++ b/install/tools/ipa-replica-install @@ -238,7 +238,8 @@ def install_http(config, auto_redirect): http.create_instance( config.realm_name, config.host_name, config.domain_name, config.dirman_password, False, pkcs12_info, - auto_redirect=auto_redirect, ca_file = config.dir + "/ca.crt") + auto_redirect=auto_redirect, ca_file = config.dir + "/ca.crt", + ca_is_configured=ipautil.file_exists(config.dir + "/cacert.p12")) # Now copy the autoconfiguration files try: diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install index 39c13547c..3fa7bd72a 100755 --- a/install/tools/ipa-server-install +++ b/install/tools/ipa-server-install @@ -1231,11 +1231,13 @@ def main(): http.create_instance( realm_name, host_name, domain_name, dm_password, pkcs12_info=http_pkcs12_info, subject_base=options.subject, - auto_redirect=options.ui_redirect) + auto_redirect=options.ui_redirect, + ca_is_configured=setup_ca) else: http.create_instance( realm_name, host_name, domain_name, dm_password, - subject_base=options.subject, auto_redirect=options.ui_redirect) + subject_base=options.subject, auto_redirect=options.ui_redirect, + ca_is_configured=setup_ca) tasks.restore_context(paths.CACHE_IPA_SESSIONS) # Export full CA chain diff --git a/install/tools/ipa-upgradeconfig b/install/tools/ipa-upgradeconfig index 945a6f663..03eb08c64 100644 --- a/install/tools/ipa-upgradeconfig +++ b/install/tools/ipa-upgradeconfig @@ -980,11 +980,13 @@ def add_ca_dns_records(): root_logger.info('IPA CA DNS records already processed') return - try: - api.Backend.ldap2.connect(autobind=True) - except ipalib.errors.PublicError, e: - root_logger.error("Cannot connect to LDAP to add DNS records: %s", e) - return + if not api.Backend.ldap2.isconnected(): + try: + api.Backend.ldap2.connect(autobind=True) + except ipalib.errors.PublicError, e: + root_logger.error( + "Cannot connect to LDAP to add DNS records: %s", e) + return ret = api.Command['dns_is_enabled']() if not ret['result']: @@ -1131,12 +1133,19 @@ def remove_ds_ra_cert(subject_base): def fix_trust_flags(): root_logger.info('[Fixing trust flags in %s]' % paths.HTTPD_ALIAS_DIR) - if not api.env.enable_ra: - root_logger.info("CA is not enabled") + if sysupgrade.get_upgrade_state('http', 'fix_trust_flags'): + root_logger.info("Trust flags already processed") return - if sysupgrade.get_upgrade_state(service, 'fix_trust_flags'): - root_logger.info("Trust flags already fixed") + if not api.Backend.ldap2.isconnected(): + try: + api.Backend.ldap2.connect(autobind=True) + except ipalib.errors.PublicError, e: + root_logger.error("Cannot connect to LDAP: %s", e) + return + + if not api.Command.ca_is_enabled()['result']: + root_logger.info("CA is not enabled") return db = certs.CertDB(api.env.realm) diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install index 3b6e581c7..7b1e2f8b0 100755 --- a/ipa-client/ipa-install/ipa-client-install +++ b/ipa-client/ipa-install/ipa-client-install @@ -1093,11 +1093,11 @@ def configure_krb5_conf(cli_realm, cli_domain, cli_server, cli_kdc, dnsok, return 0 def configure_certmonger(fstore, subject_base, cli_realm, hostname, options, - remote_env): + ca_enabled): if not options.request_cert: return - if not remote_env['enable_ra']: + if not ca_enabled: root_logger.warning( "An RA is not configured on the server. " "Not requesting host certificate.") @@ -1696,11 +1696,11 @@ def print_port_conf_info(): " TCP: 464\n" " UDP: 464, 123 (if NTP enabled)") -def get_certs_from_ldap(server, base_dn, realm, enable_ra): +def get_certs_from_ldap(server, base_dn, realm, ca_enabled): conn = ipaldap.IPAdmin(server, sasl_nocanon=True) try: conn.do_sasl_gssapi_bind() - certs = certstore.get_ca_certs(conn, base_dn, realm, enable_ra) + certs = certstore.get_ca_certs(conn, base_dn, realm, ca_enabled) except errors.NotFound: raise errors.NoCertificateError(entry=server) except errors.NetworkError, e: @@ -2640,13 +2640,20 @@ def install(options, env, fstore, statestore): return CLIENT_INSTALL_ERROR # Use the RPC directly so older servers are supported - result = api.Backend.rpcclient.forward( - 'env', - server=True, - version=u'2.0', - ) - remote_env = result['result'] - if not remote_env['enable_ra']: + try: + result = api.Backend.rpcclient.forward( + 'ca_is_enabled', + version=u'2.0', + ) + ca_enabled = result['result'] + except errors.CommandError: + result = api.Backend.rpcclient.forward( + 'env', + server=True, + version=u'2.0', + ) + ca_enabled = result['result']['enable_ra'] + if not ca_enabled: disable_ra() # Create IPA NSS database @@ -2658,7 +2665,7 @@ def install(options, env, fstore, statestore): # Get CA certificates from the certificate store ca_certs = get_certs_from_ldap(cli_server[0], cli_basedn, cli_realm, - remote_env['enable_ra']) + ca_enabled) ca_certs_trust = [(c, n, certstore.key_policy_to_trust_flags(t, True, u)) for (c, n, t, u) in ca_certs] @@ -2692,7 +2699,7 @@ def install(options, env, fstore, statestore): if not options.on_master: client_dns(cli_server[0], hostname, options.dns_updates) configure_certmonger(fstore, subject_base, cli_realm, hostname, - options, remote_env) + options, ca_enabled) update_ssh_keys(cli_server[0], hostname, services.knownservices.sshd.get_config_dir(), options.create_sshfp) diff --git a/ipa-client/ipaclient/ipa_certupdate.py b/ipa-client/ipaclient/ipa_certupdate.py index ff16b9b7a..7ef11d058 100644 --- a/ipa-client/ipaclient/ipa_certupdate.py +++ b/ipa-client/ipaclient/ipa_certupdate.py @@ -27,7 +27,7 @@ from ipapython import (admintool, ipautil, ipaldap, sysrestore, dogtag, from ipaplatform import services from ipaplatform.paths import paths from ipaplatform.tasks import tasks -from ipalib import api, x509, certstore +from ipalib import api, errors, x509, certstore class CertUpdate(admintool.AdminTool): @@ -59,10 +59,26 @@ class CertUpdate(admintool.AdminTool): principal = str('host/%s@%s' % (api.env.host, api.env.realm)) ipautil.kinit_hostprincipal(paths.KRB5_KEYTAB, tmpdir, principal) + api.Backend.rpcclient.connect() + try: + result = api.Backend.rpcclient.forward( + 'ca_is_enabled', + version=u'2.0', + ) + ca_enabled = result['result'] + except errors.CommandError: + result = api.Backend.rpcclient.forward( + 'env', + server=True, + version=u'2.0', + ) + ca_enabled = result['result']['enable_ra'] + api.Backend.rpcclient.disconnect() + ldap.do_sasl_gssapi_bind() certs = certstore.get_ca_certs(ldap, api.env.basedn, - api.env.realm, api.env.enable_ra) + api.env.realm, ca_enabled) finally: shutil.rmtree(tmpdir) diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py index 679ac14a6..7e2c77622 100644 --- a/ipalib/plugins/cert.py +++ b/ipalib/plugins/cert.py @@ -19,13 +19,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -from ipalib import api, SkipPluginModule -if api.env.enable_ra is not True: - # In this case, abort loading this plugin module... - raise SkipPluginModule(reason='env.enable_ra is not True') import os import time from ipalib import Command, Str, Int, Bytes, Flag, File +from ipalib import api from ipalib import errors from ipalib import pkcs10 from ipalib import x509 @@ -33,6 +30,7 @@ from ipalib import util from ipalib import ngettext from ipalib.plugable import Registry from ipalib.plugins.virtual import * +from ipalib.plugins.baseldap import pkey_to_value from ipalib.plugins.service import split_principal import base64 import traceback @@ -214,6 +212,10 @@ def get_host_from_principal(principal): return hostname +def ca_enabled_check(): + if not api.Command.ca_is_enabled()['result']: + raise errors.NotFound(reason=_('CA is not configured')) + @register() class cert_request(VirtualCommand): __doc__ = _('Submit a certificate signing request.') @@ -289,6 +291,8 @@ class cert_request(VirtualCommand): } def execute(self, csr, **kw): + ca_enabled_check() + ldap = self.api.Backend.ldap2 principal = kw.get('principal') add = kw.get('add') @@ -475,6 +479,7 @@ class cert_status(VirtualCommand): def execute(self, request_id, **kw): + ca_enabled_check() self.check_access() return dict( result=self.Backend.ra.check_request_status(request_id) @@ -536,6 +541,7 @@ class cert_show(VirtualCommand): operation="retrieve certificate" def execute(self, serial_number, **options): + ca_enabled_check() hostname = None try: self.check_access() @@ -603,6 +609,7 @@ class cert_revoke(VirtualCommand): ) def execute(self, serial_number, **kw): + ca_enabled_check() hostname = None try: self.check_access() @@ -641,6 +648,7 @@ class cert_remove_hold(VirtualCommand): operation = "certificate remove hold" def execute(self, serial_number, **kw): + ca_enabled_check() self.check_access() return dict( result=self.Backend.ra.take_certificate_off_hold(serial_number) @@ -740,6 +748,7 @@ class cert_find(Command): ) def execute(self, **options): + ca_enabled_check() ret = dict( result=self.Backend.ra.find(options) ) @@ -747,3 +756,24 @@ class cert_find(Command): ret['truncated'] = False return ret + +@register() +class ca_is_enabled(Command): + """ + Checks if any of the servers has the CA service enabled. + """ + NO_CLI = True + has_output = output.standard_value + + def execute(self, *args, **options): + base_dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), + self.api.env.basedn) + filter = '(&(objectClass=ipaConfigObject)(cn=CA))' + try: + self.api.Backend.ldap2.find_entries( + base_dn=base_dn, filter=filter, attrs_list=[]) + except errors.NotFound: + result = False + else: + result = True + return dict(result=result, value=pkey_to_value(None, options)) diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py index bbee09395..91fb75b87 100644 --- a/ipalib/plugins/host.py +++ b/ipalib/plugins/host.py @@ -721,7 +721,7 @@ class host_del(LDAPDelete): **delkw) break - if self.api.env.enable_ra: + if self.api.Command.ca_is_enabled()['result']: try: entry_attrs = ldap.get_entry(dn, ['usercertificate']) except errors.NotFound: @@ -806,7 +806,7 @@ class host_mod(LDAPUpdate): entry_attrs['objectclass'] = obj_classes cert = x509.normalize_certificate(entry_attrs.get('usercertificate')) if cert: - if self.api.env.enable_ra: + if self.api.Command.ca_is_enabled()['result']: x509.verify_cert_subject(ldap, keys[-1], cert) entry_attrs_old = ldap.get_entry(dn, ['usercertificate']) oldcert = entry_attrs_old.single_value.get('usercertificate') @@ -1084,7 +1084,7 @@ class host_disable(LDAPQuery): self.obj.handle_not_found(*keys) cert = entry_attrs.single_value.get('usercertificate') if cert: - if self.api.env.enable_ra: + if self.api.Command.ca_is_enabled()['result']: cert = x509.normalize_certificate(cert) try: serial = unicode(x509.get_serial_number(cert, x509.DER)) diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py index 3ca5066f3..55f412625 100644 --- a/ipalib/plugins/service.py +++ b/ipalib/plugins/service.py @@ -486,7 +486,7 @@ class service_del(LDAPDelete): # custom services allow them to manage them. (service, hostname, realm) = split_principal(keys[-1]) check_required_principal(ldap, hostname, service) - if self.api.env.enable_ra: + if self.api.Command.ca_is_enabled()['result']: try: entry_attrs = ldap.get_entry(dn, ['usercertificate']) except errors.NotFound: @@ -676,7 +676,7 @@ class service_disable(LDAPQuery): done_work = False if 'usercertificate' in entry_attrs: - if self.api.env.enable_ra: + if self.api.Command.ca_is_enabled()['result']: cert = x509.normalize_certificate(entry_attrs.get('usercertificate')[0]) try: serial = unicode(x509.get_serial_number(cert, x509.DER)) diff --git a/ipalib/x509.py b/ipalib/x509.py index 4be46e144..88ea415bf 100644 --- a/ipalib/x509.py +++ b/ipalib/x509.py @@ -71,7 +71,7 @@ def subject_base(): return _subject_base def valid_issuer(issuer): - if not api.env.enable_ra: + if not api.Command.ca_is_enabled()['result']: return True # Handle all supported forms of issuer -- currently dogtag only. if api.env.ra_plugin == 'dogtag': diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py index 367c536b9..e34034706 100644 --- a/ipaserver/install/httpinstance.py +++ b/ipaserver/install/httpinstance.py @@ -82,12 +82,14 @@ class HTTPInstance(service.Service): self.fstore = sysrestore.FileStore(paths.SYSRESTORE) self.cert_nickname = cert_nickname + self.ca_is_configured = True subject_base = ipautil.dn_attribute_property('_subject_base') def create_instance(self, realm, fqdn, domain_name, dm_password=None, autoconfig=True, pkcs12_info=None, - subject_base=None, auto_redirect=True, ca_file=None): + subject_base=None, auto_redirect=True, ca_file=None, + ca_is_configured=None): self.fqdn = fqdn self.realm = realm self.domain = domain_name @@ -105,6 +107,8 @@ class HTTPInstance(service.Service): CRL_PUBLISH_PATH=dogtag.install_constants.CRL_PUBLISH_PATH, ) self.ca_file = ca_file + if ca_is_configured is not None: + self.ca_is_configured = ca_is_configured # get a connection to the DS self.ldap_connect() @@ -219,7 +223,7 @@ class HTTPInstance(service.Service): db = certs.CertDB(self.realm, subject_base=self.subject_base) if self.pkcs12_info: - if api.env.enable_ra: + if self.ca_is_configured: trust_flags = 'CT,C,C' else: trust_flags = None @@ -236,7 +240,7 @@ class HTTPInstance(service.Service): nickname = server_certs[0][0] self.dercert = db.get_cert_from_db(nickname, pem=False) - if api.env.enable_ra: + if self.ca_is_configured: db.track_server_cert(nickname, self.principal, db.passwd_fname, 'restart_httpd') self.__set_mod_nss_nickname(nickname) @@ -267,7 +271,7 @@ class HTTPInstance(service.Service): def __import_ca_certs(self): db = certs.CertDB(self.realm, subject_base=self.subject_base) - self.import_ca_certs(db, api.env.enable_ra) + self.import_ca_certs(db, self.ca_is_configured) def __setup_autoconfig(self): target_fname = paths.PREFERENCES_HTML diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py index ce0cff22a..59a9862d5 100644 --- a/ipaserver/install/ipa_replica_prepare.py +++ b/ipaserver/install/ipa_replica_prepare.py @@ -161,12 +161,6 @@ class ReplicaPrepare(admintool.AdminTool): if api.env.host == self.replica_fqdn: raise admintool.ScriptError("You can't create a replica on itself") - if not api.env.enable_ra and not options.http_cert_files: - raise admintool.ScriptError( - "Cannot issue certificates: a CA is not installed. Use the " - "--http-cert-file, --dirsrv-cert-file options to provide " - "custom certificates.") - config_dir = dsinstance.config_dirname( dsinstance.realm_to_serverid(api.env.realm)) if not ipautil.dir_exists(config_dir): @@ -198,10 +192,11 @@ class ReplicaPrepare(admintool.AdminTool): # Try out the password & get the subject base suffix = ipautil.realm_to_suffix(api.env.realm) try: - conn = ldap2(shared_instance=False, base_dn=suffix) + conn = api.Backend.ldap2 conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=self.dirman_password) entry_attrs = conn.get_ipa_config() + ca_enabled = api.Command.ca_is_enabled()['result'] conn.disconnect() except errors.ACIError: raise admintool.ScriptError("The password provided is incorrect " @@ -212,6 +207,12 @@ class ReplicaPrepare(admintool.AdminTool): except errors.DatabaseError, e: raise admintool.ScriptError(e.desc) + if not ca_enabled and not options.http_cert_files: + raise admintool.ScriptError( + "Cannot issue certificates: a CA is not installed. Use the " + "--http-cert-file, --dirsrv-cert-file options to provide " + "custom certificates.") + self.subject_base = entry_attrs.get( 'ipacertificatesubjectbase', [None])[0] if self.subject_base is not None: diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py index 9165ac1c9..80cf6d5d5 100644 --- a/ipaserver/install/ipa_server_certinstall.py +++ b/ipaserver/install/ipa_server_certinstall.py @@ -83,7 +83,7 @@ class ServerCertInstall(admintool.AdminTool): def ask_for_options(self): super(ServerCertInstall, self).ask_for_options() - if self.options.dirsrv and not self.options.dirman_password: + if not self.options.dirman_password: self.options.dirman_password = installutils.read_password( "Directory Manager", confirm=False, validate=False, retry=False) if self.options.dirman_password is None: @@ -101,20 +101,23 @@ class ServerCertInstall(admintool.AdminTool): api.bootstrap(in_server=True) api.finalize() + conn = api.Backend.ldap2 + conn.connect(bind_dn=DN(('cn', 'directory manager')), + bind_pw=self.options.dirman_password) + if self.options.dirsrv: self.install_dirsrv_cert() if self.options.http: self.install_http_cert() + conn.disconnect() + def install_dirsrv_cert(self): serverid = dsinstance.realm_to_serverid(api.env.realm) dirname = dsinstance.config_dirname(serverid) - conn = ldap2(shared_instance=False, base_dn='') - conn.connect(bind_dn=DN(('cn', 'directory manager')), - bind_pw=self.options.dirman_password) - + conn = api.Backend.ldap2 entry = conn.get_entry(DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')), ['nssslpersonalityssl']) @@ -130,8 +133,6 @@ class ServerCertInstall(admintool.AdminTool): except errors.EmptyModlist: pass - conn.disconnect() - def install_http_cert(self): dirname = certs.NSS_DIR @@ -165,14 +166,15 @@ class ServerCertInstall(admintool.AdminTool): cdb = certs.CertDB(api.env.realm, nssdir=dirname) try: - if api.env.enable_ra: + ca_enabled = api.Command.ca_is_enabled()['result'] + if ca_enabled: cdb.untrack_server_cert(old_cert) cdb.delete_cert(old_cert) cdb.import_pkcs12(pkcs12_file.name, pin) server_cert = cdb.find_server_certs()[0][0] - if api.env.enable_ra: + if ca_enabled: cdb.track_server_cert(server_cert, principal, cdb.passwd_fname, command) except RuntimeError, e: diff --git a/ipaserver/install/plugins/upload_cacrt.py b/ipaserver/install/plugins/upload_cacrt.py index 1a1325733..66270ae76 100644 --- a/ipaserver/install/plugins/upload_cacrt.py +++ b/ipaserver/install/plugins/upload_cacrt.py @@ -34,7 +34,8 @@ class update_upload_cacrt(PostUpdate): db = certs.CertDB(self.api.env.realm) ca_cert = None - if self.api.env.enable_ra: + ca_enabled = self.api.Command.ca_is_enabled()['result'] + if ca_enabled: ca_nickname = certdb.get_ca_nickname(self.api.env.realm) else: ca_nickname = None @@ -49,7 +50,7 @@ class update_upload_cacrt(PostUpdate): for nickname, trust_flags in db.list_certs(): if 'u' in trust_flags: continue - if nickname == ca_nickname and self.api.env.enable_ra: + if nickname == ca_nickname and ca_enabled: trust_flags = 'CT,C,C' cert = db.get_cert_from_db(nickname, pem=False) try: @@ -60,7 +61,7 @@ class update_upload_cacrt(PostUpdate): continue if nickname == ca_nickname: ca_cert = cert - if self.api.env.enable_ra: + if ca_enabled: entry.append('ipaConfigString:ipaCA') entry.append('ipaConfigString:compatCA') updates[dn] = {'dn': dn, 'default': entry} |