def create_controls(pagesize, LDAP_API_CHECK):
    """Create an LDAP control with a page size of "pagesize"."""
    # Initialize the LDAP controls for paging. Note that we pass ''
    # for the cookie because on first iteration, it starts out empty.
    if LDAP_API_CHECK:
        return SimplePagedResultsControl(True, size=pagesize, cookie='')
    return SimplePagedResultsControl(ldap.LDAP_CONTROL_PAGE_OID, True,
                                     (pagesize, ''))
Пример #2
0
 def create_controls(self, pagesize):
     # Initialize the LDAP controls for paging. Note that we pass ''
     # for the cookie because on first iteration, it starts out empty.
     if LDAP24API:
         return SimplePagedResultsControl(True, size=pagesize, cookie='')
     else:
         return SimplePagedResultsControl(ldap.LDAP_CONTROL_PAGE_OID, True,
                                          (pagesize, ''))
Пример #3
0
def create_controls(pagesize):
    """
    Create an LDAP control with a page size of "pagesize".
    """
    if LDAP24API:
        return SimplePagedResultsControl(True, size=pagesize, cookie='')
    else:
        return SimplePagedResultsControl(ldap.LDAP_CONTROL_PAGE_OID, True,
                                         (pagesize, ''))
def create_ldif_from_master(lo, ldif_file, base, page_size):
    """
	create ldif file from everything from lo
	"""
    logging.info('Fetching LDIF ...')
    if ldif_file == '-':
        output = sys.stdout
    else:
        if os.path.isfile(ldif_file):
            os.unlink(ldif_file)
        output = gzip.open(ldif_file, 'wb')

    if hasattr(ldap, 'LDAP_CONTROL_PAGE_OID'):  # python-ldap <= 2.3
        logging.debug('Using old python-ldap 2.3 API')
        api24 = False
        lc = SimplePagedResultsControl(controlType=ldap.LDAP_CONTROL_PAGE_OID,
                                       criticality=True,
                                       controlValue=(page_size, ''))
        page_ctrl_oid = ldap.LDAP_CONTROL_PAGE_OID
    else:  # python-ldap >= 2.4
        logging.debug('Using new python-ldap 2.4 API')
        api24 = True
        lc = SimplePagedResultsControl(criticality=True,
                                       size=page_size,
                                       cookie='')
        page_ctrl_oid = lc.controlType

    while True:
        msgid = lo.lo.search_ext(base,
                                 ldap.SCOPE_SUBTREE,
                                 '(objectclass=*)', ['+', '*'],
                                 serverctrls=[lc])
        rtype, rdata, rmsgid, serverctrls = lo.lo.result3(msgid)

        for dn, data in rdata:
            logging.debug('Processing %s ...', dn)
            for attr in replication.EXCLUDE_ATTRIBUTES:
                data.pop(attr, None)

            output.write(ldif.CreateLDIF(dn, data, cols=10000))

        pctrls = [c for c in serverctrls if c.controlType == page_ctrl_oid]
        if pctrls:
            if api24:
                cookie = lc.cookie = pctrls[0].cookie
            else:
                _est, cookie = pctrls[0].controlValue
                lc.controlValue = (page_size, cookie)

            if not cookie:
                break
        else:
            logging.warning(
                "Server ignores RFC 2696 Simple Paged Results Control.")
            break

    output.close()
Пример #5
0
def create_controls(pagesize):
    """Create an LDAP control with a page size of "pagesize"."""
    # Initialize the LDAP controls for paging. Note that we pass ''
    # for the cookie because on first iteration, it starts out empty.
    LDAP24API = StrictVersion(ldap.__version__) >= StrictVersion('2.4')
    if LDAP24API:
        return SimplePagedResultsControl(True, size=pagesize, cookie='')
    else:
        return SimplePagedResultsControl(ldap.LDAP_CONTROL_PAGE_OID, True,
                                         (pagesize, ''))
Пример #6
0
    def _paged_search(self, base_dn, scope, search_filter, attrs):
        conn = self.connect()

        # Get paged results to prevent exceeding server size limit
        page_size = 1000
        if PYTHON_LDAP_24:
            lc = SimplePagedResultsControl(size=page_size, cookie='')
        else:
            lc = SimplePagedResultsControl(LDAP_CONTROL_PAGED_RESULTS,
                                           True,
                                           (page_size, ''),)
        is_last_page = False
        results = []

        while not is_last_page:
            msgid = conn.search_ext(base_dn,
                                    scope,
                                    search_filter,
                                    attrs,
                                    serverctrls=[lc])

            rtype, rdata, rmsgid, serverctrls = conn.result3(msgid)
            pctrls = [c for c in serverctrls
                      if c.controlType == LDAP_CONTROL_PAGED_RESULTS]

            results.extend(rdata)

            if pctrls:
                if PYTHON_LDAP_24:
                    cookie = pctrls[0].cookie
                    if cookie:
                        lc.cookie = cookie
                    else:
                        is_last_page = True
                else:
                    cookie = pctrls[0].controlValue[1]
                    if cookie:
                        # lc.controlValue seems to have been mutable at some
                        # point, now it's a tuple.
                        cv = list(lc.controlValue)
                        cv[1] = cookie
                        lc.controlValue = tuple(cv)
                    else:
                        is_last_page = True
            else:
                is_last_page = True
                if results:
                    # If the search returned an empty result, page controls
                    # aren't included - so don't produce a bogus warning
                    logger.warn(
                        "Server ignores paged results control (RFC 2696).")

        return results
