Beispiel #1
0
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
Beispiel #2
0
    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()
Beispiel #3
0
    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()
Beispiel #4
0
    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()
Beispiel #5
0
    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()
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
    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)
Beispiel #9
0
    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)
Beispiel #10
0
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)
Beispiel #11
0
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)
Beispiel #12
0
 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)
Beispiel #13
0
 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
Beispiel #14
0
    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()
Beispiel #15
0
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"])
Beispiel #16
0
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'])
Beispiel #17
0
    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()
Beispiel #18
0
 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
         )
Beispiel #19
0
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'])
Beispiel #20
0
    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)
Beispiel #21
0
    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
Beispiel #22
0
    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
Beispiel #23
0
    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)
Beispiel #24
0
    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()
Beispiel #25
0
    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()
Beispiel #26
0
    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()
Beispiel #27
0
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
Beispiel #28
0
    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
Beispiel #30
0
    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)
Beispiel #31
0
    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
Beispiel #32
0
    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()
Beispiel #33
0
    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
Beispiel #34
0
    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'))
Beispiel #35
0
    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)
Beispiel #36
0
    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
Beispiel #37
0
    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
Beispiel #38
0
    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)
Beispiel #39
0
    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)
Beispiel #40
0
    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)
Beispiel #41
0
    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
            )
Beispiel #42
0
    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]
Beispiel #43
0
    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)
Beispiel #44
0
    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]
Beispiel #45
0
    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
Beispiel #47
0
    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)
Beispiel #48
0
    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)