def connect(ldapi=False, realm=None, fqdn=None, dm_password=None): """Create a connection for updates""" ldap_uri = ipaldap.get_ldap_uri(fqdn, ldapi=ldapi, realm=realm) conn = ipaldap.LDAPClient(ldap_uri, decode_attrs=False) try: if dm_password: conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=dm_password) elif os.getegid() == 0: try: # autobind conn.external_bind() except errors.NotFound: # Fall back conn.gssapi_bind() else: conn.gssapi_bind() except (ldap.CONNECT_ERROR, ldap.SERVER_DOWN): raise RuntimeError("Unable to connect to LDAP server %s" % fqdn) except ldap.INVALID_CREDENTIALS: raise RuntimeError( "The password provided is incorrect for LDAP server %s" % fqdn) except ldap.LOCAL_ERROR as e: raise RuntimeError('%s' % e.args[0].get('info', '').strip()) return conn
def __upload_ca_cert(self): """ Upload the CA certificate from the NSS database to the LDAP directory. """ dirname = config_dirname(self.serverid) dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base) trust_flags = dict(reversed(dsdb.list_certs())) ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) nicknames = dsdb.find_root_cert(self.cacert_name)[:-1] for nickname in nicknames: cert = dsdb.get_cert_from_db(nickname, pem=False) certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname, trust_flags[nickname]) nickname = self.cacert_name cert = dsdb.get_cert_from_db(nickname, pem=False) certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname, trust_flags[nickname], config_ipa=self.ca_is_configured, config_compat=self.master_fqdn is None) conn.unbind()
def __setup_replica(self): """ Setup initial replication between replica and remote master. GSSAPI is always used as a replication bind method. Note, however, that the bind method for the replication differs between domain levels: * in domain level 0, Directory Manager credentials are used to bind to remote master * in domain level 1, GSSAPI using admin/privileged host credentials is used (we do not have access to masters' DM password in this stage) """ replication.enable_replication_version_checking( self.realm, self.dm_password) # Always connect to self over ldapi ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm) conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() repl = replication.ReplicationManager(self.realm, self.fqdn, self.dm_password, conn=conn) if self.dm_password is not None and not self.promote: bind_dn = DN(('cn', 'Directory Manager')) bind_pw = self.dm_password else: bind_dn = bind_pw = None repl.setup_promote_replication(self.master_fqdn, r_binddn=bind_dn, r_bindpw=bind_pw, cacert=self.ca_file) self.run_init_memberof = repl.needs_memberof_fixup()
def __upload_ca_cert(self): """ Upload the CA certificate from the NSS database to the LDAP directory. """ dirname = config_dirname(self.serverid) dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base) trust_flags = dict(reversed(dsdb.list_certs())) ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) nicknames = dsdb.find_root_cert(self.cacert_name)[:-1] for nickname in nicknames: cert = dsdb.get_cert_from_db(nickname, pem=False) certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname, trust_flags[nickname]) nickname = self.cacert_name cert = dsdb.get_cert_from_db(nickname, pem=False) certstore.put_ca_cert_nss( conn, self.suffix, cert, nickname, trust_flags[nickname], config_ipa=self.ca_is_configured, config_compat=self.master_fqdn is None, ) conn.unbind()
def __setup_replica(self): """ Setup initial replication between replica and remote master. GSSAPI is always used as a replication bind method. Note, however, that the bind method for the replication differs between domain levels: * in domain level 0, Directory Manager credentials are used to bind to remote master * in domain level 1, GSSAPI using admin/privileged host credentials is used (we do not have access to masters' DM password in this stage) """ replication.enable_replication_version_checking( self.realm, self.dm_password) # Always connect to self over ldapi ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm) conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() repl = replication.ReplicationManager(self.realm, self.fqdn, self.dm_password, conn=conn) if self.dm_password is not None and not self.promote: bind_dn = DN(('cn', 'Directory Manager')) bind_pw = self.dm_password else: bind_dn = bind_pw = None repl.setup_promote_replication(self.master_fqdn, r_binddn=bind_dn, r_bindpw=bind_pw, cacert=self.ca_file) self.run_init_memberof = repl.needs_memberof_fixup()
def dns_container_exists(fqdn, suffix, dm_password=None, ldapi=False, realm=None): """ Test whether the dns container exists. """ assert isinstance(suffix, DN) try: # At install time we may need to use LDAPI to avoid chicken/egg # issues with SSL certs and truting CAs ldap_uri = ipaldap.get_ldap_uri(fqdn, 636, ldapi=ldapi, realm=realm, cacert=CACERT) conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) conn.do_bind(dm_password) except ldap.SERVER_DOWN: raise RuntimeError( 'LDAP server on %s is not responding. Is IPA installed?' % fqdn) ret = conn.entry_exists(DN(('cn', 'dns'), suffix)) conn.unbind() return ret
def connect(ldapi=False, realm=None, fqdn=None, dm_password=None): """Create a connection for updates""" ldap_uri = ipaldap.get_ldap_uri(fqdn, ldapi=ldapi, realm=realm) conn = ipaldap.LDAPClient(ldap_uri, decode_attrs=False) try: if dm_password: conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=dm_password) elif os.getegid() == 0: try: # autobind conn.external_bind() except errors.NotFound: # Fall back conn.gssapi_bind() else: conn.gssapi_bind() except (ldap.CONNECT_ERROR, ldap.SERVER_DOWN): raise RuntimeError("Unable to connect to LDAP server %s" % fqdn) except ldap.INVALID_CREDENTIALS: raise RuntimeError( "The password provided is incorrect for LDAP server %s" % fqdn) except ldap.LOCAL_ERROR as e: raise RuntimeError('%s' % e.args[0].get('info', '').strip()) return conn
def __get_ds_cert(self): subject = self.subject_base or DN(('O', self.realm)) nssdb_dir = config_dirname(self.serverid) db = certs.CertDB(self.realm, nssdir=nssdb_dir, subject_base=subject) db.create_from_cacert(paths.IPA_CA_CRT) db.request_service_cert(self.nickname, self.principal, self.fqdn) db.create_pin_file() # Connect to self over ldapi as Directory Manager and configure SSL ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm) conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"), (ldap.MOD_REPLACE, "nsSSL3Ciphers", "default"), (ldap.MOD_REPLACE, "allowWeakCipher", "off")] conn.modify_s(DN(('cn', 'encryption'), ('cn', 'config')), mod) mod = [(ldap.MOD_ADD, "nsslapd-security", "on")] conn.modify_s(DN(('cn', 'config')), mod) entry = conn.make_entry( DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')), objectclass=["top", "nsEncryptionModule"], cn=["RSA"], nsSSLPersonalitySSL=[self.nickname], nsSSLToken=["internal (software)"], nsSSLActivation=["on"], ) conn.add_entry(entry) conn.unbind() # check for open secure port 636 from now on self.open_ports.append(636)
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_with_args(api): """ Run the certupdate procedure with the given API object. :param api: API object with ldap2/rpcclient backend connected (such that Commands can be invoked) """ 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') old_krb5ccname = os.environ.get('KRB5CCNAME') 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 try: result = api.Command.ca_is_enabled(version=u'2.107') ca_enabled = result['result'] except (errors.CommandError, errors.NetworkError): result = api.Command.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 = [] finally: if old_krb5ccname is None: del os.environ['KRB5CCNAME'] else: os.environ['KRB5CCNAME'] = old_krb5ccname shutil.rmtree(tmpdir) server_fstore = sysrestore.FileStore(paths.SYSRESTORE) if server_fstore.has_files(): 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") update_client(certs)
def run_with_args(api): """ Run the certupdate procedure with the given API object. :param api: API object with ldap2/rpcclient backend connected (such that Commands can be invoked) """ 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') old_krb5ccname = os.environ.get('KRB5CCNAME') 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 try: result = api.Command.ca_is_enabled(version=u'2.107') ca_enabled = result['result'] except (errors.CommandError, errors.NetworkError): result = api.Command.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 = [] finally: if old_krb5ccname is None: del os.environ['KRB5CCNAME'] else: os.environ['KRB5CCNAME'] = old_krb5ccname shutil.rmtree(tmpdir) server_fstore = sysrestore.FileStore(paths.SYSRESTORE) if server_fstore.has_files(): 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") update_client(certs)
def _wait_for_replica_kdc_entry(self): master_dn = self.api.Object.server.get_dn(self.fqdn) kdc_dn = DN(('cn', 'KDC'), master_dn) ldap_uri = ipaldap.get_ldap_uri(self.master_fqdn) with ipaldap.LDAPClient(ldap_uri, cacert=paths.IPA_CA_CRT, start_tls=True) as remote_ldap: remote_ldap.gssapi_bind() replication.wait_for_entry( remote_ldap, kdc_dn, timeout=api.env.replication_wait_timeout)
def ldap_connect(self): """Return an LDAPClient authenticated to this host as directory manager """ self.log.info('Connecting to LDAP at %s', self.external_hostname) ldap_uri = ipaldap.get_ldap_uri(self.external_hostname) ldap = ipaldap.LDAPClient(ldap_uri) binddn = self.config.dirman_dn self.log.info('LDAP bind as %s' % binddn) ldap.simple_bind(binddn, self.config.dirman_password) return ldap
def __import_ca_certs(self): dirname = config_dirname(self.serverid) dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base) ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) self.import_ca_certs(dsdb, self.ca_is_configured, conn) conn.unbind()
def get_domain_level(api=api): ldap_uri = ipaldap.get_ldap_uri(protocol="ldapi", realm=api.env.realm) conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() dn = DN(("cn", "Domain Level"), ("cn", "ipa"), ("cn", "etc"), api.env.basedn) try: entry = conn.get_entry(dn, ["ipaDomainLevel"]) except errors.NotFound: return constants.DOMAIN_LEVEL_0 return int(entry.single_value["ipaDomainLevel"])
def get_domain_level(api=api): ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() dn = DN(('cn', 'Domain Level'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) try: entry = conn.get_entry(dn, ['ipaDomainLevel']) except errors.NotFound: return constants.DOMAIN_LEVEL_0 return int(entry.single_value['ipaDomainLevel'])
def __import_ca_certs(self): dirname = config_dirname(self.serverid) dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base) ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) self.import_ca_certs(dsdb, self.ca_is_configured, conn) conn.unbind()
def _wait_for_replica_kdc_entry(self): master_dn = self.api.Object.server.get_dn(self.fqdn) kdc_dn = DN(('cn', 'KDC'), master_dn) ldap_uri = ipaldap.get_ldap_uri(self.master_fqdn) with ipaldap.LDAPClient( ldap_uri, cacert=paths.IPA_CA_CRT, start_tls=True ) as remote_ldap: remote_ldap.gssapi_bind() replication.wait_for_entry( remote_ldap, kdc_dn, timeout=api.env.replication_wait_timeout )
def get_domain_level(api=api): ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() dn = DN(('cn', 'Domain Level'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) try: entry = conn.get_entry(dn, ['ipaDomainLevel']) except errors.NotFound: return constants.DOMAIN_LEVEL_0 return int(entry.single_value['ipaDomainLevel'])
def request_service_keytab(self): super(HTTPInstance, self).request_service_keytab() if self.master_fqdn is not None: service_dn = DN(('krbprincipalname', self.principal), api.env.container_service, self.suffix) ldap_uri = ipaldap.get_ldap_uri(self.master_fqdn) with ipaldap.LDAPClient(ldap_uri, start_tls=not self.promote, cacert=paths.IPA_CA_CRT) as remote_ldap: if self.promote: remote_ldap.gssapi_bind() else: remote_ldap.simple_bind(ipaldap.DIRMAN_DN, self.dm_password) replication.wait_for_entry(remote_ldap, service_dn, timeout=60)
def get_connection(self): ''' Create an ldapi connection and bind to it using autobind as root. ''' if self._conn is not None: return self._conn ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) self._conn = ipaldap.LDAPClient(ldap_uri) try: self._conn.external_bind() except Exception as e: logger.error("Unable to bind to LDAP server %s: %s", self._conn.host, e) return self._conn
def get_connection(self): ''' Create an ldapi connection and bind to it using autobind as root. ''' if self._conn is not None: return self._conn ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) self._conn = ipaldap.LDAPClient(ldap_uri) try: self._conn.external_bind() except Exception as e: logger.error("Unable to bind to LDAP server %s: %s", self._conn.host, e) return self._conn
def request_service_keytab(self): super(HTTPInstance, self).request_service_keytab() if self.master_fqdn is not None: service_dn = DN(('krbprincipalname', self.principal), api.env.container_service, self.suffix) ldap_uri = ipaldap.get_ldap_uri(self.master_fqdn) with ipaldap.LDAPClient(ldap_uri, start_tls=not self.promote, cacert=paths.IPA_CA_CRT) as remote_ldap: if self.promote: remote_ldap.gssapi_bind() else: remote_ldap.simple_bind(ipaldap.DIRMAN_DN, self.dm_password) replication.wait_for_entry(remote_ldap, service_dn, timeout=60)
def init_memberof(self): if not self.run_init_memberof: return self._ldap_mod("memberof-task.ldif", self.sub_dict) # Note, keep dn in sync with dn in install/share/memberof-task.ldif dn = DN(('cn', 'IPA install %s' % self.sub_dict["TIME"]), ('cn', 'memberof task'), ('cn', 'tasks'), ('cn', 'config')) logger.debug("Waiting for memberof task to complete.") ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) if self.dm_password: conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) else: conn.gssapi_bind() replication.wait_for_task(conn, dn) conn.unbind()
def init_memberof(self): if not self.run_init_memberof: return self._ldap_mod("memberof-task.ldif", self.sub_dict) # Note, keep dn in sync with dn in install/share/memberof-task.ldif dn = DN(('cn', 'IPA install %s' % self.sub_dict["TIME"]), ('cn', 'memberof task'), ('cn', 'tasks'), ('cn', 'config')) root_logger.debug("Waiting for memberof task to complete.") ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) if self.dm_password: conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) else: conn.gssapi_bind() replication.wait_for_task(conn, dn) conn.unbind()
def __upload_ca_cert(self): """ Upload the CA certificate from the NSS database to the LDAP directory. """ dirname = config_dirname(self.serverid) dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base) trust_flags = dict(reversed(dsdb.list_certs())) ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) nicknames = dsdb.find_root_cert(self.cacert_name)[:-1] for nickname in nicknames: cert = dsdb.get_cert_from_db(nickname) certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname, trust_flags[nickname]) nickname = self.cacert_name cert = dsdb.get_cert_from_db(nickname) cacert_flags = trust_flags[nickname] if self.setup_pkinit: cacert_flags = TrustFlags( cacert_flags.has_key, cacert_flags.trusted, cacert_flags.ca, (cacert_flags.usages | {x509.EKU_PKINIT_CLIENT_AUTH, x509.EKU_PKINIT_KDC}), ) certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname, cacert_flags, config_ipa=self.ca_is_configured, config_compat=self.master_fqdn is None) conn.unbind()
def dns_container_exists(fqdn, suffix, dm_password=None, ldapi=False, realm=None): """ Test whether the dns container exists. """ assert isinstance(suffix, DN) try: # At install time we may need to use LDAPI to avoid chicken/egg # issues with SSL certs and truting CAs ldap_uri = ipaldap.get_ldap_uri(fqdn, 636, ldapi=ldapi, realm=realm, cacert=CACERT) conn = ipaldap.LDAPClient(ldap_uri, cacert=CACERT) conn.do_bind(dm_password) except ldap.SERVER_DOWN: raise RuntimeError('LDAP server on %s is not responding. Is IPA installed?' % fqdn) ret = conn.entry_exists(DN(('cn', 'dns'), suffix)) conn.unbind() return ret
def setUp(self): fqdn = installutils.get_fqdn() pwfile = api.env.dot_ipa + os.sep + ".dmpw" if os.path.isfile(pwfile): fp = open(pwfile, "r") self.dm_password = fp.read().rstrip() fp.close() else: raise unittest.SkipTest("No directory manager password") self.updater = LDAPUpdate(dm_password=self.dm_password, sub_dict={}) ldap_uri = ipaldap.get_ldap_uri(fqdn) self.ld = ipaldap.LDAPClient(ldap_uri) self.ld.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) self.testdir = os.path.abspath(os.path.dirname(__file__)) if not os.path.isfile(os.path.join(self.testdir, "0_reset.update")): raise unittest.SkipTest("Unable to find test update files") self.container_dn = DN(self.updater._template_str('cn=test, cn=accounts, $SUFFIX')) self.user_dn = DN(self.updater._template_str('uid=tuser, cn=test, cn=accounts, $SUFFIX'))
def get_connection(self): ''' Create an ldapi connection and bind to it using autobind as root. ''' instance_name = installutils.realm_to_serverid(api.env.realm) if not services.knownservices.dirsrv.is_running(instance_name): raise admintool.ScriptError( "directory server instance is not running/configured") if self._conn is not None: return self._conn ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) self._conn = ipaldap.LDAPClient(ldap_uri) try: self._conn.external_bind() except Exception as e: raise admintool.ScriptError('Unable to bind to LDAP server: %s' % e) return self._conn
def get_admin_cert(self): """ Get the certificate for the admin user by checking the ldap entry for the user. There should be only one certificate per user. """ self.log.debug('Trying to find the certificate for the admin user') conn = None try: ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm) conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() entry_attrs = conn.get_entry(self.admin_dn, ['usercertificate']) admin_cert = entry_attrs.get('usercertificate')[0] # TODO(edewata) Add check to warn if there is more than one cert. finally: if conn is not None: conn.unbind() return base64.b64encode(admin_cert)
def get_admin_cert(self): """ Get the certificate for the admin user by checking the ldap entry for the user. There should be only one certificate per user. """ logger.debug('Trying to find the certificate for the admin user') conn = None try: ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm) conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() entry_attrs = conn.get_entry(self.admin_dn, ['usercertificate']) admin_cert = entry_attrs.get('usercertificate')[0] # TODO(edewata) Add check to warn if there is more than one cert. finally: if conn is not None: conn.unbind() return admin_cert
def __upload_ca_cert(self): """ Upload the CA certificate from the NSS database to the LDAP directory. """ dirname = config_dirname(self.serverid) dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base) trust_flags = dict(reversed(dsdb.list_certs())) ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) nicknames = dsdb.find_root_cert(self.cacert_name)[:-1] for nickname in nicknames: cert = dsdb.get_cert_from_db(nickname) certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname, trust_flags[nickname]) nickname = self.cacert_name cert = dsdb.get_cert_from_db(nickname) cacert_flags = trust_flags[nickname] if self.setup_pkinit: cacert_flags = TrustFlags( cacert_flags.has_key, cacert_flags.trusted, cacert_flags.ca, (cacert_flags.usages | {x509.EKU_PKINIT_CLIENT_AUTH, x509.EKU_PKINIT_KDC}), ) certstore.put_ca_cert_nss(conn, self.suffix, cert, nickname, cacert_flags, config_ipa=self.ca_is_configured, config_compat=self.master_fqdn is None) conn.unbind()
def get_connection(self): ''' Create an ldapi connection and bind to it using autobind as root. ''' instance_name = installutils.realm_to_serverid(api.env.realm) if not services.knownservices.dirsrv.is_running(instance_name): raise admintool.ScriptError( "directory server instance is not running/configured" ) if self._conn is not None: return self._conn ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm) self._conn = ipaldap.LDAPClient(ldap_uri) try: self._conn.external_bind() except Exception as e: raise admintool.ScriptError('Unable to bind to LDAP server: %s' % e) return self._conn
def setUp(self): fqdn = installutils.get_fqdn() pwfile = api.env.dot_ipa + os.sep + ".dmpw" if os.path.isfile(pwfile): fp = open(pwfile, "r") self.dm_password = fp.read().rstrip() fp.close() else: raise nose.SkipTest("No directory manager password") self.updater = LDAPUpdate(dm_password=self.dm_password, sub_dict={}) ldap_uri = ipaldap.get_ldap_uri(fqdn) self.ld = ipaldap.LDAPClient(ldap_uri) self.ld.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) self.testdir = os.path.abspath(os.path.dirname(__file__)) if not os.path.isfile(os.path.join(self.testdir, "0_reset.update")): raise nose.SkipTest("Unable to find test update files") self.container_dn = DN( self.updater._template_str('cn=test, cn=accounts, $SUFFIX')) self.user_dn = DN( self.updater._template_str( 'uid=tuser, cn=test, cn=accounts, $SUFFIX'))
def __get_ds_cert(self): subject = self.subject_base or DN(("O", self.realm)) nssdb_dir = config_dirname(self.serverid) db = certs.CertDB(self.realm, nssdir=nssdb_dir, subject_base=subject) db.create_from_cacert(paths.IPA_CA_CRT) db.request_service_cert(self.nickname, self.principal, self.fqdn) db.create_pin_file() # Connect to self over ldapi as Directory Manager and configure SSL ldap_uri = ipaldap.get_ldap_uri(protocol="ldapi", realm=self.realm) conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() mod = [ (ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"), (ldap.MOD_REPLACE, "nsSSL3Ciphers", "default"), (ldap.MOD_REPLACE, "allowWeakCipher", "off"), ] conn.modify_s(DN(("cn", "encryption"), ("cn", "config")), mod) mod = [(ldap.MOD_ADD, "nsslapd-security", "on")] conn.modify_s(DN(("cn", "config")), mod) entry = conn.make_entry( DN(("cn", "RSA"), ("cn", "encryption"), ("cn", "config")), objectclass=["top", "nsEncryptionModule"], cn=["RSA"], nsSSLPersonalitySSL=[self.nickname], nsSSLToken=["internal (software)"], nsSSLActivation=["on"], ) conn.add_entry(entry) conn.unbind() # check for open secure port 636 from now on self.open_ports.append(636)
def setup_admin(self): self.admin_user = "******" % self.fqdn self.admin_password = ipautil.ipa_generate_password() self.admin_dn = DN(('uid', self.admin_user), ('ou', 'people'), ('o', 'ipaca')) # remove user if left-over exists try: entry = api.Backend.ldap2.delete_entry(self.admin_dn) except errors.NotFound: pass # add user entry = api.Backend.ldap2.make_entry( self.admin_dn, objectclass=[ "top", "person", "organizationalPerson", "inetOrgPerson", "cmsuser" ], uid=[self.admin_user], cn=[self.admin_user], sn=[self.admin_user], usertype=['adminType'], mail=['root@localhost'], userPassword=[self.admin_password], userstate=['1']) api.Backend.ldap2.add_entry(entry) for group in self.admin_groups: self.__add_admin_to_group(group) # Now wait until the other server gets replicated this data ldap_uri = ipaldap.get_ldap_uri(self.master_host) master_conn = ipaldap.LDAPClient(ldap_uri) master_conn.gssapi_bind() replication.wait_for_entry(master_conn, entry.dn) del master_conn
def setup_admin(self): self.admin_user = "******" % self.fqdn self.admin_password = binascii.hexlify(os.urandom(16)) self.admin_dn = DN(('uid', self.admin_user), ('ou', 'people'), ('o', 'ipaca')) # remove user if left-over exists try: entry = api.Backend.ldap2.delete_entry(self.admin_dn) except errors.NotFound: pass # add user entry = api.Backend.ldap2.make_entry( self.admin_dn, objectclass=["top", "person", "organizationalPerson", "inetOrgPerson", "cmsuser"], uid=[self.admin_user], cn=[self.admin_user], sn=[self.admin_user], usertype=['adminType'], mail=['root@localhost'], userPassword=[self.admin_password], userstate=['1'] ) api.Backend.ldap2.add_entry(entry) for group in self.admin_groups: self.__add_admin_to_group(group) # Now wait until the other server gets replicated this data ldap_uri = ipaldap.get_ldap_uri(self.master_host) master_conn = ipaldap.LDAPClient(ldap_uri) master_conn.gssapi_bind() replication.wait_for_entry(master_conn, entry) del master_conn
def __enable_ssl(self): dirname = config_dirname(self.serverid) dsdb = certs.CertDB( self.realm, nssdir=dirname, subject_base=self.subject_base, ca_subject=self.ca_subject, ) if self.pkcs12_info: if self.ca_is_configured: trust_flags = IPA_CA_TRUST_FLAGS else: trust_flags = EXTERNAL_CA_TRUST_FLAGS dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], ca_file=self.ca_file, trust_flags=trust_flags) server_certs = dsdb.find_server_certs() if len(server_certs) == 0: raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0]) # We only handle one server cert self.nickname = server_certs[0][0] self.cert = dsdb.get_cert_from_db(self.nickname) if self.ca_is_configured: dsdb.track_server_cert( self.nickname, self.principal, dsdb.passwd_fname, 'restart_dirsrv %s' % self.serverid) self.add_cert_to_service() else: dsdb.create_from_cacert() if self.master_fqdn is None: ca_args = [ paths.CERTMONGER_DOGTAG_SUBMIT, '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn, '--certfile', paths.RA_AGENT_PEM, '--keyfile', paths.RA_AGENT_KEY, '--cafile', paths.IPA_CA_CRT, '--agent-submit' ] helper = " ".join(ca_args) prev_helper = certmonger.modify_ca_helper('IPA', helper) else: prev_helper = None try: cmd = 'restart_dirsrv %s' % self.serverid certmonger.request_and_wait_for_cert( certpath=dirname, nickname=self.nickname, principal=self.principal, passwd_fname=dsdb.passwd_fname, subject=str(DN(('CN', self.fqdn), self.subject_base)), ca='IPA', profile=dogtag.DEFAULT_PROFILE, dns=[self.fqdn], post_command=cmd) finally: if prev_helper is not None: certmonger.modify_ca_helper('IPA', prev_helper) # restart_dirsrv in the request above restarts DS, reconnect ldap2 api.Backend.ldap2.disconnect() api.Backend.ldap2.connect() self.cert = dsdb.get_cert_from_db(self.nickname) if prev_helper is not None: self.add_cert_to_service() dsdb.create_pin_file() self.cacert_name = dsdb.cacert_name ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"), (ldap.MOD_REPLACE, "nsSSL3Ciphers", "default"), (ldap.MOD_REPLACE, "allowWeakCipher", "off")] conn.modify_s(DN(('cn', 'encryption'), ('cn', 'config')), mod) mod = [(ldap.MOD_ADD, "nsslapd-security", "on")] conn.modify_s(DN(('cn', 'config')), mod) entry = conn.make_entry( DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')), objectclass=["top", "nsEncryptionModule"], cn=["RSA"], nsSSLPersonalitySSL=[self.nickname], nsSSLToken=["internal (software)"], nsSSLActivation=["on"], ) conn.add_entry(entry) conn.unbind() # check for open secure port 636 from now on self.open_ports.append(636)
def __enable_ssl(self): dirname = config_dirname(self.serverid) dsdb = certs.CertDB( self.realm, nssdir=dirname, subject_base=self.subject_base, ca_subject=self.ca_subject, ) if self.pkcs12_info: if self.ca_is_configured: trust_flags = IPA_CA_TRUST_FLAGS else: trust_flags = EXTERNAL_CA_TRUST_FLAGS dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], ca_file=self.ca_file, trust_flags=trust_flags) server_certs = dsdb.find_server_certs() if len(server_certs) == 0: raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0]) # We only handle one server cert self.nickname = server_certs[0][0] self.cert = dsdb.get_cert_from_db(self.nickname) if self.ca_is_configured: dsdb.track_server_cert( self.nickname, self.principal, dsdb.passwd_fname, 'restart_dirsrv %s' % self.serverid) self.add_cert_to_service() else: dsdb.create_from_cacert() if self.master_fqdn is None: ca_args = [ paths.CERTMONGER_DOGTAG_SUBMIT, '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn, '--certfile', paths.RA_AGENT_PEM, '--keyfile', paths.RA_AGENT_KEY, '--cafile', paths.IPA_CA_CRT, '--agent-submit' ] helper = " ".join(ca_args) prev_helper = certmonger.modify_ca_helper('IPA', helper) else: prev_helper = None try: cmd = 'restart_dirsrv %s' % self.serverid certmonger.request_and_wait_for_cert( certpath=dirname, storage='NSSDB', nickname=self.nickname, principal=self.principal, passwd_fname=dsdb.passwd_fname, subject=str(DN(('CN', self.fqdn), self.subject_base)), ca='IPA', profile=dogtag.DEFAULT_PROFILE, dns=[self.fqdn], post_command=cmd ) finally: if prev_helper is not None: certmonger.modify_ca_helper('IPA', prev_helper) # restart_dirsrv in the request above restarts DS, reconnect ldap2 api.Backend.ldap2.disconnect() api.Backend.ldap2.connect() self.cert = dsdb.get_cert_from_db(self.nickname) if prev_helper is not None: self.add_cert_to_service() dsdb.create_pin_file() self.cacert_name = dsdb.cacert_name ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"), (ldap.MOD_REPLACE, "nsSSL3Ciphers", "default"), (ldap.MOD_REPLACE, "allowWeakCipher", "off")] conn.modify_s(DN(('cn', 'encryption'), ('cn', 'config')), mod) mod = [(ldap.MOD_ADD, "nsslapd-security", "on")] conn.modify_s(DN(('cn', 'config')), mod) entry = conn.make_entry( DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')), objectclass=["top", "nsEncryptionModule"], cn=["RSA"], nsSSLPersonalitySSL=[self.nickname], nsSSLToken=["internal (software)"], nsSSLActivation=["on"], ) try: conn.add_entry(entry) except errors.DuplicateEntry: # 389-DS >= 1.4.0 has a default entry, update it. conn.update_entry(entry) conn.unbind() # check for open secure port 636 from now on self.open_ports.append(636)
def run(self): fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) if (not fstore.has_files() and not os.path.exists(paths.IPA_DEFAULT_CONF)): raise admintool.ScriptError( "IPA client is not configured on this system.") api.bootstrap(context='cli_installer') 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)) ipautil.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: from ipaserver.install import cainstance cainstance.add_lightweight_ca_tracking_requests( self.log, lwcas) except Exception: self.log.exception( "Failed to add lightweight CA tracking requests") self.update_client(certs)
def setup_admin(self): self.admin_user = "******" % self.fqdn self.admin_password = ipautil.ipa_generate_password() self.admin_dn = DN( ('uid', self.admin_user), self.ipaca_people ) # remove user if left-over exists try: api.Backend.ldap2.delete_entry(self.admin_dn) except errors.NotFound: pass # add user entry = api.Backend.ldap2.make_entry( self.admin_dn, objectclass=["top", "person", "organizationalPerson", "inetOrgPerson", "cmsuser"], uid=[self.admin_user], cn=[self.admin_user], sn=[self.admin_user], usertype=['adminType'], mail=['root@localhost'], userPassword=[self.admin_password], userstate=['1'] ) api.Backend.ldap2.add_entry(entry) wait_groups = [] for group in self.admin_groups: group_dn = DN(('cn', group), self.ipaca_groups) mod = [(ldap.MOD_ADD, 'uniqueMember', [self.admin_dn])] try: api.Backend.ldap2.modify_s(group_dn, mod) except ldap.TYPE_OR_VALUE_EXISTS: # already there return None else: wait_groups.append(group_dn) # Now wait until the other server gets replicated this data ldap_uri = ipaldap.get_ldap_uri(self.master_host) master_conn = ipaldap.LDAPClient(ldap_uri, start_tls=True) logger.debug( "Waiting for %s to appear on %s", self.admin_dn, master_conn ) deadline = time.time() + api.env.replication_wait_timeout while time.time() < deadline: time.sleep(1) try: master_conn.simple_bind(self.admin_dn, self.admin_password) except errors.ACIError: # user not replicated yet pass else: logger.debug("Successfully logged in as %s", self.admin_dn) break else: logger.error( "Unable to log in as %s on %s", self.admin_dn, master_conn ) raise errors.NotFound( reason="{} did not replicate to {}".format( self.admin_dn, master_conn ) ) # wait for group membership for group_dn in wait_groups: replication.wait_for_entry( master_conn, group_dn, timeout=api.env.replication_wait_timeout, attr='uniqueMember', attrvalue=self.admin_dn )
def ipacheckldap(self, thost, trealm, ca_cert_path=None): """ Given a host and kerberos realm verify that it is an IPA LDAP server hosting the realm. Returns a list [errno, host, realm] or an empty list on error. Errno is an error number: 0 means all ok 1 means we could not check the info in LDAP (may happend when anonymous binds are disabled) 2 means the server is certainly not an IPA server """ lrealms = [] #now verify the server is really an IPA server try: ldap_uri = ipaldap.get_ldap_uri(thost) start_tls = False if ca_cert_path: start_tls = True root_logger.debug("Init LDAP connection to: %s", ldap_uri) lh = ipaldap.LDAPClient( ldap_uri, cacert=ca_cert_path, start_tls=start_tls, no_schema=True, decode_attrs=False) try: lh.simple_bind(DN(), '') # get IPA base DN root_logger.debug("Search LDAP server for IPA base DN") basedn = get_ipa_basedn(lh) except errors.ACIError: root_logger.debug("LDAP Error: Anonymous access not allowed") return [NO_ACCESS_TO_LDAP] except errors.DatabaseError as err: root_logger.error("Error checking LDAP: %s" % err.strerror) # We should only get UNWILLING_TO_PERFORM if the remote LDAP # server has minssf > 0 and we have attempted a non-TLS conn. if ca_cert_path is None: root_logger.debug( "Cannot connect to LDAP server. Check that minssf is " "not enabled") return [NO_TLS_LDAP] else: return [UNKNOWN_ERROR] if basedn is None: root_logger.debug("The server is not an IPA server") return [NOT_IPA_SERVER] self.basedn = basedn self.basedn_source = 'From IPA server %s' % lh.ldap_uri #search and return known realms root_logger.debug( "Search for (objectClass=krbRealmContainer) in %s (sub)", self.basedn) try: lret = lh.get_entries( DN(('cn', 'kerberos'), self.basedn), lh.SCOPE_SUBTREE, "(objectClass=krbRealmContainer)") except errors.NotFound: #something very wrong return [REALM_NOT_FOUND] for lres in lret: root_logger.debug("Found: %s", lres.dn) [cn] = lres.raw['cn'] if six.PY3: cn = cn.decode('utf-8') lrealms.append(cn) if trealm: for r in lrealms: if trealm == r: return [0, thost, trealm] # must match or something is very wrong root_logger.debug("Realm %s does not match any realm in LDAP " "database", trealm) return [REALM_NOT_FOUND] else: if len(lrealms) != 1: #which one? we can't attach to a multi-realm server without DNS working root_logger.debug("Multiple realms found, cannot decide " "which realm is the right without " "working DNS") return [REALM_NOT_FOUND] else: return [0, thost, lrealms[0]] #we shouldn't get here assert False, "Unknown error in ipadiscovery" except errors.DatabaseTimeout: root_logger.debug("LDAP Error: timeout") return [NO_LDAP_SERVER] except errors.NetworkError as err: root_logger.debug("LDAP Error: %s" % err.strerror) return [NO_LDAP_SERVER] except errors.ACIError: root_logger.debug("LDAP Error: Anonymous access not allowed") return [NO_ACCESS_TO_LDAP] except errors.DatabaseError as err: root_logger.debug("Error checking LDAP: %s" % err.strerror) return [UNKNOWN_ERROR] except Exception as err: root_logger.debug("Error checking LDAP: %s" % err) return [UNKNOWN_ERROR]
def run(self): fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) if (not fstore.has_files() and not os.path.exists(paths.IPA_DEFAULT_CONF)): raise admintool.ScriptError( "IPA client is not configured on this system.") 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 ipacheckldap(self, thost, trealm, ca_cert_path=None): """ Given a host and kerberos realm verify that it is an IPA LDAP server hosting the realm. Returns a list [errno, host, realm] or an empty list on error. Errno is an error number: 0 means all ok 1 means we could not check the info in LDAP (may happend when anonymous binds are disabled) 2 means the server is certainly not an IPA server """ lrealms = [] #now verify the server is really an IPA server try: ldap_uri = ipaldap.get_ldap_uri(thost) start_tls = False if ca_cert_path: start_tls = True logger.debug("Init LDAP connection to: %s", ldap_uri) lh = ipaldap.LDAPClient(ldap_uri, cacert=ca_cert_path, start_tls=start_tls, no_schema=True, decode_attrs=False) try: lh.simple_bind(DN(), '') # get IPA base DN logger.debug("Search LDAP server for IPA base DN") basedn = get_ipa_basedn(lh) except errors.ACIError: logger.debug("LDAP Error: Anonymous access not allowed") return [NO_ACCESS_TO_LDAP] except errors.DatabaseError as err: logger.error("Error checking LDAP: %s", err.strerror) # We should only get UNWILLING_TO_PERFORM if the remote LDAP # server has minssf > 0 and we have attempted a non-TLS conn. if ca_cert_path is None: logger.debug( "Cannot connect to LDAP server. Check that minssf is " "not enabled") return [NO_TLS_LDAP] else: return [UNKNOWN_ERROR] if basedn is None: logger.debug("The server is not an IPA server") return [NOT_IPA_SERVER] self.basedn = basedn self.basedn_source = 'From IPA server %s' % lh.ldap_uri #search and return known realms logger.debug( "Search for (objectClass=krbRealmContainer) in %s (sub)", self.basedn) try: lret = lh.get_entries(DN(('cn', 'kerberos'), self.basedn), lh.SCOPE_SUBTREE, "(objectClass=krbRealmContainer)") except errors.NotFound: #something very wrong return [REALM_NOT_FOUND] for lres in lret: logger.debug("Found: %s", lres.dn) [cn] = lres.raw['cn'] if six.PY3: cn = cn.decode('utf-8') lrealms.append(cn) if trealm: for r in lrealms: if trealm == r: return [0, thost, trealm] # must match or something is very wrong logger.debug( "Realm %s does not match any realm in LDAP " "database", trealm) return [REALM_NOT_FOUND] else: if len(lrealms) != 1: #which one? we can't attach to a multi-realm server without DNS working logger.debug("Multiple realms found, cannot decide " "which realm is the right without " "working DNS") return [REALM_NOT_FOUND] else: return [0, thost, lrealms[0]] #we shouldn't get here assert False, "Unknown error in ipadiscovery" except errors.DatabaseTimeout: logger.debug("LDAP Error: timeout") return [NO_LDAP_SERVER] except errors.NetworkError as err: logger.debug("LDAP Error: %s", err.strerror) return [NO_LDAP_SERVER] except errors.ACIError: logger.debug("LDAP Error: Anonymous access not allowed") return [NO_ACCESS_TO_LDAP] except errors.DatabaseError as err: logger.debug("Error checking LDAP: %s", err.strerror) return [UNKNOWN_ERROR] except Exception as err: logger.debug("Error checking LDAP: %s", err) return [UNKNOWN_ERROR]
def setup_admin(self): self.admin_user = "******" % self.fqdn self.admin_password = ipautil.ipa_generate_password() self.admin_dn = DN(('uid', self.admin_user), self.ipaca_people) # remove user if left-over exists try: api.Backend.ldap2.delete_entry(self.admin_dn) except errors.NotFound: pass # add user entry = api.Backend.ldap2.make_entry( self.admin_dn, objectclass=[ "top", "person", "organizationalPerson", "inetOrgPerson", "cmsuser" ], uid=[self.admin_user], cn=[self.admin_user], sn=[self.admin_user], usertype=['adminType'], mail=['root@localhost'], userPassword=[self.admin_password], userstate=['1']) api.Backend.ldap2.add_entry(entry) wait_groups = [] for group in self.admin_groups: group_dn = DN(('cn', group), self.ipaca_groups) mod = [(ldap.MOD_ADD, 'uniqueMember', [self.admin_dn])] try: api.Backend.ldap2.modify_s(group_dn, mod) except ldap.TYPE_OR_VALUE_EXISTS: # already there return None else: wait_groups.append(group_dn) # Now wait until the other server gets replicated this data ldap_uri = ipaldap.get_ldap_uri(self.master_host) master_conn = ipaldap.LDAPClient(ldap_uri, start_tls=True) logger.debug("Waiting for %s to appear on %s", self.admin_dn, master_conn) deadline = time.time() + api.env.replication_wait_timeout while time.time() < deadline: time.sleep(1) try: master_conn.simple_bind(self.admin_dn, self.admin_password) except errors.ACIError: # user not replicated yet pass else: logger.debug("Successfully logged in as %s", self.admin_dn) break else: logger.error("Unable to log in as %s on %s", self.admin_dn, master_conn) raise errors.NotFound(reason="{} did not replicate to {}".format( self.admin_dn, master_conn)) # wait for group membership for group_dn in wait_groups: replication.wait_for_entry( master_conn, group_dn, timeout=api.env.replication_wait_timeout, attr='uniqueMember', attrvalue=self.admin_dn)
def replica_ds_init_info(ansible_log, config, options, ca_is_configured, remote_api, ds_ca_subject, ca_file, promote=False, pkcs12_info=None): dsinstance.check_ports() # if we have a pkcs12 file, create the cert db from # that. Otherwise the ds setup will create the CA # cert if pkcs12_info is None: pkcs12_info = make_pkcs12_info(config.dir, "dscert.p12", "dirsrv_pin.txt") # during replica install, this gets invoked before local DS is # available, so use the remote api. #if ca_is_configured: # ca_subject = ca.lookup_ca_subject(_api, config.subject_base) #else: # ca_subject = installutils.default_ca_subject_dn(config.subject_base) ca_subject = ds_ca_subject ds = dsinstance.DsInstance(config_ldif=options.dirsrv_config_file) ds.set_output(ansible_log) # Source: ipaserver/install/dsinstance.py # idstart and idmax are configured so that the range is seen as # depleted by the DNA plugin and the replica will go and get a # new range from the master. # This way all servers use the initially defined range by default. idstart = 1101 idmax = 1100 with redirect_stdout(ansible_log): ds.init_info( realm_name=config.realm_name, fqdn=config.host_name, domain_name=config.domain_name, dm_password=config.dirman_password, subject_base=config.subject_base, ca_subject=ca_subject, idstart=idstart, idmax=idmax, pkcs12_info=pkcs12_info, ca_file=ca_file, setup_pkinit=not options.no_pkinit, ) ds.master_fqdn = config.master_host_name if ca_is_configured is not None: ds.ca_is_configured = ca_is_configured ds.promote = promote ds.api = remote_api # from __setup_replica # Always connect to ds over ldapi ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=ds.realm) conn = ipaldap.LDAPClient(ldap_uri) conn.external_bind() return ds
def __enable_ssl(self): dirname = config_dirname(self.serverid) dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base) if self.pkcs12_info: if self.ca_is_configured: trust_flags = 'CT,C,C' else: trust_flags = None dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], ca_file=self.ca_file, trust_flags=trust_flags) server_certs = dsdb.find_server_certs() if len(server_certs) == 0: raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0]) # We only handle one server cert self.nickname = server_certs[0][0] self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False) if self.ca_is_configured: dsdb.track_server_cert( self.nickname, self.principal, dsdb.passwd_fname, 'restart_dirsrv %s' % self.serverid) else: cadb = certs.CertDB(self.realm, host_name=self.fqdn, subject_base=self.subject_base) # FIXME, need to set this nickname in the RA plugin cadb.export_ca_cert('ipaCert', False) dsdb.create_from_cacert(cadb.cacert_fname, passwd=None) ca_args = ['/usr/libexec/certmonger/dogtag-submit', '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn, '--dbdir', paths.HTTPD_ALIAS_DIR, '--nickname', 'ipaCert', '--sslpinfile', paths.ALIAS_PWDFILE_TXT, '--agent-submit'] helper = " ".join(ca_args) prev_helper = certmonger.modify_ca_helper('IPA', helper) try: cmd = 'restart_dirsrv %s' % self.serverid certmonger.request_and_wait_for_cert( nssdb=dirname, nickname=self.nickname, principal=self.principal, passwd_fname=dsdb.passwd_fname, subject=str(DN(('CN', self.fqdn), self.subject_base)), ca='IPA', profile=dogtag.DEFAULT_PROFILE, dns=[self.fqdn], post_command=cmd) finally: certmonger.modify_ca_helper('IPA', prev_helper) self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False) dsdb.create_pin_file() self.cacert_name = dsdb.cacert_name ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"), (ldap.MOD_REPLACE, "nsSSL3Ciphers", "default"), (ldap.MOD_REPLACE, "allowWeakCipher", "off")] conn.modify_s(DN(('cn', 'encryption'), ('cn', 'config')), mod) mod = [(ldap.MOD_ADD, "nsslapd-security", "on")] conn.modify_s(DN(('cn', 'config')), mod) entry = conn.make_entry( DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')), objectclass=["top", "nsEncryptionModule"], cn=["RSA"], nsSSLPersonalitySSL=[self.nickname], nsSSLToken=["internal (software)"], nsSSLActivation=["on"], ) conn.add_entry(entry) conn.unbind() # check for open secure port 636 from now on self.open_ports.append(636)
def __enable_ssl(self): dirname = config_dirname(self.serverid) dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base) if self.pkcs12_info: if self.ca_is_configured: trust_flags = "CT,C,C" else: trust_flags = None dsdb.create_from_pkcs12( self.pkcs12_info[0], self.pkcs12_info[1], ca_file=self.ca_file, trust_flags=trust_flags ) server_certs = dsdb.find_server_certs() if len(server_certs) == 0: raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0]) # We only handle one server cert self.nickname = server_certs[0][0] self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False) if self.ca_is_configured: dsdb.track_server_cert( self.nickname, self.principal, dsdb.passwd_fname, "restart_dirsrv %s" % self.serverid ) else: cadb = certs.CertDB(self.realm, host_name=self.fqdn, subject_base=self.subject_base) # FIXME, need to set this nickname in the RA plugin cadb.export_ca_cert("ipaCert", False) dsdb.create_from_cacert(cadb.cacert_fname, passwd=None) ca_args = [ "/usr/libexec/certmonger/dogtag-submit", "--ee-url", "https://%s:8443/ca/ee/ca" % self.fqdn, "--dbdir", paths.HTTPD_ALIAS_DIR, "--nickname", "ipaCert", "--sslpinfile", paths.ALIAS_PWDFILE_TXT, "--agent-submit", ] helper = " ".join(ca_args) prev_helper = certmonger.modify_ca_helper("IPA", helper) try: cmd = "restart_dirsrv %s" % self.serverid certmonger.request_and_wait_for_cert( certpath=dirname, nickname=self.nickname, principal=self.principal, passwd_fname=dsdb.passwd_fname, subject=str(DN(("CN", self.fqdn), self.subject_base)), ca="IPA", profile=dogtag.DEFAULT_PROFILE, dns=[self.fqdn], post_command=cmd, ) finally: certmonger.modify_ca_helper("IPA", prev_helper) self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False) dsdb.create_pin_file() self.cacert_name = dsdb.cacert_name ldap_uri = ipaldap.get_ldap_uri(self.fqdn) conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn=ipaldap.DIRMAN_DN, bind_password=self.dm_password) mod = [ (ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"), (ldap.MOD_REPLACE, "nsSSL3Ciphers", "default"), (ldap.MOD_REPLACE, "allowWeakCipher", "off"), ] conn.modify_s(DN(("cn", "encryption"), ("cn", "config")), mod) mod = [(ldap.MOD_ADD, "nsslapd-security", "on")] conn.modify_s(DN(("cn", "config")), mod) entry = conn.make_entry( DN(("cn", "RSA"), ("cn", "encryption"), ("cn", "config")), objectclass=["top", "nsEncryptionModule"], cn=["RSA"], nsSSLPersonalitySSL=[self.nickname], nsSSLToken=["internal (software)"], nsSSLActivation=["on"], ) conn.add_entry(entry) conn.unbind() # check for open secure port 636 from now on self.open_ports.append(636)