示例#1
0
def connect(ldapi=False, realm=None, fqdn=None, dm_password=None, pw_name=None):
    """Create a connection for updates"""
    if ldapi:
        conn = ipaldap.IPAdmin(ldapi=True, realm=realm, decode_attrs=False)
    else:
        conn = ipaldap.IPAdmin(fqdn, ldapi=False, realm=realm, decode_attrs=False)
    try:
        if dm_password:
            conn.do_simple_bind(binddn=DN(('cn', 'directory manager')),
                                bindpw=dm_password)
        elif os.getegid() == 0:
            try:
                # autobind
                conn.do_external_bind(pw_name)
            except errors.NotFound:
                # Fall back
                conn.do_sasl_gssapi_bind()
        else:
            conn.do_sasl_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
示例#2
0
def dnssec_container_exists(fqdn,
                            suffix,
                            dm_password=None,
                            ldapi=False,
                            realm=None,
                            autobind=ipaldap.AUTOBIND_DISABLED):
    """
    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
        if ldapi:
            conn = ipaldap.IPAdmin(host=fqdn, ldapi=True, realm=realm)
        else:
            conn = ipaldap.IPAdmin(host=fqdn, port=636, cacert=CACERT)

        conn.do_bind(dm_password, autobind=autobind)
    except ldap.SERVER_DOWN:
        raise RuntimeError(
            'LDAP server on %s is not responding. Is IPA installed?' % fqdn)

    ret = conn.entry_exists(DN(('cn', 'sec'), ('cn', 'dns'), suffix))
    conn.unbind()

    return ret
示例#3
0
    def ldap_connect(self):
        # If DM password is provided, we use it
        # If autobind was requested, attempt autobind when root and ldapi
        # If autobind was disabled or not succeeded, go with GSSAPI
        # LDAPI can be used with either autobind or GSSAPI
        # LDAPI requires realm to be set
        try:
            if self.ldapi:
                if not self.realm:
                    raise errors.NotFound(reason="realm is missing for %s" %
                                          (self))
                conn = ipaldap.IPAdmin(ldapi=self.ldapi, realm=self.realm)
            elif self.start_tls:
                conn = ipaldap.IPAdmin(self.fqdn,
                                       port=389,
                                       protocol='ldap',
                                       cacert=paths.IPA_CA_CRT,
                                       start_tls=self.start_tls)
            else:
                conn = ipaldap.IPAdmin(self.fqdn, port=389)

            conn.do_bind(self.dm_password, autobind=self.autobind)
        except Exception, e:
            root_logger.debug(
                "Could not connect to the Directory Server on %s: %s" %
                (self.fqdn, str(e)))
            raise
def make_wikitests(declarative_test_class,
                   run=False,
                   permission_acishow=False):
    yield '<h2>%s</h2>' % declarative_test_class.__name__.replace(
        '_', ' ').capitalize()
    yield 'Implemented in <tt>%s.%s</tt>' % (declarative_test_class.__module__,
                                             declarative_test_class.__name__)

    yield ''
    if declarative_test_class.__doc__:
        yield declarative_test_class.__doc__
        yield ''

    yield 'Like other tests in the test_xmlrpc suite, these tests should run '
    yield 'on a clean IPA installation, or possibly after other similar tests.'

    if run:
        ldap = ipaldap.IPAdmin()

        for cmd_name, args, opts in declarative_test_class.cleanup_commands:
            print '<!-- Run %s %s %s -->' % (cmd_name, args, opts)
            try:
                api.Command[cmd_name](*args, **opts)
            except Exception, e:
                print '<!-- %s: Err, %s: %s -->' % (cmd_name, type(e).__name__,
                                                    e)
            else:
                print '<!-- %s: OK -->' % cmd_name
示例#5
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

        self._conn = ipaldap.IPAdmin(host=api.env.host,
                                   ldapi=True,
                                   protocol='ldapi',
                                   realm=api.env.realm)

        try:
            pw_name = pwd.getpwuid(os.geteuid()).pw_name
            self._conn.do_external_bind(pw_name)
        except Exception as e:
            raise admintool.ScriptError('Unable to bind to LDAP server: %s'
                % e)
        return self._conn
示例#6
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 = urlparse.urlsplit(api.env.jsonrpc_uri).hostname
        ldap = ipaldap.IPAdmin(server)

        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']
            api.Backend.rpcclient.disconnect()

            ldap.do_sasl_gssapi_bind()

            certs = certstore.get_ca_certs(ldap, api.env.basedn,
                                           api.env.realm, ca_enabled)
        finally:
            shutil.rmtree(tmpdir)

        server_fstore = sysrestore.FileStore(paths.SYSRESTORE)
        if server_fstore.has_files():
            self.update_server(certs)

        self.update_client(certs)
示例#7
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

        self._conn = ipaldap.IPAdmin(host=api.env.host,
                                     ldapi=True,
                                     protocol='ldapi',
                                     realm=api.env.realm)

        try:
            pw_name = pwd.getpwuid(os.geteuid()).pw_name
            self._conn.do_external_bind(pw_name)
        except Exception, e:
            self.log.error("Unable to bind to LDAP server %s: %s" %
                           (self._conn.host, e))
示例#8
0
    def setup_admin(self):
        self.admin_user = "******" % self.fqdn
        self.admin_password = binascii.hexlify(os.urandom(16))

        if not self.admin_conn:
            self.ldap_connect()

        self.admin_dn = DN(('uid', self.admin_user), ('ou', 'people'),
                           ('o', 'ipaca'))

        # remove user if left-over exists
        try:
            entry = self.admin_conn.delete_entry(self.admin_dn)
        except errors.NotFound:
            pass

        # add user
        entry = self.admin_conn.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'])
        self.admin_conn.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
        master_conn = ipaldap.IPAdmin(self.master_host,
                                      port=389,
                                      protocol='ldap')
        master_conn.do_sasl_gssapi_bind()
        replication.wait_for_entry(master_conn, entry)
        del master_conn
示例#9
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:
            conn = ipaldap.IPAdmin(self.fqdn, ldapi=True, realm=self.realm)
            conn.do_external_bind('root')

            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)
示例#10
0
    def setUp(self):
        fqdn = installutils.get_fqdn()
        pwfile = api.env.dot_ipa + os.sep + ".dmpw"
        if ipautil.file_exists(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={})
        self.ld = ipaldap.IPAdmin(fqdn)
        self.ld.do_simple_bind(bindpw=self.dm_password)
        self.testdir = os.path.abspath(os.path.dirname(__file__))
        if not ipautil.file_exists(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'))
示例#11
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:
            conn = ipaldap.IPAdmin(self.fqdn, self.ds_port)
            conn.do_simple_bind(
                DN(('cn', 'Directory Manager')),
                self.dm_password)

            entry_attrs = conn.get_entry(self.admin_user, ['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)
示例#12
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 = []

        i = 0

        #now verify the server is really an IPA server
        try:
            root_logger.debug("Init LDAP connection to: %s", thost)
            if ca_cert_path:
                lh = ipaldap.IPAdmin(thost,
                                     protocol='ldap',
                                     cacert=ca_cert_path,
                                     start_tls=True,
                                     no_schema=True,
                                     decode_attrs=False,
                                     demand_cert=True)
            else:
                lh = ipaldap.IPAdmin(thost,
                                     protocol='ldap',
                                     no_schema=True,
                                     decode_attrs=False)
            try:
                lh.do_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, 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)
                lrealms.append(lres.single_value['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
            return [UNKNOWN_ERROR]
示例#13
0
def uninstall_check(installer):
    options = installer

    tasks.check_selinux_status()

    installer._installation_cleanup = False

    if not is_ipa_configured():
        print("WARNING:\nIPA server is not configured on this system. "
              "If you want to install the\nIPA server, please install "
              "it using 'ipa-server-install'.")

    fstore = sysrestore.FileStore(SYSRESTORE_DIR_PATH)
    sstore = sysrestore.StateFile(SYSRESTORE_DIR_PATH)

    # Configuration for ipalib, we will bootstrap and finalize later, after
    # we are sure we have the configuration file ready.
    cfg = dict(
        context='installer',
        in_server=True,
    )

    # We will need at least api.env, finalize api now. This system is
    # already installed, so the configuration file is there.
    api.bootstrap(**cfg)
    api.finalize()

    if installer.interactive:
        print("\nThis is a NON REVERSIBLE operation and will delete all data "
              "and configuration!\n")
        if not user_input("Are you sure you want to continue with the "
                          "uninstall procedure?", False):
            raise ScriptError("Aborting uninstall operation.")

    try:
        conn = ipaldap.IPAdmin(
            api.env.host,
            ldapi=True,
            realm=api.env.realm
        )
        conn.do_external_bind(pwd.getpwuid(os.geteuid()).pw_name)
        api.Backend.ldap2.connect(autobind=True)
        domain_level = dsinstance.get_domain_level(api)
    except Exception:
        msg = ("\nWARNING: Failed to connect to Directory Server to find "
               "information about replication agreements. Uninstallation "
               "will continue despite the possible existing replication "
               "agreements.\n\n"
               "If this server is the last instance of CA, KRA, or DNSSEC "
               "master, uninstallation may result in data loss.\n\n"
        )
        print(textwrap.fill(msg, width=80, replace_whitespace=False))

        if (installer.interactive and not user_input(
                "Are you sure you want to continue with the uninstall "
                "procedure?", False)):
            raise ScriptError("Aborting uninstall operation.")
    else:
        dns.uninstall_check(options)

        if domain_level == constants.DOMAIN_LEVEL_0:
            rm = replication.ReplicationManager(
                realm=api.env.realm,
                hostname=api.env.host,
                dirman_passwd=None,
                conn=conn
            )
            agreements = rm.find_ipa_replication_agreements()

            if agreements:
                other_masters = [a.get('cn')[0][4:] for a in agreements]
                msg = (
                    "\nReplication agreements with the following IPA masters "
                    "found: %s. Removing any replication agreements before "
                    "uninstalling the server is strongly recommended. You can "
                    "remove replication agreements by running the following "
                    "command on any other IPA master:\n" % ", ".join(
                        other_masters)
                )
                cmd = "$ ipa-replica-manage del %s\n" % api.env.host
                print(textwrap.fill(msg, width=80, replace_whitespace=False))
                print(cmd)
                if (installer.interactive and
                        not user_input("Are you sure you want to continue with"
                                       " the uninstall procedure?", False)):
                    raise ScriptError("Aborting uninstall operation.")
        else:
            remove_master_from_managed_topology(api, options)

    installer._fstore = fstore
    installer._sstore = sstore