Пример #7
0
def ldap_search(username):
    auth_info = AuthMode.get_or_none(AuthMode.mode == "LDAP")
    if not auth_info:
        return

    auth_info = model_to_dict(auth_info)

    config = json.loads(auth_info.get('config'))
    host = config.get('host')
    port = config.get('port')
    Server = "ldap://{}:{}".format(host, port)
    baseDN = config.get('basedn')

    ldapuser = config.get('account') or ""
    ldappass = config.get('password') or ""

    dn = ""
    try:
        conn = ldap.initialize(Server)
        retrieveAttributes = [
            'name', 'sAMAccountName', 'searchFiltername', 'mail'
        ]
        conn.protocol_version = ldap.VERSION3
        conn.simple_bind_s(ldapuser, ldappass)

        searchScope = ldap.SCOPE_SUBTREE
        searchFiltername = config.get("loginname_property") or "sAMAccountName"
        searchFilter = '{}=*{}*'.format(searchFiltername, username)

        pg_ctrl = SimplePagedResultsControl(True, size=20, cookie="")
        ldap_result = conn.search_ext_s(baseDN,
                                        searchScope,
                                        searchFilter,
                                        retrieveAttributes,
                                        serverctrls=[pg_ctrl])

        r1 = []
        pg_ctrl = SimplePagedResultsControl(True, size=20, cookie="")
        searchFilter = 'name=*{}*'.format(username)
        r1 = conn.search_ext_s(baseDN,
                               searchScope,
                               searchFilter,
                               retrieveAttributes,
                               serverctrls=[pg_ctrl])

        return True, list(ldap_result) + list(r1)

    except Exception as e:
        return False, str(e)

    return True, []
Пример #8
0
def test_ger_basic(topology_st, create_user):
    """Verify that search with a simple paged results control
    and get effective rights control returns all entries
    it should without errors.

    :id: 7b0bdfc7-a2f2-4c1a-bcab-f1eb8b330d45
    :setup: Standalone instance, test user for binding,
            varying number of users for the search base
    :steps:
        1. Search through added users with a simple paged control
           and get effective rights control
    :expectedresults:
        1. All users should be found, every found entry should have
           an 'attributeLevelRights' returned
    """

    users_list = add_users(topology_st, 20, DEFAULT_SUFFIX)
    search_flt = r'(uid=test*)'
    searchreq_attrlist = ['dn', 'sn']
    page_size = 4

    try:
        spr_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
        ger_ctrl = GetEffectiveRightsControl(True, ensure_bytes("dn: " + DN_DM))

        all_results = paged_search(topology_st.standalone, DEFAULT_SUFFIX, [spr_ctrl, ger_ctrl],
                                   search_flt, searchreq_attrlist)

        log.info('{} results'.format(len(all_results)))
        assert len(all_results) == len(users_list)
        log.info('Check for attributeLevelRights')
        assert all(attrs['attributeLevelRights'][0] for dn, attrs in all_results)
    finally:
        log.info('Remove added users')
        del_users(users_list)
Пример #9
0
    def get_all_users(self, username, password):

        base_dn = 'OU=上海二三四五网络科技有限公司,DC=trump,DC=local'
        self.l.simple_bind_s(username + "@trump.local", password)

        PAGE_SIZE = 500  # 设置每页返回的条数
        pg_ctrl = SimplePagedResultsControl(True, size=PAGE_SIZE, cookie="")
        userdata = []
        retdata = []

        while True:
            msgid = self.l.search_ext(base_dn,
                                      ldap.SCOPE_SUBTREE,
                                      "(&(objectClass=person))",
                                      None,
                                      serverctrls=[pg_ctrl])
            _a, res_data, _b, srv_ctrls = self.l.result3(msgid)
            userdata.extend(res_data)
            cookie = srv_ctrls[0].cookie
            if cookie:
                pg_ctrl.cookie = cookie
            else:
                break
        print('totalnum:', len(userdata))
        for u in userdata:
            retdict = {}
            for k, v in u[1].items():
                retdict[k] = v[0]
            retdata.append(retdict)
        return retdata
Пример #10
0
def _create_controls(pagesize):
    """Create an LDAP control with a page size of "pagesize"."""
    # Initialize the LDAP controls for paging. Note that we pass ''
    # for the cookie because on first iteration, it starts out empty.
    return SimplePagedResultsControl(criticality=True,
                                     size=pagesize,
                                     cookie="")
