def run(api): error = None try: (_options, argv) = api.bootstrap_with_global_options(context='cli') try: check_client_configuration() except ScriptError as e: sys.exit(e) for klass in cli_plugins: api.add_plugin(klass) api.finalize() if not 'config_loaded' in api.env and not 'help' in argv: raise NotConfiguredError() sys.exit(api.Backend.cli.run(argv)) except KeyboardInterrupt: print('') logger.info('operation aborted') except PublicError as e: error = e except Exception as e: logger.exception('%s: %s', e.__class__.__name__, str(e)) error = InternalError() if error is not None: assert isinstance(error, PublicError) logger.error(error.strerror) sys.exit(error.rval)
def run(self): check_client_configuration() old_krb5ccname = os.environ.get('KRB5CCNAME') os.environ['KRB5_CLIENT_KTNAME'] = '/etc/krb5.keytab' os.environ['KRB5CCNAME'] = "MEMORY:" try: api.bootstrap(context='cli_installer', confdir=paths.ETC_IPA) api.finalize() api.Backend.rpcclient.connect() run_with_args(api) api.Backend.rpcclient.disconnect() except errors.CCacheError: logger.error( "Unable to obtain credentials for %s from /etc/krb5.keytab", FQDN ) raise finally: if old_krb5ccname is None: del os.environ['KRB5CCNAME'] else: os.environ['KRB5CCNAME'] = old_krb5ccname
def run(self): check_client_configuration() api.bootstrap(context='cli_installer', confdir=paths.ETC_IPA) api.finalize() server = urlsplit(api.env.jsonrpc_uri).hostname ldap_uri = ipaldap.get_ldap_uri(server) ldap = ipaldap.LDAPClient(ldap_uri) tmpdir = tempfile.mkdtemp(prefix="tmp-") ccache_name = os.path.join(tmpdir, 'ccache') try: principal = str('host/%s@%s' % (api.env.host, api.env.realm)) kinit_keytab(principal, paths.KRB5_KEYTAB, ccache_name) os.environ['KRB5CCNAME'] = ccache_name api.Backend.rpcclient.connect() try: result = api.Backend.rpcclient.forward( 'ca_is_enabled', version=u'2.107', ) ca_enabled = result['result'] except (errors.CommandError, errors.NetworkError): result = api.Backend.rpcclient.forward( 'env', server=True, version=u'2.0', ) ca_enabled = result['result']['enable_ra'] ldap.gssapi_bind() certs = certstore.get_ca_certs(ldap, api.env.basedn, api.env.realm, ca_enabled) if ca_enabled: lwcas = api.Command.ca_find()['result'] else: lwcas = [] api.Backend.rpcclient.disconnect() finally: shutil.rmtree(tmpdir) server_fstore = sysrestore.FileStore(paths.SYSRESTORE) if server_fstore.has_files(): self.update_server(certs) try: # pylint: disable=import-error,ipa-forbidden-import from ipaserver.install import cainstance # pylint: enable=import-error,ipa-forbidden-import cainstance.add_lightweight_ca_tracking_requests(lwcas) except Exception: logger.exception( "Failed to add lightweight CA tracking requests") self.update_client(certs)
def run(self): check_client_configuration() api.bootstrap(context='cli_installer', confdir=paths.ETC_IPA) api.finalize() api.Backend.rpcclient.connect() run_with_args(api) api.Backend.rpcclient.disconnect()
def run(self): check_client_configuration() old_krb5ccname = os.environ.get('KRB5CCNAME') os.environ['KRB5_CLIENT_KTNAME'] = '/etc/krb5.keytab' os.environ['KRB5CCNAME'] = "MEMORY:" try: api.bootstrap(context='cli_installer', confdir=paths.ETC_IPA) api.finalize() api.Backend.rpcclient.connect() run_with_args(api) api.Backend.rpcclient.disconnect() finally: if old_krb5ccname is None: del os.environ['KRB5CCNAME'] else: os.environ['KRB5CCNAME'] = old_krb5ccname
def configure_automount(): try: check_client_configuration() except ScriptError as e: print(e.msg) sys.exit(e.rval) fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE) options, _args = parse_options() standard_logging_setup( paths.IPACLIENT_INSTALL_LOG, verbose=False, debug=options.debug, filemode='a', console_format='%(message)s', ) cfg = dict( context='cli_installer', confdir=paths.ETC_IPA, in_server=False, debug=options.debug, verbose=0, ) # Bootstrap API early so that env object is available api.bootstrap(**cfg) if options.uninstall: return uninstall(fstore, statestore) ca_cert_path = None if os.path.exists(paths.IPA_CA_CRT): ca_cert_path = paths.IPA_CA_CRT if statestore.has_state('autofs'): print('An automount location is already configured') sys.exit(CLIENT_ALREADY_CONFIGURED) autodiscover = False ds = ipadiscovery.IPADiscovery() if not options.server: print("Searching for IPA server...") ret = ds.search(ca_cert_path=ca_cert_path) logger.debug('Executing DNS discovery') if ret == ipadiscovery.NO_LDAP_SERVER: logger.debug('Autodiscovery did not find LDAP server') s = urlsplit(api.env.xmlrpc_uri) server = [s.netloc] logger.debug('Setting server to %s', s.netloc) else: autodiscover = True if not ds.servers: sys.exit( 'Autodiscovery was successful but didn\'t return a server' ) logger.debug( 'Autodiscovery success, possible servers %s', ','.join(ds.servers), ) server = ds.servers[0] else: server = options.server logger.debug("Verifying that %s is an IPA server", server) ldapret = ds.ipacheckldap(server, api.env.realm, ca_cert_path) if ldapret[0] == ipadiscovery.NO_ACCESS_TO_LDAP: print("Anonymous access to the LDAP server is disabled.") print("Proceeding without strict verification.") print( "Note: This is not an error if anonymous access has been " "explicitly restricted." ) elif ldapret[0] == ipadiscovery.NO_TLS_LDAP: logger.warning("Unencrypted access to LDAP is not supported.") elif ldapret[0] != 0: sys.exit('Unable to confirm that %s is an IPA server' % server) if not autodiscover: print("IPA server: %s" % server) logger.debug('Using fixed server %s', server) else: print("IPA server: DNS discovery") logger.debug('Configuring to use DNS discovery') print("Location: %s" % options.location) logger.debug('Using automount location %s', options.location) ccache_dir = tempfile.mkdtemp() ccache_name = os.path.join(ccache_dir, 'ccache') try: try: host_princ = str('host/%s@%s' % (api.env.host, api.env.realm)) kinit_keytab(host_princ, paths.KRB5_KEYTAB, ccache_name) os.environ['KRB5CCNAME'] = ccache_name except gssapi.exceptions.GSSError as e: sys.exit("Failed to obtain host TGT: %s" % e) # Finalize API when TGT obtained using host keytab exists api.finalize() # Now we have a TGT, connect to IPA try: api.Backend.rpcclient.connect() except errors.KerberosError as e: sys.exit('Cannot connect to the server due to ' + str(e)) try: # Use the RPC directly so older servers are supported api.Backend.rpcclient.forward( 'automountlocation_show', ipautil.fsdecode(options.location), version=u'2.0', ) except errors.VersionError as e: sys.exit('This client is incompatible: ' + str(e)) except errors.NotFound: sys.exit( "Automount location '%s' does not exist" % options.location ) except errors.PublicError as e: sys.exit( "Cannot connect to the server due to generic error: %s" % str(e) ) finally: shutil.rmtree(ccache_dir) if not options.unattended and not ipautil.user_input( "Continue to configure the system with these values?", False ): sys.exit("Installation aborted") try: if not options.sssd: tasks.enable_ldap_automount(statestore) configure_nfs(fstore, statestore, options) if options.sssd: configure_autofs_sssd(fstore, statestore, autodiscover, options) else: configure_xml(fstore) configure_autofs( fstore, statestore, autodiscover, server, options ) configure_autofs_common(fstore, statestore, options) except Exception as e: logger.debug('Raised exception %s', e) print("Installation failed. Rolling back changes.") uninstall(fstore, statestore) return 1 return 0
def run(): try: check_client_configuration() except ScriptError as e: print(e.msg) return e.rval fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE) options, _args = parse_options() logfile = paths.IPACLIENTSAMBA_INSTALL_LOG if options.uninstall: logfile = paths.IPACLIENTSAMBA_UNINSTALL_LOG standard_logging_setup( logfile, verbose=False, debug=options.debug, filemode="a", console_format="%(message)s", ) cfg = dict( context="cli_installer", confdir=paths.ETC_IPA, in_server=False, debug=options.debug, verbose=0, ) # Bootstrap API early so that env object is available api.bootstrap(**cfg) local_config = dict( host_princ=str("host/%s@%s" % (api.env.host, api.env.realm)), smb_princ=str("cifs/%s@%s" % (api.env.host, api.env.realm)), ) # Until api.finalize() is called, we can add our own configuration api.env._merge(**local_config) if options.uninstall: if statestore.has_state("domain_member"): uninstall(fstore, statestore, options) try: keys = ("configured", "hardening", "groupmap", "tdb", "service.principal", "smb.conf") for key in keys: statestore.delete_state("domain_member", key) except Exception as e: print("Error: Failed to remove the domain_member statestores: " "%s" % e) return 1 else: print("Samba configuration is reverted. " "However, Samba databases were fully cleaned and " "old configuration file will not be usable anymore.") else: print("Samba domain member is not configured yet") return 0 ca_cert_path = None if os.path.exists(paths.IPA_CA_CRT): ca_cert_path = paths.IPA_CA_CRT if statestore.has_state("domain_member") and not options.force: print("Samba domain member is already configured") return CLIENT_ALREADY_CONFIGURED if not os.path.exists(paths.SMBD): print("Samba suite is not installed") return CLIENT_NOT_CONFIGURED autodiscover = False ds = discovery.IPADiscovery() if not options.server: print("Searching for IPA server...") ret = ds.search(ca_cert_path=ca_cert_path) logger.debug("Executing DNS discovery") if ret == discovery.NO_LDAP_SERVER: logger.debug("Autodiscovery did not find LDAP server") s = urlsplit(api.env.xmlrpc_uri) server = [s.netloc] logger.debug("Setting server to %s", s.netloc) else: autodiscover = True if not ds.servers: print( "Autodiscovery was successful but didn't return a server") return 1 logger.debug( "Autodiscovery success, possible servers %s", ",".join(ds.servers), ) server = ds.servers[0] else: server = options.server logger.debug("Verifying that %s is an IPA server", server) ldapret = ds.ipacheckldap(server, api.env.realm, ca_cert_path) if ldapret[0] == discovery.NO_ACCESS_TO_LDAP: print("Anonymous access to the LDAP server is disabled.") print("Proceeding without strict verification.") print("Note: This is not an error if anonymous access has been " "explicitly restricted.") elif ldapret[0] == discovery.NO_TLS_LDAP: logger.warning("Unencrypted access to LDAP is not supported.") elif ldapret[0] != 0: print("Unable to confirm that %s is an IPA server" % server) return 1 if not autodiscover: print("IPA server: %s" % server) logger.debug("Using fixed server %s", server) else: print("IPA server: DNS discovery") logger.info("Configured to use DNS discovery") if api.env.host == server: logger.error("Cannot run on IPA master. " "Cannot configure Samba as a domain member on a domain " "controller. Please use ipa-adtrust-install for that!") return 1 if not options.netbiosname: options.netbiosname = DNSName.from_text(api.env.host)[0].decode() options.netbiosname = options.netbiosname.upper() with use_api_as_principal(api.env.host_princ, paths.KRB5_KEYTAB): try: # Try to access 'service_add_smb' command, if it throws # AttributeError exception, the IPA server doesn't support # setting up Samba as a domain member. service_add_smb = api.Command.service_add_smb # Now try to see if SMB principal already exists api.Command.service_show(api.env.smb_princ) # If no exception was raised, the object exists. # We cannot continue because we would break existing configuration print("WARNING: SMB service principal %s already exists. " "Please remove it before proceeding." % (api.env.smb_princ)) if not options.force: return 1 # For --force, we should then delete cifs/.. service object api.Command.service_del(api.env.smb_princ) except AttributeError: logger.error( "Chosen IPA master %s does not have support to " "set up Samba domain members", server, ) return 1 except errors.VersionError as e: print("This client is incompatible: " + str(e)) return 1 except errors.NotFound: logger.debug("No SMB service principal exists, OK to proceed") except errors.PublicError as e: logger.error( "Cannot connect to the server due to " "a generic error: %s", e, ) return 1 # At this point we have proper setup: # - we connected to IPA API end-point as a host principal # - no cifs/... principal exists so we can create it print("Chosen IPA master: %s" % server) print("SMB principal to be created: %s" % api.env.smb_princ) print("NetBIOS name to be used: %s" % options.netbiosname) logger.info("Chosen IPA master: %s", server) logger.info("SMB principal to be created: %s", api.env.smb_princ) logger.info("NetBIOS name to be used: %s", options.netbiosname) # 1. Pull down ID range and other details of known domains domains = retrieve_domain_information(api) if len(domains) == 0: # logger.error() produces both log file and stderr output logger.error("No configured trust controller detected " "on IPA masters. Use ipa-adtrust-install on an IPA " "master to configure trust controller role.") return 1 str_info = pretty_print_domain_information(domains) logger.info("Discovered domains to use:\n%s", str_info) print("Discovered domains to use:\n%s" % str_info) if not options.unattended and not ipautil.user_input( "Continue to configure the system with these values?", False): print("Installation aborted") return 1 # 2. Create SMB service principal, if we are here, the command exists if (not statestore.get_state("domain_member", "service.principal") or options.force): service_add_smb(api.env.host, options.netbiosname) statestore.backup_state("domain_member", "service.principal", "configured") # 3. Generate machine account password for reuse password = generate_smb_machine_account(fstore, statestore, options, domains[0]) # 4. Now that we have all domains retrieved, we can generate smb.conf if (not statestore.get_state("domain_member", "smb.conf") or options.force): configure_smb_conf(fstore, statestore, options, domains) statestore.backup_state("domain_member", "smb.conf", "configured") # 5. Create SMB service if statestore.get_state("domain_member", "service.principal") == "configured": retrieve_service_principal(fstore, statestore, options, domains[0], api.env.smb_princ, password) statestore.backup_state("domain_member", "service.principal", "configured") # 6. Configure databases to contain proper details if not statestore.get_state("domain_member", "tdb") or options.force: populate_samba_databases(fstore, statestore, options, domains[0], password) statestore.backup_state("domain_member", "tdb", "configured") # 7. Configure default group mapping if (not statestore.get_state("domain_member", "groupmap") or options.force): configure_default_groupmap(fstore, statestore, options, domains[0]) statestore.backup_state("domain_member", "groupmap", "configured") # 8. Enable SELinux policies if (not statestore.get_state("domain_member", "hardening") or options.force): harden_configuration(fstore, statestore, options, domains[0]) statestore.backup_state("domain_member", "hardening", "configured") # 9. Finally, store the state of upgrade statestore.backup_state("domain_member", "configured", True) # Suggest service start only after validating smb.conf print("Samba domain member is configured. " "Please check configuration at %s and " "start smb and winbind services" % paths.SMB_CONF) logger.info( "Samba domain member is configured. " "Please check configuration at %s and " "start smb and winbind services", paths.SMB_CONF, ) return 0