def read_host_name(host_default, no_host_dns=False): print("Enter the fully qualified domain name of the computer") print("on which you're setting up server software. Using the form") print("<hostname>.<domainname>") print("Example: master.example.com.") print("") print("") if host_default == "": host_default = "master.example.com" host_name = user_input("Server host name", host_default, allow_empty=False) print("") verify_fqdn(host_name, no_host_dns) return host_name
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 dirsrv_ca_cert = None pkinit_ca_cert = None tasks.check_ipv6_stack_enabled() tasks.check_selinux_status() check_ldap_conf() mask_str = validate_mask() if mask_str: print("Unexpected system mask: %s, expected 0022" % mask_str) if installer.interactive: if not user_input("Do you want to continue anyway?", True): raise ScriptError( "Unexpected system mask: %s" % mask_str) else: raise ScriptError("Unexpected system mask: %s" % mask_str) 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 os.path.isfile(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("Version {}".format(version.VERSION)) 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 NTP client (chronyd)") 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 NTP client (chronyd)") 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.timeconf.check_timedate_services() except ipaclient.install.timeconf.NTPConflictingService as e: print("WARNING: conflicting time&date synchronization service '{}'" " will be disabled".format(e.conflicting_service)) print("in favor of chronyd") print("") except ipaclient.install.timeconf.NTPConfigurationError: pass 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() 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) 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) logger.debug("read realm_name: %s\n", realm_name) try: validate_domain_name(realm_name, entity="realm") except ValueError as e: raise ScriptError("Invalid realm name: {}".format(unicode(e))) 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, realm_name=realm_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 (options.http_cert_files and options.pkinit_cert_files and http_ca_cert != pkinit_ca_cert): raise ScriptError( "Apache Server SSL certificate and PKINIT KDC " "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 ipaconf = IPAChangeConf("IPA Server Install") ipaconf.setOptionAssignment(" = ") ipaconf.setSectionNameDelimiters(("[", "]")) xmlrpc_uri = 'https://{0}/ipa/xml'.format( ipautil.format_netloc(host_name)) ldapi_uri = ipaldap.realm_to_ldapi_uri(realm_name) # [global] section gopts = [ ipaconf.setOption('host', host_name), ipaconf.setOption('basedn', ipautil.realm_to_suffix(realm_name)), ipaconf.setOption('realm', realm_name), ipaconf.setOption('domain', domain_name), ipaconf.setOption('xmlrpc_uri', xmlrpc_uri), ipaconf.setOption('ldap_uri', ldapi_uri), ipaconf.setOption('mode', 'production') ] if setup_ca: gopts.extend([ ipaconf.setOption('enable_ra', 'True'), ipaconf.setOption('ra_plugin', 'dogtag'), ipaconf.setOption('dogtag_version', '10') ]) 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) # 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 no_matching_interface_for_ip_address_warning(ip_addresses) instance_name = "-".join(realm_name.split(".")) dirsrv = services.knownservices.dirsrv if (options.external_cert_files and dirsrv.is_installed(instance_name) and not dirsrv.is_running(instance_name)): logger.debug('Starting Directory Server') services.knownservices.dirsrv.start(instance_name) 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 setup_ca: ca.print_ca_configuration(options) 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 establish 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 establish 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 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
# 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 host_default = "" if options.host_name: host_default = options.host_name else: host_default = get_fqdn() try: if options.unattended 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, e: sys.exit(str(e) + "\n") host_name = host_name.lower() root_logger.debug("will use host_name: %s\n" % host_name) system_hostname = get_fqdn() if host_name != system_hostname: print >>sys.stderr print >>sys.stderr, ("Warning: hostname %s does not match system " "hostname %s." % (host_name, system_hostname)) print >>sys.stderr, ("System hostname will be updated during the "
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 dirsrv_ca_cert = None pkinit_ca_cert = None tasks.check_ipv6_stack_enabled() tasks.check_selinux_status() check_ldap_conf() mask_str = validate_mask() if mask_str: print("Unexpected system mask: %s, expected 0022" % mask_str) if installer.interactive: if not user_input("Do you want to continue anyway?", True): raise ScriptError( "Unexpected system mask: %s" % mask_str) else: raise ScriptError("Unexpected system mask: %s" % mask_str) 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 os.path.isfile(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("Version {}".format(version.VERSION)) 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 NTP client (chronyd)") 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 NTP client (chronyd)") 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: timeconf.check_timedate_services() except timeconf.NTPConflictingService as e: print( "WARNING: conflicting time&date synchronization service " "'{}' will be disabled in favor of chronyd\n".format( e.conflicting_service ) ) except timeconf.NTPConfigurationError: pass 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() 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) 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) logger.debug("read realm_name: %s\n", realm_name) try: validate_domain_name(realm_name, entity="realm") except ValueError as e: raise ScriptError("Invalid realm name: {}".format(unicode(e))) 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, realm_name=realm_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 (options.http_cert_files and options.pkinit_cert_files and http_ca_cert != pkinit_ca_cert): raise ScriptError( "Apache Server SSL certificate and PKINIT KDC " "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 ipaconf = IPAChangeConf("IPA Server Install") ipaconf.setOptionAssignment(" = ") ipaconf.setSectionNameDelimiters(("[", "]")) xmlrpc_uri = 'https://{0}/ipa/xml'.format( ipautil.format_netloc(host_name)) ldapi_uri = ipaldap.realm_to_ldapi_uri(realm_name) # [global] section gopts = [ ipaconf.setOption('host', host_name), ipaconf.setOption('basedn', ipautil.realm_to_suffix(realm_name)), ipaconf.setOption('realm', realm_name), ipaconf.setOption('domain', domain_name), ipaconf.setOption('xmlrpc_uri', xmlrpc_uri), ipaconf.setOption('ldap_uri', ldapi_uri), ipaconf.setOption('mode', 'production') ] if setup_ca: gopts.extend([ ipaconf.setOption('enable_ra', 'True'), ipaconf.setOption('ra_plugin', 'dogtag'), ipaconf.setOption('dogtag_version', '10') ]) 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) # 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 no_matching_interface_for_ip_address_warning(ip_addresses) instance_name = "-".join(realm_name.split(".")) dirsrv = services.knownservices.dirsrv if (options.external_cert_files and dirsrv.is_installed(instance_name) and not dirsrv.is_running(instance_name)): logger.debug('Starting Directory Server') services.knownservices.dirsrv.start(instance_name) 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 if not options.no_ntp and not options.unattended and not ( options.ntp_servers or options.ntp_pool): options.ntp_servers, options.ntp_pool = timeconf.get_time_source() 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 setup_ca: ca.print_ca_configuration(options) 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 establish 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 establish trusts with Active " "Directory unless\nthe realm name of the IPA server matches " "its domain name.\n\n") if options.ntp_servers or options.ntp_pool: if options.ntp_servers: for server in options.ntp_servers: print("NTP server:\t{}".format(server)) if options.ntp_pool: print("NTP pool:\t{}".format(options.ntp_pool)) 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 ask_for_options(self): options = self.options super(ReplicaPrepare, self).ask_for_options() # get the directory manager password self.dirman_password = options.password if not options.password: self.dirman_password = installutils.read_password( "Directory Manager (existing master)", confirm=False, validate=False) if self.dirman_password is None: raise admintool.ScriptError( "Directory Manager password required") # Try out the password & get the subject base suffix = ipautil.realm_to_suffix(api.env.realm) try: conn = api.Backend.ldap2 conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=self.dirman_password) entry_attrs = conn.get_ipa_config() self.subject_base = entry_attrs.get( 'ipacertificatesubjectbase', [None])[0] ca_enabled = api.Command.ca_is_enabled()['result'] conn.disconnect() except errors.ACIError: raise admintool.ScriptError("The password provided is incorrect " "for LDAP server %s" % api.env.host) except errors.LDAPError: raise admintool.ScriptError( "Unable to connect to LDAP server %s" % api.env.host) except errors.DatabaseError as e: raise admintool.ScriptError(e.desc) if not ca_enabled and not options.http_cert_files: raise admintool.ScriptError( "Cannot issue certificates: a CA is not installed. Use the " "--http-cert-file, --dirsrv-cert-file options to provide " "custom certificates.") if self.subject_base is not None: self.subject_base = DN(self.subject_base) # Validate more options using the password try: installutils.verify_fqdn(self.replica_fqdn, local_hostname=False) except installutils.BadHostError as e: msg = str(e) if isinstance(e, installutils.HostLookupError): if not options.ip_addresses: if dns_container_exists( api.env.host, api.env.basedn, dm_password=self.dirman_password, ldapi=True, realm=api.env.realm): self.log.info('You might use the --ip-address option ' 'to create a DNS entry if the DNS zone ' 'is managed by IPA.') raise else: # The host doesn't exist in DNS but we're adding it. pass else: raise if options.ip_addresses: if not dns_container_exists(api.env.host, api.env.basedn, dm_password=self.dirman_password, ldapi=True, realm=api.env.realm): self.log.error( "It is not possible to add a DNS record automatically " "because DNS is not managed by IPA. Please create DNS " "record manually and then omit --ip-address option.") raise admintool.ScriptError("Cannot add DNS record") disconnect = False if not api.Backend.ldap2.isconnected(): api.Backend.ldap2.connect( bind_dn=DN(('cn', 'Directory Manager')), bind_pw=self.dirman_password) disconnect = True options.reverse_zones = bindinstance.check_reverse_zones( options.ip_addresses, options.reverse_zones, options, False, True) host, zone = self.replica_fqdn.split('.', 1) if not bindinstance.dns_zone_exists(zone, api=api): self.log.error("DNS zone %s does not exist in IPA managed DNS " "server. Either create DNS zone or omit " "--ip-address option." % zone) raise admintool.ScriptError("Cannot add DNS record") if disconnect: api.Backend.ldap2.disconnect() self.http_pin = self.dirsrv_pin = self.pkinit_pin = None 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) if options.http_pin is None: raise admintool.ScriptError( "Apache Server private key unlock password required") http_pkcs12_file, http_pin, http_ca_cert = self.load_pkcs12( options.http_cert_files, options.http_pin, options.http_cert_name) self.http_pkcs12_file = http_pkcs12_file self.http_pin = http_pin if options.dirsrv_cert_files: if options.dirsrv_pin is None: options.dirsrv_pin = installutils.read_password( "Enter Directory Server private key unlock", confirm=False, validate=False) if options.dirsrv_pin is None: raise admintool.ScriptError( "Directory Server private key unlock password required") dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = self.load_pkcs12( options.dirsrv_cert_files, options.dirsrv_pin, options.dirsrv_cert_name) self.dirsrv_pkcs12_file = dirsrv_pkcs12_file self.dirsrv_pin = dirsrv_pin if options.pkinit_cert_files: if options.pkinit_pin is None: options.pkinit_pin = installutils.read_password( "Enter Kerberos KDC private key unlock", confirm=False, validate=False) if options.pkinit_pin is None: raise admintool.ScriptError( "Kerberos KDC private key unlock password required") pkinit_pkcs12_file, pkinit_pin, pkinit_ca_cert = self.load_pkcs12( options.pkinit_cert_files, options.pkinit_pin, options.pkinit_cert_name) self.pkinit_pkcs12_file = pkinit_pkcs12_file self.pkinit_pin = pkinit_pin if (options.http_cert_files and options.dirsrv_cert_files and http_ca_cert != dirsrv_ca_cert): raise admintool.ScriptError( "Apache Server SSL certificate and Directory Server SSL " "certificate are not signed by the same CA certificate") if (not ipautil.file_exists( dogtag.configured_constants().CS_CFG_PATH) and options.dirsrv_pin is None): self.log.info("If you installed IPA with your own certificates " "using PKCS#12 files you must provide PKCS#12 files for any " "replicas you create as well.") raise admintool.ScriptError("The replica must be created on the " "primary IPA server.")
def ask_for_options(self): options = self.options super(ReplicaPrepare, self).ask_for_options() # get the directory manager password self.dirman_password = options.password if not options.password: self.dirman_password = installutils.read_password( "Directory Manager (existing master)", confirm=False, validate=False) if self.dirman_password is None: raise admintool.ScriptError( "Directory Manager password required") # Try out the password & get the subject base api.Backend.ldap2.disconnect() try: api.Backend.ldap2.connect(bind_pw=self.dirman_password) entry_attrs = api.Backend.ldap2.get_ipa_config() self.subject_base = entry_attrs.get('ipacertificatesubjectbase', [None])[0] ca_enabled = api.Command.ca_is_enabled()['result'] except errors.ACIError: raise admintool.ScriptError("The password provided is incorrect " "for LDAP server %s" % api.env.host) except errors.LDAPError: raise admintool.ScriptError("Unable to connect to LDAP server %s" % api.env.host) except errors.DatabaseError as e: raise admintool.ScriptError(e.desc) if ca_enabled and not ipautil.file_exists(paths.CA_CS_CFG_PATH): raise admintool.ScriptError( "CA is not installed on this server. " "ipa-replica-prepare must be run on an IPA server with CA.") if not ca_enabled and not options.http_cert_files: raise admintool.ScriptError( "Cannot issue certificates: a CA is not installed. Use the " "--http-cert-file, --dirsrv-cert-file options to provide " "custom certificates.") if self.subject_base is not None: self.subject_base = DN(self.subject_base) # Validate more options using the password try: installutils.verify_fqdn(self.replica_fqdn, local_hostname=False) except installutils.BadHostError as e: if isinstance(e, installutils.HostLookupError): if not options.ip_addresses: if dns_container_exists(api.env.basedn): logger.info('You might use the --ip-address option ' 'to create a DNS entry if the DNS zone ' 'is managed by IPA.') raise else: # The host doesn't exist in DNS but we're adding it. pass else: raise if options.ip_addresses: if not dns_container_exists(api.env.basedn): logger.error( "It is not possible to add a DNS record automatically " "because DNS is not managed by IPA. Please create DNS " "record manually and then omit --ip-address option.") raise admintool.ScriptError("Cannot add DNS record") options.reverse_zones = bindinstance.check_reverse_zones( options.ip_addresses, options.reverse_zones, options, False, True) _host, zone = self.replica_fqdn.split('.', 1) if not bindinstance.dns_zone_exists(zone, api=api): logger.error( "DNS zone %s does not exist in IPA managed DNS " "server. Either create DNS zone or omit " "--ip-address option.", zone) raise admintool.ScriptError("Cannot add DNS record") self.http_pin = self.dirsrv_pin = None 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 admintool.ScriptError( "Apache Server private key unlock password required") http_pkcs12_file, http_pin, http_ca_cert = self.load_pkcs12( options.http_cert_files, options.http_pin, options.http_cert_name) self.http_pkcs12_file = http_pkcs12_file self.http_pin = http_pin if options.dirsrv_cert_files: if options.dirsrv_pin is None: options.dirsrv_pin = installutils.read_password( "Enter Directory Server private key unlock", confirm=False, validate=False, retry=False) if options.dirsrv_pin is None: raise admintool.ScriptError( "Directory Server private key unlock password required" ) dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = self.load_pkcs12( options.dirsrv_cert_files, options.dirsrv_pin, options.dirsrv_cert_name) self.dirsrv_pkcs12_file = dirsrv_pkcs12_file self.dirsrv_pin = dirsrv_pin if (options.http_cert_files and options.dirsrv_cert_files and http_ca_cert != dirsrv_ca_cert): raise admintool.ScriptError( "Apache Server SSL certificate and Directory Server SSL " "certificate are not signed by the same CA certificate")
def promote_check(installer): options = installer installer._enrollment_performed = False installer._top_dir = tempfile.mkdtemp("ipa") # check selinux status, http and DS ports, NTP conflicting services common_check(options.no_ntp) client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) if not client_fstore.has_files(): ensure_enrolled(installer) else: if (options.domain_name or options.server or options.realm_name or options.host_name or options.password or options.keytab): print("IPA client is already configured on this system, ignoring " "the --domain, --server, --realm, --hostname, --password " "and --keytab options.") # The NTP configuration can not be touched on pre-installed client: if options.no_ntp or options.ntp_servers or options.ntp_pool: raise ScriptError( "NTP configuration cannot be updated during promotion") sstore = sysrestore.StateFile(paths.SYSRESTORE) fstore = sysrestore.FileStore(paths.SYSRESTORE) env = Env() env._bootstrap(context='installer', confdir=paths.ETC_IPA, log=None) env._finalize_core(**dict(constants.DEFAULT_CONFIG)) # pylint: disable=no-member xmlrpc_uri = 'https://{}/ipa/xml'.format(ipautil.format_netloc(env.host)) api.bootstrap(in_server=True, context='installer', confdir=paths.ETC_IPA, ldap_uri=installutils.realm_to_ldapi_uri(env.realm), xmlrpc_uri=xmlrpc_uri) # pylint: enable=no-member api.finalize() config = ReplicaConfig() config.realm_name = api.env.realm config.host_name = api.env.host config.domain_name = api.env.domain config.master_host_name = api.env.server config.ca_host_name = api.env.ca_host config.kra_host_name = config.ca_host_name config.ca_ds_port = 389 config.setup_ca = options.setup_ca config.setup_kra = options.setup_kra config.dir = installer._top_dir config.basedn = api.env.basedn http_pkcs12_file = None http_pkcs12_info = None http_ca_cert = None dirsrv_pkcs12_file = None dirsrv_pkcs12_info = None dirsrv_ca_cert = None pkinit_pkcs12_file = None pkinit_pkcs12_info = None pkinit_ca_cert = None 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=config.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 = installutils.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=config.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 = installutils.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, realm_name=config.realm_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 RuntimeError("Apache Server SSL certificate and Directory " "Server SSL certificate are not signed by the same" " CA certificate") if (options.http_cert_files and options.pkinit_cert_files and http_ca_cert != pkinit_ca_cert): raise RuntimeError("Apache Server SSL certificate and PKINIT KDC " "certificate are not signed by the same CA " "certificate") installutils.verify_fqdn(config.host_name, options.no_host_dns) installutils.verify_fqdn(config.master_host_name, options.no_host_dns) ccache = os.environ['KRB5CCNAME'] kinit_keytab('host/{env.host}@{env.realm}'.format(env=api.env), paths.KRB5_KEYTAB, ccache) cafile = paths.IPA_CA_CRT if not os.path.isfile(cafile): raise RuntimeError("CA cert file is not available! Please reinstall" "the client and try again.") ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name) xmlrpc_uri = 'https://{}/ipa/xml'.format( ipautil.format_netloc(config.master_host_name)) remote_api = create_api(mode=None) remote_api.bootstrap(in_server=True, context='installer', confdir=paths.ETC_IPA, ldap_uri=ldapuri, xmlrpc_uri=xmlrpc_uri) remote_api.finalize() installer._remote_api = remote_api with rpc_client(remote_api) as client: check_remote_version(client, parse_version(api.env.version)) check_remote_fips_mode(client, api.env.fips_mode) conn = remote_api.Backend.ldap2 replman = None try: # Try out authentication conn.connect(ccache=ccache) replman = ReplicationManager(config.realm_name, config.master_host_name, None) promotion_check_ipa_domain(conn, remote_api.env.basedn) # Make sure that domain fulfills minimal domain level # requirement domain_level = current_domain_level(remote_api) check_domain_level_is_supported(domain_level) if domain_level < constants.MIN_DOMAIN_LEVEL: raise RuntimeError( "Cannot promote this client to a replica. The domain level " "must be raised to {mindomainlevel} before the replica can be " "installed".format(mindomainlevel=constants.MIN_DOMAIN_LEVEL)) # Check authorization result = remote_api.Command['hostgroup_find']( cn=u'ipaservers', host=[unicode(api.env.host)])['result'] add_to_ipaservers = not result if add_to_ipaservers: if options.password and not options.admin_password: raise errors.ACIError(info="Not authorized") if installer._ccache is None: del os.environ['KRB5CCNAME'] else: os.environ['KRB5CCNAME'] = installer._ccache try: installutils.check_creds(options, config.realm_name) installer._ccache = os.environ.get('KRB5CCNAME') finally: os.environ['KRB5CCNAME'] = ccache conn.disconnect() conn.connect(ccache=installer._ccache) try: result = remote_api.Command['hostgroup_show']( u'ipaservers', all=True, rights=True)['result'] if 'w' not in result['attributelevelrights']['member']: raise errors.ACIError(info="Not authorized") finally: conn.disconnect() conn.connect(ccache=ccache) # Check that we don't already have a replication agreement if replman.get_replication_agreement(config.host_name): msg = ("A replication agreement for this host already exists. " "It needs to be removed.\n" "Run this command:\n" " %% ipa-replica-manage del {host} --force".format( host=config.host_name)) raise ScriptError(msg, rval=3) # Detect if the other master can handle replication managers # cn=replication managers,cn=sysaccounts,cn=etc,$SUFFIX dn = DN(('cn', 'replication managers'), ('cn', 'sysaccounts'), ('cn', 'etc'), ipautil.realm_to_suffix(config.realm_name)) try: conn.get_entry(dn) except errors.NotFound: msg = ("The Replication Managers group is not available in " "the domain. Replica promotion requires the use of " "Replication Managers to be able to replicate data. " "Upgrade the peer master or use the ipa-replica-prepare " "command on the master and use a prep file to install " "this replica.") logger.error("%s", msg) raise ScriptError(rval=3) dns_masters = remote_api.Object['dnsrecord'].get_dns_masters() if dns_masters: if not options.no_host_dns: logger.debug('Check forward/reverse DNS resolution') resolution_ok = ( check_dns_resolution(config.master_host_name, dns_masters) and check_dns_resolution(config.host_name, dns_masters)) if not resolution_ok and installer.interactive: if not ipautil.user_input("Continue?", False): raise ScriptError(rval=0) else: logger.debug('No IPA DNS servers, ' 'skipping forward/reverse resolution check') entry_attrs = conn.get_ipa_config() subject_base = entry_attrs.get('ipacertificatesubjectbase', [None])[0] if subject_base is not None: config.subject_base = DN(subject_base) # Find if any server has a CA ca_host = service.find_providing_server('CA', conn, config.ca_host_name) if ca_host is not None: config.ca_host_name = ca_host ca_enabled = True if options.dirsrv_cert_files: logger.error("Certificates could not be provided when " "CA is present on some master.") raise ScriptError(rval=3) else: if options.setup_ca: logger.error("The remote master does not have a CA " "installed, can't set up CA") raise ScriptError(rval=3) ca_enabled = False if not options.dirsrv_cert_files: logger.error("Cannot issue certificates: a CA is not " "installed. Use the --http-cert-file, " "--dirsrv-cert-file options to provide " "custom certificates.") raise ScriptError(rval=3) kra_host = service.find_providing_server('KRA', conn, config.kra_host_name) if kra_host is not None: config.kra_host_name = kra_host kra_enabled = True else: if options.setup_kra: logger.error("There is no KRA server in the domain, " "can't setup a KRA clone") raise ScriptError(rval=3) kra_enabled = False if ca_enabled: options.realm_name = config.realm_name options.host_name = config.host_name ca.install_check(False, config, options) if kra_enabled: try: kra.install_check(remote_api, config, options) except RuntimeError as e: raise ScriptError(e) if options.setup_dns: dns.install_check(False, remote_api, True, options, config.host_name) config.ips = dns.ip_addresses else: config.ips = installutils.get_server_ip_address( config.host_name, not installer.interactive, False, options.ip_addresses) # check addresses here, dns module is doing own check no_matching_interface_for_ip_address_warning(config.ips) if options.setup_adtrust: adtrust.install_check(False, options, remote_api) except errors.ACIError: logger.debug("%s", traceback.format_exc()) raise ScriptError("\nInsufficient privileges to promote the server." "\nPossible issues:" "\n- A user has insufficient privileges" "\n- This client has insufficient privileges " "to become an IPA replica") except errors.LDAPError: logger.debug("%s", traceback.format_exc()) raise ScriptError("\nUnable to connect to LDAP server %s" % config.master_host_name) finally: if replman and replman.conn: replman.conn.unbind() if conn.isconnected(): conn.disconnect() # check connection if not options.skip_conncheck: if add_to_ipaservers: # use user's credentials when the server host is not ipaservers if installer._ccache is None: del os.environ['KRB5CCNAME'] else: os.environ['KRB5CCNAME'] = installer._ccache try: replica_conn_check(config.master_host_name, config.host_name, config.realm_name, options.setup_ca, 389, options.admin_password, principal=options.principal, ca_cert_file=cafile) finally: if add_to_ipaservers: os.environ['KRB5CCNAME'] = ccache installer._ca_enabled = ca_enabled installer._kra_enabled = kra_enabled installer._ca_file = cafile installer._fstore = fstore installer._sstore = sstore installer._config = config installer._add_to_ipaservers = add_to_ipaservers installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info installer._http_pkcs12_file = http_pkcs12_file installer._http_pkcs12_info = http_pkcs12_info installer._pkinit_pkcs12_file = pkinit_pkcs12_file installer._pkinit_pkcs12_info = pkinit_pkcs12_info
if options.setup_ca: options.realm_name = config.realm_name options.host_name = config.host_name options.subject = config.subject_base ca.install_check(False, config, options) if config.setup_kra: try: kra.install_check(config, options, False, dogtag.install_constants.DOGTAG_VERSION) except RuntimeError as e: print str(e) sys.exit(1) installutils.verify_fqdn(config.master_host_name, options.no_host_dns) if options.setup_dns: dns.install_check(False, True, options, config.host_name) else: installutils.get_server_ip_address(config.host_name, fstore, options.unattended, False, options.ip_addresses) # check connection if not options.skip_conncheck: replica_conn_check( config.master_host_name, config.host_name, config.realm_name, options.setup_ca, config.ca_ds_port, options.admin_password) # Automatically disable pkinit w/ dogtag until that is supported
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 if tasks.is_fips_enabled(): raise RuntimeError( "Installing IPA server in FIPS mode is not supported") 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 # first instance of KRA must be installed by ipa-kra-install options.setup_kra = False 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_dns: print(" * Configure DNS (bind)") 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: options.subject = DN(('O', realm_name)) 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 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", 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) 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) # 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 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 promote_check(installer): options = installer installer._enrollment_performed = False installer._top_dir = tempfile.mkdtemp("ipa") # check selinux status, http and DS ports, NTP conflicting services common_check(options.no_ntp) client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) if not client_fstore.has_files(): # One-step replica installation if options.password and options.admin_password: raise ScriptError("--password and --admin-password options are " "mutually exclusive") ensure_enrolled(installer) else: if (options.domain_name or options.server or options.realm_name or options.host_name or options.password or options.keytab): print("IPA client is already configured on this system, ignoring " "the --domain, --server, --realm, --hostname, --password " "and --keytab options.") # The NTP configuration can not be touched on pre-installed client: if options.no_ntp or options.ntp_servers or options.ntp_pool: raise ScriptError( "NTP configuration cannot be updated during promotion") sstore = sysrestore.StateFile(paths.SYSRESTORE) fstore = sysrestore.FileStore(paths.SYSRESTORE) env = Env() env._bootstrap(context='installer', confdir=paths.ETC_IPA, log=None) env._finalize_core(**dict(constants.DEFAULT_CONFIG)) # pylint: disable=no-member xmlrpc_uri = 'https://{}/ipa/xml'.format(ipautil.format_netloc(env.host)) api.bootstrap(in_server=True, context='installer', confdir=paths.ETC_IPA, ldap_uri=ipaldap.realm_to_ldapi_uri(env.realm), xmlrpc_uri=xmlrpc_uri) # pylint: enable=no-member api.finalize() config = ReplicaConfig() config.realm_name = api.env.realm config.host_name = api.env.host config.domain_name = api.env.domain config.master_host_name = api.env.server if not api.env.ca_host or api.env.ca_host == api.env.host: # ca_host has not been configured explicitly, prefer source master config.ca_host_name = api.env.server else: # default to ca_host from IPA config config.ca_host_name = api.env.ca_host config.kra_host_name = config.ca_host_name config.ca_ds_port = 389 config.setup_ca = options.setup_ca config.setup_kra = options.setup_kra config.dir = installer._top_dir config.basedn = api.env.basedn config.hidden_replica = options.hidden_replica http_pkcs12_file = None http_pkcs12_info = None http_ca_cert = None dirsrv_pkcs12_file = None dirsrv_pkcs12_info = None dirsrv_ca_cert = None pkinit_pkcs12_file = None pkinit_pkcs12_info = None pkinit_ca_cert = None 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=config.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 = installutils.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=config.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 = installutils.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, realm_name=config.realm_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 RuntimeError("Apache Server SSL certificate and Directory " "Server SSL certificate are not signed by the same" " CA certificate") if (options.http_cert_files and options.pkinit_cert_files and http_ca_cert != pkinit_ca_cert): raise RuntimeError("Apache Server SSL certificate and PKINIT KDC " "certificate are not signed by the same CA " "certificate") installutils.verify_fqdn(config.host_name, options.no_host_dns) installutils.verify_fqdn(config.master_host_name, options.no_host_dns) ccache = os.environ['KRB5CCNAME'] kinit_keytab('host/{env.host}@{env.realm}'.format(env=api.env), paths.KRB5_KEYTAB, ccache) cafile = paths.IPA_CA_CRT if not os.path.isfile(cafile): raise RuntimeError("CA cert file is not available! Please reinstall" "the client and try again.") ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name) xmlrpc_uri = 'https://{}/ipa/xml'.format( ipautil.format_netloc(config.master_host_name)) remote_api = create_api(mode=None) remote_api.bootstrap(in_server=True, context='installer', confdir=paths.ETC_IPA, ldap_uri=ldapuri, xmlrpc_uri=xmlrpc_uri) remote_api.finalize() installer._remote_api = remote_api with rpc_client(remote_api) as client: check_remote_version(client, parse_version(api.env.version)) check_remote_fips_mode(client, api.env.fips_mode) conn = remote_api.Backend.ldap2 replman = None try: # Try out authentication conn.connect(ccache=ccache) replman = ReplicationManager(config.realm_name, config.master_host_name, None) promotion_check_ipa_domain(conn, remote_api.env.basedn) # Make sure that domain fulfills minimal domain level # requirement domain_level = current_domain_level(remote_api) check_domain_level_is_supported(domain_level) if domain_level < constants.MIN_DOMAIN_LEVEL: raise RuntimeError( "Cannot promote this client to a replica. The domain level " "must be raised to {mindomainlevel} before the replica can be " "installed".format( mindomainlevel=constants.MIN_DOMAIN_LEVEL )) # Check authorization result = remote_api.Command['hostgroup_find']( cn=u'ipaservers', host=[unicode(api.env.host)] )['result'] add_to_ipaservers = not result if add_to_ipaservers: if options.password and not options.admin_password: raise errors.ACIError(info="Not authorized") if installer._ccache is None: del os.environ['KRB5CCNAME'] else: os.environ['KRB5CCNAME'] = installer._ccache try: installutils.check_creds(options, config.realm_name) installer._ccache = os.environ.get('KRB5CCNAME') finally: os.environ['KRB5CCNAME'] = ccache conn.disconnect() conn.connect(ccache=installer._ccache) try: result = remote_api.Command['hostgroup_show']( u'ipaservers', all=True, rights=True )['result'] if 'w' not in result['attributelevelrights']['member']: raise errors.ACIError(info="Not authorized") finally: conn.disconnect() conn.connect(ccache=ccache) # Check that we don't already have a replication agreement if replman.get_replication_agreement(config.host_name): msg = ("A replication agreement for this host already exists. " "It needs to be removed.\n" "Run this command:\n" " %% ipa-replica-manage del {host} --force" .format(host=config.host_name)) raise ScriptError(msg, rval=3) # Detect if the other master can handle replication managers # cn=replication managers,cn=sysaccounts,cn=etc,$SUFFIX dn = DN(('cn', 'replication managers'), ('cn', 'sysaccounts'), ('cn', 'etc'), ipautil.realm_to_suffix(config.realm_name)) try: conn.get_entry(dn) except errors.NotFound: msg = ("The Replication Managers group is not available in " "the domain. Replica promotion requires the use of " "Replication Managers to be able to replicate data. " "Upgrade the peer master or use the ipa-replica-prepare " "command on the master and use a prep file to install " "this replica.") logger.error("%s", msg) raise ScriptError(rval=3) dns_masters = remote_api.Object['dnsrecord'].get_dns_masters() if dns_masters: if not options.no_host_dns: logger.debug('Check forward/reverse DNS resolution') resolution_ok = ( check_dns_resolution(config.master_host_name, dns_masters) and check_dns_resolution(config.host_name, dns_masters)) if not resolution_ok and installer.interactive: if not ipautil.user_input("Continue?", False): raise ScriptError(rval=0) else: logger.debug('No IPA DNS servers, ' 'skipping forward/reverse resolution check') entry_attrs = conn.get_ipa_config() subject_base = entry_attrs.get('ipacertificatesubjectbase', [None])[0] if subject_base is not None: config.subject_base = DN(subject_base) # Find any server with a CA ca_host = find_providing_server( 'CA', conn, [config.ca_host_name] ) if ca_host is not None: config.ca_host_name = ca_host ca_enabled = True if options.dirsrv_cert_files: logger.error("Certificates could not be provided when " "CA is present on some master.") raise ScriptError(rval=3) else: if options.setup_ca: logger.error("The remote master does not have a CA " "installed, can't set up CA") raise ScriptError(rval=3) ca_enabled = False if not options.dirsrv_cert_files: logger.error("Cannot issue certificates: a CA is not " "installed. Use the --http-cert-file, " "--dirsrv-cert-file options to provide " "custom certificates.") raise ScriptError(rval=3) # Find any server with a KRA kra_host = find_providing_server( 'KRA', conn, [config.kra_host_name] ) if kra_host is not None: config.kra_host_name = kra_host kra_enabled = True else: if options.setup_kra: logger.error("There is no active KRA server in the domain, " "can't setup a KRA clone") raise ScriptError(rval=3) kra_enabled = False if ca_enabled: options.realm_name = config.realm_name options.host_name = config.host_name ca.install_check(False, config, options) if kra_enabled: try: kra.install_check(remote_api, config, options) except RuntimeError as e: raise ScriptError(e) if options.setup_dns: dns.install_check(False, remote_api, True, options, config.host_name) config.ips = dns.ip_addresses else: config.ips = installutils.get_server_ip_address( config.host_name, not installer.interactive, False, options.ip_addresses) # check addresses here, dns module is doing own check no_matching_interface_for_ip_address_warning(config.ips) if options.setup_adtrust: adtrust.install_check(False, options, remote_api) except errors.ACIError: logger.debug("%s", traceback.format_exc()) raise ScriptError("\nInsufficient privileges to promote the server." "\nPossible issues:" "\n- A user has insufficient privileges" "\n- This client has insufficient privileges " "to become an IPA replica") except errors.LDAPError: logger.debug("%s", traceback.format_exc()) raise ScriptError("\nUnable to connect to LDAP server %s" % config.master_host_name) finally: if replman and replman.conn: replman.conn.unbind() if conn.isconnected(): conn.disconnect() # check connection if not options.skip_conncheck: if add_to_ipaservers: # use user's credentials when the server host is not ipaservers if installer._ccache is None: del os.environ['KRB5CCNAME'] else: os.environ['KRB5CCNAME'] = installer._ccache try: replica_conn_check( config.master_host_name, config.host_name, config.realm_name, options.setup_ca, 389, options.admin_password, principal=options.principal, ca_cert_file=cafile) finally: if add_to_ipaservers: os.environ['KRB5CCNAME'] = ccache installer._ca_enabled = ca_enabled installer._kra_enabled = kra_enabled installer._ca_file = cafile installer._fstore = fstore installer._sstore = sstore installer._config = config installer._add_to_ipaservers = add_to_ipaservers installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info installer._http_pkcs12_file = http_pkcs12_file installer._http_pkcs12_info = http_pkcs12_info installer._pkinit_pkcs12_file = pkinit_pkcs12_file installer._pkinit_pkcs12_info = pkinit_pkcs12_info
class ReplicaPrepare(admintool.AdminTool): command_name = 'ipa-replica-prepare' usage = "%prog [options] <replica-fqdn>" description = "Prepare a file for replica installation." @classmethod def add_options(cls, parser): super(ReplicaPrepare, cls).add_options(parser, debug_option=True) parser.add_option( "-p", "--password", dest="password", help="Directory Manager password (for the existing master)") parser.add_option( "--ip-address", dest="ip_addresses", type="ip", action="append", default=[], metavar="IP_ADDRESS", help= "add A and PTR records of the future replica. This option can be used multiple times" ) parser.add_option( "--reverse-zone", dest="reverse_zones", action="append", default=[], metavar="REVERSE_ZONE", help= "the reverse DNS zone to use. This option can be used multiple times" ) parser.add_option("--no-reverse", dest="no_reverse", action="store_true", default=False, help="do not create reverse DNS zone") parser.add_option("--no-pkinit", dest="setup_pkinit", action="store_false", default=True, help="disables pkinit setup steps") parser.add_option( "--ca", dest="ca_file", default=paths.CACERT_P12, metavar="FILE", help="location of CA PKCS#12 file, default /root/cacert.p12") parser.add_option( '--no-wait-for-dns', dest='wait_for_dns', action='store_false', default=True, help="do not wait until the replica is resolvable in DNS") group = OptionGroup( parser, "SSL certificate options", "Only used if the server was installed using custom SSL certificates" ) group.add_option( "--dirsrv-cert-file", dest="dirsrv_cert_files", action="append", metavar="FILE", help= "File containing the Directory Server SSL certificate and private key" ) group.add_option("--dirsrv_pkcs12", dest="dirsrv_cert_files", action="append", help=SUPPRESS_HELP) group.add_option( "--http-cert-file", dest="http_cert_files", action="append", metavar="FILE", help= "File containing the Apache Server SSL certificate and private key" ) group.add_option("--http_pkcs12", dest="http_cert_files", action="append", help=SUPPRESS_HELP) group.add_option( "--pkinit-cert-file", dest="pkinit_cert_files", action="append", metavar="FILE", help= "File containing the Kerberos KDC SSL certificate and private key") group.add_option("--pkinit_pkcs12", dest="pkinit_cert_files", action="append", help=SUPPRESS_HELP) group.add_option( "--dirsrv-pin", dest="dirsrv_pin", sensitive=True, metavar="PIN", help="The password to unlock the Directory Server private key") group.add_option("--dirsrv_pin", dest="dirsrv_pin", sensitive=True, help=SUPPRESS_HELP) group.add_option( "--http-pin", dest="http_pin", sensitive=True, metavar="PIN", help="The password to unlock the Apache Server private key") group.add_option("--http_pin", dest="http_pin", sensitive=True, help=SUPPRESS_HELP) group.add_option( "--pkinit-pin", dest="pkinit_pin", sensitive=True, metavar="PIN", help="The password to unlock the Kerberos KDC private key") group.add_option("--pkinit_pin", dest="pkinit_pin", sensitive=True, help=SUPPRESS_HELP) group.add_option( "--dirsrv-cert-name", dest="dirsrv_cert_name", metavar="NAME", help="Name of the Directory Server SSL certificate to install") group.add_option( "--http-cert-name", dest="http_cert_name", metavar="NAME", help="Name of the Apache Server SSL certificate to install") group.add_option( "--pkinit-cert-name", dest="pkinit_cert_name", metavar="NAME", help="Name of the Kerberos KDC SSL certificate to install") parser.add_option_group(group) 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() 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 load_pkcs12(self, cert_files, key_password, key_nickname): return installutils.load_pkcs12(cert_files=cert_files, key_password=key_password, key_nickname=key_nickname, ca_cert_files=[CACERT], host_name=self.replica_fqdn) def ask_for_options(self): options = self.options super(ReplicaPrepare, self).ask_for_options() # get the directory manager password self.dirman_password = options.password if not options.password: self.dirman_password = installutils.read_password( "Directory Manager (existing master)", confirm=False, validate=False) if self.dirman_password is None: raise admintool.ScriptError( "Directory Manager password required") # Try out the password & get the subject base suffix = ipautil.realm_to_suffix(api.env.realm) try: conn = api.Backend.ldap2 conn.connect(bind_dn=DN(('cn', 'directory manager')), bind_pw=self.dirman_password) entry_attrs = conn.get_ipa_config() ca_enabled = api.Command.ca_is_enabled()['result'] conn.disconnect() except errors.ACIError: raise admintool.ScriptError("The password provided is incorrect " "for LDAP server %s" % api.env.host) except errors.LDAPError: raise admintool.ScriptError("Unable to connect to LDAP server %s" % api.env.host) except errors.DatabaseError, e: raise admintool.ScriptError(e.desc) if not ca_enabled and not options.http_cert_files: raise admintool.ScriptError( "Cannot issue certificates: a CA is not installed. Use the " "--http-cert-file, --dirsrv-cert-file options to provide " "custom certificates.") self.subject_base = entry_attrs.get('ipacertificatesubjectbase', [None])[0] if self.subject_base is not None: self.subject_base = DN(self.subject_base) # Validate more options using the password try: installutils.verify_fqdn(self.replica_fqdn, local_hostname=False) except installutils.BadHostError, e: msg = str(e) if isinstance(e, installutils.HostLookupError): if not options.ip_addresses: if dns_container_exists(api.env.host, api.env.basedn, dm_password=self.dirman_password, ldapi=True, realm=api.env.realm): self.log.info('Add the --ip-address argument to ' 'create a DNS entry.') raise else: # The host doesn't exist in DNS but we're adding it. pass else: raise
def install_check(installer): options = installer filename = installer.replica_file tasks.check_selinux_status() client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) if client_fstore.has_files(): sys.exit("IPA client is already configured on this system.\n" "Please uninstall it first before configuring the replica, " "using 'ipa-client-install --uninstall'.") sstore = sysrestore.StateFile(paths.SYSRESTORE) fstore = sysrestore.FileStore(paths.SYSRESTORE) # Check to see if httpd is already configured to listen on 443 if httpinstance.httpd_443_configured(): sys.exit("Aborting installation") check_dirsrv() if not options.no_ntp: try: ipaclient.ntpconf.check_timedate_services() except ipaclient.ntpconf.NTPConflictingService as e: print(("WARNING: conflicting time&date synchronization service '%s'" " will" % e.conflicting_service)) print("be disabled in favor of ntpd") print("") except ipaclient.ntpconf.NTPConfigurationError: pass # get the directory manager password dirman_password = options.password if not dirman_password: try: dirman_password = get_dirman_password() except KeyboardInterrupt: sys.exit(0) if dirman_password is None: sys.exit("Directory Manager password required") config = create_replica_config(dirman_password, filename, options) installer._top_dir = config.top_dir config.setup_ca = options.setup_ca config.setup_kra = options.setup_kra # Create the management framework config file # Note: We must do this before bootstraping and finalizing ipalib.api old_umask = os.umask(0o22) # must be readable for httpd try: fd = open(paths.IPA_DEFAULT_CONF, "w") fd.write("[global]\n") fd.write("host=%s\n" % config.host_name) fd.write("basedn=%s\n" % str(ipautil.realm_to_suffix(config.realm_name))) fd.write("realm=%s\n" % config.realm_name) fd.write("domain=%s\n" % config.domain_name) fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % ipautil.format_netloc(config.host_name)) fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % installutils.realm_to_serverid(config.realm_name)) if ipautil.file_exists(config.dir + "/cacert.p12"): 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("mode=production\n") fd.close() finally: os.umask(old_umask) api.bootstrap(in_server=True, context='installer') api.finalize() installutils.verify_fqdn(config.master_host_name, options.no_host_dns) cafile = config.dir + "/ca.crt" if not ipautil.file_exists(cafile): raise RuntimeError("CA cert file is not available. Please run " "ipa-replica-prepare to create a new replica file.") ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name) remote_api = create_api(mode=None) remote_api.bootstrap(in_server=True, context='installer', ldap_uri=ldapuri) remote_api.finalize() conn = remote_api.Backend.ldap2 replman = None try: # Try out the password conn.connect(bind_dn=DIRMAN_DN, bind_pw=config.dirman_password, tls_cacertfile=cafile) replman = ReplicationManager(config.realm_name, config.master_host_name, config.dirman_password) # Check that we don't already have a replication agreement if replman.get_replication_agreement(config.host_name): root_logger.info('Error: A replication agreement for this ' 'host already exists.') print('A replication agreement for this host already exists. ' 'It needs to be removed.') print("Run this on the master that generated the info file:") print((" %% ipa-replica-manage del %s --force" % config.host_name)) sys.exit(3) # Detect the current domain level try: current = remote_api.Command['domainlevel_get']()['result'] except errors.NotFound: # If we're joining an older master, domain entry is not # available current = 0 # Detect if current level is out of supported range # for this IPA version under_lower_bound = current < constants.MIN_DOMAIN_LEVEL above_upper_bound = current > constants.MAX_DOMAIN_LEVEL if under_lower_bound or above_upper_bound: message = ("This version of FreeIPA does not support " "the Domain Level which is currently set for " "this domain. The Domain Level needs to be " "raised before installing a replica with " "this version is allowed to be installed " "within this domain.") root_logger.error(message) print(message) sys.exit(3) # Check pre-existing host entry try: entry = conn.find_entries(u'fqdn=%s' % config.host_name, ['fqdn'], DN(api.env.container_host, api.env.basedn)) except errors.NotFound: pass else: root_logger.info('Error: Host %s already exists on the master ' 'server.' % config.host_name) print(('The host %s already exists on the master server.' % config.host_name)) print("You should remove it before proceeding:") print(" %% ipa host-del %s" % config.host_name) sys.exit(3) dns_masters = remote_api.Object['dnsrecord'].get_dns_masters() if dns_masters: if not options.no_host_dns: master = config.master_host_name root_logger.debug('Check forward/reverse DNS resolution') resolution_ok = ( check_dns_resolution(master, dns_masters) and check_dns_resolution(config.host_name, dns_masters)) if not resolution_ok and installer.interactive: if not ipautil.user_input("Continue?", False): sys.exit(0) else: root_logger.debug('No IPA DNS servers, ' 'skipping forward/reverse resolution check') if options.setup_ca: options.realm_name = config.realm_name options.host_name = config.host_name options.subject = config.subject_base ca.install_check(False, config, options) if config.setup_kra: try: kra.install_check(remote_api, config, options) except RuntimeError as e: print(str(e)) sys.exit(1) except errors.ACIError: sys.exit("\nThe password provided is incorrect for LDAP server " "%s" % config.master_host_name) except errors.LDAPError: sys.exit("\nUnable to connect to LDAP server %s" % config.master_host_name) finally: if replman and replman.conn: replman.conn.unbind() if conn.isconnected(): conn.disconnect() if options.setup_dns: dns.install_check(False, True, options, config.host_name) config.ips = dns.ip_addresses else: config.ips = installutils.get_server_ip_address( config.host_name, not installer.interactive, False, options.ip_addresses) # installer needs to update hosts file when DNS subsystem will be # installed or custom addresses are used if options.setup_dns or options.ip_addresses: installer._update_hosts_file = True # check connection if not options.skip_conncheck: replica_conn_check( config.master_host_name, config.host_name, config.realm_name, options.setup_ca, config.ca_ds_port, options.admin_password) installer._remote_api = remote_api installer._fstore = fstore installer._sstore = sstore installer._config = config
def ask_for_options(self): options = self.options super(ReplicaPrepare, self).ask_for_options() # get the directory manager password self.dirman_password = options.password if not options.password: self.dirman_password = installutils.read_password( "Directory Manager (existing master)", confirm=False, validate=False) if self.dirman_password is None: raise admintool.ScriptError( "Directory Manager password required") # Try out the password & get the subject base api.Backend.ldap2.disconnect() try: api.Backend.ldap2.connect(bind_pw=self.dirman_password) entry_attrs = api.Backend.ldap2.get_ipa_config() self.subject_base = entry_attrs.get( 'ipacertificatesubjectbase', [None])[0] ca_enabled = api.Command.ca_is_enabled()['result'] except errors.ACIError: raise admintool.ScriptError("The password provided is incorrect " "for LDAP server %s" % api.env.host) except errors.LDAPError: raise admintool.ScriptError( "Unable to connect to LDAP server %s" % api.env.host) except errors.DatabaseError as e: raise admintool.ScriptError(e.desc) if ca_enabled and not ipautil.file_exists(paths.CA_CS_CFG_PATH): raise admintool.ScriptError( "CA is not installed on this server. " "ipa-replica-prepare must be run on an IPA server with CA.") if not ca_enabled and not options.http_cert_files: raise admintool.ScriptError( "Cannot issue certificates: a CA is not installed. Use the " "--http-cert-file, --dirsrv-cert-file options to provide " "custom certificates.") if self.subject_base is not None: self.subject_base = DN(self.subject_base) # Validate more options using the password try: installutils.verify_fqdn(self.replica_fqdn, local_hostname=False) except installutils.BadHostError as e: if isinstance(e, installutils.HostLookupError): if not options.ip_addresses: if dns_container_exists(api.env.basedn): logger.info('You might use the --ip-address option ' 'to create a DNS entry if the DNS zone ' 'is managed by IPA.') raise else: # The host doesn't exist in DNS but we're adding it. pass else: raise if options.ip_addresses: if not dns_container_exists(api.env.basedn): logger.error( "It is not possible to add a DNS record automatically " "because DNS is not managed by IPA. Please create DNS " "record manually and then omit --ip-address option.") raise admintool.ScriptError("Cannot add DNS record") options.reverse_zones = bindinstance.check_reverse_zones( options.ip_addresses, options.reverse_zones, options, False, True) _host, zone = self.replica_fqdn.split('.', 1) if not bindinstance.dns_zone_exists(zone, api=api): logger.error("DNS zone %s does not exist in IPA managed DNS " "server. Either create DNS zone or omit " "--ip-address option.", zone) raise admintool.ScriptError("Cannot add DNS record") self.http_pin = self.dirsrv_pin = None 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 admintool.ScriptError( "Apache Server private key unlock password required") http_pkcs12_file, http_pin, http_ca_cert = self.load_pkcs12( options.http_cert_files, options.http_pin, options.http_cert_name) self.http_pkcs12_file = http_pkcs12_file self.http_pin = http_pin if options.dirsrv_cert_files: if options.dirsrv_pin is None: options.dirsrv_pin = installutils.read_password( "Enter Directory Server private key unlock", confirm=False, validate=False, retry=False) if options.dirsrv_pin is None: raise admintool.ScriptError( "Directory Server private key unlock password required") dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = self.load_pkcs12( options.dirsrv_cert_files, options.dirsrv_pin, options.dirsrv_cert_name) self.dirsrv_pkcs12_file = dirsrv_pkcs12_file self.dirsrv_pin = dirsrv_pin if (options.http_cert_files and options.dirsrv_cert_files and http_ca_cert != dirsrv_ca_cert): raise admintool.ScriptError( "Apache Server SSL certificate and Directory Server SSL " "certificate are not signed by the same CA certificate")