Пример #11
0
def test_maxsimplepaged_per_conn_failure(topology_st, create_user,
                                         conf_attr_value):
    """Verify that nsslapd-maxsimplepaged-per-conn acts according design

    :id: eb609e63-2829-4331-8439-a35f99694efa
    :customerscenario: True
    :parametrized: yes
    :setup: Standalone instance, test user for binding,
            20 users for the search base
    :steps:
        1. Set nsslapd-maxsimplepaged-per-conn = 0 in cn=config
        2. Search through the added users with a simple paged control
           using page size = 4
        3. Set nsslapd-maxsimplepaged-per-conn = 1 in cn=config
        4. Search through the added users with a simple paged control
           using page size = 4 two times, but don't close the connections
    :expectedresults:
        1. nsslapd-maxsimplepaged-per-conn should be successfully set
        2. UNWILLING_TO_PERFORM should be thrown
        3. Bind should be successful
        4. UNWILLING_TO_PERFORM should be thrown
    """

    users_list = add_users(topology_st, 20, DEFAULT_SUFFIX)
    search_flt = r'(uid=test*)'
    searchreq_attrlist = ['dn', 'sn']
    page_size = 4
    max_per_con_bck = change_conf_attr(topology_st, DN_CONFIG,
                                       'nsslapd-maxsimplepaged-per-conn',
                                       conf_attr_value)

    try:
        log.info('Set user bind')
        conn = create_user.bind(TEST_USER_PWD)

        log.info('Create simple paged results control instance')
        req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')

        with pytest.raises(ldap.UNWILLING_TO_PERFORM):
            msgid = conn.search_ext(DEFAULT_SUFFIX,
                                    ldap.SCOPE_SUBTREE,
                                    search_flt,
                                    searchreq_attrlist,
                                    serverctrls=[req_ctrl])
            rtype, rdata, rmsgid, rctrls = conn.result3(msgid)

            # If nsslapd-maxsimplepaged-per-conn = 1,
            # it should pass this point, but failed on the next search
            assert conf_attr_value == '1'
            msgid = conn.search_ext(DEFAULT_SUFFIX,
                                    ldap.SCOPE_SUBTREE,
                                    search_flt,
                                    searchreq_attrlist,
                                    serverctrls=[req_ctrl])
            rtype, rdata, rmsgid, rctrls = conn.result3(msgid)
    finally:
        log.info('Remove added users')
        del_users(users_list)
        change_conf_attr(topology_st, DN_CONFIG,
                         'nsslapd-maxsimplepaged-per-conn', max_per_con_bck)
Пример #12
0
def test_search_success(topology_st, test_user, page_size, users_num):
    """Verify that search with a simple paged results control
    returns all entries it should without errors.

    :id: ddd15b70-64f1-4a85-a793-b24761e50354
    :feature: Simple paged results
    :setup: Standalone instance, test user for binding,
            varying number of users for the search base
    :steps:
        1. Bind as test user
        2. Search through added users with a simple paged control
    :expectedresults:
        1. Bind should be successful
        2. All users should be found
    """

    users_list = add_users(topology_st, users_num, DEFAULT_SUFFIX)
    search_flt = r'(uid=test*)'
    searchreq_attrlist = ['dn', 'sn']

    log.info('Set user bind %s ' % test_user)
    conn = test_user.bind(TEST_USER_PWD)

    req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
    all_results = paged_search(conn, DEFAULT_SUFFIX, [req_ctrl], search_flt,
                               searchreq_attrlist)

    log.info('%d results' % len(all_results))
    assert len(all_results) == len(users_list)

    del_users(users_list)
Пример #13
0
	def pagedsearch(self, search_flt, searchreq_attrlist):
		req_ctrl = SimplePagedResultsControl(True,size=self.page_size,cookie='')
		known_ldap_resp_ctrls = { SimplePagedResultsControl.controlType:SimplePagedResultsControl,}

		# Send search request
		msgid = self.lcon.search_ext( self.base, ldap.SCOPE_SUBTREE, search_flt, attrlist=searchreq_attrlist, serverctrls=[req_ctrl])

		pages = 0
		i = 0

		while True:
			pages += 1
			rtype, rdata, rmsgid, serverctrls = self.lcon.result3(msgid,resp_ctrl_classes=known_ldap_resp_ctrls)

			yield rdata

			pctrls = [c for c in serverctrls if c.controlType == SimplePagedResultsControl.controlType]
			if pctrls:
				if pctrls[0].cookie:
				  # Copy cookie from response control to request control
					req_ctrl.cookie = pctrls[0].cookie
					msgid = self.lcon.search_ext(self.base,ldap.SCOPE_SUBTREE,search_flt,attrlist=searchreq_attrlist,serverctrls=[req_ctrl])
				else:
					break
			else:
				print "Warning: Server ignores RFC 2696 control."
				break
Пример #14
0
def search(base_dn, search_filter, attributes):
    """Iterative LDAP search using page control.

    :param base_dn: str -- The base DN from which to start the search.
    :param search_filter: str -- Representation of the filter to apply
                          in the search.
    :param attributes: list -- Attributes to be retrieved for each
                       entry. If ``None``, all attributes will be
                       retrieved.
    :returns: A generator which yields one search result at a time as a
              tuple containing a `dn` as ``str`` and `attributes` as
              ``dict``.
    """
    connection, settings = current_ldap
    page_ctrl = SimplePagedResultsControl(True, size=settings['page_size'], cookie='')
    search_filter = search_filter.encode('utf-8')

    while True:
        msg_id = connection.search_ext(base_dn, SCOPE_SUBTREE, filterstr=search_filter, attrlist=attributes,
                                       serverctrls=[page_ctrl], timeout=settings['timeout'])
        try:
            _, r_data, __, server_ctrls = connection.result3(msg_id, timeout=settings['timeout'])
        except NO_SUCH_OBJECT:
            break

        for dn, entry in r_data:
            if dn:
                yield dn, entry

        page_ctrl.cookie = get_page_cookie(server_ctrls)
        if not page_ctrl.cookie:
            # End of results
            break
