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 check(self): try: conn = ipaldap.LDAPClient.from_realm(api.env.realm) except AttributeError: conn = ipaldap.LDAPClient(api.env.ldap_uri) conn.external_bind() filterstr = "(&(!(objectclass=nstombstone))(nsds5ReplConflict=*))" attrlist = ['nsds5ReplConflict', 'objectclass'] try: entries = conn.get_entries(api.env.basedn, ldap.SCOPE_SUBTREE, filterstr, attrlist) except errors.EmptyResult: entries = [] if entries: for entry in entries: glue = 'glue' in entry['objectclass'] yield Result(self, constants.ERROR, key=str(entry.dn), glue=glue, conflict=entry['nsds5replconflict'][0], msg='Replication conflict') else: yield Result(self, constants.SUCCESS)
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 __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 __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 __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 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 _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 _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 = 'ldap://{}'.format(self.master_fqdn) with ipaldap.LDAPClient(ldap_uri, cacert=paths.IPA_CA_CRT) as remote_ldap: remote_ldap.gssapi_bind() replication.wait_for_entry(remote_ldap, kdc_dn, timeout=60)
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 validate_dm_password_ldap(password): """ Validate DM password by attempting to connect to LDAP. api.env has to contain valid ldap_uri. """ client = ipaldap.LDAPClient(api.env.ldap_uri, cacert=paths.IPA_CA_CRT) try: client.simple_bind(ipaldap.DIRMAN_DN, password) except errors.ACIError: raise ValueError("Invalid Directory Manager password") else: client.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 __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_thread_ldap_connection(): if not hasattr(ldapcache, 'connection'): conn = ipaldap.LDAPClient( ldap_uri=APP.config['LDAP_SERVER'], cacert=APP.config['LDAP_CACERT'], ) with private_ccache() as ccache: kinit_keytab( principal='%s@%s' % (APP.config['KRB5_PRINCIPAL'], APP.config['KRB5_REALM']), keytab=APP.config['KRB5_KEYTAB'], ccache_name=ccache, ) conn.gssapi_bind() ldapcache.connection = conn return ldapcache.connection
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 bind(ldap_uri, base_dn, username, password): if not base_dn: logger.error('migration unable to get base dn') raise IOError(errno.EIO, 'Cannot get Base DN') bind_dn = DN(('uid', username), ('cn', 'users'), ('cn', 'accounts'), base_dn) try: conn = ipaldap.LDAPClient(ldap_uri) conn.simple_bind(bind_dn, password) except (errors.ACIError, errors.DatabaseError, errors.NotFound) as e: logger.error('migration invalid credentials for %s: %s', bind_dn, e) raise IOError(errno.EPERM, 'Invalid LDAP credentials for user %s' % username) except Exception as e: logger.error('migration bind failed: %s', e) raise IOError(errno.EIO, 'Bind error') finally: 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 bind(ldap_uri, base_dn, username, password): if not base_dn: logger.error('migration unable to get base dn') raise IOError(errno.EIO, 'Cannot get Base DN') bind_dn = DN(('uid', username), ('cn', 'users'), ('cn', 'accounts'), base_dn) # ldap_uri should be ldapi:// in all common cases. Enforce start_tls just # in case it's a plain LDAP connection. start_tls = ldap_uri.startswith('ldap://') try: conn = ipaldap.LDAPClient(ldap_uri, start_tls=start_tls) conn.simple_bind(bind_dn, password) except (errors.ACIError, errors.DatabaseError, errors.NotFound) as e: logger.error('migration invalid credentials for %s: %s', bind_dn, e) raise IOError(errno.EPERM, 'Invalid LDAP credentials for user %s' % username) except Exception as e: logger.error('migration bind failed: %s', e) raise IOError(errno.EIO, 'Bind error') finally: 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 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 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 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 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 __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 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
if __name__ == '__main__': # this is debugging mode # print information we think are useful to stdout # other garbage goes via logger to stderr ipa_log_manager.standard_logging_setup(debug=True) # IPA framework initialization # no logging to file ipalib.api.bootstrap(in_server=True, log=None, confdir=paths.ETC_IPA) ipalib.api.finalize() # LDAP initialization dns_dn = DN(ipalib.api.env.container_dns, ipalib.api.env.basedn) ldap = ipaldap.LDAPClient(ipalib.api.env.ldap_uri) logger.debug('Connecting to LDAP') # GSSAPI will be used, used has to be kinited already ldap.gssapi_bind() logger.debug('Connected') ldapkeydb = LdapKeyDB( ldap, DN(('cn', 'keys'), ('cn', 'sec'), ipalib.api.env.container_dns, ipalib.api.env.basedn)) print('replica public keys: CKA_WRAP = TRUE') print('====================================') for pubkey_id, pubkey in ldapkeydb.replica_pubkeys_wrap.items(): print(hexlify(pubkey_id)) pprint(pubkey)
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)