diff options
Diffstat (limited to 'ipaserver/install')
-rw-r--r-- | ipaserver/install/cainstance.py | 2 | ||||
-rw-r--r-- | ipaserver/install/certs.py | 10 | ||||
-rw-r--r-- | ipaserver/install/dsinstance.py | 2 | ||||
-rw-r--r-- | ipaserver/install/httpinstance.py | 2 | ||||
-rw-r--r-- | ipaserver/install/krbinstance.py | 62 | ||||
-rw-r--r-- | ipaserver/install/server/__init__.py | 4 | ||||
-rw-r--r-- | ipaserver/install/server/install.py | 21 | ||||
-rw-r--r-- | ipaserver/install/server/replicainstall.py | 4 | ||||
-rw-r--r-- | ipaserver/install/server/upgrade.py | 35 |
9 files changed, 109 insertions, 33 deletions
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index bf798211d..dbea519ee 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -831,7 +831,7 @@ class CAInstance(DogtagInstance): # The certificate must be requested using caServerCert profile # because this profile does not require agent authentication reqId = certmonger.request_and_wait_for_cert( - nssdb=self.ra_agent_db, + certpath=self.ra_agent_db, nickname='ipaCert', principal='host/%s' % self.fqdn, passwd_fname=self.ra_agent_pwd, diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py index 45602baa6..02b03d48b 100644 --- a/ipaserver/install/certs.py +++ b/ipaserver/install/certs.py @@ -633,7 +633,13 @@ class CertDB(object): def install_pem_from_p12(self, p12_fname, p12_passwd, pem_fname): pwd = ipautil.write_tmp_file(p12_passwd) - ipautil.run([paths.OPENSSL, "pkcs12", "-nodes", + ipautil.run([paths.OPENSSL, "pkcs12", "-nokeys", + "-in", p12_fname, "-out", pem_fname, + "-passin", "file:" + pwd.name]) + + def install_key_from_p12(self, p12_fname, p12_passwd, pem_fname): + pwd = ipautil.write_tmp_file(p12_passwd) + ipautil.run([paths.OPENSSL, "pkcs12", "-nodes", "-nocerts", "-in", p12_fname, "-out", pem_fname, "-passin", "file:" + pwd.name]) @@ -647,7 +653,7 @@ class CertDB(object): def request_service_cert(self, nickname, principal, host, pwdconf=False): if pwdconf: self.create_password_conf() - certmonger.request_and_wait_for_cert(nssdb=self.secdir, + certmonger.request_and_wait_for_cert(certpath=self.secdir, nickname=nickname, principal=principal, subject=host, diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 1be5ac73c..bcfcb0500 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -816,7 +816,7 @@ class DsInstance(service.Service): try: cmd = 'restart_dirsrv %s' % self.serverid certmonger.request_and_wait_for_cert( - nssdb=dirname, + certpath=dirname, nickname=self.nickname, principal=self.principal, passwd_fname=dsdb.passwd_fname, diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py index 15c310780..b7ce857ed 100644 --- a/ipaserver/install/httpinstance.py +++ b/ipaserver/install/httpinstance.py @@ -376,7 +376,7 @@ class HTTPInstance(service.Service): try: certmonger.request_and_wait_for_cert( - nssdb=db.secdir, + certpath=db.secdir, nickname=self.cert_nickname, principal=self.principal, passwd_fname=db.passwd_fname, diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py index 8de92f764..2b63b4ebd 100644 --- a/ipaserver/install/krbinstance.py +++ b/ipaserver/install/krbinstance.py @@ -24,6 +24,7 @@ import shutil import os import pwd import socket +import dbus import dns.name @@ -32,6 +33,7 @@ from ipaserver.install import installutils from ipapython import ipautil from ipapython import kernel_keyring from ipalib import api +from ipalib.install import certmonger from ipapython.ipa_log_manager import root_logger from ipapython.dn import DN @@ -153,12 +155,15 @@ class KrbInstance(service.Service): self.step("creating a keytab for the directory", self.__create_ds_keytab) self.step("creating a keytab for the machine", self.__create_host_keytab) self.step("adding the password extension to the directory", self.__add_pwd_extop_module) - if setup_pkinit: - self.step("creating X509 Certificate for PKINIT", self.__setup_pkinit) - self.step("creating principal for anonymous PKINIT", self.__add_anonymous_pkinit_principal) self.__common_post_setup() + if setup_pkinit: + self.step("installing X509 Certificate for PKINIT", + self.setup_pkinit) + self.step("creating principal for anonymous PKINIT", + self.__add_anonymous_pkinit_principal) + self.start_creation(runtime=30) self.kpasswd = KpasswdInstance() @@ -179,7 +184,8 @@ class KrbInstance(service.Service): self.step("configuring KDC", self.__configure_instance) self.step("adding the password extension to the directory", self.__add_pwd_extop_module) if setup_pkinit: - self.step("installing X509 Certificate for PKINIT", self.__setup_pkinit) + self.step("installing X509 Certificate for PKINIT", + self.setup_pkinit) self.__common_post_setup() @@ -214,7 +220,8 @@ class KrbInstance(service.Service): KRB5KDC_KADM5_ACL=paths.KRB5KDC_KADM5_ACL, DICT_WORDS=paths.DICT_WORDS, KRB5KDC_KADM5_KEYTAB=paths.KRB5KDC_KADM5_KEYTAB, - KDC_PEM=paths.KDC_PEM, + KDC_CERT=paths.KDC_CERT, + KDC_KEY=paths.KDC_KEY, CACERT_PEM=paths.CACERT_PEM) # IPA server/KDC is not a subdomain of default domain @@ -338,31 +345,49 @@ class KrbInstance(service.Service): self.move_service_to_host(host_principal) - def __setup_pkinit(self): + def setup_pkinit(self): ca_db = certs.CertDB(self.realm, host_name=self.fqdn, subject_base=self.subject_base) if self.pkcs12_info: ca_db.install_pem_from_p12(self.pkcs12_info[0], self.pkcs12_info[1], - paths.KDC_PEM) + paths.KDC_CERT) + ca_db.install_key_from_p12(self.pkcs12_info[0], + self.pkcs12_info[1], + paths.KDC_KEY) else: - raise RuntimeError("PKI not supported yet\n") + subject = str(DN(('cn', self.fqdn), self.subject_base)) + krbtgt = "krbtgt/" + self.realm + "@" + self.realm + certpath = (paths.KDC_CERT, paths.KDC_KEY) + try: + reqid = certmonger.request_cert(certpath, u'KDC-Cert', + subject, krbtgt, + dns=self.fqdn, storage='FILE', + profile='KDCs_PKINIT_Certs') + except dbus.DBusException as e: + # if the certificate is already tracked, ignore the error + name = e.get_dbus_name() + if name != 'org.fedorahosted.certmonger.duplicate': + root_logger.error("Failed to initiate the request: %s", e) + + try: + certmonger.wait_for_request(reqid) + except RuntimeError as e: + root_logger.error("Failed to wait for request: %s", e) # Finally copy the cacert in the krb directory so we don't # have any selinux issues with the file context shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM) - def __add_anonymous_pkinit_principal(self): + def get_anonymous_principal(self): princ = "WELLKNOWN/ANONYMOUS" - princ_realm = "%s@%s" % (princ, self.realm) + return "%s@%s" % (princ, self.realm) + def __add_anonymous_pkinit_principal(self): # Create the special anonymous principal + princ_realm = self.get_anonymous_principal() installutils.kadmin_addprinc(princ_realm) - dn = DN(('krbprincipalname', princ_realm), self.get_realm_suffix()) - entry = api.Backend.ldap2.get_entry(dn) - entry['nsAccountlock'] = ['TRUE'] - api.Backend.ldap2.update_entry(entry) def __convert_to_gssapi_replication(self): repl = replication.ReplicationManager(self.realm, @@ -372,6 +397,9 @@ class KrbInstance(service.Service): r_binddn=DN(('cn', 'Directory Manager')), r_bindpw=self.dm_password) + def stop_tracking_certs(self): + certmonger.stop_tracking(certfile=paths.KDC_CERT) + def uninstall(self): if self.is_configured(): self.print_msg("Unconfiguring %s" % self.service_name) @@ -394,6 +422,12 @@ class KrbInstance(service.Service): if enabled: self.enable() + # stop tracking and remove certificates + self.stop_tracking_certs() + installutils.remove_file(paths.CACERT_PEM) + installutils.remove_file(paths.KDC_CERT) + installutils.remove_file(paths.KDC_KEY) + if running: self.restart() diff --git a/ipaserver/install/server/__init__.py b/ipaserver/install/server/__init__.py index 0237702cc..28cdd066a 100644 --- a/ipaserver/install/server/__init__.py +++ b/ipaserver/install/server/__init__.py @@ -501,8 +501,8 @@ class ServerInstallInterface(client.ClientInstallInterface, "You must specify at least one of --forwarder, " "--auto-forwarders, or --no-forwarders options") - # Automatically disable pkinit w/ dogtag until that is supported - self.no_pkinit = True + # Automatically enable pkinit w/ dogtag + self.no_pkinit = not self.setup_ca ServerMasterInstallInterface = installs_master(ServerInstallInterface) diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py index f81c202cc..b5b9cb48a 100644 --- a/ipaserver/install/server/install.py +++ b/ipaserver/install/server/install.py @@ -521,6 +521,11 @@ def install_check(installer): dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, dirsrv_pin) if options.pkinit_cert_files: + if not options.no_pkinit: + raise ScriptError("Cannot create KDC PKINIT certificate and use " + "provided external PKINIT certificate at the " + "same time. Please choose one of them.") + if options.pkinit_pin is None: options.pkinit_pin = read_password( "Enter Kerberos KDC private key unlock", @@ -792,17 +797,11 @@ def install(installer): ds.enable_ssl() krb = krbinstance.KrbInstance(fstore) - if options.pkinit_cert_files: - krb.create_instance(realm_name, host_name, domain_name, - dm_password, master_password, - setup_pkinit=not options.no_pkinit, - pkcs12_info=pkinit_pkcs12_info, - subject_base=options.subject) - else: - krb.create_instance(realm_name, host_name, domain_name, - dm_password, master_password, - setup_pkinit=not options.no_pkinit, - subject_base=options.subject) + krb.create_instance(realm_name, host_name, domain_name, + dm_password, master_password, + setup_pkinit=not options.no_pkinit, + pkcs12_info=pkinit_pkcs12_info, + subject_base=options.subject) # restart DS to enable ipa-pwd-extop plugin print("Restarting directory server to enable password extension plugin") diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index f1f7b1bf8..0cd346849 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -124,7 +124,9 @@ def install_krb(config, setup_pkinit=False, promote=False): krb.create_replica(config.realm_name, config.master_host_name, config.host_name, config.domain_name, config.dirman_password, - setup_pkinit, pkcs12_info, promote=promote) + setup_pkinit, pkcs12_info, + subject_base=config.subject_base, + promote=promote) return krb diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py index 245450701..5056f833e 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -47,6 +47,7 @@ from ipaserver.install import sysupgrade from ipaserver.install import dnskeysyncinstance from ipaserver.install import krainstance from ipaserver.install import dogtaginstance +from ipaserver.install import krbinstance from ipaserver.install.upgradeinstance import IPAUpgrade from ipaserver.install.ldapupdate import BadSyntax @@ -1492,6 +1493,20 @@ def add_default_caacl(ca): sysupgrade.set_upgrade_state('caacl', 'add_default_caacl', True) +def enable_anonymous_principal(krb): + princ_realm = krb.get_anonymous_principal() + dn = DN(('krbprincipalname', princ_realm), krb.get_realm_suffix()) + try: + _ = api.Backend.ldap2.get_entry(dn) # pylint: disable=unused-variable + except ipalib.errors.NotFound: + installutils.kadmin_addprinc(princ_realm) + + try: + api.Backend.ldap2.set_entry_active(dn, True) + except ipalib.errors.AlreadyActive: + pass + + def upgrade_configuration(): """ Execute configuration upgrade of the IPA services @@ -1735,6 +1750,26 @@ def upgrade_configuration(): set_sssd_domain_option('ipa_server_mode', 'True') + krb = krbinstance.KrbInstance(fstore) + krb.fqdn = fqdn + krb.realm = api.env.realm + krb.suffix = ipautil.realm_to_suffix(krb.realm) + krb.subject_base = subject_base + if not os.path.exists(paths.KDC_CERT): + krb.setup_pkinit() + enable_anonymous_principal(krb) + replacevars = dict() + replacevars['pkinit_identity'] = 'FILE:{},{}'.format( + paths.KDC_CERT,paths.KDC_KEY) + appendvars = {} + ipautil.backup_config_and_replace_variables( + fstore, paths.KRB5KDC_KDC_CONF, replacevars=replacevars, + appendvars=appendvars) + tasks.restore_context(paths.KRB5KDC_KDC_CONF) + if krb.is_running(): + krb.stop() + krb.start() + if not ds_running: ds.stop(ds_serverid) |