Пример #15
0
def get_ldap_list_membership(l, search_strings, list_name):
    results = set()
    known_ldap_resp_ctrls = {
        SimplePagedResultsControl.controlType: SimplePagedResultsControl,
    }
    req_ctrl = SimplePagedResultsControl(True, size=ldap_pagination_size, cookie='')
    while True:
        msgid = l.search_ext(search_strings['user_search_string'],
                             ldap.SCOPE_SUBTREE,
                             serverctrls=[req_ctrl],
                             attrlist=[search_strings['user_account_name_field']],
                             filterstr=search_strings['user_membership_filter'] % escape_filter_chars(list_name)
                             )
        rtype, rdata, rmsgid, serverctrls = l.result3(msgid, resp_ctrl_classes=known_ldap_resp_ctrls)

        results |= {data[1][search_strings['user_account_name_field']][0] for data in rdata}

        pctrls = [c for c in serverctrls
                  if c.controlType == SimplePagedResultsControl.controlType]

        cookie = pctrls[0].cookie
        if not cookie:
            break
        req_ctrl.cookie = cookie

    return results
Пример #16
0
def test_multi_suffix_search(topology_st, test_user, new_suffixes):
    """Verify that page result search returns empty cookie
    if there is no returned entry.

    :id: 9712345b-9e38-4df6-8794-05f12c457d39
    :setup: Standalone instance, test user for binding,
            two suffixes with backends, one is inserted into another,
            10 users for the search base within each suffix
    :steps:
        1. Bind as test user
        2. Search through all 20 added users with a simple paged control
           using page_size = 4
        3. Wait some time for the logs to be updated
        4. Check access log
    :expectedresults:
        1. Bind should be successful
        2. All users should be found
        3. Some time should pass
        4. The access log should contain the pr_cookie for each page request
           and it should be equal 0, except the last one should be equal -1
    """

    search_flt = r'(uid=test*)'
    searchreq_attrlist = ['dn', 'sn']
    page_size = 4
    users_num = 20

    log.info('Clear the access log')
    topology_st.standalone.deleteAccessLogs()

    users_list_1 = add_users(topology_st, 10, NEW_SUFFIX_1)
    users_list_2 = add_users(topology_st, 10, NEW_SUFFIX_2)

    try:
        req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')

        all_results = paged_search(topology_st.standalone, NEW_SUFFIX_1,
                                   [req_ctrl], search_flt, searchreq_attrlist)

        log.info('{} results'.format(len(all_results)))
        assert len(all_results) == users_num

        log.info('Restart the server to flush the logs')
        topology_st.standalone.restart(timeout=10)

        access_log_lines = topology_st.standalone.ds_access_log.match(
            '.*pr_cookie=.*')
        pr_cookie_list = ([
            line.rsplit('=', 1)[-1] for line in access_log_lines
        ])
        pr_cookie_list = [int(pr_cookie) for pr_cookie in pr_cookie_list]
        log.info('Assert that last pr_cookie == -1 and others pr_cookie == 0')
        pr_cookie_zeros = list(pr_cookie == 0
                               for pr_cookie in pr_cookie_list[0:-1])
        assert all(pr_cookie_zeros)
        assert pr_cookie_list[-1] == -1
    finally:
        log.info('Remove added users')
        del_users(users_list_1)
        del_users(users_list_2)
Пример #17
0
    def search(self, name, base, get_disabled=False):
        """
        Return a list of results, searching by name
        :param name: the string to search for
        :param base: the string "people" or "companies" to choose the base of what we are searching for
        :param get_disabled: true if we are going to find non-active users as well
        :return:
        """
        if base == 'companies':
            ldap_filter = ldap.filter.filter_format('cn=%s*', [name])
        elif ' ' in name:
            ldap_filter = ldap.filter.filter_format('|(cn~=%s)(cn=%s*)',
                                                    [name, name])
        else:
            ldap_filter = ldap.filter.filter_format(
                '|(cn~=%s)(cn=%s*)(sn=%s*)', [name, name, name])

        if not get_disabled:
            ldap_filter = '(&(active=TRUE)(%s))' % ldap_filter

        paged_control = SimplePagedResultsControl(
            True, size=LdapService.SEARCH_LIMIT, cookie='')
        ldap_response = self.ldap_connection.search_ext_s(
            LdapService.LDAP_BASES[base],
            ldap.SCOPE_SUBTREE,
            ldap_filter,
            serverctrls=[paged_control])

        if ldap_response is None:
            return []
        return self.map_ldap_response(ldap_response, base)
