def expired_ipa_certs(now): """ Determine which IPA certs are expired, or close to expiry. Return a list of (IPACertType, cert) pairs. """ certs = [] # IPA RA cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM) if cert.not_valid_after <= now: certs.append((IPACertType.IPARA, cert)) # Apache HTTPD cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE) if cert.not_valid_after <= now: certs.append((IPACertType.HTTPS, cert)) # LDAPS ds_dbdir = dsinstance.config_dirname(realm_to_serverid(api.env.realm)) db = NSSDatabase(nssdir=ds_dbdir) cert = db.get_cert('Server-Cert') if cert.not_valid_after <= now: certs.append((IPACertType.LDAPS, cert)) # KDC cert = x509.load_certificate_from_file(paths.KDC_CERT) if cert.not_valid_after <= now: certs.append((IPACertType.KDC, cert)) return certs
def check(self): self.files = [] self.collect_files(dsinstance.config_dirname(self.serverid), NSS_SQL_FILES, 'dirsrv', 'root', '0640') # There always has to be a special one. pkcs11.txt has a different # group so pop off the auto-generated one and add a replacement. old = (os.path.join(dsinstance.config_dirname(self.serverid), 'pkcs11.txt'), 'dirsrv', 'root', '0640') self.files.remove(old) new = (os.path.join(dsinstance.config_dirname(self.serverid), 'pkcs11.txt'), 'dirsrv', 'dirsrv', '0640') self.files.append(new) if self.ca.is_configured(): self.collect_files(paths.PKI_TOMCAT_ALIAS_DIR, NSS_SQL_FILES, 'pkiuser', 'pkiuser', '0600') return FileCheck.check(self)
def validate_options(self): options = self.options super(ReplicaPrepare, self).validate_options(needs_root=True) installutils.check_server_configuration() if not options.ip_addresses: if options.reverse_zones: self.option_parser.error( "You cannot specify a --reverse-zone " "option without the --ip-address option") if options.no_reverse: self.option_parser.error( "You cannot specify a --no-reverse " "option without the --ip-address option") elif options.reverse_zones and options.no_reverse: self.option_parser.error("You cannot specify a --reverse-zone " "option together with --no-reverse") #Automatically disable pkinit w/ dogtag until that is supported options.setup_pkinit = False # If any of the PKCS#12 options are selected, all are required. cert_file_req = (options.dirsrv_cert_files, options.http_cert_files) cert_file_opt = (options.pkinit_cert_files, ) if any(cert_file_req + cert_file_opt) and not all(cert_file_req): self.option_parser.error( "--dirsrv-cert-file and --http-cert-file are required if any " "PKCS#12 options are used.") if len(self.args) < 1: self.option_parser.error( "must provide the fully-qualified name of the replica") elif len(self.args) > 1: self.option_parser.error( "must provide exactly one name for the replica") else: [self.replica_fqdn] = self.args api.bootstrap(in_server=True) api.finalize() # Connect to LDAP, connection is closed at the end of run() api.Backend.ldap2.connect() self.check_for_supported_domain_level() if api.env.host == self.replica_fqdn: raise admintool.ScriptError("You can't create a replica on itself") config_dir = dsinstance.config_dirname( installutils.realm_to_serverid(api.env.realm)) if not ipautil.dir_exists(config_dir): raise admintool.ScriptError( "could not find directory instance: %s" % config_dir)
def validate_options(self): options = self.options super(ReplicaPrepare, self).validate_options(needs_root=True) installutils.check_server_configuration() if not options.ip_address: if options.reverse_zone: self.option_parser.error("You cannot specify a --reverse-zone " "option without the --ip-address option") if options.no_reverse: self.option_parser.error("You cannot specify a --no-reverse " "option without the --ip-address option") elif options.reverse_zone and options.no_reverse: self.option_parser.error("You cannot specify a --reverse-zone " "option together with --no-reverse") #Automatically disable pkinit w/ dogtag until that is supported options.setup_pkinit = False # If any of the PKCS#12 options are selected, all are required. pkcs12_req = (options.dirsrv_pkcs12, options.http_pkcs12) pkcs12_opt = (options.pkinit_pkcs12,) if any(pkcs12_req + pkcs12_opt) and not all(pkcs12_req): self.option_parser.error( "--dirsrv_pkcs12 and --http_pkcs12 are required if any " "PKCS#12 options are used.") if len(self.args) < 1: self.option_parser.error( "must provide the fully-qualified name of the replica") elif len(self.args) > 1: self.option_parser.error( "must provide exactly one name for the replica") else: [self.replica_fqdn] = self.args api.bootstrap(in_server=True) api.finalize() 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_pkcs12: raise admintool.ScriptError( "Cannot issue certificates: a CA is not installed. Use the " "--http_pkcs12, --dirsrv_pkcs12 options to provide custom " "certificates.") config_dir = dsinstance.config_dirname( dsinstance.realm_to_serverid(api.env.realm)) if not ipautil.dir_exists(config_dir): raise admintool.ScriptError( "could not find directory instance: %s" % config_dir)
def validate_options(self): options = self.options super(ReplicaPrepare, self).validate_options(needs_root=True) installutils.check_server_configuration() if not options.ip_addresses: if options.reverse_zones: self.option_parser.error("You cannot specify a --reverse-zone " "option without the --ip-address option") if options.no_reverse: self.option_parser.error("You cannot specify a --no-reverse " "option without the --ip-address option") elif options.reverse_zones and options.no_reverse: self.option_parser.error("You cannot specify a --reverse-zone " "option together with --no-reverse") #Automatically disable pkinit w/ dogtag until that is supported options.setup_pkinit = False # If any of the PKCS#12 options are selected, all are required. cert_file_req = (options.dirsrv_cert_files, options.http_cert_files) cert_file_opt = (options.pkinit_cert_files,) if any(cert_file_req + cert_file_opt) and not all(cert_file_req): self.option_parser.error( "--dirsrv-cert-file and --http-cert-file are required if any " "PKCS#12 options are used.") if len(self.args) < 1: self.option_parser.error( "must provide the fully-qualified name of the replica") elif len(self.args) > 1: self.option_parser.error( "must provide exactly one name for the replica") else: [self.replica_fqdn] = self.args api.bootstrap(in_server=True) api.finalize() # Connect to LDAP, connection is closed at the end of run() api.Backend.ldap2.connect() self.check_for_supported_domain_level() if api.env.host == self.replica_fqdn: raise admintool.ScriptError("You can't create a replica on itself") config_dir = dsinstance.config_dirname( installutils.realm_to_serverid(api.env.realm)) if not ipautil.dir_exists(config_dir): raise admintool.ScriptError( "could not find directory instance: %s" % config_dir)
def expired_ipa_certs(now): """ Determine which IPA certs are expired, or close to expiry. Return a list of (IPACertType, cert) pairs. """ certs = [] non_renewed = [] # IPA RA cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM) if cert.not_valid_after <= now: certs.append((IPACertType.IPARA, cert)) # Apache HTTPD cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE) if cert.not_valid_after <= now: if not is_ipa_issued_cert(api, cert): non_renewed.append((IPACertType.HTTPS, cert)) else: certs.append((IPACertType.HTTPS, cert)) # LDAPS serverid = realm_to_serverid(api.env.realm) ds = dsinstance.DsInstance(realm_name=api.env.realm) ds_dbdir = dsinstance.config_dirname(serverid) ds_nickname = ds.get_server_cert_nickname(serverid) db = NSSDatabase(nssdir=ds_dbdir) cert = db.get_cert(ds_nickname) if cert.not_valid_after <= now: if not is_ipa_issued_cert(api, cert): non_renewed.append((IPACertType.LDAPS, cert)) else: certs.append((IPACertType.LDAPS, cert)) # KDC cert = x509.load_certificate_from_file(paths.KDC_CERT) if cert.not_valid_after <= now: if not is_ipa_issued_cert(api, cert): non_renewed.append((IPACertType.HTTPS, cert)) else: certs.append((IPACertType.KDC, cert)) return certs, non_renewed
def install_dirsrv_cert(self): serverid = installutils.realm_to_serverid(api.env.realm) dirname = dsinstance.config_dirname(serverid) conn = api.Backend.ldap2 entry = conn.get_entry(DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')), ['nssslpersonalityssl']) old_cert = entry.single_value['nssslpersonalityssl'] server_cert = self.import_cert(dirname, self.options.pin, old_cert, 'ldap/%s' % api.env.host, 'restart_dirsrv %s' % serverid) entry['nssslpersonalityssl'] = [server_cert] try: conn.update_entry(entry) except errors.EmptyModlist: pass
def install_dirsrv_cert(self): serverid = installutils.realm_to_serverid(api.env.realm) dirname = dsinstance.config_dirname(serverid) conn = api.Backend.ldap2 entry = conn.get_entry( DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')), ['nssslpersonalityssl']) old_cert = entry.single_value['nssslpersonalityssl'] server_cert = self.import_cert(dirname, self.options.pin, old_cert, 'ldap/%s' % api.env.host, 'restart_dirsrv %s' % serverid) entry['nssslpersonalityssl'] = [server_cert] try: conn.update_entry(entry) except errors.EmptyModlist: pass
def execute(self, **options): ldap = self.obj.backend (cdn, ipa_config) = ldap.get_ipa_config() subject_base = ipa_config.get('ipacertificatesubjectbase', [None])[0] dirname = config_dirname(realm_to_serverid(api.env.realm)) certdb = certs.CertDB(api.env.realm, nssdir=dirname, subject_base=subject_base) dercert = certdb.get_cert_from_db(certdb.cacert_name, pem=False) updates = {} dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'), api.env.basedn) cacrt_entry = ['objectclass:nsContainer', 'objectclass:pkiCA', 'cn:CAcert', 'cACertificate;binary:%s' % dercert, ] updates[dn] = {'dn': dn, 'default': cacrt_entry} return (False, True, [updates])
def install_ipa_certs(subject_base, ca_subject_dn, certs): """Print details and install renewed IPA certificates.""" for certtype, oldcert in certs: cert_path = "/etc/pki/pki-tomcat/certs/{}-renewed.crt" \ .format(oldcert.serial_number) cert = x509.load_certificate_from_file(cert_path) print_cert_info("Renewed IPA", certtype.value, cert) if certtype is IPACertType.IPARA: shutil.copyfile(cert_path, paths.RA_AGENT_PEM) cainstance.update_people_entry(cert) replicate_cert(subject_base, ca_subject_dn, cert) elif certtype is IPACertType.HTTPS: shutil.copyfile(cert_path, paths.HTTPD_CERT_FILE) elif certtype is IPACertType.LDAPS: ds_dbdir = dsinstance.config_dirname( realm_to_serverid(api.env.realm)) db = NSSDatabase(nssdir=ds_dbdir) db.delete_cert('Server-Cert') db.import_pem_cert('Server-Cert', EMPTY_TRUST_FLAGS, cert_path) elif certtype is IPACertType.KDC: shutil.copyfile(cert_path, paths.KDC_CERT)
def install_ipa_certs(subject_base, ca_subject_dn, certs): """Print details and install renewed IPA certificates.""" for certtype, oldcert in certs: cert_path = RENEWED_CERT_PATH_TEMPLATE.format(oldcert.serial_number) cert = x509.load_certificate_from_file(cert_path) print_cert_info("Renewed IPA", certtype.value, cert) if certtype is IPACertType.IPARA: shutil.copyfile(cert_path, paths.RA_AGENT_PEM) cainstance.update_people_entry(cert) replicate_cert(subject_base, ca_subject_dn, cert) elif certtype is IPACertType.HTTPS: shutil.copyfile(cert_path, paths.HTTPD_CERT_FILE) elif certtype is IPACertType.LDAPS: serverid = realm_to_serverid(api.env.realm) ds = dsinstance.DsInstance(realm_name=api.env.realm) ds_dbdir = dsinstance.config_dirname(serverid) db = NSSDatabase(nssdir=ds_dbdir) ds_nickname = ds.get_server_cert_nickname(serverid) db.delete_cert(ds_nickname) db.import_pem_cert(ds_nickname, EMPTY_TRUST_FLAGS, cert_path) elif certtype is IPACertType.KDC: shutil.copyfile(cert_path, paths.KDC_CERT)
def is_dirsrv_debugging_enabled(): """ Check the 389-ds instance to see if debugging is enabled. If so we suppress that in our output. returns True or False """ debugging = False serverid = realm_to_serverid(api.env.realm) dselist = [config_dirname(serverid)] for dse in dselist: try: fd = open(dse + "dse.ldif", "r") except IOError: continue lines = fd.readlines() fd.close() for line in lines: if line.lower().startswith("nsslapd-errorlog-level"): _option, value = line.split(":") if int(value) > 0: debugging = True return debugging
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) entry = conn.get_entry(DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')), ['nssslpersonalityssl']) old_cert = entry.single_value['nssslpersonalityssl'] server_cert = self.import_cert(dirname, self.options.pin, old_cert, 'ldap/%s' % api.env.host, 'restart_dirsrv %s' % serverid) entry['nssslpersonalityssl'] = [server_cert] try: conn.update_entry(entry) except errors.EmptyModlist: pass conn.disconnect()
def install_step_1(standalone, replica_config, options): realm_name = options.realm_name domain_name = options.domain_name dm_password = options.dm_password host_name = options.host_name subject_base = options.subject basedn = ipautil.realm_to_suffix(realm_name) ca = cainstance.CAInstance(realm_name, certs.NSS_DIR, host_name=host_name) if standalone: ca.stop('pki-tomcat') # We need to ldap_enable the CA now that DS is up and running if replica_config is None: config = ['caRenewalMaster'] else: config = [] ca.ldap_enable('CA', host_name, dm_password, basedn, config) # This is done within stopped_service context, which restarts CA ca.enable_client_auth_to_db(paths.CA_CS_CFG_PATH) # Lightweight CA key retrieval is configured in step 1 instead # of CAInstance.configure_instance (which is invoked from step # 0) because kadmin_addprinc fails until krb5.conf is installed # by krb.create_instance. # ca.setup_lightweight_ca_key_retrieval() if standalone and replica_config is None: serverid = installutils.realm_to_serverid(realm_name) dirname = dsinstance.config_dirname(serverid) # Store the new IPA CA cert chain in DS NSS database and LDAP cadb = certs.CertDB(realm_name, subject_base=subject_base) dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base) trust_flags = dict(reversed(cadb.list_certs())) trust_chain = cadb.find_root_cert('ipaCert')[:-1] for nickname in trust_chain[:-1]: cert = cadb.get_cert_from_db(nickname, pem=False) dsdb.add_cert(cert, nickname, trust_flags[nickname]) certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags[nickname]) nickname = trust_chain[-1] cert = cadb.get_cert_from_db(nickname, pem=False) dsdb.add_cert(cert, nickname, trust_flags[nickname]) certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags[nickname], config_ipa=True, config_compat=True) api.Backend.ldap2.disconnect() # Restart DS services.knownservices.dirsrv.restart(serverid) api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dm_password) # Store DS CA cert in Dogtag NSS database dogtagdb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR) trust_flags = dict(reversed(dsdb.list_certs())) server_certs = dsdb.find_server_certs() trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1] nickname = trust_chain[-1] cert = dsdb.get_cert_from_db(nickname) dogtagdb.add_cert(cert, nickname, trust_flags[nickname]) if standalone: ca.start('pki-tomcat') # We need to restart apache as we drop a new config file in there services.knownservices.httpd.restart(capture_output=True) # Install CA DNS records if bindinstance.dns_container_exists(host_name, basedn, dm_password): bind = bindinstance.BindInstance(dm_password=dm_password) bind.update_system_records()
def check(self): validate = [] ca_pw_fname = None if self.ca.is_configured(): try: ca_passwd = get_dogtag_cert_password() except IOError as e: yield Result( self, constants.ERROR, error=str(e), msg='Unable to read CA NSSDB token password: {error}') return else: with tempfile.NamedTemporaryFile(mode='w', delete=False) as ca_pw_file: ca_pw_file.write(ca_passwd) ca_pw_fname = ca_pw_file.name validate.append(( paths.PKI_TOMCAT_ALIAS_DIR, 'Server-Cert cert-pki-ca', ca_pw_fname, ), ) validate.append(( dsinstance.config_dirname(self.serverid), self.ds.get_server_cert_nickname(self.serverid), os.path.join(dsinstance.config_dirname(self.serverid), 'pwdfile.txt'), )) # Wrap in try/except to ensure the temporary password file is # removed try: for (dbdir, nickname, pinfile) in validate: # detect the database type so we have the right prefix db = certdb.NSSDatabase(dbdir) key = os.path.normpath(dbdir) + ':' + nickname try: response = self.validate_nss(dbdir, db.dbtype, pinfile, nickname) except ipautil.CalledProcessError as e: logger.debug('Validation of NSS certificate failed %s', e) yield Result( self, constants.ERROR, key=key, dbdir=dbdir, nickname=nickname, reason=response.output_error, msg='Validation of {nickname} in {dbdir} failed: ' '{reason}') else: if 'certificate is valid' not in \ response.raw_output.decode('utf-8'): yield Result( self, constants.ERROR, key=key, dbdir=dbdir, nickname=nickname, reason="%s: %s" % (response.raw_output.decode('utf-8'), response.error_log), msg='Validation of {nickname} in {dbdir} failed: ' '{reason}') else: yield Result(self, constants.SUCCESS, dbdir=dbdir, nickname=nickname, key=key) finally: if ca_pw_fname: ipautil.remove_file(ca_pw_fname)
def install_step_1(standalone, replica_config, options): realm_name = options.realm_name dm_password = options.dm_password host_name = options.host_name subject_base = options.subject basedn = ipautil.realm_to_suffix(realm_name) ca = cainstance.CAInstance(realm_name, certs.NSS_DIR, host_name=host_name) if standalone: ca.stop('pki-tomcat') # We need to ldap_enable the CA now that DS is up and running if replica_config is None: config = ['caRenewalMaster'] else: config = [] ca.ldap_enable('CA', host_name, dm_password, basedn, config) # This is done within stopped_service context, which restarts CA ca.enable_client_auth_to_db(paths.CA_CS_CFG_PATH) # Lightweight CA key retrieval is configured in step 1 instead # of CAInstance.configure_instance (which is invoked from step # 0) because kadmin_addprinc fails until krb5.conf is installed # by krb.create_instance. # ca.setup_lightweight_ca_key_retrieval() if standalone and replica_config is None: serverid = installutils.realm_to_serverid(realm_name) dirname = dsinstance.config_dirname(serverid) # Store the new IPA CA cert chain in DS NSS database and LDAP cadb = certs.CertDB(realm_name, subject_base=subject_base) dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base) trust_flags = dict(reversed(cadb.list_certs())) trust_chain = cadb.find_root_cert('ipaCert')[:-1] for nickname in trust_chain[:-1]: cert = cadb.get_cert_from_db(nickname, pem=False) dsdb.add_cert(cert, nickname, trust_flags[nickname]) certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags[nickname]) nickname = trust_chain[-1] cert = cadb.get_cert_from_db(nickname, pem=False) dsdb.add_cert(cert, nickname, trust_flags[nickname]) certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags[nickname], config_ipa=True, config_compat=True) api.Backend.ldap2.disconnect() # Restart DS services.knownservices.dirsrv.restart(serverid) api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dm_password) # Store DS CA cert in Dogtag NSS database dogtagdb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR) trust_flags = dict(reversed(dsdb.list_certs())) server_certs = dsdb.find_server_certs() trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1] nickname = trust_chain[-1] cert = dsdb.get_cert_from_db(nickname) dogtagdb.add_cert(cert, nickname, trust_flags[nickname]) if standalone: ca.start('pki-tomcat') # We need to restart apache as we drop a new config file in there services.knownservices.httpd.restart(capture_output=True) # Install CA DNS records if bindinstance.dns_container_exists(host_name, basedn, dm_password): bind = bindinstance.BindInstance(dm_password=dm_password) bind.update_system_records()
def get_requests(self): """Get certmonger tracking requests""" # TODO: put this in some central place for here and for # ipaserver/install/server/upgrade.py template = paths.CERTMONGER_COMMAND_TEMPLATE requests = [ { 'cert-file': paths.RA_AGENT_PEM, 'key-file': paths.RA_AGENT_KEY, 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'renew_ra_cert_pre', 'cert-postsave-command': template % 'renew_ra_cert', }, ] ca_requests = [ { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'auditSigningCert cert-pki-ca', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "auditSigningCert cert-pki-ca"'), }, { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'ocspSigningCert cert-pki-ca', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "ocspSigningCert cert-pki-ca"'), }, { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'subsystemCert cert-pki-ca', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "subsystemCert cert-pki-ca"'), }, { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'caSigningCert cert-pki-ca', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "caSigningCert cert-pki-ca"'), 'template-profile': None, }, { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'Server-Cert cert-pki-ca', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "Server-Cert cert-pki-ca"'), }, ] if self.ca.is_configured(): db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR) for nickname, _trust_flags in db.list_certs(): if nickname.startswith('caSigningCert cert-pki-ca '): requests.append({ 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': nickname, 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % ('renew_ca_cert "%s"' % nickname)), 'template-profile': 'caCACert', }) if self.ca.is_configured(): requests += ca_requests # Check the http server cert if issued by IPA if version.NUM_VERSION >= 40700: cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE) if is_ipa_issued_cert(api, cert): requests.append({ 'cert-file': paths.HTTPD_CERT_FILE, 'key-file': paths.HTTPD_KEY_FILE, 'ca-name': 'IPA', 'cert-postsave-command': template % 'restart_httpd', }) else: http_nickname = self.http.get_mod_nss_nickname() http_db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR) if http_db.is_ipa_issued_cert(api, http_nickname): requests.append({ 'cert-database': paths.HTTPD_ALIAS_DIR, 'cert-nickname': http_nickname, 'ca-name': 'IPA', 'cert-postsave-command': template % 'restart_httpd', }) # Check the ldap server cert if issued by IPA ds_nickname = self.ds.get_server_cert_nickname(self.serverid) ds_db_dirname = dsinstance.config_dirname(self.serverid) ds_db = certs.CertDB(api.env.realm, nssdir=ds_db_dirname) if ds_db.is_ipa_issued_cert(api, ds_nickname): requests.append({ 'cert-database': ds_db_dirname[:-1], 'cert-nickname': ds_nickname, 'ca-name': 'IPA', 'cert-postsave-command': '%s %s' % (template % 'restart_dirsrv', self.serverid), }) # Check the KDC cert if issued by IPA cert = x509.load_certificate_from_file(paths.KDC_CERT) if is_ipa_issued_cert(api, cert): requests.append({ 'cert-file': paths.KDC_CERT, 'key-file': paths.KDC_KEY, 'ca-name': 'IPA', 'cert-postsave-command': template % 'renew_kdc_cert', }) return requests
def get_expected_requests(ca, ds, serverid): """Provide the expected certmonger tracking request data This list is based in part on certificate_renewal_update() in ipaserver/install/server/upgrade.py and various start_tracking_certificates() methods in *instance.py. The list is filtered depending on whether a CA is running and the certificates have been issued by IPA. :param ca: the CAInstance :param ds: the DSInstance :param serverid: the DS serverid name """ template = paths.CERTMONGER_COMMAND_TEMPLATE if api.Command.ca_is_enabled()['result']: requests = [ { 'cert-file': paths.RA_AGENT_PEM, 'key-file': paths.RA_AGENT_KEY, 'ca-name': RENEWAL_CA_NAME, 'cert-presave-command': template % 'renew_ra_cert_pre', 'cert-postsave-command': template % 'renew_ra_cert', }, ] else: requests = [] if ca.is_configured(): dogtag_reqs = ca.tracking_reqs.items() kra = krainstance.KRAInstance(api.env.realm) if kra.is_installed(): dogtag_reqs = itertools.chain(dogtag_reqs, kra.tracking_reqs.items()) for nick, profile in dogtag_reqs: req = { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': nick, 'ca-name': RENEWAL_CA_NAME, 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "{}"'.format(nick)), 'template-profile': profile, } requests.append(req) else: logger.debug('CA is not configured, skipping CA tracking') cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE) issued = is_ipa_issued_cert(api, cert) if issued is None: logger.debug('Unable to determine if \'%s\' was issued by IPA ' 'because no LDAP connection, assuming yes.') if issued or issued is None: requests.append({ 'cert-file': paths.HTTPD_CERT_FILE, 'key-file': paths.HTTPD_KEY_FILE, 'ca-name': 'IPA', 'cert-postsave-command': template % 'restart_httpd', }) else: logger.debug( 'HTTP cert not issued by IPA, \'%s\', skip tracking ' 'check', DN(cert.issuer)) # Check the ldap server cert if issued by IPA ds_nickname = ds.get_server_cert_nickname(serverid) ds_db_dirname = dsinstance.config_dirname(serverid) ds_db = certs.CertDB(api.env.realm, nssdir=ds_db_dirname) connected = api.Backend.ldap2.isconnected() if not connected: logger.debug('Unable to determine if \'%s\' was issued by IPA ' 'because no LDAP connection, assuming yes.') if not connected or ds_db.is_ipa_issued_cert(api, ds_nickname): requests.append({ 'cert-database': ds_db_dirname[:-1], 'cert-nickname': ds_nickname, 'ca-name': 'IPA', 'cert-postsave-command': '%s %s' % (template % 'restart_dirsrv', serverid), }) else: logger.debug('DS cert is not issued by IPA, skip tracking check') # Check if pkinit is enabled if os.path.exists(paths.KDC_CERT): pkinit_request_ca = krbinstance.get_pkinit_request_ca() requests.append({ 'cert-file': paths.KDC_CERT, 'key-file': paths.KDC_KEY, 'ca-name': pkinit_request_ca, 'cert-postsave-command': template % 'renew_kdc_cert', }) else: logger.debug('No KDC pkinit certificate') return requests
def install_check(standalone, replica_config, options): global external_cert_file global external_ca_file if replica_config is not None and not replica_config.setup_ca: return realm_name = options.realm_name host_name = options.host_name subject_base = options.subject if replica_config is not None: if standalone and api.env.ra_plugin == 'selfsign': raise ScriptError('A selfsign CA can not be added') cafile = os.path.join(replica_config.dir, 'cacert.p12') if not options.promote and not ipautil.file_exists(cafile): raise ScriptError('CA cannot be installed in CA-less setup.') if standalone and not options.skip_conncheck: principal = options.principal replica_conn_check(replica_config.ca_host_name, host_name, realm_name, True, replica_config.ca_ds_port, options.admin_password, principal=principal, ca_cert_file=options.ca_cert_file) if options.skip_schema_check: root_logger.info("Skipping CA DS schema check") else: cainstance.replica_ca_install_check(replica_config, options.promote) return if standalone: if api.Command.ca_is_enabled()['result']: raise ScriptError( "One or more CA masters are already present in IPA realm " "'%s'.\nIf you wish to replicate CA to this host, please " "re-run 'ipa-ca-install'\nwith a replica file generated on " "an existing CA master as argument." % realm_name) if options.external_cert_files: if not cainstance.is_step_one_done(): # This can happen if someone passes external_ca_file without # already having done the first stage of the CA install. raise ScriptError( "CA is not installed yet. To install with an external CA " "is a two-stage process.\nFirst run the installer with " "--external-ca.") external_cert_file, external_ca_file = installutils.load_external_cert( options.external_cert_files, options.subject) elif options.external_ca: if cainstance.is_step_one_done(): raise ScriptError( "CA is already installed.\nRun the installer with " "--external-cert-file.") if ipautil.file_exists(paths.ROOT_IPA_CSR): raise ScriptError( "CA CSR file %s already exists.\nIn order to continue " "remove the file and run the installer again." % paths.ROOT_IPA_CSR) if not options.external_cert_files: if not cainstance.check_port(): print("IPA requires port 8443 for PKI but it is currently in use.") raise ScriptError("Aborting installation") if standalone: dirname = dsinstance.config_dirname( installutils.realm_to_serverid(realm_name)) cadb = certs.CertDB(realm_name, subject_base=subject_base) dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base) for db in (cadb, dsdb): for nickname, _trust_flags in db.list_certs(): if nickname in (certdb.get_ca_nickname(realm_name), 'ipaCert'): raise ScriptError( "Certificate with nickname %s is present in %s, " "cannot continue." % (nickname, db.secdir)) cert = db.get_cert_from_db(nickname) if not cert: continue subject = DN(x509.load_certificate(cert).subject) if subject in (DN('CN=Certificate Authority', subject_base), DN('CN=IPA RA', subject_base)): raise ScriptError( "Certificate with subject %s is present in %s, " "cannot continue." % (subject, db.secdir))
def uninstall(installer): fstore = installer._fstore sstore = installer._sstore rv = 0 print("Shutting down all IPA services") try: run([paths.IPACTL, "stop"], raiseonerr=False) except Exception as e: pass ntpinstance.NTPInstance(fstore).uninstall() kra.uninstall(False) ca.uninstall() dns.uninstall() httpinstance.HTTPInstance(fstore).uninstall() krbinstance.KrbInstance(fstore).uninstall() dsinstance.DsInstance(fstore=fstore).uninstall() if _server_trust_ad_installed: adtrustinstance.ADTRUSTInstance(fstore).uninstall() custodiainstance.CustodiaInstance().uninstall() memcacheinstance.MemcacheInstance().uninstall() otpdinstance.OtpdInstance().uninstall() tasks.restore_hostname(fstore, sstore) fstore.restore_all_files() try: os.remove(paths.ROOT_IPA_CACHE) except Exception: pass try: os.remove(paths.ROOT_IPA_CSR) except Exception: pass # ipa-client-install removes /etc/ipa/default.conf sstore._load() ipaclient.ntpconf.restore_forced_ntpd(sstore) # Clean up group_exists (unused since IPA 2.2, not being set since 4.1) sstore.restore_state("install", "group_exists") services.knownservices.ipa.disable() # remove upgrade state file sysupgrade.remove_upgrade_file() if fstore.has_files(): root_logger.error('Some files have not been restored, see ' '%s/sysrestore.index' % SYSRESTORE_DIR_PATH) has_state = False for module in IPA_MODULES: # from installutils if sstore.has_state(module): root_logger.error('Some installation state for %s has not been ' 'restored, see %s/sysrestore.state' % (module, SYSRESTORE_DIR_PATH)) has_state = True rv = 1 if has_state: root_logger.error('Some installation state has not been restored.\n' 'This may cause re-installation to fail.\n' 'It should be safe to remove %s/sysrestore.state ' 'but it may\n' 'mean your system hasn\'t be restored to its ' 'pre-installation state.' % SYSRESTORE_DIR_PATH) # Note that this name will be wrong after the first uninstall. dirname = dsinstance.config_dirname( installutils.realm_to_serverid(api.env.realm)) dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, certs.NSS_DIR] ids = certmonger.check_state(dirs) if ids: root_logger.error('Some certificates may still be tracked by ' 'certmonger.\n' 'This will cause re-installation to fail.\n' 'Start the certmonger service and list the ' 'certificates being tracked\n' ' # getcert list\n' 'These may be untracked by executing\n' ' # getcert stop-tracking -i <request_id>\n' 'for each id in: %s' % ', '.join(ids)) print("Removing IPA client configuration") try: result = run([paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended", "--uninstall"], raiseonerr=False, redirect_output=True) if result.returncode not in [0, 2]: raise RuntimeError("Failed to configure the client") except Exception: rv = 1 print("Uninstall of client side components failed!") sys.exit(rv)
def install_check(standalone, replica_config, options): global external_cert_file global external_ca_file realm_name = options.realm_name host_name = options.host_name if replica_config is None: options._subject_base = options.subject_base options._ca_subject = options.ca_subject else: # during replica install, this gets invoked before local DS is # available, so use the remote api. _api = api if standalone else options._remote_api # for replica-install the knobs cannot be written, hence leading '_' options._subject_base = str(replica_config.subject_base) options._ca_subject = lookup_ca_subject(_api, options._subject_base) if replica_config is not None and not replica_config.setup_ca: return if replica_config is not None: if standalone and api.env.ra_plugin == 'selfsign': raise ScriptError('A selfsign CA can not be added') if standalone and not options.skip_conncheck: principal = options.principal replica_conn_check(replica_config.ca_host_name, host_name, realm_name, True, replica_config.ca_ds_port, options.admin_password, principal=principal, ca_cert_file=options.ca_cert_file) if options.skip_schema_check: logger.info("Skipping CA DS schema check") return if standalone: if api.Command.ca_is_enabled()['result']: raise ScriptError( "One or more CA masters are already present in IPA realm " "'%s'.\nIf you wish to replicate CA to this host, please " "re-run 'ipa-ca-install'\nwith a replica file generated on " "an existing CA master as argument." % realm_name) if options.external_cert_files: if not cainstance.is_step_one_done(): # This can happen if someone passes external_ca_file without # already having done the first stage of the CA install. raise ScriptError( "CA is not installed yet. To install with an external CA " "is a two-stage process.\nFirst run the installer with " "--external-ca.") external_cert_file, external_ca_file = installutils.load_external_cert( options.external_cert_files, options._ca_subject) elif options.external_ca: if cainstance.is_step_one_done(): raise ScriptError( "CA is already installed.\nRun the installer with " "--external-cert-file.") if os.path.isfile(paths.ROOT_IPA_CSR): raise ScriptError( "CA CSR file %s already exists.\nIn order to continue " "remove the file and run the installer again." % paths.ROOT_IPA_CSR) if not options.external_ca_type: options.external_ca_type = x509.ExternalCAType.GENERIC.value if options.external_ca_profile is not None: # check that profile is valid for the external ca type if options.external_ca_type \ not in options.external_ca_profile.valid_for: raise ScriptError( "External CA profile specification '{}' " "cannot be used with external CA type '{}'.".format( options.external_ca_profile.unparsed_input, options.external_ca_type)) if not options.external_cert_files: if not cainstance.check_ports(): print("IPA requires ports 8080 and 8443 for PKI, but one or more " "are currently in use.") raise ScriptError("Aborting installation") if standalone: dirname = dsinstance.config_dirname( ipaldap.realm_to_serverid(realm_name)) cadb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR, subject_base=options._subject_base) dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=options._subject_base) # Check that we can add our CA cert to DS and PKI NSS databases for db in (cadb, dsdb): if not db.exists(): continue for nickname, _trust_flags in db.list_certs(): if nickname == certdb.get_ca_nickname(realm_name): raise ScriptError( "Certificate with nickname %s is present in %s, " "cannot continue." % (nickname, db.secdir)) cert = db.get_cert_from_db(nickname) if not cert: continue subject = DN(cert.subject) if subject == DN(options._ca_subject): raise ScriptError( "Certificate with subject %s is present in %s, " "cannot continue." % (subject, db.secdir))
def uninstall(installer): fstore = installer._fstore sstore = installer._sstore rv = 0 # further steps assumes that temporary directories exists so rather # ensure they are created tasks.create_tmpfiles_dirs() print("Shutting down all IPA services") try: services.knownservices.ipa.stop() except Exception: # Fallback to direct ipactl stop only if system command fails try: run([paths.IPACTL, "stop"], raiseonerr=False) except Exception: pass ntpinstance.NTPInstance(fstore).uninstall() kra.uninstall() ca.uninstall() dns.uninstall() httpinstance.HTTPInstance(fstore).uninstall() krbinstance.KrbInstance(fstore).uninstall() dsinstance.DsInstance(fstore=fstore).uninstall() if _server_trust_ad_installed: adtrustinstance.ADTRUSTInstance(fstore).uninstall() custodiainstance.CustodiaInstance().uninstall() otpdinstance.OtpdInstance().uninstall() tasks.restore_hostname(fstore, sstore) fstore.restore_all_files() try: os.remove(paths.ROOT_IPA_CACHE) except Exception: pass try: os.remove(paths.ROOT_IPA_CSR) except Exception: pass # ipa-client-install removes /etc/ipa/default.conf sstore._load() ipaclient.install.ntpconf.restore_forced_ntpd(sstore) # Clean up group_exists (unused since IPA 2.2, not being set since 4.1) sstore.restore_state("install", "group_exists") services.knownservices.ipa.disable() # remove upgrade state file sysupgrade.remove_upgrade_file() if fstore.has_files(): root_logger.error('Some files have not been restored, see ' '%s/sysrestore.index' % SYSRESTORE_DIR_PATH) has_state = False for module in IPA_MODULES: # from installutils if sstore.has_state(module): root_logger.error('Some installation state for %s has not been ' 'restored, see %s/sysrestore.state' % (module, SYSRESTORE_DIR_PATH)) has_state = True rv = 1 if has_state: root_logger.error('Some installation state has not been restored.\n' 'This may cause re-installation to fail.\n' 'It should be safe to remove %s/sysrestore.state ' 'but it may\n' 'mean your system hasn\'t be restored to its ' 'pre-installation state.' % SYSRESTORE_DIR_PATH) # Note that this name will be wrong after the first uninstall. dirname = dsinstance.config_dirname( installutils.realm_to_serverid(api.env.realm)) dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR] ids = certmonger.check_state(dirs) if ids: root_logger.error('Some certificates may still be tracked by ' 'certmonger.\n' 'This will cause re-installation to fail.\n' 'Start the certmonger service and list the ' 'certificates being tracked\n' ' # getcert list\n' 'These may be untracked by executing\n' ' # getcert stop-tracking -i <request_id>\n' 'for each id in: %s' % ', '.join(ids)) # Remove the cert renewal lock file try: os.remove(paths.IPA_RENEWAL_LOCK) except OSError as e: if e.errno != errno.ENOENT: root_logger.warning("Failed to remove file %s: %s", paths.IPA_RENEWAL_LOCK, e) print("Removing IPA client configuration") try: result = run([ paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended", "--uninstall" ], raiseonerr=False, redirect_output=True) if result.returncode not in [0, 2]: raise RuntimeError("Failed to configure the client") except Exception: rv = 1 print("Uninstall of client side components failed!") sys.exit(rv)
def install_step_1(standalone, replica_config, options): realm_name = options.realm_name domain_name = options.domain_name dm_password = options.dm_password host_name = options.host_name subject_base = options.subject basedn = ipautil.realm_to_suffix(realm_name) dogtag_constants = dogtag.install_constants ca = cainstance.CAInstance(realm_name, certs.NSS_DIR, dogtag_constants=dogtag_constants) if standalone: ca.stop(ca.dogtag_constants.PKI_INSTANCE_NAME) # We need to ldap_enable the CA now that DS is up and running ca.ldap_enable('CA', host_name, dm_password, basedn, ['caRenewalMaster']) # This is done within stopped_service context, which restarts CA ca.enable_client_auth_to_db(dogtag_constants.CS_CFG_PATH) if standalone and replica_config is None: serverid = installutils.realm_to_serverid(realm_name) dirname = dsinstance.config_dirname(serverid) # Store the new IPA CA cert chain in DS NSS database and LDAP cadb = certs.CertDB(realm_name, subject_base=subject_base) dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base) trust_flags = dict(reversed(cadb.list_certs())) trust_chain = cadb.find_root_cert('ipaCert')[:-1] for nickname in trust_chain[:-1]: cert = cadb.get_cert_from_db(nickname, pem=False) dsdb.add_cert(cert, nickname, trust_flags[nickname]) certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags[nickname]) nickname = trust_chain[-1] cert = cadb.get_cert_from_db(nickname, pem=False) dsdb.add_cert(cert, nickname, trust_flags[nickname]) certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags[nickname], config_ipa=True, config_compat=True) api.Backend.ldap2.disconnect() # Restart DS services.knownservices.dirsrv.restart(serverid) api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=dm_password) # Store DS CA cert in Dogtag NSS database dogtagdb = certs.CertDB(realm_name, nssdir=dogtag_constants.ALIAS_DIR) trust_flags = dict(reversed(dsdb.list_certs())) server_certs = dsdb.find_server_certs() trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1] nickname = trust_chain[-1] cert = dsdb.get_cert_from_db(nickname) dogtagdb.add_cert(cert, nickname, trust_flags[nickname]) if standalone: ca.start(ca.dogtag_constants.PKI_INSTANCE_NAME) # Update config file try: parser = RawConfigParser() parser.read(paths.IPA_DEFAULT_CONF) parser.set('global', 'enable_ra', 'True') parser.set('global', 'ra_plugin', 'dogtag') parser.set('global', 'dogtag_version', str(dogtag_constants.DOGTAG_VERSION)) with open(paths.IPA_DEFAULT_CONF, 'w') as f: parser.write(f) except IOError as e: print "Failed to update /etc/ipa/default.conf" root_logger.error(str(e)) sys.exit(1) # We need to restart apache as we drop a new config file in there services.knownservices.httpd.restart(capture_output=True) # Install CA DNS records if bindinstance.dns_container_exists(host_name, basedn, dm_password): bind = bindinstance.BindInstance(dm_password=dm_password) bind.add_ipa_ca_dns_records(host_name, domain_name)
def check_permissions(self): # TODO: see if this is something unique about my install if version.NUM_VERSION < 40700: dirsrv_group = 'root' else: dirsrv_group = 'dirsrv' databases = [ { 'dirname': dsinstance.config_dirname(self.serverid), 'files': [ (KEYDB, 'dirsrv', 'root', '0640'), (CERTDB, 'dirsrv', 'root', '0640'), (SECDB, 'dirsrv', dirsrv_group, '0640'), ] }, { 'dirname': paths.VAR_LIB_IPA, 'files': [ ('ra-agent.key', 'root', 'ipaapi', '0440'), ('ra-agent.pem', 'root', 'ipaapi', '0440'), ] }, ] if self.ca.is_configured(): databases.append( { 'dirname': paths.PKI_TOMCAT_ALIAS_DIR, 'files': [ (KEYDB, 'pkiuser', 'pkiuser', '0600'), (CERTDB, 'pkiuser', 'pkiuser', '0600'), (SECDB, 'pkiuser', 'pkiuser', '0600'), ] }, ) if version.NUM_VERSION < 40700: databases.append( { 'dirname': paths.HTTPD_ALIAS_DIR, 'files': [ # file, owner, group, perms (KEYDB, 'root', 'apache', '0640'), (CERTDB, 'root', 'apache', '0640'), (SECDB, 'root', 'apache', '0640'), ] }, ) for db in databases: for (file, owner, group, mode) in db['files']: path = os.path.join(db['dirname'], file) stat = os.stat(path) fmode = str(oct(stat.st_mode)[-4:]) logger.debug(path) if mode != fmode: self.failure('Permissions of %s are %s and should ' 'be %s' % (path, fmode, mode)) fowner = pwd.getpwnam(owner) if fowner.pw_uid != stat.st_uid: actual = pwd.getpwuid(stat.st_uid) self.failure('Ownership of %s is %s and should ' 'be %s' % (path, actual.pw_name, owner)) fgroup = grp.getgrnam(group) if fgroup.gr_gid != stat.st_gid: actual = grp.getgrgid(stat.st_gid) self.failure('Group of %s is %s and should ' 'be %s' % (path, actual.gr_name, group))
def get_expected_requests(ca, ds, serverid): """Provide the expected certmonger tracking request data This list is based in part on certificate_renewal_update() in ipaserver/install/server/upgrade.py and various start_tracking_certificates() methods in *instance.py. The list is filtered depending on whether a CA is running and the certificates have been issued by IPA. :param ca: the CAInstance :param ds: the DSInstance :param serverid: the DS serverid name """ template = paths.CERTMONGER_COMMAND_TEMPLATE if api.Command.ca_is_enabled()['result']: requests = [ { 'cert-file': paths.RA_AGENT_PEM, 'key-file': paths.RA_AGENT_KEY, 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'renew_ra_cert_pre', 'cert-postsave-command': template % 'renew_ra_cert', }, ] else: requests = [] ca_requests = [ { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'auditSigningCert cert-pki-ca', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "auditSigningCert cert-pki-ca"'), }, { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'ocspSigningCert cert-pki-ca', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "ocspSigningCert cert-pki-ca"'), }, { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'subsystemCert cert-pki-ca', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "subsystemCert cert-pki-ca"'), }, { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'caSigningCert cert-pki-ca', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "caSigningCert cert-pki-ca"'), 'template-profile': None, }, { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'Server-Cert cert-pki-ca', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "Server-Cert cert-pki-ca"'), }, ] kra_requests = [ { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'auditSigningCert cert-pki-kra', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "auditSigningCert cert-pki-kra"'), }, { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'transportCert cert-pki-kra', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "transportCert cert-pki-kra"'), }, { 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': 'storageCert cert-pki-kra', 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % 'renew_ca_cert "storageCert cert-pki-kra"'), }, ] if ca.is_configured(): db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR) for nickname, _trust_flags in db.list_certs(): if nickname.startswith('caSigningCert cert-pki-ca '): requests.append({ 'cert-database': paths.PKI_TOMCAT_ALIAS_DIR, 'cert-nickname': nickname, 'ca-name': 'dogtag-ipa-ca-renew-agent', 'cert-presave-command': template % 'stop_pkicad', 'cert-postsave-command': (template % ('renew_ca_cert "%s"' % nickname)), 'template-profile': 'caCACert', }) requests += ca_requests kra = krainstance.KRAInstance(api.env.realm) if kra.is_installed(): requests += kra_requests else: logger.debug('CA is not configured, skipping CA tracking') cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE) issued = is_ipa_issued_cert(api, cert) if issued is None: logger.debug('Unable to determine if \'%s\' was issued by IPA ' 'because no LDAP connection, assuming yes.') if issued or issued is None: requests.append({ 'cert-file': paths.HTTPD_CERT_FILE, 'key-file': paths.HTTPD_KEY_FILE, 'ca-name': 'IPA', 'cert-postsave-command': template % 'restart_httpd', }) else: logger.debug( 'HTTP cert not issued by IPA, \'%s\', skip tracking ' 'check', DN(cert.issuer)) # Check the ldap server cert if issued by IPA ds_nickname = ds.get_server_cert_nickname(serverid) ds_db_dirname = dsinstance.config_dirname(serverid) ds_db = certs.CertDB(api.env.realm, nssdir=ds_db_dirname) connected = api.Backend.ldap2.isconnected() if not connected: logger.debug('Unable to determine if \'%s\' was issued by IPA ' 'because no LDAP connection, assuming yes.') if not connected or ds_db.is_ipa_issued_cert(api, ds_nickname): requests.append({ 'cert-database': ds_db_dirname[:-1], 'cert-nickname': ds_nickname, 'ca-name': 'IPA', 'cert-postsave-command': '%s %s' % (template % 'restart_dirsrv', serverid), }) else: logger.debug( 'DS cert is not issued by IPA, \'%s\', skip tracking ' 'check', DN(cert.issuer)) # Check if pkinit is enabled if os.path.exists(paths.KDC_CERT): pkinit_request_ca = krbinstance.get_pkinit_request_ca() cert = x509.load_certificate_from_file(paths.KDC_CERT) requests.append({ 'cert-file': paths.KDC_CERT, 'key-file': paths.KDC_KEY, 'ca-name': pkinit_request_ca, 'cert-postsave-command': template % 'renew_kdc_cert', }) else: logger.debug('No KDC pkinit certificate') return requests
def execute(self, **options): serverid = realm_to_serverid(self.api.env.realm) db = certs.CertDB(self.api.env.realm, nssdir=dsinstance.config_dirname(serverid)) ca_cert = None ca_enabled = self.api.Command.ca_is_enabled()['result'] if ca_enabled: ca_nickname = certdb.get_ca_nickname(self.api.env.realm) ca_subject = certstore.get_ca_subject(self.api.Backend.ldap2, self.api.env.container_ca, self.api.env.basedn) else: ca_nickname = None server_certs = db.find_server_certs() if server_certs: ca_chain = db.find_root_cert(server_certs[0][0])[:-1] if ca_chain: ca_nickname = ca_chain[-1] ldap = self.api.Backend.ldap2 for nickname, trust_flags in db.list_certs(): if trust_flags.has_key: continue cert = db.get_cert_from_db(nickname) subject = cert.subject if ca_enabled and subject == ca_subject: # When ca is enabled, we can have the IPA CA cert stored # in the nss db with a different nickname (for instance # when the server was installed with --subject to # customize the CA cert subject), but it must always be # stored in LDAP with the DN cn=$DOMAIN IPA CA # This is why we check the subject instead of the nickname here nickname = ca_nickname trust_flags = certdb.IPA_CA_TRUST_FLAGS trust, _ca, eku = certstore.trust_flags_to_key_policy(trust_flags) dn = DN(('cn', nickname), ('cn', 'certificates'), ('cn', 'ipa'), ('cn', 'etc'), self.api.env.basedn) entry = ldap.make_entry(dn) try: certstore.init_ca_entry(entry, cert, nickname, trust, eku) except Exception as e: logger.warning("Failed to create entry for %s: %s", nickname, e) continue if nickname == ca_nickname: ca_cert = cert config = entry.setdefault('ipaConfigString', []) if ca_enabled: config.append('ipaCa') config.append('ipaCa') try: ldap.add_entry(entry) except errors.DuplicateEntry: if nickname == ca_nickname and ca_enabled: try: ldap.update_entry(entry) except errors.EmptyModlist: pass if ca_cert: dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn', 'etc'), self.api.env.basedn) try: entry = ldap.get_entry(dn) except errors.NotFound: entry = ldap.make_entry(dn) entry['objectclass'] = ['nsContainer', 'pkiCA'] entry.single_value['cn'] = 'CAcert' entry.single_value['cACertificate;binary'] = ca_cert ldap.add_entry(entry) else: force_write = False try: _cert_bin = entry['cACertificate;binary'] except ValueError: # BZ 1644874 # sometimes the cert is badly stored, twice encoded # force write to fix the value logger.debug( 'Fixing the value of cACertificate;binary ' 'in entry %s', entry.dn) force_write = True if force_write or b'' in entry['cACertificate;binary']: entry.single_value['cACertificate;binary'] = ca_cert ldap.update_entry(entry) return False, []
def uninstall(installer): fstore = installer._fstore sstore = installer._sstore rv = 0 # Uninstall the KRA prior to shutting the services down so it # can un-register with the CA. kra.uninstall() print("Shutting down all IPA services") try: services.knownservices.ipa.stop() except Exception: # Fallback to direct ipactl stop only if system command fails try: run([paths.IPACTL, "stop"], raiseonerr=False) except Exception: pass restore_time_sync(sstore, fstore) ca.uninstall() dns.uninstall() httpinstance.HTTPInstance(fstore).uninstall() krbinstance.KrbInstance(fstore).uninstall() dsinstance.DsInstance(fstore=fstore).uninstall() adtrustinstance.ADTRUSTInstance(fstore).uninstall() # realm isn't used, but IPAKEMKeys parses /etc/ipa/default.conf # otherwise, see https://pagure.io/freeipa/issue/7474 . custodiainstance.CustodiaInstance(realm='REALM.INVALID').uninstall() otpdinstance.OtpdInstance().uninstall() tasks.restore_hostname(fstore, sstore) tasks.restore_pkcs11_modules(fstore) fstore.restore_all_files() try: os.remove(paths.ROOT_IPA_CACHE) except Exception: pass try: os.remove(paths.ROOT_IPA_CSR) except Exception: pass # ipa-client-install removes /etc/ipa/default.conf sstore._load() timeconf.restore_forced_timeservices(sstore) # Clean up group_exists (unused since IPA 2.2, not being set since 4.1) sstore.restore_state("install", "group_exists") services.knownservices.ipa.disable() # remove upgrade state file sysupgrade.remove_upgrade_file() if fstore.has_files(): logger.error('Some files have not been restored, see ' '%s/sysrestore.index', SYSRESTORE_DIR_PATH) sstore.delete_state('installation', 'complete') has_state = False for module in IPA_MODULES: # from installutils if sstore.has_state(module): logger.error('Some installation state for %s has not been ' 'restored, see %s/sysrestore.state', module, SYSRESTORE_DIR_PATH) has_state = True rv = 1 if has_state: logger.error('Some installation state has not been restored.\n' 'This may cause re-installation to fail.\n' 'It should be safe to remove %s/sysrestore.state ' 'but it may\n' 'mean your system hasn\'t be restored to its ' 'pre-installation state.', SYSRESTORE_DIR_PATH) else: # sysrestore.state has no state left, remove it sysrestore = os.path.join(SYSRESTORE_DIR_PATH, 'sysrestore.state') ipautil.remove_file(sysrestore) # Note that this name will be wrong after the first uninstall. dirname = dsinstance.config_dirname( ipaldap.realm_to_serverid(api.env.realm)) dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR] ids = certmonger.check_state(dirs) if ids: logger.error('Some certificates may still be tracked by ' 'certmonger.\n' 'This will cause re-installation to fail.\n' 'Start the certmonger service and list the ' 'certificates being tracked\n' ' # getcert list\n' 'These may be untracked by executing\n' ' # getcert stop-tracking -i <request_id>\n' 'for each id in: %s', ', '.join(ids)) # Remove the cert renewal lock file try: os.remove(paths.IPA_RENEWAL_LOCK) except OSError as e: if e.errno != errno.ENOENT: logger.warning("Failed to remove file %s: %s", paths.IPA_RENEWAL_LOCK, e) print("Removing IPA client configuration") try: result = run([paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended", "--uninstall"], raiseonerr=False, redirect_output=True) if result.returncode not in [0, 2]: raise RuntimeError("Failed to configure the client") except Exception: rv = 1 print("Uninstall of client side components failed!") sys.exit(rv)
def install_step_1(standalone, replica_config, options, custodia): if replica_config is not None and not replica_config.setup_ca: return realm_name = options.realm_name host_name = options.host_name subject_base = options._subject_base basedn = ipautil.realm_to_suffix(realm_name) ca = cainstance.CAInstance( realm=realm_name, host_name=host_name, custodia=custodia ) ca.stop('pki-tomcat') # This is done within stopped_service context, which restarts CA ca.enable_client_auth_to_db() # Lightweight CA key retrieval is configured in step 1 instead # of CAInstance.configure_instance (which is invoked from step # 0) because kadmin_addprinc fails until krb5.conf is installed # by krb.create_instance. # ca.setup_lightweight_ca_key_retrieval() serverid = ipaldap.realm_to_serverid(realm_name) if standalone and replica_config is None: dirname = dsinstance.config_dirname(serverid) # Store the new IPA CA cert chain in DS NSS database and LDAP cadb = certs.CertDB( realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR, subject_base=subject_base) dsdb = certs.CertDB( realm_name, nssdir=dirname, subject_base=subject_base) cacert = cadb.get_cert_from_db('caSigningCert cert-pki-ca') nickname = certdb.get_ca_nickname(realm_name) trust_flags = certdb.IPA_CA_TRUST_FLAGS dsdb.add_cert(cacert, nickname, trust_flags) certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cacert, nickname, trust_flags, config_ipa=True, config_compat=True) # Store DS CA cert in Dogtag NSS database trust_flags = dict(reversed(dsdb.list_certs())) server_certs = dsdb.find_server_certs() trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1] nickname = trust_chain[-1] cert = dsdb.get_cert_from_db(nickname) cadb.add_cert(cert, nickname, trust_flags[nickname]) installutils.restart_dirsrv() ca.start('pki-tomcat') if standalone or replica_config is not None: # We need to restart apache as we drop a new config file in there services.knownservices.httpd.restart(capture_output=True) if standalone: # Install CA DNS records if bindinstance.dns_container_exists(basedn): bind = bindinstance.BindInstance() bind.update_system_records()
def install_check(standalone, replica_config, options): global external_cert_file global external_ca_file realm_name = options.realm_name host_name = options.host_name if replica_config is None: options._subject_base = options.subject_base options._ca_subject = options.ca_subject else: # during replica install, this gets invoked before local DS is # available, so use the remote api. _api = api if standalone else options._remote_api # for replica-install the knobs cannot be written, hence leading '_' options._subject_base = str(replica_config.subject_base) options._ca_subject = lookup_ca_subject(_api, options._subject_base) if replica_config is not None and not replica_config.setup_ca: return if replica_config is not None: if standalone and api.env.ra_plugin == 'selfsign': raise ScriptError('A selfsign CA can not be added') if standalone and not options.skip_conncheck: principal = options.principal replica_conn_check( replica_config.ca_host_name, host_name, realm_name, True, replica_config.ca_ds_port, options.admin_password, principal=principal, ca_cert_file=options.ca_cert_file) if options.skip_schema_check: logger.info("Skipping CA DS schema check") return if standalone: if api.Command.ca_is_enabled()['result']: raise ScriptError( "One or more CA masters are already present in IPA realm " "'%s'.\nIf you wish to replicate CA to this host, please " "re-run 'ipa-ca-install'\nwith a replica file generated on " "an existing CA master as argument." % realm_name ) if options.external_cert_files: if not cainstance.is_step_one_done(): # This can happen if someone passes external_ca_file without # already having done the first stage of the CA install. raise ScriptError( "CA is not installed yet. To install with an external CA " "is a two-stage process.\nFirst run the installer with " "--external-ca.") external_cert_file, external_ca_file = installutils.load_external_cert( options.external_cert_files, options._ca_subject) elif options.external_ca: if cainstance.is_step_one_done(): raise ScriptError( "CA is already installed.\nRun the installer with " "--external-cert-file.") if os.path.isfile(paths.ROOT_IPA_CSR): raise ScriptError( "CA CSR file %s already exists.\nIn order to continue " "remove the file and run the installer again." % paths.ROOT_IPA_CSR) if not options.external_ca_type: options.external_ca_type = \ cainstance.ExternalCAType.GENERIC.value if options.external_ca_profile is not None: # check that profile is valid for the external ca type if options.external_ca_type \ not in options.external_ca_profile.valid_for: raise ScriptError( "External CA profile specification '{}' " "cannot be used with external CA type '{}'." .format( options.external_ca_profile.unparsed_input, options.external_ca_type) ) if not options.external_cert_files: if not cainstance.check_ports(): print( "IPA requires ports 8080 and 8443 for PKI, but one or more " "are currently in use." ) raise ScriptError("Aborting installation") if standalone: dirname = dsinstance.config_dirname( ipaldap.realm_to_serverid(realm_name)) cadb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR, subject_base=options._subject_base) dsdb = certs.CertDB( realm_name, nssdir=dirname, subject_base=options._subject_base) # Check that we can add our CA cert to DS and PKI NSS databases for db in (cadb, dsdb): if not db.exists(): continue for nickname, _trust_flags in db.list_certs(): if nickname == certdb.get_ca_nickname(realm_name): raise ScriptError( "Certificate with nickname %s is present in %s, " "cannot continue." % (nickname, db.secdir)) cert = db.get_cert_from_db(nickname) if not cert: continue subject = DN(cert.subject) if subject == DN(options._ca_subject): raise ScriptError( "Certificate with subject %s is present in %s, " "cannot continue." % (subject, db.secdir))
root_logger.error('Some installation state for %s has not been ' 'restored, see %s/sysrestore.state' % (module, SYSRESTORE_DIR_PATH)) has_state = True rv = 1 if has_state: root_logger.error('Some installation state has not been restored.\n' 'This may cause re-installation to fail.\n' 'It should be safe to remove %s/sysrestore.state ' 'but it may\n' 'mean your system hasn\'t be restored to its ' 'pre-installation state.' % SYSRESTORE_DIR_PATH) # Note that this name will be wrong after the first uninstall. dirname = dsinstance.config_dirname( installutils.realm_to_serverid(api.env.realm)) dirs = [dirname, dogtag_constants.ALIAS_DIR, certs.NSS_DIR] ids = certmonger.check_state(dirs) if ids: root_logger.error('Some certificates may still be tracked by ' 'certmonger.\n' 'This will cause re-installation to fail.\n' 'Start the certmonger service and list the ' 'certificates being tracked\n' ' # getcert list\n' 'These may be untracked by executing\n' ' # getcert stop-tracking -i <request_id>\n' 'for each id in: %s' % ', '.join(ids)) # Use private ccache destroy_private_ccache()
def install_check(standalone, replica_config, options): global external_cert_file global external_ca_file realm_name = options.realm_name host_name = options.host_name subject_base = options.subject if replica_config is not None: if standalone and api.env.ra_plugin == 'selfsign': sys.exit('A selfsign CA can not be added') if ((not options.promote and not ipautil.file_exists(replica_config.dir + "/cacert.p12"))): print('CA cannot be installed in CA-less setup.') sys.exit(1) if standalone and not options.skip_conncheck: principal = options.principal replica_conn_check( replica_config.master_host_name, host_name, realm_name, True, replica_config.ca_ds_port, options.admin_password, principal=principal, ca_cert_file=options.ca_cert_file) if options.skip_schema_check or options.promote: root_logger.info("Skipping CA DS schema check") else: cainstance.replica_ca_install_check(replica_config) return if standalone: if api.Command.ca_is_enabled()['result']: sys.exit( "One or more CA masters are already present in IPA realm " "'%s'.\nIf you wish to replicate CA to this host, please " "re-run 'ipa-ca-install'\nwith a replica file generated on " "an existing CA master as argument." % realm_name ) if options.external_cert_files: if not cainstance.is_step_one_done(): # This can happen if someone passes external_ca_file without # already having done the first stage of the CA install. print("CA is not installed yet. To install with an external CA " "is a two-stage process.\nFirst run the installer with " "--external-ca.") sys.exit(1) external_cert_file, external_ca_file = installutils.load_external_cert( options.external_cert_files, options.subject) elif options.external_ca: if cainstance.is_step_one_done(): print("CA is already installed.\nRun the installer with " "--external-cert-file.") sys.exit(1) if ipautil.file_exists(paths.ROOT_IPA_CSR): print(("CA CSR file %s already exists.\nIn order to continue " "remove the file and run the installer again." % paths.ROOT_IPA_CSR)) sys.exit(1) if not options.external_cert_files: if not cainstance.check_port(): print("IPA requires port 8443 for PKI but it is currently in use.") sys.exit("Aborting installation") if standalone: dirname = dsinstance.config_dirname( installutils.realm_to_serverid(realm_name)) cadb = certs.CertDB(realm_name, subject_base=subject_base) dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base) for db in (cadb, dsdb): for nickname, trust_flags in db.list_certs(): if nickname in (certdb.get_ca_nickname(realm_name), 'ipaCert', 'Signing-Cert'): print(("Certificate with nickname %s is present in %s, " "cannot continue." % (nickname, db.secdir))) sys.exit(1) cert = db.get_cert_from_db(nickname) if not cert: continue subject = DN(str(x509.get_subject(cert))) if subject in (DN('CN=Certificate Authority', subject_base), DN('CN=IPA RA', subject_base), DN('CN=Object Signing Cert', subject_base)): print(("Certificate with subject %s is present in %s, " "cannot continue." % (subject, db.secdir))) sys.exit(1)
def install_step_1(standalone, replica_config, options, custodia): if replica_config is not None and not replica_config.setup_ca: return realm_name = options.realm_name host_name = options.host_name subject_base = options._subject_base basedn = ipautil.realm_to_suffix(realm_name) ca = cainstance.CAInstance(realm=realm_name, host_name=host_name, custodia=custodia) ca.stop('pki-tomcat') # This is done within stopped_service context, which restarts CA ca.enable_client_auth_to_db() # Lightweight CA key retrieval is configured in step 1 instead # of CAInstance.configure_instance (which is invoked from step # 0) because kadmin_addprinc fails until krb5.conf is installed # by krb.create_instance. # ca.setup_lightweight_ca_key_retrieval() serverid = ipaldap.realm_to_serverid(realm_name) if standalone and replica_config is None: dirname = dsinstance.config_dirname(serverid) # Store the new IPA CA cert chain in DS NSS database and LDAP cadb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR, subject_base=subject_base) dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base) cacert = cadb.get_cert_from_db('caSigningCert cert-pki-ca') nickname = certdb.get_ca_nickname(realm_name) trust_flags = certdb.IPA_CA_TRUST_FLAGS dsdb.add_cert(cacert, nickname, trust_flags) certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cacert, nickname, trust_flags, config_ipa=True, config_compat=True) # Store DS CA cert in Dogtag NSS database trust_flags = dict(reversed(dsdb.list_certs())) server_certs = dsdb.find_server_certs() trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1] nickname = trust_chain[-1] cert = dsdb.get_cert_from_db(nickname) cadb.add_cert(cert, nickname, trust_flags[nickname]) installutils.restart_dirsrv() ca.start('pki-tomcat') if standalone or replica_config is not None: # We need to restart apache as we drop a new config file in there services.knownservices.httpd.restart(capture_output=True) if standalone: # Install CA DNS records if bindinstance.dns_container_exists(basedn): bind = bindinstance.BindInstance() bind.update_system_records()
def validate_certs(self): """Use certutil -V to validate the certs we can""" ca_pw_name = None if self.ca.is_configured(): ca_passwd = None token = 'internal' with open(paths.PKI_TOMCAT_PASSWORD_CONF, 'r') as f: for line in f: (tok, pin) = line.split('=', 1) if token == tok: ca_passwd = pin.strip() break else: self.failure("The password to the 'internal' " "token of the Dogtag certificate " "store was not found.") with tempfile.NamedTemporaryFile(mode='w', delete=False) as ca_pw_file: ca_pw_file.write(ca_passwd) ca_pw_name = ca_pw_file.name try: validate = [ ( dsinstance.config_dirname(self.serverid), self.ds.get_server_cert_nickname(self.serverid), os.path.join(dsinstance.config_dirname(self.serverid), 'pwdfile.txt'), ), ] if self.ca.is_configured(): validate.append(( paths.PKI_TOMCAT_ALIAS_DIR, 'Server-Cert cert-pki-ca', ca_pw_name, ), ) if version.NUM_VERSION < 40700: validate.append(( paths.HTTPD_ALIAS_DIR, self.http.get_mod_nss_nickname(), os.path.join(paths.HTTPD_ALIAS_DIR, 'pwdfile.txt'), ), ) for (dbdir, nickname, pinfile) in validate: args = [paths.CERTUTIL, "-V", "-u", "V", "-e"] args.extend(["-d", dbdir]) args.extend(["-n", nickname]) args.extend(["-f", pinfile]) try: result = ipautil.run(args) except ipautil.CalledProcessError as e: self.failure('Validation of %s in %s failed: %s' % (nickname, dbdir, e)) else: if 'certificate is valid' not in \ result.raw_output.decode('utf-8'): self.failure('Validation of %s in %s failed: ' '%s %s' % (nickname, dbdir, result.raw_output, result.error_log)) finally: if ca_pw_name: installutils.remove_file(ca_pw_name) if version.NUM_VERSION >= 40700: self.validate_openssl(paths.HTTPD_CERT_FILE) self.validate_openssl(paths.RA_AGENT_PEM)
def uninstall(installer): fstore = installer._fstore sstore = installer._sstore rv = 0 print("Shutting down all IPA services") try: services.knownservices.ipa.stop() except Exception: # Fallback to direct ipactl stop only if system command fails try: run([paths.IPACTL, "stop"], raiseonerr=False) except Exception: pass ipaclient.install.client.restore_time_sync(sstore, fstore) kra.uninstall() ca.uninstall() dns.uninstall() httpinstance.HTTPInstance(fstore).uninstall() krbinstance.KrbInstance(fstore).uninstall() dsinstance.DsInstance(fstore=fstore).uninstall() if _server_trust_ad_installed: adtrustinstance.ADTRUSTInstance(fstore).uninstall() # realm isn't used, but IPAKEMKeys parses /etc/ipa/default.conf # otherwise, see https://pagure.io/freeipa/issue/7474 . custodiainstance.CustodiaInstance(realm='REALM.INVALID').uninstall() otpdinstance.OtpdInstance().uninstall() tasks.restore_hostname(fstore, sstore) fstore.restore_all_files() try: os.remove(paths.ROOT_IPA_CACHE) except Exception: pass try: os.remove(paths.ROOT_IPA_CSR) except Exception: pass # ipa-client-install removes /etc/ipa/default.conf sstore._load() ipaclient.install.timeconf.restore_forced_timeservices(sstore) # Clean up group_exists (unused since IPA 2.2, not being set since 4.1) sstore.restore_state("install", "group_exists") services.knownservices.ipa.disable() # remove upgrade state file sysupgrade.remove_upgrade_file() if fstore.has_files(): logger.error('Some files have not been restored, see ' '%s/sysrestore.index', SYSRESTORE_DIR_PATH) has_state = False for module in IPA_MODULES: # from installutils if sstore.has_state(module): logger.error('Some installation state for %s has not been ' 'restored, see %s/sysrestore.state', module, SYSRESTORE_DIR_PATH) has_state = True rv = 1 if has_state: logger.error('Some installation state has not been restored.\n' 'This may cause re-installation to fail.\n' 'It should be safe to remove %s/sysrestore.state ' 'but it may\n' 'mean your system hasn\'t be restored to its ' 'pre-installation state.', SYSRESTORE_DIR_PATH) else: # sysrestore.state has no state left, remove it sysrestore = os.path.join(SYSRESTORE_DIR_PATH, 'sysrestore.state') installutils.remove_file(sysrestore) # Note that this name will be wrong after the first uninstall. dirname = dsinstance.config_dirname( ipaldap.realm_to_serverid(api.env.realm)) dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR] ids = certmonger.check_state(dirs) if ids: logger.error('Some certificates may still be tracked by ' 'certmonger.\n' 'This will cause re-installation to fail.\n' 'Start the certmonger service and list the ' 'certificates being tracked\n' ' # getcert list\n' 'These may be untracked by executing\n' ' # getcert stop-tracking -i <request_id>\n' 'for each id in: %s', ', '.join(ids)) # Remove the cert renewal lock file try: os.remove(paths.IPA_RENEWAL_LOCK) except OSError as e: if e.errno != errno.ENOENT: logger.warning("Failed to remove file %s: %s", paths.IPA_RENEWAL_LOCK, e) print("Removing IPA client configuration") try: result = run([paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended", "--uninstall"], raiseonerr=False, redirect_output=True) if result.returncode not in [0, 2]: raise RuntimeError("Failed to configure the client") except Exception: rv = 1 print("Uninstall of client side components failed!") sys.exit(rv)
def execute(self, **options): serverid = realm_to_serverid(self.api.env.realm) db = certs.CertDB(self.api.env.realm, nssdir=dsinstance.config_dirname(serverid)) ca_cert = None ca_enabled = self.api.Command.ca_is_enabled()['result'] if ca_enabled: ca_nickname = certdb.get_ca_nickname(self.api.env.realm) ca_subject = certstore.get_ca_subject( self.api.Backend.ldap2, self.api.env.container_ca, self.api.env.basedn) else: ca_nickname = None server_certs = db.find_server_certs() if server_certs: ca_chain = db.find_root_cert(server_certs[0][0])[:-1] if ca_chain: ca_nickname = ca_chain[-1] ldap = self.api.Backend.ldap2 for nickname, trust_flags in db.list_certs(): if trust_flags.has_key: continue cert = db.get_cert_from_db(nickname) subject = cert.subject if ca_enabled and subject == ca_subject: # When ca is enabled, we can have the IPA CA cert stored # in the nss db with a different nickname (for instance # when the server was installed with --subject to # customize the CA cert subject), but it must always be # stored in LDAP with the DN cn=$DOMAIN IPA CA # This is why we check the subject instead of the nickname here nickname = ca_nickname trust_flags = certdb.IPA_CA_TRUST_FLAGS trust, _ca, eku = certstore.trust_flags_to_key_policy(trust_flags) dn = DN(('cn', nickname), ('cn', 'certificates'), ('cn', 'ipa'), ('cn','etc'), self.api.env.basedn) entry = ldap.make_entry(dn) try: certstore.init_ca_entry(entry, cert, nickname, trust, eku) except Exception as e: logger.warning("Failed to create entry for %s: %s", nickname, e) continue if nickname == ca_nickname: ca_cert = cert config = entry.setdefault('ipaConfigString', []) if ca_enabled: config.append('ipaCa') config.append('ipaCa') try: ldap.add_entry(entry) except errors.DuplicateEntry: if nickname == ca_nickname and ca_enabled: try: ldap.update_entry(entry) except errors.EmptyModlist: pass if ca_cert: dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'), self.api.env.basedn) try: entry = ldap.get_entry(dn) except errors.NotFound: entry = ldap.make_entry(dn) entry['objectclass'] = ['nsContainer', 'pkiCA'] entry.single_value['cn'] = 'CAcert' entry.single_value['cACertificate;binary'] = ca_cert ldap.add_entry(entry) else: force_write = False try: _cert_bin = entry['cACertificate;binary'] except ValueError: # BZ 1644874 # sometimes the cert is badly stored, twice encoded # force write to fix the value logger.debug('Fixing the value of cACertificate;binary ' 'in entry %s', entry.dn) force_write = True if force_write or b'' in entry['cACertificate;binary']: entry.single_value['cACertificate;binary'] = ca_cert ldap.update_entry(entry) return False, []