def init_api(self, **overrides): overrides.setdefault('confdir', paths.ETC_IPA) api.bootstrap(in_server=True, context='restore', **overrides) api.finalize() self.instances = [installutils.realm_to_serverid(api.env.realm)] self.backends = ['userRoot', 'ipaca']
def add_instance_specific_data(self): ''' Add instance-specific files and directories. NOTE: this adds some things that may not get backed up. ''' serverid = installutils.realm_to_serverid(api.env.realm) for dir in [paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, paths.VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE % serverid, paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % serverid]: if os.path.exists(dir): self.dirs.append(dir) for file in ( paths.SYSCONFIG_DIRSRV_INSTANCE % serverid, paths.ETC_TMPFILESD_DIRSRV % serverid, ): if os.path.exists(file): self.files.append(file) self.files.append( paths.HTTPD_PASSWD_FILE_FMT.format(host=api.env.host) ) self.logs.append(paths.VAR_LOG_DIRSRV_INSTANCE_TEMPLATE % serverid)
def get_connection(self): ''' Create an ldapi connection and bind to it using autobind as root. ''' instance_name = installutils.realm_to_serverid(api.env.realm) if not services.knownservices.dirsrv.is_running(instance_name): raise admintool.ScriptError( "directory server instance is not running/configured" ) if self._conn is not None: return self._conn self._conn = ipaldap.IPAdmin(host=api.env.host, ldapi=True, protocol='ldapi', realm=api.env.realm) try: pw_name = pwd.getpwuid(os.geteuid()).pw_name self._conn.do_external_bind(pw_name) except Exception as e: raise admintool.ScriptError('Unable to bind to LDAP server: %s' % e) return self._conn
def __setup_sub_dict(self): self.sub_dict = dict(FQDN=self.fqdn, IP=self.ip, PASSWORD=self.kdc_password, SUFFIX=self.suffix, DOMAIN=self.domain, HOST=self.host, SERVER_ID=installutils.realm_to_serverid(self.realm), REALM=self.realm) # IPA server/KDC is not a subdomain of default domain # Proper domain-realm mapping needs to be specified domain = dns.name.from_text(self.domain) fqdn = dns.name.from_text(self.fqdn) if not fqdn.is_subdomain(domain): root_logger.debug("IPA FQDN '%s' is not located in default domain '%s'", fqdn, domain) server_domain = fqdn.parent().to_unicode(omit_final_dot=True) root_logger.debug("Domain '%s' needs additional mapping in krb5.conf", server_domain) dr_map = " .%(domain)s = %(realm)s\n %(domain)s = %(realm)s\n" \ % dict(domain=server_domain, realm=self.realm) else: dr_map = "" self.sub_dict['OTHER_DOMAIN_REALM_MAPS'] = dr_map # Configure KEYRING CCACHE if supported if kernel_keyring.is_persistent_keyring_supported(): root_logger.debug("Enabling persistent keyring CCACHE") self.sub_dict['OTHER_LIBDEFAULTS'] = \ " default_ccache_name = KEYRING:persistent:%{uid}\n" else: root_logger.debug("Persistent keyring CCACHE is not enabled") self.sub_dict['OTHER_LIBDEFAULTS'] = ''
def add_instance_specific_data(self): ''' Add instance-specific files and directories. NOTE: this adds some things that may not get backed up, like the PKI-IPA instance. ''' serverid = installutils.realm_to_serverid(api.env.realm) for dir in [ paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, paths.VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE % serverid, paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % serverid, paths.VAR_LIB_SLAPD_PKI_IPA_DIR_TEMPLATE, paths.USR_LIB_SLAPD_PKI_IPA_DIR, paths.ETC_SLAPD_PKI_IPA_DIR, paths.VAR_LIB_SLAPD_PKI_IPA_DIR_TEMPLATE, self.__find_scripts_dir('PKI-IPA'), ]: if os.path.exists(dir): self.dirs.append(dir) for file in [ paths.SYSCONFIG_DIRSRV_INSTANCE % serverid, paths.SYSCONFIG_DIRSRV_PKI_IPA_DIR]: if os.path.exists(file): self.files.append(file) for log in [ paths.VAR_LOG_DIRSRV_INSTANCE_TEMPLATE % serverid, ]: self.logs.append(log)
def init_api(self, **overrides): api.bootstrap(in_server=False, context='restore', **overrides) api.finalize() self.instances = [ installutils.realm_to_serverid(api.env.realm), 'PKI-IPA' ] self.backends = ['userRoot', 'ipaca']
def find_subject_base(self): """ Try to find the current value of certificate subject base. 1) Look in sysupgrade first 2) If no value is found there, look in DS (start DS if necessary) 3) Last resort, look in the certmap.conf itself 4) If all fails, log loudly and return None Note that this method can only be executed AFTER the ipa server is configured, the api is initialized elsewhere and that a ticket already have been acquired. """ root_logger.debug("Trying to find certificate subject base in sysupgrade") subject_base = sysupgrade.get_upgrade_state("certmap.conf", "subject_base") if subject_base: root_logger.debug("Found certificate subject base in sysupgrade: %s", subject_base) return subject_base root_logger.debug("Unable to find certificate subject base in sysupgrade") root_logger.debug("Trying to find certificate subject base in DS") ds_is_running = is_ds_running() if not ds_is_running: try: self.start() ds_is_running = True except ipautil.CalledProcessError as e: root_logger.error("Cannot start DS to find certificate " "subject base: %s", e) if ds_is_running: try: ret = api.Command["config_show"]() subject_base = str(ret["result"]["ipacertificatesubjectbase"][0]) root_logger.debug("Found certificate subject base in DS: %s", subject_base) except errors.PublicError as e: root_logger.error("Cannot connect to DS to find certificate " "subject base: %s", e) if not subject_base: root_logger.debug("Unable to find certificate subject base in DS") root_logger.debug("Trying to find certificate subject base in " "certmap.conf") certmap_dir = config_dirname(installutils.realm_to_serverid(api.env.realm)) try: with open(os.path.join(certmap_dir, "certmap.conf")) as f: for line in f: if line.startswith("certmap ipaca"): subject_base = line.strip().split(",")[-1] root_logger.debug("Found certificate subject base in certmap.conf: " "%s", subject_base) except IOError as e: root_logger.error("Cannot open certmap.conf to find certificate " "subject base: %s", e.strerror) if subject_base: return subject_base root_logger.debug("Unable to find certificate subject base in " "certmap.conf") return None
def write_certmap_conf(realm, ca_subject): """(Re)write certmap.conf with given CA subject DN.""" serverid = installutils.realm_to_serverid(realm) ds_dirname = config_dirname(serverid) certmap_filename = os.path.join(ds_dirname, "certmap.conf") shutil.copyfile( os.path.join(paths.USR_SHARE_IPA_DIR, "certmap.conf.template"), certmap_filename) installutils.update_file(certmap_filename, '$ISSUER_DN', str(ca_subject))
def test_failed_uninstall(self): self.master.run_command(['ipactl', 'stop']) serverid = realm_to_serverid(self.master.domain.realm) instance_name = ''.join([dsinstance.DS_INSTANCE_PREFIX, serverid]) try: # Moving the DS instance out of the way will cause the # uninstaller to raise an exception and return with a # non-zero return code. self.master.run_command([ '/usr/bin/mv', '%s/%s' % (paths.ETC_DIRSRV, instance_name), '%s/%s.test' % (paths.ETC_DIRSRV, instance_name) ]) cmd = self.master.run_command([ 'ipa-server-install', '--uninstall', '-U'], raiseonerr=False ) assert cmd.returncode == 1 finally: # Be paranoid. If something really went wrong then DS may # be marked as uninstalled so server cert will still be # tracked and the instances may remain. This can cause # subsequent installations to fail so be thorough. ds = dsinstance.DsInstance() ds_running = ds.is_running() if ds_running: ds.stop(serverid) # Moving it back should allow the uninstall to finish # successfully. self.master.run_command([ '/usr/bin/mv', '%s/%s.test' % (paths.ETC_DIRSRV, instance_name), '%s/%s' % (paths.ETC_DIRSRV, instance_name) ]) # DS has been marked as uninstalled so force the issue ds.stop_tracking_certificates(serverid) self.master.run_command([ paths.REMOVE_DS_PL, '-i', instance_name ]) cmd = self.master.run_command([ 'ipa-server-install', '--uninstall', '-U'], raiseonerr=False ) assert cmd.returncode == 0
def set_subject_in_config(realm_name, dm_password, suffix, subject_base): ldapuri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % ( installutils.realm_to_serverid(realm_name) ) try: conn = ldap2(shared_instance=False, ldap_uri=ldapuri, base_dn=suffix) conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password) except errors.ExecutionError, e: root_logger.critical("Could not connect to the Directory Server " "on %s" % realm_name) raise e
def __setup_sub_dict(self): self.sub_dict = dict( FQDN=self.fqdn, SERVER_ID=installutils.realm_to_serverid(self.realm), SUFFIX=self.suffix, BINDKEYS_FILE=paths.NAMED_BINDKEYS_FILE, MANAGED_KEYS_DIR=paths.NAMED_MANAGED_KEYS_DIR, ROOT_KEY=paths.NAMED_ROOT_KEY, NAMED_KEYTAB=paths.NAMED_KEYTAB, RFC1912_ZONES=paths.NAMED_RFC1912_ZONES, NAMED_PID=paths.NAMED_PID, NAMED_VAR_DIR=paths.NAMED_VAR_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 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") # If any of the PKCS#12 options are selected, all are required. cert_file_req = (options.dirsrv_cert_files, options.http_cert_files) if any(cert_file_req) and not all(cert_file_req): self.option_parser.error( "--dirsrv-cert-file and --http-cert-file are required if any " "key file 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, confdir=paths.ETC_IPA) 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 __setup_sub_dict(self): if os.path.exists(paths.COMMON_KRB5_CONF_DIR): includes = 'includedir {}'.format(paths.COMMON_KRB5_CONF_DIR) else: includes = '' self.sub_dict = dict(FQDN=self.fqdn, IP=self.ip, PASSWORD=self.kdc_password, SUFFIX=self.suffix, DOMAIN=self.domain, HOST=self.host, SERVER_ID=installutils.realm_to_serverid(self.realm), REALM=self.realm, KRB5KDC_KADM5_ACL=paths.KRB5KDC_KADM5_ACL, DICT_WORDS=paths.DICT_WORDS, KRB5KDC_KADM5_KEYTAB=paths.KRB5KDC_KADM5_KEYTAB, KDC_CERT=paths.KDC_CERT, KDC_KEY=paths.KDC_KEY, CACERT_PEM=paths.CACERT_PEM, KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM, CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM, INCLUDES=includes) # IPA server/KDC is not a subdomain of default domain # Proper domain-realm mapping needs to be specified domain = dns.name.from_text(self.domain) fqdn = dns.name.from_text(self.fqdn) if not fqdn.is_subdomain(domain): logger.debug("IPA FQDN '%s' is not located in default domain '%s'", fqdn, domain) server_domain = fqdn.parent().to_unicode(omit_final_dot=True) logger.debug("Domain '%s' needs additional mapping in krb5.conf", server_domain) dr_map = " .%(domain)s = %(realm)s\n %(domain)s = %(realm)s\n" \ % dict(domain=server_domain, realm=self.realm) else: dr_map = "" self.sub_dict['OTHER_DOMAIN_REALM_MAPS'] = dr_map # Configure KEYRING CCACHE if supported if kernel_keyring.is_persistent_keyring_supported(): logger.debug("Enabling persistent keyring CCACHE") self.sub_dict['OTHER_LIBDEFAULTS'] = \ " default_ccache_name = KEYRING:persistent:%{uid}\n" else: logger.debug("Persistent keyring CCACHE is not enabled") self.sub_dict['OTHER_LIBDEFAULTS'] = ''
def set_subject_in_config(realm_name, dm_password, suffix, subject_base): ldapuri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % ( installutils.realm_to_serverid(realm_name)) try: conn = ldap2(api, ldap_uri=ldapuri) conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password) except errors.ExecutionError as e: root_logger.critical("Could not connect to the Directory Server " "on %s" % realm_name) raise e entry_attrs = conn.get_ipa_config() if 'ipacertificatesubjectbase' not in entry_attrs: entry_attrs['ipacertificatesubjectbase'] = [str(subject_base)] conn.update_entry(entry_attrs) conn.disconnect()
def add_ca_cert(self, cacert_fname, cacert_name=''): """Add a CA certificate to the directory server cert db. We first have to shut down the directory server in case it has opened the cert db read-only. Then we use the CertDB class to add the CA cert. We have to provide a nickname, and we do not use 'IPA CA' since that's the default, so we use 'Imported CA' if none specified. Then we restart the server.""" # first make sure we have a valid cacert_fname try: if not os.access(cacert_fname, os.R_OK): root_logger.critical( "The given CA cert file named [%s] could not be read" % cacert_fname) return False except OSError as e: root_logger.critical( "The given CA cert file named [%s] could not be read: %s" % (cacert_fname, str(e))) return False # ok - ca cert file can be read # shutdown the server self.stop() dirname = config_dirname(installutils.realm_to_serverid(self.realm)) certdb = certs.CertDB( self.realm, nssdir=dirname, subject_base=self.subject_base, ca_subject=self.ca_subject, ) if not cacert_name or len(cacert_name) == 0: cacert_name = "Imported CA" # we can't pass in the nickname, so we set the instance variable certdb.cacert_name = cacert_name status = True try: certdb.load_cacert(cacert_fname, 'C,,') except ipautil.CalledProcessError as e: root_logger.critical( "Error importing CA cert file named [%s]: %s" % (cacert_fname, str(e))) status = False # restart the directory server self.start() return status
def init_info(self, realm_name, fqdn, domain_name, dm_password, subject_base, idstart, idmax, pkcs12_info, ca_file=None): self.realm = realm_name.upper() self.serverid = installutils.realm_to_serverid(self.realm) self.suffix = ipautil.realm_to_suffix(self.realm) self.fqdn = fqdn self.dm_password = dm_password self.domain = domain_name self.subject_base = subject_base self.idstart = idstart self.idmax = idmax self.pkcs12_info = pkcs12_info if pkcs12_info: self.ca_is_configured = False self.ca_file = ca_file self.__setup_sub_dict()
def set_subject_in_config(realm_name, dm_password, suffix, subject_base): ldapuri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % ( installutils.realm_to_serverid(realm_name) ) try: conn = ldap2(api, ldap_uri=ldapuri) conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=dm_password) except errors.ExecutionError as e: root_logger.critical("Could not connect to the Directory Server " "on %s" % realm_name) raise e entry_attrs = conn.get_ipa_config() if 'ipacertificatesubjectbase' not in entry_attrs: entry_attrs['ipacertificatesubjectbase'] = [str(subject_base)] conn.update_entry(entry_attrs) conn.disconnect()
def __create_kra_agent(self): """ Create KRA agent, assign a certificate, and add the user to the appropriate groups for accessing KRA services. """ # get ipaCert certificate with certdb.NSSDatabase(paths.HTTPD_ALIAS_DIR) as ipa_nssdb: cert_data = ipa_nssdb.get_cert("ipaCert") cert = x509.load_certificate(cert_data, x509.DER) # connect to KRA database server_id = installutils.realm_to_serverid(api.env.realm) dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id conn = ldap2.ldap2(api, ldap_uri=dogtag_uri) conn.connect(autobind=True) # create ipakra user with ipaCert certificate user_dn = DN(('uid', "ipakra"), ('ou', 'people'), self.basedn) entry = conn.make_entry( user_dn, objectClass=[ 'top', 'person', 'organizationalPerson', 'inetOrgPerson', 'cmsuser' ], uid=["ipakra"], sn=["IPA KRA User"], cn=["IPA KRA User"], usertype=["undefined"], userCertificate=[cert_data], description=[ '2;%s;%s;%s' % (cert.serial_number, DN(('CN', 'Certificate Authority'), self.subject_base), DN( ('CN', 'IPA RA'), self.subject_base)) ]) conn.add_entry(entry) # add ipakra user to Data Recovery Manager Agents group group_dn = DN(('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'), self.basedn) conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember') conn.disconnect()
def test_failed_uninstall(self): self.master.run_command(['ipactl', 'stop']) serverid = realm_to_serverid(self.master.domain.realm) instance_name = ''.join([dsinstance.DS_INSTANCE_PREFIX, serverid]) try: # Moving the DS instance out of the way will cause the # uninstaller to raise an exception and return with a # non-zero return code. self.master.run_command([ '/usr/bin/mv', '%s/%s' % (paths.ETC_DIRSRV, instance_name), '%s/%s.test' % (paths.ETC_DIRSRV, instance_name) ]) cmd = self.master.run_command( ['ipa-server-install', '--uninstall', '-U'], raiseonerr=False) assert cmd.returncode == 1 finally: # Be paranoid. If something really went wrong then DS may # be marked as uninstalled so server cert will still be # tracked and the instances may remain. This can cause # subsequent installations to fail so be thorough. ds = dsinstance.DsInstance() ds_running = ds.is_running() if ds_running: ds.stop(serverid) # Moving it back should allow the uninstall to finish # successfully. self.master.run_command([ '/usr/bin/mv', '%s/%s.test' % (paths.ETC_DIRSRV, instance_name), '%s/%s' % (paths.ETC_DIRSRV, instance_name) ]) # DS has been marked as uninstalled so force the issue ds.stop_tracking_certificates(serverid) self.master.run_command([paths.REMOVE_DS_PL, '-i', instance_name]) cmd = self.master.run_command( ['ipa-server-install', '--uninstall', '-U'], raiseonerr=False) assert cmd.returncode == 0
def cert_restore_prepare(self): cainstance.CAInstance().stop_tracking_certificates() httpinstance.HTTPInstance().stop_tracking_certificates() try: dsinstance.DsInstance().stop_tracking_certificates( installutils.realm_to_serverid(api.env.realm)) except OSError: # When IPA is not installed, DS NSS DB does not exist pass for basename in ('cert8.db', 'key3.db', 'secmod.db', 'pwdfile.txt'): filename = os.path.join(paths.IPA_NSSDB_DIR, basename) try: ipautil.backup_file(filename) except OSError as e: self.log.error("Failed to backup %s: %s" % (filename, e)) tasks.remove_ca_certs_from_systemwide_ca_store()
def init_info( self, realm_name, fqdn, domain_name, dm_password, subject_base, idstart, idmax, pkcs12_info, ca_file=None ): self.realm = realm_name.upper() self.serverid = installutils.realm_to_serverid(self.realm) self.suffix = ipautil.realm_to_suffix(self.realm) self.fqdn = fqdn self.dm_password = dm_password self.domain = domain_name self.subject_base = subject_base self.idstart = idstart self.idmax = idmax self.pkcs12_info = pkcs12_info if pkcs12_info: self.ca_is_configured = False self.ca_file = ca_file self.__setup_sub_dict()
def __setup_sub_dict(self): if self.forwarders: fwds = "\n" for forwarder in self.forwarders: fwds += "\t\t%s;\n" % forwarder fwds += "\t" else: fwds = " " if self.ntp: optional_ntp = "\n;ntp server\n" optional_ntp += "_ntp._udp\t\tIN SRV 0 100 123\t%s" % self.host_in_rr else: optional_ntp = "" ipa_ca = "" for addr in self.ip_addresses: if addr.version in (4, 6): ipa_ca += "%s\t\t\tIN %s\t\t\t%s\n" % ( IPA_CA_RECORD, "A" if addr.version == 4 else "AAAA", str(addr)) self.sub_dict = dict( FQDN=self.fqdn, IP=[str(ip) for ip in self.ip_addresses], DOMAIN=self.domain, HOST=self.host, REALM=self.realm, SERVER_ID=installutils.realm_to_serverid(self.realm), FORWARDERS=fwds, FORWARD_POLICY=self.forward_policy, SUFFIX=self.suffix, OPTIONAL_NTP=optional_ntp, ZONEMGR=self.zonemgr, IPA_CA_RECORD=ipa_ca, BINDKEYS_FILE=paths.NAMED_BINDKEYS_FILE, MANAGED_KEYS_DIR=paths.NAMED_MANAGED_KEYS_DIR, ROOT_KEY=paths.NAMED_ROOT_KEY, NAMED_KEYTAB=paths.NAMED_KEYTAB, RFC1912_ZONES=paths.NAMED_RFC1912_ZONES, NAMED_PID=paths.NAMED_PID, NAMED_VAR_DIR=paths.NAMED_VAR_DIR, )
def add_ca_cert(self, cacert_fname, cacert_name=''): """Add a CA certificate to the directory server cert db. We first have to shut down the directory server in case it has opened the cert db read-only. Then we use the CertDB class to add the CA cert. We have to provide a nickname, and we do not use 'IPA CA' since that's the default, so we use 'Imported CA' if none specified. Then we restart the server.""" # first make sure we have a valid cacert_fname try: if not os.access(cacert_fname, os.R_OK): logger.critical("The given CA cert file named [%s] could not " "be read", cacert_fname) return False except OSError as e: logger.critical("The given CA cert file named [%s] could not " "be read: %s", cacert_fname, str(e)) return False # ok - ca cert file can be read # shutdown the server self.stop() dirname = config_dirname(installutils.realm_to_serverid(self.realm)) certdb = certs.CertDB( self.realm, nssdir=dirname, subject_base=self.subject_base, ca_subject=self.ca_subject, ) if not cacert_name or len(cacert_name) == 0: cacert_name = "Imported CA" # we can't pass in the nickname, so we set the instance variable certdb.cacert_name = cacert_name status = True try: certdb.load_cacert(cacert_fname, EXTERNAL_CA_TRUST_FLAGS) except ipautil.CalledProcessError as e: logger.critical("Error importing CA cert file named [%s]: %s", cacert_fname, str(e)) status = False # restart the directory server self.start() return status
def __create_kra_agent(self): """ Create KRA agent, assign a certificate, and add the user to the appropriate groups for accessing KRA services. """ # get ipaCert certificate with certdb.NSSDatabase(paths.HTTPD_ALIAS_DIR) as ipa_nssdb: cert_data = ipa_nssdb.get_cert("ipaCert") cert = x509.load_certificate(cert_data, x509.DER) # connect to KRA database server_id = installutils.realm_to_serverid(api.env.realm) dogtag_uri = "ldapi://%%2fvar%%2frun%%2fslapd-%s.socket" % server_id conn = ldap2.ldap2(api, ldap_uri=dogtag_uri) conn.connect(autobind=True) # create ipakra user with ipaCert certificate user_dn = DN(("uid", "ipakra"), ("ou", "people"), self.basedn) entry = conn.make_entry( user_dn, objectClass=["top", "person", "organizationalPerson", "inetOrgPerson", "cmsuser"], uid=["ipakra"], sn=["IPA KRA User"], cn=["IPA KRA User"], usertype=["undefined"], userCertificate=[cert_data], description=[ "2;%s;%s;%s" % ( cert.serial_number, DN(("CN", "Certificate Authority"), self.subject_base), DN(("CN", "IPA RA"), self.subject_base), ) ], ) conn.add_entry(entry) # add ipakra user to Data Recovery Manager Agents group group_dn = DN(("cn", "Data Recovery Manager Agents"), ("ou", "groups"), self.basedn) conn.add_entry_to_group(user_dn, group_dn, "uniqueMember") conn.disconnect()
def __init__(self, realm_name, files=[], schema_files=[]): """ realm_name: kerberos realm name, used to determine DS instance dir files: list of update files to process. If none use UPDATEDIR """ ext = '' rand = random.Random() for _i in range(8): h = "%02x" % rand.randint(0,255) ext += h super(IPAUpgrade, self).__init__("dirsrv", realm_name=realm_name) serverid = installutils.realm_to_serverid(realm_name) self.filename = '%s/%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, DSE) self.savefilename = '%s/%s.ipa.%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, DSE, ext) self.files = files self.modified = False self.serverid = serverid self.schema_files = schema_files
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 cert_restore_prepare(self): cainstance.CAInstance().stop_tracking_certificates() httpinstance.HTTPInstance().stop_tracking_certificates() try: dsinstance.DsInstance().stop_tracking_certificates( installutils.realm_to_serverid(api.env.realm)) except (OSError, IOError): # When IPA is not installed, DS NSS DB does not exist pass krbinstance.KrbInstance().stop_tracking_certs() for basename in certdb.NSS_FILES: filename = os.path.join(paths.IPA_NSSDB_DIR, basename) try: ipautil.backup_file(filename) except OSError as e: logger.error("Failed to backup %s: %s", filename, e) tasks.remove_ca_certs_from_systemwide_ca_store()
def __setup_sub_dict(self): if paths.NAMED_CRYPTO_POLICY_FILE is not None: crypto_policy = 'include "{}";'.format( paths.NAMED_CRYPTO_POLICY_FILE) else: crypto_policy = "// not available" self.sub_dict = dict( FQDN=self.fqdn, SERVER_ID=installutils.realm_to_serverid(self.realm), SUFFIX=self.suffix, BINDKEYS_FILE=paths.NAMED_BINDKEYS_FILE, MANAGED_KEYS_DIR=paths.NAMED_MANAGED_KEYS_DIR, ROOT_KEY=paths.NAMED_ROOT_KEY, NAMED_KEYTAB=self.keytab, RFC1912_ZONES=paths.NAMED_RFC1912_ZONES, NAMED_PID=paths.NAMED_PID, NAMED_VAR_DIR=paths.NAMED_VAR_DIR, BIND_LDAP_SO=paths.BIND_LDAP_SO, INCLUDE_CRYPTO_POLICY=crypto_policy, )
def __setup_default_attributes(self): """ This method setups default attributes that are either constants, or based on api.env attributes, such as realm, hostname or domain name. """ # Constants self.smb_conf = paths.SMB_CONF self.samba_keytab = paths.SAMBA_KEYTAB self.cifs_hosts = [] # Values obtained from API.env self.fqdn = self.fqdn or api.env.host self.host_netbios_name = make_netbios_name(self.fqdn) self.realm = self.realm or api.env.realm self.domain_name = self.domain_name or api.env.domain self.cifs_principal = "cifs/" + self.fqdn + "@" + self.realm self.suffix = ipautil.realm_to_suffix(self.realm) self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \ installutils.realm_to_serverid(self.realm) # DN definitions self.trust_dn = DN(api.env.container_trusts, self.suffix) self.smb_dn = DN(('cn', 'adtrust agents'), ('cn', 'sysaccounts'), ('cn', 'etc'), self.suffix) self.smb_dom_dn = DN(('cn', self.domain_name), api.env.container_cifsdomains, self.suffix) self.cifs_agent = DN(('krbprincipalname', self.cifs_principal.lower()), api.env.container_service, self.suffix) self.host_princ = DN(('fqdn', self.fqdn), api.env.container_host, self.suffix)
def get_connection(self): ''' Create an ldapi connection and bind to it using autobind as root. ''' instance_name = installutils.realm_to_serverid(api.env.realm) if not services.knownservices.dirsrv.is_running(instance_name): raise admintool.ScriptError( "directory server instance is not running/configured") if self._conn is not None: return self._conn ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) self._conn = ipaldap.LDAPClient(ldap_uri) try: self._conn.external_bind() except Exception as e: raise admintool.ScriptError('Unable to bind to LDAP server: %s' % e) return self._conn
def __setup_sub_dict(self): if paths.NAMED_CRYPTO_POLICY_FILE is not None: crypto_policy = 'include "{}";'.format( paths.NAMED_CRYPTO_POLICY_FILE ) else: crypto_policy = "// not available" self.sub_dict = dict( FQDN=self.fqdn, SERVER_ID=installutils.realm_to_serverid(self.realm), SUFFIX=self.suffix, BINDKEYS_FILE=paths.NAMED_BINDKEYS_FILE, MANAGED_KEYS_DIR=paths.NAMED_MANAGED_KEYS_DIR, ROOT_KEY=paths.NAMED_ROOT_KEY, NAMED_KEYTAB=self.keytab, RFC1912_ZONES=paths.NAMED_RFC1912_ZONES, NAMED_PID=paths.NAMED_PID, NAMED_VAR_DIR=paths.NAMED_VAR_DIR, BIND_LDAP_SO=paths.BIND_LDAP_SO, INCLUDE_CRYPTO_POLICY=crypto_policy, )
def add_instance_specific_data(self): ''' Add instance-specific files and directories. NOTE: this adds some things that may not get backed up. ''' serverid = installutils.realm_to_serverid(api.env.realm) for dir in [paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, paths.VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE % serverid, paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % serverid]: if os.path.exists(dir): self.dirs.append(dir) for file in ( paths.SYSCONFIG_DIRSRV_INSTANCE % serverid, paths.ETC_TMPFILESD_DIRSRV % serverid, ): if os.path.exists(file): self.files.append(file) self.logs.append(paths.VAR_LOG_DIRSRV_INSTANCE_TEMPLATE % serverid)
def get_connection(self): ''' Create an ldapi connection and bind to it using autobind as root. ''' instance_name = installutils.realm_to_serverid(api.env.realm) if not services.knownservices.dirsrv.is_running(instance_name): raise admintool.ScriptError( "directory server instance is not running/configured" ) if self._conn is not None: return self._conn ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) self._conn = ipaldap.LDAPClient(ldap_uri) try: self._conn.external_bind() except Exception as e: raise admintool.ScriptError('Unable to bind to LDAP server: %s' % e) return self._conn
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 create_ipa_conf(fstore, config, ca_enabled, master=None): """ Create /etc/ipa/default.conf master configuration :param fstore: sysrestore file store used for backup and restore of the server configuration :param config: replica config :param ca_enabled: True if the topology includes a CA :param master: if set, the xmlrpc_uri parameter will use the provided master instead of this host """ # Save client file on Domain Level 1 target_fname = paths.IPA_DEFAULT_CONF fstore.backup_file(target_fname) ipaconf = IPAChangeConf("IPA Replica Install") ipaconf.setOptionAssignment(" = ") ipaconf.setSectionNameDelimiters(("[", "]")) if master: xmlrpc_uri = 'https://{0}/ipa/xml'.format( ipautil.format_netloc(master)) else: xmlrpc_uri = 'https://{0}/ipa/xml'.format( ipautil.format_netloc(config.host_name)) ldapi_uri = 'ldapi://%2fvar%2frun%2fslapd-{0}.socket\n'.format( installutils.realm_to_serverid(config.realm_name)) # [global] section gopts = [ ipaconf.setOption('basedn', str(config.basedn)), ipaconf.setOption('host', config.host_name), ipaconf.setOption('realm', config.realm_name), ipaconf.setOption('domain', config.domain_name), ipaconf.setOption('xmlrpc_uri', xmlrpc_uri), ipaconf.setOption('ldap_uri', ldapi_uri), ipaconf.setOption('mode', 'production') ] if ca_enabled: gopts.extend([ ipaconf.setOption('enable_ra', 'True'), ipaconf.setOption('ra_plugin', 'dogtag'), ipaconf.setOption('dogtag_version', '10') ]) if not config.setup_ca: gopts.append(ipaconf.setOption('ca_host', config.ca_host_name)) else: gopts.extend([ ipaconf.setOption('enable_ra', 'False'), ipaconf.setOption('ra_plugin', 'None') ]) opts = [ ipaconf.setSection('global', gopts), { 'name': 'empty', 'type': 'empty' } ] ipaconf.newConf(target_fname, opts) # the new file must be readable for httpd # Also, umask applies when creating a new file but we want 0o644 here os.chmod(target_fname, 0o644)
'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 replica_krb_init_info(ansible_log, fstore, realm_name, master_host_name, host_name, domain_name, admin_password, no_pkinit, subject_base, pkcs12_info=None): # promote is not needed here # From replicainstall.install_krb krb = krbinstance.KrbInstance(fstore=fstore) krb.set_output(ansible_log) # pkinit files if pkcs12_info is None: pkcs12_info = make_pkcs12_info(config.dir, "pkinitcert.p12", "pkinit_pin.txt") #krb.create_replica(realm_name, # master_host_name, host_name, # domain_name, dirman_password, # setup_pkinit, pkcs12_info, # subject_base=subject_base, # promote=promote) with redirect_stdout(ansible_log): krb.init_info(realm_name, host_name, setup_pkinit=not no_pkinit, subject_base=subject_base) # From ipaserver.install.krbinstance.create_replica krb.pkcs12_info = pkcs12_info krb.subject_base = subject_base krb.master_fqdn = master_host_name krb.config_pkinit = not no_pkinit #krb.__common_setup(realm_name, host_name, domain_name, admin_password) krb.fqdn = host_name krb.realm = realm_name.upper() krb.host = host_name.split(".")[0] krb.ip = socket.getaddrinfo(host_name, None, socket.AF_UNSPEC, socket.SOCK_STREAM)[0][4][0] krb.domain = domain_name krb.suffix = ipautil.realm_to_suffix(krb.realm) krb.kdc_password = ipautil.ipa_generate_password() krb.admin_password = admin_password krb.dm_password = admin_password #krb.__setup_sub_dict() if os.path.exists(paths.COMMON_KRB5_CONF_DIR): includes = 'includedir {}'.format(paths.COMMON_KRB5_CONF_DIR) else: includes = '' krb.sub_dict = dict(FQDN=krb.fqdn, IP=krb.ip, PASSWORD=krb.kdc_password, SUFFIX=krb.suffix, DOMAIN=krb.domain, HOST=krb.host, SERVER_ID=installutils.realm_to_serverid( krb.realm), REALM=krb.realm, KRB5KDC_KADM5_ACL=paths.KRB5KDC_KADM5_ACL, DICT_WORDS=paths.DICT_WORDS, KRB5KDC_KADM5_KEYTAB=paths.KRB5KDC_KADM5_KEYTAB, KDC_CERT=paths.KDC_CERT, KDC_KEY=paths.KDC_KEY, CACERT_PEM=paths.CACERT_PEM, KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM, CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM, INCLUDES=includes) # IPA server/KDC is not a subdomain of default domain # Proper domain-realm mapping needs to be specified domain = dnsname.from_text(krb.domain) fqdn = dnsname.from_text(krb.fqdn) if not fqdn.is_subdomain(domain): logger.debug("IPA FQDN '%s' is not located in default domain '%s'", fqdn, domain) server_domain = fqdn.parent().to_unicode(omit_final_dot=True) logger.debug("Domain '%s' needs additional mapping in krb5.conf", server_domain) dr_map = " .%(domain)s = %(realm)s\n %(domain)s = %(realm)s\n" \ % dict(domain=server_domain, realm=krb.realm) else: dr_map = "" krb.sub_dict['OTHER_DOMAIN_REALM_MAPS'] = dr_map # Configure KEYRING CCACHE if supported if kernel_keyring.is_persistent_keyring_supported(): logger.debug("Enabling persistent keyring CCACHE") krb.sub_dict['OTHER_LIBDEFAULTS'] = \ " default_ccache_name = KEYRING:persistent:%{uid}\n" else: logger.debug("Persistent keyring CCACHE is not enabled") krb.sub_dict['OTHER_LIBDEFAULTS'] = '' return krb
def run(self): options = self.options super(Backup, self).run() api.bootstrap(in_server=True, context='backup', confdir=paths.ETC_IPA) api.finalize() logger.info("Preparing backup on %s", api.env.host) pent = pwd.getpwnam(constants.DS_USER) self.top_dir = tempfile.mkdtemp("ipa") os.chown(self.top_dir, pent.pw_uid, pent.pw_gid) os.chmod(self.top_dir, 0o750) self.dir = os.path.join(self.top_dir, "ipa") os.mkdir(self.dir) os.chmod(self.dir, 0o750) os.chown(self.dir, pent.pw_uid, pent.pw_gid) self.header = os.path.join(self.top_dir, 'header') cwd = os.getcwd() try: dirsrv = services.knownservices.dirsrv self.add_instance_specific_data() # We need the dirsrv running to get the list of services dirsrv.start(capture_output=False) self.get_connection() self.create_header(options.data_only) if options.data_only: if not options.online: logger.info('Stopping Directory Server') dirsrv.stop(capture_output=False) else: logger.info('Stopping IPA services') run([paths.IPACTL, 'stop']) instance = installutils.realm_to_serverid(api.env.realm) if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % instance): if os.path.exists(paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE % (instance, 'ipaca')): self.db2ldif(instance, 'ipaca', online=options.online) self.db2ldif(instance, 'userRoot', online=options.online) self.db2bak(instance, online=options.online) if not options.data_only: # create backup of auth configuration auth_backup_path = os.path.join(paths.VAR_LIB_IPA, 'auth_backup') tasks.backup_auth_configuration(auth_backup_path) self.file_backup(options) self.finalize_backup(options.data_only, options.gpg, options.gpg_keyring) if options.data_only: if not options.online: logger.info('Starting Directory Server') dirsrv.start(capture_output=False) else: logger.info('Starting IPA service') run([paths.IPACTL, 'start']) finally: try: os.chdir(cwd) except Exception as e: logger.error('Cannot change directory to %s: %s', cwd, e) shutil.rmtree(self.top_dir)
def run(self): options = self.options super(Backup, self).run() api.bootstrap(in_server=True, context='backup') api.finalize() self.log.info("Preparing backup on %s", api.env.host) pent = pwd.getpwnam(constants.DS_USER) self.top_dir = tempfile.mkdtemp("ipa") os.chown(self.top_dir, pent.pw_uid, pent.pw_gid) os.chmod(self.top_dir, 0o750) self.dir = os.path.join(self.top_dir, "ipa") os.mkdir(self.dir) os.chmod(self.dir, 0o750) os.chown(self.dir, pent.pw_uid, pent.pw_gid) self.header = os.path.join(self.top_dir, 'header') cwd = os.getcwd() try: dirsrv = services.knownservices.dirsrv self.add_instance_specific_data() # We need the dirsrv running to get the list of services dirsrv.start(capture_output=False) self.get_connection() self.create_header(options.data_only) if options.data_only: if not options.online: self.log.info('Stopping Directory Server') dirsrv.stop(capture_output=False) else: self.log.info('Stopping IPA services') run(['ipactl', 'stop']) instance = installutils.realm_to_serverid(api.env.realm) if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % instance): if os.path.exists(paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE % (instance, 'ipaca')): self.db2ldif(instance, 'ipaca', online=options.online) self.db2ldif(instance, 'userRoot', online=options.online) self.db2bak(instance, online=options.online) if not options.data_only: # create backup of auth configuration auth_backup_path = os.path.join(paths.VAR_LIB_IPA, 'auth_backup') tasks.backup_auth_configuration(auth_backup_path) self.file_backup(options) self.finalize_backup(options.data_only, options.gpg, options.gpg_keyring) if options.data_only: if not options.online: self.log.info('Starting Directory Server') dirsrv.start(capture_output=False) else: self.log.info('Starting IPA service') run(['ipactl', 'start']) finally: try: os.chdir(cwd) except Exception as e: self.log.error('Cannot change directory to %s: %s' % (cwd, e)) shutil.rmtree(self.top_dir)
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 find_subject_base(self): """ Try to find the current value of certificate subject base. 1) Look in sysupgrade first 2) If no value is found there, look in DS (start DS if necessary) 3) Last resort, look in the certmap.conf itself 4) If all fails, log loudly and return None Note that this method can only be executed AFTER the ipa server is configured, the api is initialized elsewhere and that a ticket already have been acquired. """ root_logger.debug( 'Trying to find certificate subject base in sysupgrade') subject_base = sysupgrade.get_upgrade_state( 'certmap.conf', 'subject_base') if subject_base: root_logger.debug( 'Found certificate subject base in sysupgrade: %s', subject_base) return subject_base root_logger.debug( 'Unable to find certificate subject base in sysupgrade') root_logger.debug( 'Trying to find certificate subject base in DS') ds_is_running = is_ds_running() if not ds_is_running: try: self.start() ds_is_running = True except ipautil.CalledProcessError as e: root_logger.error('Cannot start DS to find certificate ' 'subject base: %s', e) if ds_is_running: try: ret = api.Command['config_show']() subject_base = str( ret['result']['ipacertificatesubjectbase'][0]) root_logger.debug( 'Found certificate subject base in DS: %s', subject_base) except errors.PublicError as e: root_logger.error('Cannot connect to DS to find certificate ' 'subject base: %s', e) if not subject_base: root_logger.debug('Unable to find certificate subject base in DS') root_logger.debug('Trying to find certificate subject base in ' 'certmap.conf') certmap_dir = config_dirname( installutils.realm_to_serverid(api.env.realm) ) try: with open(os.path.join(certmap_dir, 'certmap.conf')) as f: for line in f: if line.startswith('certmap ipaca'): subject_base = line.strip().split(',')[-1] root_logger.debug( 'Found certificate subject base in certmap.conf: ' '%s', subject_base) except IOError as e: root_logger.error('Cannot open certmap.conf to find certificate ' 'subject base: %s', e.strerror) if subject_base: return subject_base root_logger.debug('Unable to find certificate subject base in ' 'certmap.conf') return None
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 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': raise ScriptError('A selfsign CA can not be added') if ((not options.promote and not ipautil.file_exists(replica_config.dir + "/cacert.p12"))): 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.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']: 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', 'Signing-Cert'): 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(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)): raise ScriptError( "Certificate with subject %s is present in %s, " "cannot continue." % (subject, db.secdir))
def install(options): global dirsrv_pkcs12_info global http_pkcs12_info global pkinit_pkcs12_info global external_cert_file global external_ca_file global http_ca_cert realm_name = options.realm_name domain_name = options.domain_name dm_password = options.dm_password master_password = options.master_password admin_password = options.admin_password host_name = options.host_name ip_addresses = options.ip_address setup_ca = options.setup_ca setup_kra = options.setup_kra global ds global installation_cleanup # Installation has started. No IPA sysrestore items are restored in case of # failure to enable root cause investigation installation_cleanup = False # Configuration for ipalib, we will bootstrap and finalize later, after # we are sure we have the configuration file ready. cfg = dict( context='installer', in_server=True, debug=options.debug ) # Figure out what external CA step we're in. See cainstance.py for more # info on the 3 states. if options.external_cert_files: external = 2 elif options.external_ca: external = 1 else: external = 0 # Create the management framework config file and finalize api target_fname = paths.IPA_DEFAULT_CONF fd = open(target_fname, "w") fd.write("[global]\n") fd.write("host=%s\n" % host_name) fd.write("basedn=%s\n" % ipautil.realm_to_suffix(realm_name)) fd.write("realm=%s\n" % realm_name) fd.write("domain=%s\n" % domain_name) fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(host_name)) fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % installutils.realm_to_serverid(realm_name)) if setup_ca: fd.write("enable_ra=True\n") fd.write("ra_plugin=dogtag\n") fd.write("dogtag_version=%s\n" % dogtag.install_constants.DOGTAG_VERSION) else: fd.write("enable_ra=False\n") fd.write("ra_plugin=none\n") fd.write("enable_kra=%s\n" % setup_kra) fd.write("mode=production\n") fd.close() # Must be readable for everyone os.chmod(target_fname, 0644) if not options.unattended: print "" print "The following operations may take some minutes to complete." print "Please wait until the prompt is returned." print "" system_hostname = get_fqdn() if host_name != system_hostname: root_logger.debug("Chosen hostname (%s) differs from system hostname " "(%s) - change it" % (host_name, system_hostname)) # configure /etc/sysconfig/network to contain the custom hostname tasks.backup_and_replace_hostname(fstore, sstore, host_name) # update `api.env.ca_host` to correct hostname # https://fedorahosted.org/freeipa/ticket/4936 api.env.ca_host = host_name api.bootstrap(**cfg) if setup_ca: # ensure profile backend is available import ipaserver.plugins.dogtag api.finalize() # Create DS user/group if it doesn't exist yet dsinstance.create_ds_user() # Create a directory server instance if external != 2: # Configure ntpd if options.conf_ntp: ipaclient.ntpconf.force_ntpd(sstore) ntp = ntpinstance.NTPInstance(fstore) if not ntp.is_configured(): ntp.create_instance() if options.dirsrv_cert_files: ds = dsinstance.DsInstance(fstore=fstore, domainlevel=options.domainlevel) ds.create_instance(realm_name, host_name, domain_name, dm_password, dirsrv_pkcs12_info, idstart=options.idstart, idmax=options.idmax, subject_base=options.subject, hbac_allow=not options.hbac_allow) else: ds = dsinstance.DsInstance(fstore=fstore, domainlevel=options.domainlevel) ds.create_instance(realm_name, host_name, domain_name, dm_password, idstart=options.idstart, idmax=options.idmax, subject_base=options.subject, hbac_allow=not options.hbac_allow) else: ds = dsinstance.DsInstance(fstore=fstore, domainlevel=options.domainlevel) ds.init_info( realm_name, host_name, domain_name, dm_password, options.subject, 1101, 1100, None) if setup_ca: ca = cainstance.CAInstance(realm_name, certs.NSS_DIR, dogtag_constants=dogtag.install_constants) if external == 0: ca.configure_instance( host_name, domain_name, dm_password, dm_password, subject_base=options.subject, ca_signing_algorithm=options.ca_signing_algorithm) elif external == 1: # stage 1 of external CA installation options.realm_name = realm_name options.domain_name = domain_name options.master_password = master_password options.dm_password = dm_password options.admin_password = admin_password options.host_name = host_name options.unattended = True options.forwarders = dns.dns_forwarders options.reverse_zones = dns.reverse_zones write_cache(vars(options)) ca.configure_instance( host_name, domain_name, dm_password, dm_password, csr_file=paths.ROOT_IPA_CSR, subject_base=options.subject, ca_signing_algorithm=options.ca_signing_algorithm, ca_type=options.external_ca_type) else: # stage 2 of external CA installation ca.configure_instance( host_name, domain_name, dm_password, dm_password, cert_file=external_cert_file.name, cert_chain_file=external_ca_file.name, subject_base=options.subject, ca_signing_algorithm=options.ca_signing_algorithm) # Now put the CA cert where other instances exepct it ca.publish_ca_cert(CACERT) else: # Put the CA cert where other instances expect it x509.write_certificate(http_ca_cert, CACERT) os.chmod(CACERT, 0444) # we now need to enable ssl on the ds ds.enable_ssl() if setup_ca: # We need to ldap_enable the CA now that DS is up and running ca.ldap_enable('CA', host_name, dm_password, ipautil.realm_to_suffix(realm_name), ['caRenewalMaster']) # This is done within stopped_service context, which restarts CA ca.enable_client_auth_to_db(ca.dogtag_constants.CS_CFG_PATH) krb = krbinstance.KrbInstance(fstore) if options.pkinit_cert_files: krb.create_instance(realm_name, host_name, domain_name, dm_password, master_password, setup_pkinit=options.setup_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=options.setup_pkinit, subject_base=options.subject) # The DS instance is created before the keytab, add the SSL cert we # generated ds.add_cert_to_service() memcache = memcacheinstance.MemcacheInstance() memcache.create_instance('MEMCACHE', host_name, dm_password, ipautil.realm_to_suffix(realm_name)) otpd = otpdinstance.OtpdInstance() otpd.create_instance('OTPD', host_name, dm_password, ipautil.realm_to_suffix(realm_name)) # Create a HTTP instance http = httpinstance.HTTPInstance(fstore) if options.http_cert_files: 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, 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, ca_is_configured=setup_ca) tasks.restore_context(paths.CACHE_IPA_SESSIONS) # Export full CA chain ca_db = certs.CertDB(realm_name) os.chmod(CACERT, 0644) ca_db.publish_ca_cert(CACERT) set_subject_in_config(realm_name, dm_password, ipautil.realm_to_suffix(realm_name), options.subject) # Apply any LDAP updates. Needs to be done after the configuration file # is created service.print_msg("Applying LDAP updates") ds.apply_updates() # Restart ds and krb after configurations have been changed service.print_msg("Restarting the directory server") ds.restart() service.print_msg("Restarting the KDC") krb.restart() if setup_ca: service.print_msg("Restarting the certificate server") ca.restart(dogtag.configured_constants().PKI_INSTANCE_NAME) service.print_msg("Importing certificate profiles") cainstance.import_included_profiles() if options.setup_dns: api.Backend.ldap2.connect(autobind=True) dns.install(False, False, options) else: # Create a BIND instance bind = bindinstance.BindInstance(fstore, dm_password) bind.setup(host_name, ip_addresses, realm_name, domain_name, (), options.conf_ntp, (), zonemgr=options.zonemgr, ca_configured=setup_ca, no_dnssec_validation=options.no_dnssec_validation) bind.create_sample_bind_zone() # Restart httpd to pick up the new IPA configuration service.print_msg("Restarting the web server") http.restart() if setup_kra: kra.install(None, options, dm_password) # Set the admin user kerberos password ds.change_admin_password(admin_password) # Call client install script try: args = [paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended", "--domain", domain_name, "--server", host_name, "--realm", realm_name, "--hostname", host_name] if not options.create_sshfp: args.append("--no-dns-sshfp") if options.trust_sshfp: args.append("--ssh-trust-dns") if not options.conf_ssh: args.append("--no-ssh") if not options.conf_sshd: args.append("--no-sshd") if options.mkhomedir: args.append("--mkhomedir") run(args) except Exception, e: sys.exit("Configuration of client side components failed!\n" "ipa-client-install returned: " + str(e))
def install_check(installer): options = installer dirsrv_pkcs12_file = installer._dirsrv_pkcs12_file http_pkcs12_file = installer._http_pkcs12_file pkinit_pkcs12_file = installer._pkinit_pkcs12_file dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info http_pkcs12_info = installer._http_pkcs12_info pkinit_pkcs12_info = installer._pkinit_pkcs12_info external_cert_file = installer._external_cert_file external_ca_file = installer._external_ca_file http_ca_cert = installer._ca_cert tasks.check_ipv6_stack_enabled() tasks.check_selinux_status() if options.master_password: msg = ("WARNING:\noption '-P/--master-password' is deprecated. " "KDC master password of sufficient strength is autogenerated " "during IPA server installation and should not be set " "manually.") print(textwrap.fill(msg, width=79, replace_whitespace=False)) installer._installation_cleanup = True print("\nThe log file for this installation can be found in " "/var/log/ipaserver-install.log") if (not options.external_ca and not options.external_cert_files and is_ipa_configured()): installer._installation_cleanup = False raise ScriptError( "IPA server is already configured on this system.\n" "If you want to reinstall the IPA server, please uninstall " "it first using 'ipa-server-install --uninstall'.") client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) if client_fstore.has_files(): installer._installation_cleanup = False raise ScriptError( "IPA client is already configured on this system.\n" "Please uninstall it before configuring the IPA server, " "using 'ipa-client-install --uninstall'") fstore = sysrestore.FileStore(SYSRESTORE_DIR_PATH) sstore = sysrestore.StateFile(SYSRESTORE_DIR_PATH) # This will override any settings passed in on the cmdline if ipautil.file_exists(paths.ROOT_IPA_CACHE): if options.dm_password is not None: dm_password = options.dm_password else: dm_password = read_password("Directory Manager", confirm=False) if dm_password is None: raise ScriptError("Directory Manager password required") try: cache_vars = read_cache(dm_password) options.__dict__.update(cache_vars) if cache_vars.get('external_ca', False): options.external_ca = False options.interactive = False except Exception as e: raise ScriptError("Cannot process the cache file: %s" % str(e)) # We only set up the CA if the PKCS#12 options are not given. if options.dirsrv_cert_files: setup_ca = False else: setup_ca = True options.setup_ca = setup_ca if not setup_ca and options.ca_subject: raise ScriptError( "--ca-subject cannot be used with CA-less installation") if not setup_ca and options.subject_base: raise ScriptError( "--subject-base cannot be used with CA-less installation") if not setup_ca and options.setup_kra: raise ScriptError( "--setup-kra cannot be used with CA-less installation") print("=======================================" "=======================================") print("This program will set up the FreeIPA Server.") print("") print("This includes:") if setup_ca: print(" * Configure a stand-alone CA (dogtag) for certificate " "management") if not options.no_ntp: print(" * Configure the Network Time Daemon (ntpd)") print(" * Create and configure an instance of Directory Server") print(" * Create and configure a Kerberos Key Distribution Center (KDC)") print(" * Configure Apache (httpd)") if options.setup_kra: print(" * Configure KRA (dogtag) for secret management") if options.setup_dns: print(" * Configure DNS (bind)") if options.setup_adtrust: print(" * Configure Samba (smb) and winbind for managing AD trusts") if not options.no_pkinit: print(" * Configure the KDC to enable PKINIT") if options.no_ntp: print("") print("Excluded by options:") print(" * Configure the Network Time Daemon (ntpd)") if installer.interactive: print("") print("To accept the default shown in brackets, press the Enter key.") print("") if not options.external_cert_files: # Make sure the 389-ds ports are available check_dirsrv(not installer.interactive) if not options.no_ntp: try: ipaclient.install.ntpconf.check_timedate_services() except ipaclient.install.ntpconf.NTPConflictingService as e: print( ("WARNING: conflicting time&date synchronization service '%s'" " will be disabled" % e.conflicting_service)) print("in favor of ntpd") print("") except ipaclient.install.ntpconf.NTPConfigurationError: pass # Check to see if httpd is already configured to listen on 443 if httpinstance.httpd_443_configured(): raise ScriptError("Aborting installation") if not options.setup_dns and installer.interactive: if ipautil.user_input( "Do you want to configure integrated DNS " "(BIND)?", False): options.setup_dns = True print("") # check bind packages are installed if options.setup_dns: # Don't require an external DNS to say who we are if we are # setting up a local DNS server. options.no_host_dns = True # check the hostname is correctly configured, it must be as the kldap # utilities just use the hostname as returned by getaddrinfo to set # up some of the standard entries if options.host_name: host_default = options.host_name else: host_default = get_fqdn() try: if not installer.interactive or options.host_name: verify_fqdn(host_default, options.no_host_dns) host_name = host_default else: host_name = read_host_name(host_default, options.no_host_dns) except BadHostError as e: raise ScriptError(e) host_name = host_name.lower() root_logger.debug("will use host_name: %s\n" % host_name) if not options.domain_name: domain_name = read_domain_name(host_name[host_name.find(".") + 1:], not installer.interactive) root_logger.debug("read domain_name: %s\n" % domain_name) try: validate_domain_name(domain_name) except ValueError as e: raise ScriptError("Invalid domain name: %s" % unicode(e)) else: domain_name = options.domain_name domain_name = domain_name.lower() if not options.realm_name: realm_name = read_realm_name(domain_name, not installer.interactive) root_logger.debug("read realm_name: %s\n" % realm_name) else: realm_name = options.realm_name.upper() if not options.subject_base: options.subject_base = installutils.default_subject_base(realm_name) if not options.ca_subject: options.ca_subject = \ installutils.default_ca_subject_dn(options.subject_base) if options.http_cert_files: if options.http_pin is None: options.http_pin = installutils.read_password( "Enter Apache Server private key unlock", confirm=False, validate=False, retry=False) if options.http_pin is None: raise ScriptError( "Apache Server private key unlock password required") http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12( cert_files=options.http_cert_files, key_password=options.http_pin, key_nickname=options.http_cert_name, ca_cert_files=options.ca_cert_files, host_name=host_name) http_pkcs12_info = (http_pkcs12_file.name, http_pin) if options.dirsrv_cert_files: if options.dirsrv_pin is None: options.dirsrv_pin = read_password( "Enter Directory Server private key unlock", confirm=False, validate=False, retry=False) if options.dirsrv_pin is None: raise ScriptError( "Directory Server private key unlock password required") dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12( cert_files=options.dirsrv_cert_files, key_password=options.dirsrv_pin, key_nickname=options.dirsrv_cert_name, ca_cert_files=options.ca_cert_files, host_name=host_name) dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, dirsrv_pin) if options.pkinit_cert_files: if options.pkinit_pin is None: options.pkinit_pin = read_password( "Enter Kerberos KDC private key unlock", confirm=False, validate=False, retry=False) if options.pkinit_pin is None: raise ScriptError( "Kerberos KDC private key unlock password required") pkinit_pkcs12_file, pkinit_pin, _pkinit_ca_cert = load_pkcs12( cert_files=options.pkinit_cert_files, key_password=options.pkinit_pin, key_nickname=options.pkinit_cert_name, ca_cert_files=options.ca_cert_files, host_name=host_name) pkinit_pkcs12_info = (pkinit_pkcs12_file.name, pkinit_pin) if (options.http_cert_files and options.dirsrv_cert_files and http_ca_cert != dirsrv_ca_cert): raise ScriptError( "Apache Server SSL certificate and Directory Server SSL " "certificate are not signed by the same CA certificate") if not options.dm_password: dm_password = read_dm_password() if dm_password is None: raise ScriptError("Directory Manager password required") else: dm_password = options.dm_password if not options.master_password: master_password = ipa_generate_password() else: master_password = options.master_password if not options.admin_password: admin_password = read_admin_password() if admin_password is None: raise ScriptError("IPA admin password required") else: admin_password = options.admin_password # Configuration for ipalib, we will bootstrap and finalize later, after # we are sure we have the configuration file ready. cfg = dict( context='installer', confdir=paths.ETC_IPA, in_server=True, # make sure host name specified by user is used instead of default host=host_name, ) if setup_ca: # we have an IPA-integrated CA cfg['ca_host'] = host_name # Create the management framework config file and finalize api target_fname = paths.IPA_DEFAULT_CONF fd = open(target_fname, "w") fd.write("[global]\n") fd.write("host=%s\n" % host_name) fd.write("basedn=%s\n" % ipautil.realm_to_suffix(realm_name)) fd.write("realm=%s\n" % realm_name) fd.write("domain=%s\n" % domain_name) fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(host_name)) fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % installutils.realm_to_serverid(realm_name)) if setup_ca: fd.write("enable_ra=True\n") fd.write("ra_plugin=dogtag\n") fd.write("dogtag_version=10\n") else: fd.write("enable_ra=False\n") fd.write("ra_plugin=none\n") fd.write("mode=production\n") fd.close() # Must be readable for everyone os.chmod(target_fname, 0o644) api.bootstrap(**cfg) api.finalize() if setup_ca: ca.install_check(False, None, options) if options.setup_kra: kra.install_check(api, None, options) if options.setup_dns: dns.install_check(False, api, False, options, host_name) ip_addresses = dns.ip_addresses else: ip_addresses = get_server_ip_address(host_name, not installer.interactive, False, options.ip_addresses) # check addresses here, dns module is doing own check network_ip_address_warning(ip_addresses) broadcast_ip_address_warning(ip_addresses) if options.setup_adtrust: adtrust.install_check(False, options, api) # installer needs to update hosts file when DNS subsystem will be # installed or custom addresses are used if options.ip_addresses or options.setup_dns: installer._update_hosts_file = True print() print("The IPA Master Server will be configured with:") print("Hostname: %s" % host_name) print("IP address(es): %s" % ", ".join(str(ip) for ip in ip_addresses)) print("Domain name: %s" % domain_name) print("Realm name: %s" % realm_name) print() if options.setup_dns: print("BIND DNS server will be configured to serve IPA domain with:") print("Forwarders: %s" % ("No forwarders" if not options.forwarders else ", ".join( [str(ip) for ip in options.forwarders]))) print('Forward policy: %s' % options.forward_policy) print("Reverse zone(s): %s" % ("No reverse zone" if options.no_reverse or not dns.reverse_zones else ", ".join(str(rz) for rz in dns.reverse_zones))) print() if not options.setup_adtrust: # If domain name and realm does not match, IPA server will not be able # to estabilish trust with Active Directory. Print big fat warning. realm_not_matching_domain = (domain_name.upper() != realm_name) if realm_not_matching_domain: print("WARNING: Realm name does not match the domain name.\n" "You will not be able to estabilish trusts with Active " "Directory unless\nthe realm name of the IPA server matches " "its domain name.\n\n") if installer.interactive and not user_input( "Continue to configure the system with these values?", False): raise ScriptError("Installation aborted") options.realm_name = realm_name options.domain_name = domain_name options.dm_password = dm_password options.master_password = master_password options.admin_password = admin_password options._host_name_overridden = bool(options.host_name) options.host_name = host_name options.ip_addresses = ip_addresses installer._fstore = fstore installer._sstore = sstore installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file installer._http_pkcs12_file = http_pkcs12_file installer._pkinit_pkcs12_file = pkinit_pkcs12_file installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info installer._http_pkcs12_info = http_pkcs12_info installer._pkinit_pkcs12_info = pkinit_pkcs12_info installer._external_cert_file = external_cert_file installer._external_ca_file = external_ca_file installer._ca_cert = http_ca_cert
def init_api(self, **overrides): api.bootstrap(in_server=True, context='restore', **overrides) api.finalize() self.instances = [installutils.realm_to_serverid(api.env.realm)] self.backends = ['userRoot', 'ipaca']
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 = six.text_type(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') 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._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 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, nssdir=paths.PKI_TOMCAT_ALIAS_DIR, subject_base=options._subject_base) dsdb = certs.CertDB( realm_name, nssdir=dirname, subject_base=options._subject_base) 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(x509.load_certificate(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 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 run(self): """Execute the tests""" api.Backend.ldap2.connect() self.serverid = installutils.realm_to_serverid(api.env.realm) self.ca = cainstance.CAInstance(api.env.realm, host_name=api.env.host) self.http = httpinstance.HTTPInstance() self.ds = dsinstance.DsInstance() self.conn = api.Backend.ldap2 logger.info("Check CA status") self.check_ca_status() logger.info("Check tracking") self.check_tracking() logger.info("Check NSS trust") self.check_trust() logger.info("Check dates") self.check_dates() logger.info("Checking certificates in CS.cfg") self.check_cs_cfg() logger.info("Comparing certificates to requests in LDAP") self.compare_requests() logger.info("Checking RA certificate") self.check_ra_cert() logger.info("Checking authorities") self.check_ipa_to_cs_authorities() self.check_cs_to_ipa_authorities() logger.info("Checking host keytab") self.check_hostkeytab() logger.info("Validating certificates") self.validate_certs() logger.info("Checking renewal master") self.check_renewal_master() logger.info("End-to-end cert API test") self.cert_api_test() logger.info("Checking permissions and ownership") self.check_permissions() if self.conn is not None and self.conn.isconnected(): self.conn.disconnect() if self.failures: logger.info("Failures:") for f in self.failures: logger.info(f) else: logger.info("All checks passed") if self.warnings: logger.info("Warnings:") for f in self.warnings: logger.info(f) return self.failures != []
def install_step_1(standalone, replica_config, options): 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_name, host_name=host_name) ca.stop('pki-tomcat') # 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() serverid = installutils.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', pem=False) nickname = certdb.get_ca_nickname(realm_name) trust_flags = 'CT,C,C' 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()