Пример #18
0
    def get_paged_users(self, filters, attributes):
        pages = 0
        result = []

        page_control = SimplePagedResultsControl(True, size=self.page_size, cookie='')
        res = self._conn.search_ext(
            self.domain_dn,
            ldap.SCOPE_SUBTREE,
            filters,
            attributes,
            serverctrls=[page_control]
        )

        while True:
            pages += 1
            self.log.debug("Page {} done".format(pages))
            rtype, rdata, rmsgid, serverctrls = self._conn.result3(res)
            result.extend(rdata)
            controls = [ctrl for ctrl in serverctrls if ctrl.controlType == SimplePagedResultsControl.controlType]
            if not controls:
                self.log.error('The server ignores RFC 2696 control')
                break
            if not controls[0].cookie:
                break
            page_control.cookie = controls[0].cookie
            res = self._conn.search_ext(
                self.domain_dn,
                ldap.SCOPE_SUBTREE,
                filters,
                attributes,
                serverctrls=[page_control]
            )
        return result
Пример #19
0
            def _pagedSearch(self,
                             attributes: str,
                             searchString: str = None,
                             pageSize: int = 1000,
                             bookmark: str = ''):
                """
                searchString: The LDAP query

                attributes: the desired attributes returned from the query.

                pageSize: number of results this function should return.

                bookmark: if previous pages already returned, this is the
                bookmark for the next page.

                returns: a tuple containing a tuple attributes per user returned
                by the query and the bookmark for the next page.
                """
                pagecontrol = SimplePagedResultsControl(True,
                                                        size=self._maxSize,
                                                        cookie=bookmark)
                response = self._ld.search_ext(self._baseUserDN,
                                               ldap.SCOPE_SUBTREE,
                                               searchString,
                                               attributes,
                                               serverctrls=[pagecontrol])

                rtype, rdata, rmsgid, serverctrls = self._ld.result3(response)
                controls = [
                    control for control in serverctrls if control.controlType
                    == SimplePagedResultsControl.controlType
                ]

                return (rdata, controls[0].cookie)
Пример #20
0
def open_ldap(url,base,search_flt,page_size=default_page_size):
   ldap.set_option(ldap.OPT_REFERRALS, 0)
   l = ldap.initialize(url)
   l.protocol_version = 3

   sasl_auth=ldap.sasl.sasl({},'GSSAPI')
   try:
      l.sasl_interactive_bind_s('',sasl_auth)
   except ldap.LOCAL_ERROR:
      print "Error: missing credential - Please run kinit"
      sys.exit()

   lc = SimplePagedResultsControl(
      ldap.LDAP_CONTROL_PAGE_OID,True,(page_size,'')
   )

   # Send search request
   msgid = l.search_ext(
     base,
     ldap.SCOPE_SUBTREE,
     search_flt,
     serverctrls=[lc]
   )

   return l,lc,msgid
Пример #21
0
    def find_users_by_name(self, keyword):
        keyword = re.sub('[^a-z\s]+', '', keyword)
        ldap_filter = "(&(objectClass=user)(givenName=*)(name=*" + keyword + "*))"
        attrs = [
            "displayName", "givenName", "sn", "company", "mail",
            "streetAddress", "l", "st", "co"
        ]

        lc = SimplePagedResultsControl(ldap.LDAP_CONTROL_PAGE_OID, True,
                                       (PAGE_SIZE, ''))

        scope = ldap.SCOPE_SUBTREE
        msgid = self.l.search_ext(self.base,
                                  scope,
                                  ldap_filter,
                                  attrs,
                                  serverctrls=[lc])

        persons = []

        pages = 0
        while True:
            pages += 1
            #print "Getting page %d" % (pages,)

            # successive tries sometimes result in unavailable messages
            tries = 5
            try:
                rtype, rdata, rmsgid, serverctrls = self.l.result3(msgid)
            except ldap.UNAVAILABLE_CRITICAL_EXTENSION, e:
                print "LDAP Error: " + str(e)
                return persons

            #print '%d results' % len(rdata)
            for search, attrs in rdata:
                try:
                    if attrs.has_key('givenName') and attrs.has_key(
                            'displayName'):
                        persons.append({
                            "name":
                            attrs.get('displayName', [''])[0],
                            "given_name":
                            attrs.get('givenName', [''])[0],
                            "surname":
                            attrs.get('sn', [''])[0],
                            "street":
                            attrs.get('streetAddress', [''])[0],
                            "city":
                            attrs.get('l', [''])[0],
                            "state":
                            attrs.get('st', [''])[0],
                            "country":
                            attrs.get('co', [''])[0],
                            "company":
                            attrs.get('company', [''])[0],
                            "email":
                            attrs.get('mail', [''])[0]
                        })
                except AttributeError, e:
                    print "Error: %s, skipping..." % str(e)
