def destroy_connection(self): """Disconnect from LDAP server.""" try: self.unbind() LDAPClient._disconnect(self) except errors.PublicError: # ignore when trying to unbind multiple times pass
def __init__(self, shared_instance=False, ldap_uri=None, base_dn=None, schema=None): self.__ldap_uri = None CrudBackend.__init__(self, shared_instance=shared_instance) LDAPClient.__init__(self, ldap_uri) self.__base_dn = base_dn
def __init__(self, api): force_schema_updates = api.env.context in ('installer', 'updates') CrudBackend.__init__(self, api) LDAPClient.__init__(self, None, force_schema_updates=force_schema_updates) self._time_limit = float(LDAPClient.time_limit) self._size_limit = int(LDAPClient.size_limit)
def __init__(self, api, ldap_uri=None): if ldap_uri is None: ldap_uri = api.env.ldap_uri force_schema_updates = api.env.context in ('installer', 'updates') CrudBackend.__init__(self, api) LDAPClient.__init__(self, ldap_uri, force_schema_updates=force_schema_updates)
def destroy_connection(self): """Disconnect from LDAP server.""" try: if self._conn is not None: self.unbind() LDAPClient._disconnect(self) except errors.PublicError: # ignore when trying to unbind multiple times pass
def execute(self, ldapuri, bindpw, **options): ldap = self.api.Backend.ldap2 self.normalize_options(options) config = ldap.get_ipa_config() ds_base_dn = options.get('basedn') if ds_base_dn is not None: assert isinstance(ds_base_dn, DN) # check if migration mode is enabled if not config.get('ipamigrationenabled', (False,))[0]: return dict(result={}, failed={}, enabled=False, compat=True) # connect to DS if options.get('cacertfile') is not None: # store CA cert into file tmp_ca_cert_f = write_tmp_file(options['cacertfile']) cacert = tmp_ca_cert_f.name # start TLS connection or STARTTLS ds_ldap = LDAPClient(ldapuri, cacert=cacert, start_tls=True) ds_ldap.simple_bind(options['binddn'], bindpw) tmp_ca_cert_f.close() else: ds_ldap = LDAPClient(ldapuri) ds_ldap.simple_bind(options['binddn'], bindpw, insecure_bind=True) # check whether the compat plugin is enabled if not options.get('compat'): try: ldap.get_entry(DN(('cn', 'users'), ('cn', 'compat'), (api.env.basedn))) return dict(result={}, failed={}, enabled=True, compat=False) except errors.NotFound: pass if not ds_base_dn: # retrieve base DN from remote LDAP server entries, _truncated = ds_ldap.find_entries( '', ['namingcontexts', 'defaultnamingcontext'], DN(''), ds_ldap.SCOPE_BASE, size_limit=-1, time_limit=0, ) if 'defaultnamingcontext' in entries[0]: ds_base_dn = DN(entries[0]['defaultnamingcontext'][0]) assert isinstance(ds_base_dn, DN) else: try: ds_base_dn = DN(entries[0]['namingcontexts'][0]) assert isinstance(ds_base_dn, DN) except (IndexError, KeyError) as e: raise Exception(str(e)) # migrate! (migrated, failed) = self.migrate( ldap, config, ds_ldap, ds_base_dn, options ) return dict(result=migrated, failed=failed, enabled=True, compat=True)
def validate_dm_password_ldap(password): """ Validate DM password by attempting to connect to LDAP. api.env has to contain valid ldap_uri. """ client = LDAPClient(api.env.ldap_uri, cacert=paths.IPA_CA_CRT) try: client.simple_bind(DIRMAN_DN, password) except errors.ACIError: raise ValueError("Invalid Directory Manager password") else: client.unbind()
def __init__(self, api, ldap_uri=None): if ldap_uri is None: ldap_uri = api.env.ldap_uri force_schema_updates = api.env.context in ('installer', 'updates') CrudBackend.__init__(self, api) LDAPClient.__init__(self, ldap_uri, force_schema_updates=force_schema_updates) self.__time_limit = float(LDAPClient.time_limit) self.__size_limit = int(LDAPClient.size_limit)
def __init__(self, api, ldap_uri=None): if ldap_uri is None: ldap_uri = api.env.ldap_uri force_schema_updates = api.env.context in ('installer', 'updates') CrudBackend.__init__(self, api) LDAPClient.__init__(self, ldap_uri, force_schema_updates=force_schema_updates) self._time_limit = float(LDAPClient.time_limit) self._size_limit = int(LDAPClient.size_limit)
def test_kra_agent_nonmatching_cert(self): cert2 = IPACertificate(2) attrs = dict( description=['2;1;CN=ISSUER;CN=RA AGENT'], usercertificate=[cert2], ) fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, DN('uid=ipakra,ou=people,o=kra,o=ipaca')) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework, config.Config()) f = IPAKRAAgent(registry) f.conn = mock_ldap([ldapentry]) self.results = capture_results(f) result = self.results.results[0] assert result.result == constants.ERROR assert result.kw.get('certfile') == paths.RA_AGENT_PEM assert result.kw.get('dn') == 'uid=ipakra,ou=people,o=kra,o=ipaca'
def test_nss_agent_multiple_certs(self): cert2 = IPACertificate(2) attrs = dict( description=['2;1;CN=ISSUER;CN=RA AGENT'], usercertificate=[cert2, self.cert], ) fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, DN('uid=ipara,ou=people,o=ipaca')) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework, config.Config) f = IPARAAgent(registry) f.conn = mock_ldap([ldapentry]) self.results = capture_results(f) assert len(self.results) == 1 result = self.results.results[0] assert result.result == constants.SUCCESS assert result.source == 'ipahealthcheck.ipa.certs' assert result.check == 'IPARAAgent'
def test_member_fail(self): agent_dn = DN(('fqdn', m_api.env.host), m_api.env.container_host, m_api.env.basedn) attrs = { 'memberof': [agent_dn], } fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, agent_dn) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework, config.Config) registry.trust_controller = True f = IPATrustControllerPrincipalCheck(registry) f.conn = mock_ldap(ldapentry) self.results = capture_results(f) assert len(self.results) == 1 result = self.results.results[0] assert result.result == constants.ERROR assert result.source == 'ipahealthcheck.ipa.trust' assert result.kw.get('key') == 'cifs/%s@%s' % \ (m_api.env.host, m_api.env.realm)
def test_service_enabled(self): service_dn = DN(('cn', 'ADTRUST')) for type in [ENABLED_SERVICE, HIDDEN_SERVICE]: attrs = { 'ipaconfigstring': [type], } fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, service_dn) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework, config.Config) registry.trust_controller = True f = IPATrustControllerServiceCheck(registry) f.conn = mock_ldap(ldapentry) self.results = capture_results(f) assert len(self.results) == 1 result = self.results.results[0] assert result.result == constants.SUCCESS assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPATrustControllerServiceCheck' assert result.kw.get('key') == 'ADTRUST'
def test_sidgen_fail(self): attrs = { 'nsslapd-pluginEnabled': ['off'], } fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, DN('cn=plugin, cn=config')) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework, config.Config) registry.trust_agent = True f = IPAsidgenpluginCheck(registry) f.conn = mock_ldap(ldapentry) self.results = capture_results(f) assert len(self.results) == 2 result = self.results.results[0] assert result.result == constants.ERROR assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPAsidgenpluginCheck' assert result.kw.get('key') == 'IPA SIDGEN' result = self.results.results[1] assert result.result == constants.ERROR assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPAsidgenpluginCheck' assert result.kw.get('key') == 'ipa-sidgen-task'
def test_principal_ok(self): agent_dn = DN(('krbprincipalname', 'cifs/%s@%s' % (m_api.env.host, m_api.env.realm)), m_api.env.container_service, m_api.env.basedn) group_dn = DN(('cn', 'adtrust agents'), m_api.env.container_sysaccounts, m_api.env.basedn) attrs = { 'memberof': [group_dn], } fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, agent_dn) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework, config.Config) registry.trust_controller = True f = IPATrustControllerPrincipalCheck(registry) f.conn = mock_ldap(ldapentry) self.results = capture_results(f) assert len(self.results) == 1 result = self.results.results[0] assert result.result == constants.SUCCESS assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPATrustControllerPrincipalCheck' assert result.kw.get('key') == 'cifs/%s@%s' % \ (m_api.env.host, m_api.env.realm)
def test_principal_fail(self): service_dn = DN(('cn', 'ADTRUST')) attrs = { 'ipaconfigstring': ['disabledService'], } fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, service_dn) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework) registry.trust_controller = True f = IPATrustControllerServiceCheck(registry) f.conn = mock_ldap(ldapentry) f.config = config.Config() self.results = capture_results(f) assert len(self.results) == 1 result = self.results.results[0] assert result.result == constants.ERROR assert result.source == 'ipahealthcheck.ipa.trust' assert result.kw.get('key') == 'ADTRUST'
def test_one_ruvs(self): fake_conn = LDAPClient('ldap://localhost', no_schema=True) entries = [] entries.append( self.create_entry(fake_conn, DN('dc=example,cn=mapping tree,cn=config'), {'nsds5ReplicaId': ['3']}) ) entries.append(None) framework = object() registry.initialize(framework, config.Config) f = RUVCheck(registry) f.conn = mock_ldap(entries) self.results = capture_results(f) assert len(self.results) == 1 result = self.results.results[0] assert result.result == constants.SUCCESS assert result.source == 'ipahealthcheck.ds.ruv' assert result.check == 'RUVCheck' assert result.kw.get('key') == str(m_api.env.basedn) assert result.kw.get('ruv') == '3'
def modify_password(self, dn, new_pass, old_pass='', otp='', skip_bind=False): """Set user password.""" assert isinstance(dn, DN) # The python-ldap passwd command doesn't verify the old password # so we'll do a simple bind to validate it. if not skip_bind and old_pass != '': pw = old_pass if (otp): pw = old_pass + otp with LDAPClient(self.ldap_uri, force_schema_updates=False) as conn: conn.simple_bind(dn, pw) conn.unbind() with self.error_handler(): old_pass = self.encode(old_pass) new_pass = self.encode(new_pass) self.conn.passwd_s(str(dn), old_pass, new_pass)
def test_nss_agent_too_many(self): attrs = dict( description=['2;1;CN=ISSUER;CN=RA AGENT'], usercertificate=[self.cert], ) fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, DN('uid=ipara,ou=people,o=ipaca')) for attr, values in attrs.items(): ldapentry[attr] = values ldapentry2 = LDAPEntry(fake_conn, DN('uid=ipara2,ou=people,o=ipaca')) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework, config.Config()) f = IPARAAgent(registry) f.conn = mock_ldap([ldapentry, ldapentry2]) self.results = capture_results(f) result = self.results.results[0] assert result.result == constants.ERROR assert result.kw.get('found') == 2
def test_member_ok(self): agent_dn = DN(('fqdn', m_api.env.host), m_api.env.container_host, m_api.env.basedn) group_dn = DN(('cn', 'adtrust agents'), m_api.env.container_sysaccounts, m_api.env.basedn) attrs = { 'memberof': [group_dn], } fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, agent_dn) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework) registry.trust_agent = True f = IPATrustAgentMemberCheck(registry) f.conn = mock_ldap(ldapentry) f.config = config.Config() self.results = capture_results(f) assert len(self.results) == 1 result = self.results.results[0] assert result.result == constants.SUCCESS assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPATrustAgentMemberCheck' assert result.kw.get('key') == m_api.env.host
def test_principal_fail(self): admin_dn = DN(('uid', 'admin')) attrs = { 'ipantsecurityidentifier': ['S-1-5-21-1234-5678-1976041503-400'], } fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, admin_dn) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework, config.Config) registry.trust_controller = True f = IPATrustControllerAdminSIDCheck(registry) f.conn = mock_ldap(ldapentry) self.results = capture_results(f) assert len(self.results) == 1 result = self.results.results[0] assert result.result == constants.ERROR assert result.source == 'ipahealthcheck.ipa.trust' assert result.check == 'IPATrustControllerAdminSIDCheck' assert result.kw.get('key') == 'ipantsecurityidentifier' assert result.kw.get('rid') == 'S-1-5-21-1234-5678-1976041503-400'
def __init__(self, shared_instance=True, ldap_uri=None, base_dn=None, schema=None): try: ldap_uri = ldap_uri or api.env.ldap_uri except AttributeError: ldap_uri = 'ldap://example.com' CrudBackend.__init__(self, shared_instance=shared_instance) LDAPClient.__init__(self, ldap_uri) try: if base_dn is not None: self.base_dn = DN(base_dn) else: self.base_dn = DN(api.env.basedn) except AttributeError: self.base_dn = DN()
def test_certs_mismatch(self, mock_certdb): """ Ensure mismatches are detected""" fake_conn = LDAPClient('ldap://localhost', no_schema=True) pkidbentry = LDAPEntry( fake_conn, DN('uid=pkidbuser,ou=people,o=ipaca'), userCertificate=[IPACertificate(serial_number=2)], subjectName=['test']) casignentry = LDAPEntry(fake_conn, DN('cn=%s IPA CA' % m_api.env.realm, 'cn=certificates,cn=ipa,cn=etc', m_api.env.basedn), CACertificate=[IPACertificate()], userCertificate=[IPACertificate()], subjectName=['test']) ldap_entries = [pkidbentry, casignentry] trust = { 'ocspSigningCert cert-pki-ca': 'u,u,u', 'caSigningCert cert-pki-ca': 'u,u,u', 'subsystemCert cert-pki-ca': 'u,u,u', 'auditSigningCert cert-pki-ca': 'u,u,Pu', 'Server-Cert cert-pki-ca': 'u,u,u', 'transportCert cert-pki-kra': 'u,u,u', 'storageCert cert-pki-kra': 'u,u,u', 'auditSigningCert cert-pki-kra': 'u,u,Pu', } dogtag_entries_subjects = ( 'CN=OCSP Subsystem,O=%s' % m_api.env.realm, 'CN=CA Subsystem,O=%s' % m_api.env.realm, 'CN=CA Audit,O=%s' % m_api.env.realm, 'CN=%s,O=%s' % (m_api.env.host, m_api.env.realm), 'CN=KRA Transport Certificate,O=%s' % m_api.env.realm, 'CN=KRA Storage Certificate,O=%s' % m_api.env.realm, 'CN=KRA Audit,O=%s' % m_api.env.realm, ) for i, subject in enumerate(dogtag_entries_subjects): entry = LDAPEntry(fake_conn, DN('cn=%i,ou=certificateRepository' % i, 'ou=ca,o=ipaca'), userCertificate=[IPACertificate()], subjectName=[subject]) ldap_entries.append(entry) mock_certdb.return_value = mock_CertDB(trust) framework = object() registry.initialize(framework, config.Config()) f = IPADogtagCertsMatchCheck(registry) f.conn = mock_ldap(ldap_entries) self.results = capture_results(f) assert len(self.results) == 3 result = self.results.results[0] assert result.result == constants.ERROR assert result.source == 'ipahealthcheck.ipa.certs' assert result.check == 'IPADogtagCertsMatchCheck'
def execute(self, ldapuri, bindpw, **options): ldap = self.api.Backend.ldap2 self.normalize_options(options) config = ldap.get_ipa_config() ds_base_dn = options.get('basedn') if ds_base_dn is not None: assert isinstance(ds_base_dn, DN) # check if migration mode is enabled if config.get('ipamigrationenabled', ('FALSE', ))[0] == 'FALSE': return dict(result={}, failed={}, enabled=False, compat=True) # connect to DS cacert = None if options.get('cacertfile') is not None: # store CA cert into file tmp_ca_cert_f = write_tmp_file(options['cacertfile']) cacert = tmp_ca_cert_f.name # start TLS connection ds_ldap = LDAPClient(ldapuri, cacert=cacert) ds_ldap.simple_bind(options['binddn'], bindpw) tmp_ca_cert_f.close() else: ds_ldap = LDAPClient(ldapuri, cacert=cacert) ds_ldap.simple_bind(options['binddn'], bindpw) # check whether the compat plugin is enabled if not options.get('compat'): try: ldap.get_entry(DN(('cn', 'compat'), (api.env.basedn))) return dict(result={}, failed={}, enabled=True, compat=False) except errors.NotFound: pass if not ds_base_dn: # retrieve base DN from remote LDAP server entries, _truncated = ds_ldap.find_entries( '', ['namingcontexts', 'defaultnamingcontext'], DN(''), ds_ldap.SCOPE_BASE, size_limit=-1, time_limit=0, ) if 'defaultnamingcontext' in entries[0]: ds_base_dn = DN(entries[0]['defaultnamingcontext'][0]) assert isinstance(ds_base_dn, DN) else: try: ds_base_dn = DN(entries[0]['namingcontexts'][0]) assert isinstance(ds_base_dn, DN) except (IndexError, KeyError) as e: raise Exception(str(e)) # migrate! (migrated, failed) = self.migrate( ldap, config, ds_ldap, ds_base_dn, options ) return dict(result=migrated, failed=failed, enabled=True, compat=True)
def main(): parser = common.mkparser(description='ipa-custodia LDAP DM hash handler') if os.getegid() != 0: parser.error("Must be run as root user.\n") # create LDAP connection using LDAPI and EXTERNAL bind as root if not api.isdone('bootstrap'): api.bootstrap() realm = api.env.realm ldap_uri = realm_to_ldapi_uri(realm) conn = LDAPClient(ldap_uri=ldap_uri, no_schema=True) try: conn.external_bind() except Exception as e: parser.error("Failed to connect to {}: {}\n".format(ldap_uri, e)) with conn: common.main(parser, export_key, import_key, conn=conn)
def main(): parser = common.mkparser( description='ipa-custodia LDAP DM hash handler' ) if os.getegid() != 0: parser.error("Must be run as root user.\n") # create LDAP connection using LDAPI and EXTERNAL bind as root if not api.isdone('bootstrap'): api.bootstrap() realm = api.env.realm ldap_uri = realm_to_ldapi_uri(realm) conn = LDAPClient(ldap_uri=ldap_uri, no_schema=True) try: conn.external_bind() except Exception as e: parser.error("Failed to connect to {}: {}\n".format(ldap_uri, e)) with conn: common.main(parser, export_key, import_key, conn=conn)
def test_nss_agent_no_description(self): attrs = dict(usercertificate=[self.cert], ) fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, DN('uid=ipara,ou=people,o=ipaca')) for attr, values in attrs.items(): ldapentry[attr] = values framework = object() registry.initialize(framework, config.Config()) f = IPARAAgent(registry) f.conn = mock_ldap([ldapentry]) self.results = capture_results(f) result = self.results.results[0] assert result.result == constants.ERROR assert 'description' in result.kw.get('msg')
def test_certs_mismatch(self, mock_certdb): """ Ensure mismatches are detected""" m_api.Command.config_show.side_effect = default_subject_base fake_conn = LDAPClient('ldap://localhost', no_schema=True) pkidbentry = LDAPEntry( fake_conn, DN('uid=pkidbuser,ou=people,o=ipaca'), userCertificate=[IPACertificate(serial_number=2)], subjectName=['test']) casignentry = LDAPEntry(fake_conn, DN('cn=%s IPA CA' % m_api.env.realm, 'cn=certificates,cn=ipa,cn=etc', m_api.env.basedn), CACertificate=[IPACertificate()], userCertificate=[IPACertificate()], subjectName=['test']) ldap_entries = [pkidbentry, casignentry] dogtag_entries_subjects = self.get_dogtag_subjects( m_api.env.host, default_subject_base) for i, subject in enumerate(dogtag_entries_subjects): entry = LDAPEntry(fake_conn, DN('cn=%i,ou=certificateRepository' % i, 'ou=ca,o=ipaca'), userCertificate=[IPACertificate()], subjectName=[subject]) ldap_entries.append(entry) mock_certdb.return_value = mock_CertDB(self.trust) framework = object() registry.initialize(framework, config.Config()) f = IPADogtagCertsMatchCheck(registry) f.conn = mock_ldap(ldap_entries) self.results = capture_results(f) assert len(self.results) == 3 result = self.results.results[0] assert result.result == constants.ERROR assert result.source == 'ipahealthcheck.ipa.certs' assert result.check == 'IPADogtagCertsMatchCheck'
def test_etc_cacert_mismatch(self, mock_certdb, mock_load_cert): """ Test mismatch with /etc/ipa/ca.crt """ fake_conn = LDAPClient('ldap://localhost', no_schema=True) cacertentry = LDAPEntry(fake_conn, DN('cn=%s IPA CA' % m_api.env.realm, 'cn=certificates,cn=ipa,cn=etc', m_api.env.basedn), CACertificate=[IPACertificate()]) mock_certdb.return_value = mock_CertDB(self.trust) mock_load_cert.return_value = [IPACertificate(serial_number=2)] framework = object() registry.initialize(framework, config.Config()) f = IPACertMatchCheck(registry) f.conn = mock_ldap([cacertentry]) self.results = capture_results(f) assert len(self.results) == 3 result = self.results.results[0] assert result.result == constants.ERROR assert result.source == 'ipahealthcheck.ipa.certs' assert result.check == 'IPACertMatchCheck'
def test_conflicts(self, mock_conn): attrs = dict(nsds5ReplConflict=['deletedEntryHasChildren'], objectclass=['top']) fake_conn = LDAPClient('ldap://localhost', no_schema=True) ldapentry = LDAPEntry(fake_conn, DN('cn=conflict', m_api.env.basedn)) for attr, values in attrs.items(): ldapentry[attr] = values mock_conn.return_value = mock_ldap([ldapentry]) framework = object() registry.initialize(framework) f = ReplicationConflictCheck(registry) f.config = config.Config() self.results = capture_results(f) result = self.results.results[0] assert result.result == constants.ERROR assert result.source == 'ipahealthcheck.ds.replication' assert result.check == 'ReplicationConflictCheck' assert result.kw.get('msg') == 'Replication conflict' assert result.kw.get('glue') is False assert result.kw.get('key') == ldapentry.dn
def test_certs_match_ok(self, mock_certdb, mock_load_cert): """ Ensure match check is ok""" fake_conn = LDAPClient('ldap://localhost', no_schema=True) cacertentry = LDAPEntry(fake_conn, DN('cn=%s IPA CA' % m_api.env.realm, 'cn=certificates,cn=ipa,cn=etc', m_api.env.basedn), CACertificate=[IPACertificate()]) mock_certdb.return_value = mock_CertDB(self.trust) mock_load_cert.return_value = [IPACertificate()] framework = object() registry.initialize(framework, config.Config()) f = IPACertMatchCheck(registry) f.conn = mock_ldap([cacertentry]) self.results = capture_results(f) assert len(self.results) == 3 for result in self.results.results: assert result.result == constants.SUCCESS assert result.source == 'ipahealthcheck.ipa.certs' assert result.check == 'IPACertMatchCheck'
def execute(self, *keys, **options): ldap = self.obj.backend dn = self.api.Object.user.get_either_dn(*keys, **options) attr_list = ['krbloginfailedcount', 'krblastsuccessfulauth', 'krblastfailedauth', 'nsaccountlock'] disabled = False masters = [] # Get list of masters try: masters, _truncated = ldap.find_entries( None, ['*'], DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn), ldap.SCOPE_ONELEVEL ) except errors.NotFound: # If this happens we have some pretty serious problems logger.error('No IPA masters found!') entries = [] count = 0 for master in masters: host = master['cn'][0] if host == api.env.host: other_ldap = self.obj.backend else: try: other_ldap = LDAPClient(ldap_uri='ldap://%s' % host) other_ldap.gssapi_bind() except Exception as e: logger.error("user_status: Connecting to %s failed with " "%s", host, str(e)) newresult = {'dn': dn} newresult['server'] = _("%(host)s failed: %(error)s") % dict(host=host, error=str(e)) entries.append(newresult) count += 1 continue try: entry = other_ldap.get_entry(dn, attr_list) newresult = {'dn': dn} for attr in ['krblastsuccessfulauth', 'krblastfailedauth']: newresult[attr] = entry.get(attr, [u'N/A']) newresult['krbloginfailedcount'] = entry.get('krbloginfailedcount', u'0') if not options.get('raw', False): for attr in ['krblastsuccessfulauth', 'krblastfailedauth']: try: if newresult[attr][0] == u'N/A': continue newtime = time.strptime(newresult[attr][0], '%Y%m%d%H%M%SZ') newresult[attr][0] = unicode(time.strftime('%Y-%m-%dT%H:%M:%SZ', newtime)) except Exception as e: logger.debug("time conversion failed with %s", str(e)) newresult['server'] = host if options.get('raw', False): time_format = '%Y%m%d%H%M%SZ' else: time_format = '%Y-%m-%dT%H:%M:%SZ' newresult['now'] = unicode(strftime(time_format, gmtime())) convert_nsaccountlock(entry) if 'nsaccountlock' in entry: disabled = entry['nsaccountlock'] self.api.Object.user.get_preserved_attribute(entry, options) entries.append(newresult) count += 1 except errors.NotFound: raise self.api.Object.user.handle_not_found(*keys) except Exception as e: logger.error("user_status: Retrieving status for %s failed " "with %s", dn, str(e)) newresult = {'dn': dn} newresult['server'] = _("%(host)s failed") % dict(host=host) entries.append(newresult) count += 1 if host != api.env.host: other_ldap.close() return dict(result=entries, count=count, truncated=False, summary=unicode(_('Account disabled: %(disabled)s' % dict(disabled=disabled))), )
def create_connection(self, ccache=None, bind_dn=None, bind_pw='', cacert=None, autobind=AUTOBIND_AUTO, serverctrls=None, clientctrls=None, time_limit=_missing, size_limit=_missing): """ Connect to LDAP server. Keyword arguments: ldapuri -- the LDAP server to connect to ccache -- Kerberos ccache name bind_dn -- dn used to bind to the server bind_pw -- password used to bind to the server debug_level -- LDAP debug level option cacert -- TLS CA certificate filename autobind - autobind as the current user time_limit, size_limit -- maximum time and size limit for LDAP possible options: - value - sets the given value - None - reads value from ipaconfig - _missing - keeps previously configured settings (unlimited set by default in constructor) Extends backend.Connectible.create_connection. """ if bind_dn is None: bind_dn = DN(('cn', 'directory manager')) assert isinstance(bind_dn, DN) if cacert is None: cacert = paths.IPA_CA_CRT if time_limit is not _missing: object.__setattr__(self, 'time_limit', time_limit) if size_limit is not _missing: object.__setattr__(self, 'size_limit', size_limit) client = LDAPClient(self.ldap_uri, force_schema_updates=self._force_schema_updates, cacert=cacert) conn = client._conn with client.error_handler(): minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN) maxssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MAX) # Always connect with at least an SSF of 56, confidentiality # This also protects us from a broken ldap.conf if minssf < 56: minssf = 56 conn.set_option(_ldap.OPT_X_SASL_SSF_MIN, minssf) if maxssf < minssf: conn.set_option(_ldap.OPT_X_SASL_SSF_MAX, minssf) ldapi = self.ldap_uri.startswith('ldapi://') if bind_pw: client.simple_bind(bind_dn, bind_pw, server_controls=serverctrls, client_controls=clientctrls) elif autobind != AUTOBIND_DISABLED and os.getegid() == 0 and ldapi: try: client.external_bind(server_controls=serverctrls, client_controls=clientctrls) except errors.NotFound: if autobind == AUTOBIND_ENABLED: # autobind was required and failed, raise # exception that it failed raise else: if ldapi: with client.error_handler(): conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host) if ccache is None: os.environ.pop('KRB5CCNAME', None) else: os.environ['KRB5CCNAME'] = ccache principal = krb_utils.get_principal(ccache_name=ccache) client.gssapi_bind(server_controls=serverctrls, client_controls=clientctrls) setattr(context, 'principal', principal) return conn
def execute(self, *keys, **options): ldap = self.obj.backend dn = self.api.Object.user.get_either_dn(*keys, **options) attr_list = [ 'krbloginfailedcount', 'krblastsuccessfulauth', 'krblastfailedauth', 'nsaccountlock' ] disabled = False masters = get_masters(ldap) entries = [] count = 0 for host in masters: if host == api.env.host: other_ldap = self.obj.backend else: try: other_ldap = LDAPClient(ldap_uri='ldap://%s' % host) other_ldap.gssapi_bind() except Exception as e: logger.error( "user_status: Connecting to %s failed with " "%s", host, str(e)) newresult = {'dn': dn} newresult['server'] = _("%(host)s failed: %(error)s" ) % dict(host=host, error=str(e)) entries.append(newresult) count += 1 continue try: entry = other_ldap.get_entry(dn, attr_list) newresult = {'dn': dn} for attr in ['krblastsuccessfulauth', 'krblastfailedauth']: newresult[attr] = entry.get(attr, [u'N/A']) newresult['krbloginfailedcount'] = entry.get( 'krbloginfailedcount', u'0') if not options.get('raw', False): for attr in ['krblastsuccessfulauth', 'krblastfailedauth']: try: if newresult[attr][0] == u'N/A': continue newtime = time.strptime(newresult[attr][0], '%Y%m%d%H%M%SZ') newresult[attr][0] = unicode( time.strftime('%Y-%m-%dT%H:%M:%SZ', newtime)) except Exception as e: logger.debug("time conversion failed with %s", str(e)) newresult['server'] = host if options.get('raw', False): time_format = '%Y%m%d%H%M%SZ' else: time_format = '%Y-%m-%dT%H:%M:%SZ' newresult['now'] = unicode(strftime(time_format, gmtime())) convert_nsaccountlock(entry) if 'nsaccountlock' in entry: disabled = entry['nsaccountlock'] self.api.Object.user.get_preserved_attribute(entry, options) entries.append(newresult) count += 1 except errors.NotFound: raise self.api.Object.user.handle_not_found(*keys) except Exception as e: logger.error( "user_status: Retrieving status for %s failed " "with %s", dn, str(e)) newresult = {'dn': dn} newresult['server'] = _("%(host)s failed") % dict(host=host) entries.append(newresult) count += 1 if host != api.env.host: other_ldap.close() return dict( result=entries, count=count, truncated=False, summary=unicode( _('Account disabled: %(disabled)s' % dict(disabled=disabled))), )
def create_connection( self, ccache=None, bind_dn=None, bind_pw='', cacert=None, autobind=AUTOBIND_AUTO, serverctrls=None, clientctrls=None, time_limit=_missing, size_limit=_missing): """ Connect to LDAP server. Keyword arguments: ldapuri -- the LDAP server to connect to ccache -- Kerberos ccache name bind_dn -- dn used to bind to the server bind_pw -- password used to bind to the server debug_level -- LDAP debug level option cacert -- TLS CA certificate filename autobind - autobind as the current user time_limit, size_limit -- maximum time and size limit for LDAP possible options: - value - sets the given value - None - reads value from ipaconfig - _missing - keeps previously configured settings (unlimited set by default in constructor) Extends backend.Connectible.create_connection. """ if bind_dn is None: bind_dn = DN(('cn', 'directory manager')) assert isinstance(bind_dn, DN) if cacert is None: cacert = constants.CACERT if time_limit is not _missing: self.time_limit = time_limit if size_limit is not _missing: self.size_limit = size_limit client = LDAPClient(self.ldap_uri, force_schema_updates=self._force_schema_updates, cacert=cacert) conn = client._conn with client.error_handler(): minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN) maxssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MAX) # Always connect with at least an SSF of 56, confidentiality # This also protects us from a broken ldap.conf if minssf < 56: minssf = 56 conn.set_option(_ldap.OPT_X_SASL_SSF_MIN, minssf) if maxssf < minssf: conn.set_option(_ldap.OPT_X_SASL_SSF_MAX, minssf) ldapi = self.ldap_uri.startswith('ldapi://') if bind_pw: client.simple_bind(bind_dn, bind_pw, server_controls=serverctrls, client_controls=clientctrls) elif autobind != AUTOBIND_DISABLED and os.getegid() == 0 and ldapi: try: client.external_bind(server_controls=serverctrls, client_controls=clientctrls) except errors.NotFound: if autobind == AUTOBIND_ENABLED: # autobind was required and failed, raise # exception that it failed raise else: if ldapi: with client.error_handler(): conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host) if ccache is None: os.environ.pop('KRB5CCNAME', None) else: os.environ['KRB5CCNAME'] = ccache principal = krb_utils.get_principal(ccache_name=ccache) client.gssapi_bind(server_controls=serverctrls, client_controls=clientctrls) setattr(context, 'principal', principal) return conn
def get_config(dirsrv): base = DN( ("cn", api.env.host), ("cn", "masters"), ("cn", "ipa"), ("cn", "etc"), api.env.basedn, ) srcfilter = LDAPClient.combine_filters( [ LDAPClient.make_filter({"objectClass": "ipaConfigObject"}), LDAPClient.make_filter( {"ipaConfigString": [ENABLED_SERVICE, HIDDEN_SERVICE]}, rules=LDAPClient.MATCH_ANY, ), ], rules=LDAPClient.MATCH_ALL, ) attrs = ["cn", "ipaConfigString"] if not dirsrv.is_running(): raise IpactlError( "Failed to get list of services to probe status:\n" "Directory Server is stopped", 3, ) try: # The start/restart functions already wait for the server to be # started. What we are doing with this wait is really checking to see # if the server is listening at all. lurl = ldapurl.LDAPUrl(api.env.ldap_uri) if lurl.urlscheme == "ldapi": wait_for_open_socket(lurl.hostport, timeout=api.env.startup_timeout) else: (host, port) = lurl.hostport.split(":") wait_for_open_ports(host, [int(port)], timeout=api.env.startup_timeout) con = LDAPClient(api.env.ldap_uri) con.external_bind() res = con.get_entries( base, filter=srcfilter, attrs_list=attrs, scope=con.SCOPE_SUBTREE, time_limit=10, ) except errors.NetworkError: # LSB status code 3: program is not running raise IpactlError( "Failed to get list of services to probe status:\n" "Directory Server is stopped", 3, ) except errors.NotFound: masters_list = [] dn = DN(("cn", "masters"), ("cn", "ipa"), ("cn", "etc"), api.env.basedn) attrs = ["cn"] try: entries = con.get_entries(dn, con.SCOPE_ONELEVEL, attrs_list=attrs) except Exception as e: masters_list.append("No master found because of error: %s" % str(e)) else: for master_entry in entries: masters_list.append(master_entry.single_value["cn"]) masters = "\n".join(masters_list) raise IpactlError( "Failed to get list of services to probe status!\n" "Configured hostname '%s' does not match any master server in " "LDAP:\n%s" % (api.env.host, masters)) except Exception as e: raise IpactlError( "Unknown error when retrieving list of services from LDAP: %s" % str(e)) svc_list = [] for entry in res: name = entry.single_value["cn"] for p in entry["ipaConfigString"]: if p.startswith("startOrder "): try: order = int(p.split()[1]) except ValueError: raise IpactlError("Expected order as integer in: %s:%s" % (name, p)) svc_list.append([order, name]) ordered_list = [] for order, svc in sorted(svc_list): if svc in service.SERVICE_LIST: ordered_list.append(service.SERVICE_LIST[svc].systemd_name) return deduplicate(ordered_list)
def create_connection(self, ccache=None, bind_dn=None, bind_pw='', tls_cacertfile=None, tls_certfile=None, tls_keyfile=None, debug_level=0, autobind=AUTOBIND_AUTO, serverctrls=None, clientctrls=None): """ Connect to LDAP server. Keyword arguments: ldapuri -- the LDAP server to connect to ccache -- Kerberos ccache name bind_dn -- dn used to bind to the server bind_pw -- password used to bind to the server debug_level -- LDAP debug level option tls_cacertfile -- TLS CA certificate filename tls_certfile -- TLS certificate filename tls_keyfile - TLS bind key filename autobind - autobind as the current user Extends backend.Connectible.create_connection. """ if bind_dn is None: bind_dn = DN() assert isinstance(bind_dn, DN) if tls_cacertfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_CACERTFILE, tls_cacertfile) if tls_certfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_CERTFILE, tls_certfile) if tls_keyfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_KEYFILE, tls_keyfile) if debug_level: _ldap.set_option(_ldap.OPT_DEBUG_LEVEL, debug_level) LDAPClient._connect(self) conn = self._conn with self.error_handler(): minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN) maxssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MAX) # Always connect with at least an SSF of 56, confidentiality # This also protects us from a broken ldap.conf if minssf < 56: minssf = 56 conn.set_option(_ldap.OPT_X_SASL_SSF_MIN, minssf) if maxssf < minssf: conn.set_option(_ldap.OPT_X_SASL_SSF_MAX, minssf) ldapi = self.ldap_uri.startswith('ldapi://') if bind_pw: self.simple_bind(bind_dn, bind_pw, server_controls=serverctrls, client_controls=clientctrls) elif autobind != AUTOBIND_DISABLED and os.getegid() == 0 and ldapi: try: pw_name = pwd.getpwuid(os.geteuid()).pw_name self.external_bind(pw_name, server_controls=serverctrls, client_controls=clientctrls) except errors.NotFound: if autobind == AUTOBIND_ENABLED: # autobind was required and failed, raise # exception that it failed raise else: if ldapi: with self.error_handler(): conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host) if ccache is None: os.environ.pop('KRB5CCNAME', None) else: os.environ['KRB5CCNAME'] = ccache principal = krb_utils.get_principal(ccache_name=ccache) self.gssapi_bind(server_controls=serverctrls, client_controls=clientctrls) setattr(context, 'principal', principal) return conn
def create_connection(self, ccache=None, bind_dn=None, bind_pw='', tls_cacertfile=None, tls_certfile=None, tls_keyfile=None, debug_level=0, autobind=AUTOBIND_AUTO, serverctrls=None, clientctrls=None, time_limit=None, size_limit=None): """ Connect to LDAP server. Keyword arguments: ldapuri -- the LDAP server to connect to ccache -- Kerberos ccache name bind_dn -- dn used to bind to the server bind_pw -- password used to bind to the server debug_level -- LDAP debug level option tls_cacertfile -- TLS CA certificate filename tls_certfile -- TLS certificate filename tls_keyfile - TLS bind key filename autobind - autobind as the current user Extends backend.Connectible.create_connection. """ if bind_dn is None: bind_dn = DN() assert isinstance(bind_dn, DN) if tls_cacertfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_CACERTFILE, tls_cacertfile) if tls_certfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_CERTFILE, tls_certfile) if tls_keyfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_KEYFILE, tls_keyfile) if time_limit is not None: self.time_limit = time_limit if size_limit is not None: self.size_limit = size_limit if debug_level: _ldap.set_option(_ldap.OPT_DEBUG_LEVEL, debug_level) client = LDAPClient(self.ldap_uri, force_schema_updates=self._force_schema_updates) conn = client._conn with client.error_handler(): minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN) maxssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MAX) # Always connect with at least an SSF of 56, confidentiality # This also protects us from a broken ldap.conf if minssf < 56: minssf = 56 conn.set_option(_ldap.OPT_X_SASL_SSF_MIN, minssf) if maxssf < minssf: conn.set_option(_ldap.OPT_X_SASL_SSF_MAX, minssf) ldapi = self.ldap_uri.startswith('ldapi://') if bind_pw: client.simple_bind(bind_dn, bind_pw, server_controls=serverctrls, client_controls=clientctrls) elif autobind != AUTOBIND_DISABLED and os.getegid() == 0 and ldapi: try: pw_name = pwd.getpwuid(os.geteuid()).pw_name client.external_bind(pw_name, server_controls=serverctrls, client_controls=clientctrls) except errors.NotFound: if autobind == AUTOBIND_ENABLED: # autobind was required and failed, raise # exception that it failed raise else: if ldapi: with client.error_handler(): conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host) if ccache is None: os.environ.pop('KRB5CCNAME', None) else: os.environ['KRB5CCNAME'] = ccache principal = krb_utils.get_principal(ccache_name=ccache) client.gssapi_bind(server_controls=serverctrls, client_controls=clientctrls) setattr(context, 'principal', principal) return conn
def create_connection(self, ccache=None, bind_dn=None, bind_pw='', tls_cacertfile=None, tls_certfile=None, tls_keyfile=None, debug_level=0, autobind=False, serverctrls=None, clientctrls=None): """ Connect to LDAP server. Keyword arguments: ldapuri -- the LDAP server to connect to ccache -- Kerberos V5 ccache object or name bind_dn -- dn used to bind to the server bind_pw -- password used to bind to the server debug_level -- LDAP debug level option tls_cacertfile -- TLS CA certificate filename tls_certfile -- TLS certificate filename tls_keyfile - TLS bind key filename autobind - autobind as the current user Extends backend.Connectible.create_connection. """ if bind_dn is None: bind_dn = DN() assert isinstance(bind_dn, DN) if tls_cacertfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_CACERTFILE, tls_cacertfile) if tls_certfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_CERTFILE, tls_certfile) if tls_keyfile is not None: _ldap.set_option(_ldap.OPT_X_TLS_KEYFILE, tls_keyfile) if debug_level: _ldap.set_option(_ldap.OPT_DEBUG_LEVEL, debug_level) object.__setattr__(self, '_force_schema_updates', self.api.env.context in ('installer', 'updates')) LDAPClient._connect(self) conn = self._conn with self.error_handler(): if self.ldap_uri.startswith('ldapi://') and ccache: conn.set_option(_ldap.OPT_HOST_NAME, self.api.env.host) minssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MIN) maxssf = conn.get_option(_ldap.OPT_X_SASL_SSF_MAX) # Always connect with at least an SSF of 56, confidentiality # This also protects us from a broken ldap.conf if minssf < 56: minssf = 56 conn.set_option(_ldap.OPT_X_SASL_SSF_MIN, minssf) if maxssf < minssf: conn.set_option(_ldap.OPT_X_SASL_SSF_MAX, minssf) if ccache is not None: if isinstance(ccache, krbV.CCache): principal = ccache.principal().name # Get a fully qualified CCACHE name (schema+name) # As we do not use the krbV.CCache object later, # we can safely overwrite it ccache = "%(type)s:%(name)s" % dict(type=ccache.type, name=ccache.name) else: principal = krbV.CCache(name=ccache, context=krbV.default_context()).principal().name os.environ['KRB5CCNAME'] = ccache self.gssapi_bind(server_controls=serverctrls, client_controls=clientctrls) setattr(context, 'principal', principal) else: # no kerberos ccache, use simple bind or external sasl if autobind: pent = pwd.getpwuid(os.geteuid()) self.external_bind(pent.pw_name, server_controls=serverctrls, client_controls=clientctrls) else: self.simple_bind(bind_dn, bind_pw, server_controls=serverctrls, client_controls=clientctrls) return conn
def execute(self, *keys, **options): ldap = self.obj.backend dn = self.api.Object.user.get_either_dn(*keys, **options) attr_list = [ 'krbloginfailedcount', 'krblastsuccessfulauth', 'krblastfailedauth', 'nsaccountlock' ] disabled = False masters = [] # Get list of masters try: masters, _truncated = ldap.find_entries( None, ['*'], DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn), ldap.SCOPE_ONELEVEL) except errors.NotFound: # If this happens we have some pretty serious problems self.error('No IPA masters found!') entries = [] count = 0 for master in masters: host = master['cn'][0] if host == api.env.host: other_ldap = self.obj.backend else: try: other_ldap = LDAPClient(ldap_uri='ldap://%s' % host) other_ldap.gssapi_bind() except Exception as e: self.error("user_status: Connecting to %s failed with %s" % (host, str(e))) newresult = {'dn': dn} newresult['server'] = _("%(host)s failed: %(error)s" ) % dict(host=host, error=str(e)) entries.append(newresult) count += 1 continue try: entry = other_ldap.get_entry(dn, attr_list) newresult = {'dn': dn} for attr in ['krblastsuccessfulauth', 'krblastfailedauth']: newresult[attr] = entry.get(attr, [u'N/A']) newresult['krbloginfailedcount'] = entry.get( 'krbloginfailedcount', u'0') if not options.get('raw', False): for attr in ['krblastsuccessfulauth', 'krblastfailedauth']: try: if newresult[attr][0] == u'N/A': continue newtime = time.strptime(newresult[attr][0], '%Y%m%d%H%M%SZ') newresult[attr][0] = unicode( time.strftime('%Y-%m-%dT%H:%M:%SZ', newtime)) except Exception as e: self.debug("time conversion failed with %s" % str(e)) newresult['server'] = host if options.get('raw', False): time_format = '%Y%m%d%H%M%SZ' else: time_format = '%Y-%m-%dT%H:%M:%SZ' newresult['now'] = unicode(strftime(time_format, gmtime())) convert_nsaccountlock(entry) if 'nsaccountlock' in entry: disabled = entry['nsaccountlock'] self.api.Object.user.get_preserved_attribute(entry, options) entries.append(newresult) count += 1 except errors.NotFound: self.api.Object.user.handle_not_found(*keys) except Exception as e: self.error( "user_status: Retrieving status for %s failed with %s" % (dn, str(e))) newresult = {'dn': dn} newresult['server'] = _("%(host)s failed") % dict(host=host) entries.append(newresult) count += 1 if host != api.env.host: other_ldap.close() return dict( result=entries, count=count, truncated=False, summary=unicode( _('Account disabled: %(disabled)s' % dict(disabled=disabled))), )