Пример #22
0
def get_ldap_lists(l, search_strings, parent_list=None):
    results = set()
    known_ldap_resp_ctrls = {
        SimplePagedResultsControl.controlType: SimplePagedResultsControl,
    }
    req_ctrl = SimplePagedResultsControl(True, size=ldap_pagination_size, cookie='')

    if parent_list:
        filterstr = search_strings['get_all_sub_lists_filter'] % escape_filter_chars(parent_list)
    else:
        filterstr = search_strings['get_all_lists_filter']

    while True:
        msgid = l.search_ext(search_strings['list_search_string'],
                             ldap.SCOPE_SUBTREE,
                             serverctrls=[req_ctrl],
                             attrlist=(search_strings['list_cn_field'], search_strings['list_name_field']),
                             filterstr=filterstr)
        rtype, rdata, rmsgid, serverctrls = l.result3(msgid, resp_ctrl_classes=known_ldap_resp_ctrls)

        results |= {(data[search_strings['list_cn_field']][0], data[search_strings['list_name_field']][0]) for (dn, data) in rdata}

        pctrls = [c for c in serverctrls
                  if c.controlType == SimplePagedResultsControl.controlType]

        cookie = pctrls[0].cookie
        if not cookie:
            break
        req_ctrl.cookie = cookie

    return results
Пример #23
0
def results_for_dn(directory: ldap.ldapobject, base_dn: str,
                   filter: str) -> List[User]:
    """Returns a list of User objects found in the directory object for filter

    :param directory: A ldap.LDAPObject that has already been bound to a
        directory.

    :param base_dn: The base of the directory tree to run the search filter
        against.

    :param filter: The LDAP search filter to run on base_dn using directory.
    """
    req_ctrl = SimplePagedResultsControl(True, size=5000, cookie="")

    known_ldap_resp_ctrls = {
        SimplePagedResultsControl.controlType: SimplePagedResultsControl,
    }

    # Send search request
    msgid = directory.search_ext(base_dn,
                                 ldap.SCOPE_SUBTREE,
                                 filterstr=LDAP_FILTER,
                                 serverctrls=[req_ctrl])

    results = []
    while True:
        __, result_data, __, serverctrls = directory.result3(
            msgid, resp_ctrl_classes=known_ldap_resp_ctrls)

        results.extend([
            User(
                ldap_entry["sAMAccountName"][0].decode(),
                ldap_entry["mail"][0].decode(),
                ldap_entry["sn"][0].decode(),
                ldap_entry["givenName"][0].decode(),
            ) for __, ldap_entry in result_data
        ])

        page_controls = [
            control for control in serverctrls
            if control.controlType == SimplePagedResultsControl.controlType
        ]
        if page_controls:
            if page_controls[0].cookie:
                # Copy cookie from response control to request control
                req_ctrl.cookie = page_controls[0].cookie
                msgid = directory.search_ext(
                    base_dn,
                    ldap.SCOPE_SUBTREE,
                    filterstr=LDAP_FILTER,
                    serverctrls=[req_ctrl],
                )
            else:
                break
        else:
            eprint("Warning: Server ignores RFC 2696 control.")
            break

    return results
Пример #24
0
def test_search_multiple_paging(topology_st, create_user):
    """Verify that after performing multiple simple paged searches
    on a single connection without a complition, it wouldn't fail.

    :id: 628b29a6-2d47-4116-a88d-00b87405ef7f
    :customerscenario: True
    :setup: Standalone instance, test user for binding,
            varying number of users for the search base
    :steps:
        1. Bind as test user
        2. Initiate the search with a simple paged control
        3. Acquire the returned cookie only one time
        4. Perform steps 2 and 3 three times in a row
    :expectedresults:
        1. Bind should be successful
        2. Search should be successfully initiated
        3. Cookie should be successfully acquired
        4. No error happens
    """

    users_num = 100
    page_size = 30
    users_list = add_users(topology_st, users_num, DEFAULT_SUFFIX)
    search_flt = r'(uid=test*)'
    searchreq_attrlist = ['dn', 'sn']

    try:
        log.info('Set user bind')
        conn = create_user.bind(TEST_USER_PWD)

        log.info('Create simple paged results control instance')
        req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
        controls = [req_ctrl]

        for ii in range(3):
            log.info('Iteration %d' % ii)
            msgid = conn.search_ext(DEFAULT_SUFFIX,
                                    ldap.SCOPE_SUBTREE,
                                    search_flt,
                                    searchreq_attrlist,
                                    serverctrls=controls)
            rtype, rdata, rmsgid, rctrls = conn.result3(msgid)
            pctrls = [
                c for c in rctrls
                if c.controlType == SimplePagedResultsControl.controlType
            ]

            # Copy cookie from response control to request control
            req_ctrl.cookie = pctrls[0].cookie
            msgid = conn.search_ext(DEFAULT_SUFFIX,
                                    ldap.SCOPE_SUBTREE,
                                    search_flt,
                                    searchreq_attrlist,
                                    serverctrls=controls)
    finally:
        del_users(users_list)
Пример #25
0
def get_ldap_lists(l, search_strings, parent_list=None):
    results = set()
    known_ldap_resp_ctrls = {
        SimplePagedResultsControl.controlType: SimplePagedResultsControl,
    }
    req_ctrl = SimplePagedResultsControl(True, size=ldap_pagination_size, cookie='')

    if parent_list:
        filterstr = search_strings['get_all_sub_lists_filter'] % escape_filter_chars(parent_list)
    else:
        filterstr = search_strings['get_all_lists_filter']

    while True:
        msgid = l.search_ext(search_strings['list_search_string'],
                             ldap.SCOPE_SUBTREE,
                             serverctrls=[req_ctrl],
                             attrlist=(search_strings['list_cn_field'], search_strings['list_name_field']),
                             filterstr=filterstr)

        retries = 0
        rdata = None
        while retries < 5:
            try:
                rtype, rdata, rmsgid, serverctrls = l.result3(msgid, timeout=ldap_timeout, resp_ctrl_classes=known_ldap_resp_ctrls)
            except Exception:
                logger.exception('Error getting ldap list memberships')
                retries += 1
            else:
                break
        # ldap sometimees returns good but does not return rdata
        if rdata is None:
            break
        for (dn, data) in rdata:
            cn_field = data[search_strings['list_cn_field']][0]
            name_field = data[search_strings['list_name_field']][0]

            if isinstance(cn_field, bytes):
                cn_field = cn_field.decode('utf-8')
            if isinstance(name_field, bytes):
                name_field = name_field.decode('utf-8')

            results |= {(cn_field, name_field)}

        pctrls = [c for c in serverctrls
                  if c.controlType == SimplePagedResultsControl.controlType]

        if not pctrls:
            # Paging not supported
            logger.debug('LDAP pagination not supported')
            break
        cookie = pctrls[0].cookie
        if not cookie:
            break
        req_ctrl.cookie = cookie

    return results
Пример #26
0
    def _search(self,
                basedn='',
                scope=pyldap.SCOPE_SUBTREE,
                filter='',
                timeout=-1,
                sizelimit=0):
        if not self._handle:
            self._open()

        result = []
        serverctrls = None
        clientctrls = None
        paged = SimplePagedResultsControl(criticality=False,
                                          size=self.pagesize,
                                          cookie='')
        paged_ctrls = {
            SimplePagedResultsControl.controlType: SimplePagedResultsControl
        }

        page = 0
        while True:
            serverctrls = [paged]

            id = self._handle.search_ext(basedn,
                                         scope,
                                         filterstr=filter,
                                         attrlist=None,
                                         attrsonly=0,
                                         serverctrls=serverctrls,
                                         clientctrls=clientctrls,
                                         timeout=timeout,
                                         sizelimit=sizelimit)

            (rtype, rdata, rmsgid,
             serverctrls) = self._handle.result3(id,
                                                 resp_ctrl_classes=paged_ctrls)

            result.extend(rdata)

            paged.size = 0
            paged.cookie = cookie = None
            for sc in serverctrls:
                if sc.controlType == SimplePagedResultsControl.controlType:
                    cookie = sc.cookie
                    if cookie:
                        paged.cookie = cookie
                        paged.size = self.pagesize

                        break

            if not cookie:
                break

            page += 1

        return result
Пример #27
0
    def handle(self, *args, **options):
        filter_string = options.get('filter', DEFAULT_FILTER)

        ldap_backend = LDAPBackend()
        ldap_user = _LDAPUser(backend=ldap_backend, username='')
        ldap_connection = ldap_user.connection

        # Initialize the LDAP controls for paging.
        # Note that we pass '' for the cookie because on first iteration, it starts out empty.
        ldap_controls = SimplePagedResultsControl(True,
                                                  size=PAGE_SIZE,
                                                  cookie='')

        while True:
            # Send search request
            # If you leave out the ATTRLIST it'll return all attributes which you have permissions to access.
            # You may want to adjust the scope level as well
            # (perhaps "ldap.SCOPE_SUBTREE", but it can reduce performance if you don't need it).
            message_id = ldap_connection.search_ext(
                base=settings.AUTH_LDAP_USER_SEARCH.base_dn,
                scope=ldap.SCOPE_SUBTREE,
                filterstr=filter_string,
                serverctrls=[ldap_controls])

            # Pull the results from the search request
            rtype, rdata, rmsgid, server_controls = ldap_connection.result3(
                message_id)
            rdata = settings.AUTH_LDAP_USER_SEARCH._process_results(rdata)

            # Each "rdata" is a tuple of the form (dn, attrs), where dn is a string containing the
            # DN (distinguished name) of the entry, and attrs is a dictionary containing the attributes associated
            # with the entry. The keys of attrs are strings, and the associated values are lists of strings.

            for distinguished_name, attributes in rdata:
                username = "".join(attributes['uid'])
                print(f"{username} \t| {distinguished_name}")
                print(attributes)

            # Look through the returned controls and find the page controls.
            # This will also have our returned cookie which we need to make the next search request.
            page_controls = [
                control for control in server_controls
                if control.controlType == SimplePagedResultsControl.controlType
            ]
            if not page_controls:
                print('Warning: Server ignores RFC 2696 control.')
                break

            # Ok, we did find the page control, yank the cookie from it and insert it into the control for our
            # next search. If however there is no cookie, we are done!

            cookie = page_controls[0].cookie
            ldap_controls.cookie = cookie
            if not cookie:
                break
Пример #28
0
def test_search_invalid_cookie(topology_st, create_user, invalid_cookie):
    """Verify that using invalid cookie while performing
    search with the simple paged results control throws
    a TypeError exception

    :id: 107be12d-4fe4-47fe-ae86-f3e340a56f42
    :customerscenario: True
    :parametrized: yes
    :setup: Standalone instance, test user for binding,
            varying number of users for the search base
    :steps:
        1. Bind as test user
        2. Initiate the search with a simple paged control
        3. Put an invalid cookie (-1, 1000) to the control
        4. Continue the search
    :expectedresults:
        1. Bind should be successful
        2. Search should be successfully initiated
        3. Cookie should be added
        4. It should throw a TypeError exception
    """

    users_num = 100
    page_size = 50
    users_list = add_users(topology_st, users_num, DEFAULT_SUFFIX)
    search_flt = r'(uid=test*)'
    searchreq_attrlist = ['dn', 'sn']

    try:
        log.info('Set user bind')
        conn = create_user.bind(TEST_USER_PWD)

        log.info('Create simple paged results control instance')
        req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='')
        controls = [req_ctrl]

        msgid = conn.search_ext(DEFAULT_SUFFIX,
                                ldap.SCOPE_SUBTREE,
                                search_flt,
                                searchreq_attrlist,
                                serverctrls=controls)
        rtype, rdata, rmsgid, rctrls = conn.result3(msgid)

        log.info(
            'Put an invalid cookie (%d) to the control. TypeError is expected'
            % invalid_cookie)
        req_ctrl.cookie = invalid_cookie
        with pytest.raises(TypeError):
            msgid = conn.search_ext(DEFAULT_SUFFIX,
                                    ldap.SCOPE_SUBTREE,
                                    search_flt,
                                    searchreq_attrlist,
                                    serverctrls=controls)
    finally:
        del_users(users_list)
Пример #29
0
    def paged_search_ext_s(self,
                           base,
                           scope,
                           filterstr='(objectClass=*)',
                           attrlist=None,
                           attrsonly=0,
                           serverctrls=None,
                           clientctrls=None,
                           timeout=30,
                           sizelimit=0):

        use_old_paging_api = False

        if hasattr(ldap, 'LDAP_CONTROL_PAGE_OID'):
            use_old_paging_api = True
            lc = SimplePagedResultsControl(ldap.LDAP_CONTROL_PAGE_OID, True,
                                           (self.page_size, ''))
            page_ctrl_oid = ldap.LDAP_CONTROL_PAGE_OID
        else:
            lc = ldap.controls.libldap.SimplePagedResultsControl(
                size=self.page_size, cookie='')
            page_ctrl_oid = ldap.controls.SimplePagedResultsControl.controlType

        msgid = self.search_ext(base,
                                scope,
                                filterstr,
                                attrlist=attrlist,
                                serverctrls=[lc])

        pages = 0
        all_results = []

        while True:
            pages += 1
            rtype, rdata, rmsgid, serverctrls = self.result3(msgid)
            all_results.extend(rdata)
            pctrls = [c for c in serverctrls if c.controlType == page_ctrl_oid]
            if pctrls:
                if use_old_paging_api:
                    est, cookie = pctrls[0].controlValue
                    lc.controlValue = (self.page_size, cookie)
                else:
                    cookie = lc.cookie = pctrls[0].cookie

                if cookie:
                    msgid = self.search_ext(base,
                                            ldap.SCOPE_SUBTREE,
                                            filterstr,
                                            attrlist=attrlist,
                                            serverctrls=[lc])
                else:
                    break
            else:
                raise ldap.LDAPError
        return all_results
Пример #30
0
        def paged_search_ext_s(self,
                               base,
                               scope,
                               filterstr='(objectClass=*)',
                               attrlist=None,
                               attrsonly=0,
                               serverctrls=None,
                               clientctrls=None,
                               timeout=-1,
                               sizelimit=0):
            """
            Behaves exactly like LDAPObject.search_ext_s() but internally uses the
            simple paged results control to retrieve search results in chunks.

            This is non-sense for really large results sets which you would like
            to process one-by-one
            """
            req_ctrl = SimplePagedResultsControl(True,
                                                 size=self.page_size,
                                                 cookie='')

            # Send first search request
            msgid = self.search_ext(base,
                                    ldap.SCOPE_SUBTREE,
                                    search_flt,
                                    attrlist=searchreq_attrlist,
                                    serverctrls=(serverctrls or []) +
                                    [req_ctrl])

            result_pages = 0
            all_results = []

            while True:
                rtype, rdata, rmsgid, rctrls = self.result3(msgid)
                all_results.extend(rdata)
                result_pages += 1
                # Extract the simple paged results response control
                pctrls = [
                    c for c in rctrls
                    if c.controlType == SimplePagedResultsControl.controlType
                ]
                if pctrls:
                    if pctrls[0].cookie:
                        # Copy cookie from response control to request control
                        req_ctrl.cookie = pctrls[0].cookie
                        msgid = self.search_ext(
                            base,
                            ldap.SCOPE_SUBTREE,
                            search_flt,
                            attrlist=searchreq_attrlist,
                            serverctrls=(serverctrls or []) + [req_ctrl])
                    else:
                        break
            return result_pages, all_results