コード例 #1
0
    def _paginate_scan_and_process(self, dn, filter, attributes, process_item, external_process, context):
        """
        Retrieve every LDAP user and apply the 'process' on each entry
        Search is paginated to support more than 1000 entries
        :param process (function): the function to apply to each LDAP entry returned by the search
        :return: the list of the user names that have been processed
        """
        cnx = self.get_ldap_connection()

        # Create the page control to work from
        page_control = SimplePagedResultsControl(True, size=1000, cookie='')

        result = []
        pages = 0
        processed_items=[]
        # Do searches until we run out of "pages" to get from
        # the LDAP server.
        while True:
            pages += 1
            # Send search request
            try:
                response = cnx.search_ext(dn,
                                      ldap.SCOPE_ONELEVEL,
                                      filter,
                                      attrlist=attributes,
                                      serverctrls=[page_control])
            except ldap.LDAPError as e:
                log.error('LDAP search failed: %s' % e)

            # Pull the results from the search request
            try:
                rtype, rdata, rmsgid, serverctrls = cnx.result3(response)
            except ldap.LDAPError as e:
                log.error('Could not pull LDAP results: %s' % e)

            # 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 item in rdata:
                processed_id = process_item(item, external_process, context)
                processed_items.append(processed_id)

            # Get cookie for next request
            result.extend(rdata)
            controls = [control for control in serverctrls
                        if control.controlType == SimplePagedResultsControl.controlType]
            if not controls:
                print('The 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!

            page_control.cookie = controls[0].cookie
            if not controls[0].cookie:
                break
        return processed_items
コード例 #2
0
        def paged_search(self,
                         base=None,
                         scope=ldap.SCOPE_SUBTREE,
                         page_size=1000,
                         criticality=True,
                         serverctrls=None,
                         **search_args):

            cookie = ''
            criticality = criticality

            initial = True

            if serverctrls is None:
                serverctrls = []
            else:
                serverctrls = list(serverctrls)

            if base is None:
                base = self._config(self.CFG_BASEDN)

            if base:

                page_control = SimplePagedResultsControl(criticality,
                                                         page_size,
                                                         cookie)

                while initial or page_control.cookie:
                    initial = False

                    try:
                        msgid = self.search_ext(
                                    base,
                                    scope,
                                    serverctrls=(serverctrls +
                                                 list([page_control])),
                                    **search_args)

                    except ldap.LDAPError as error:
                        raise error

                    # (rtype, results, msgid, sent_serverctrls)
                    (_, results, _, controls) = self.result3(msgid)

                    for control in controls:
                        if control.controlType == page_control.controlType:
                            page_control.cookie = control.cookie

                    yield results
コード例 #3
0
ファイル: ldap_conn.py プロジェクト: liyan-web/filesharing
    def paged_search(self, base_dn, scope, search_filter, attr_list):
        if not self.conn:
            return None

        total_result = []
        ctrl = SimplePagedResultsControl(True,
                                         size=LdapConn.PAGE_SIZE,
                                         cookie='')
        while True:
            try:
                result = self.conn.search_ext(base_dn,
                                              scope,
                                              search_filter,
                                              attr_list,
                                              serverctrls=[ctrl])
                rtype, rdata, rmsgid, ctrls = self.conn.result3(result)
            except ldap.LDAPError as e:
                if type(e.message
                        ) == dict and e.message['desc'] == 'No such object':
                    pass
                else:
                    logging.warning(
                        'Search failed for base dn(%s), filter(%s) '
                        'on server %s error: %s' %
                        (base_dn, search_filter, self.host, e.message))
                return None

            total_result.extend(rdata)

            page_ctrls = [
                c for c in ctrls
                if c.controlType == SimplePagedResultsControl.controlType
            ]
            if not page_ctrls or not page_ctrls[0].cookie:
                break

            ctrl.cookie = page_ctrls[0].cookie

        return total_result
コード例 #4
0
    def get_page(self, page_size, full_record):
        """
        Method used to retrieve all the objects in the "page" using Simple Paged Results Manipulation
        and Server Side Sorting extensions

        https://tools.ietf.org/html/rfc2696
        https://tools.ietf.org/html/rfc2891

        :param full_record: flag identifying that we hav to extract the full set of fields
        :param page_size: size of page
        :return: generator
        """
        fields = self.ldap_query_fields
        if full_record:
            fields = None

        # set ldap control extensions
        if not self.pg_ctrl:
            self.pg_ctrl = SimplePagedResultsControl(True, page_size, '')

        serverctrls = [self.pg_ctrl]
        if fields:
            # if we have defined set of fields, use the last one for the sorting
            serverctrls.append(SSSRequestControl(ordering_rules=[fields[-1]]))

        msgid = self.ldap_connection.search_ext(self.settings['base_dn'],
                                                ldap.SCOPE_SUBTREE,
                                                self.settings['filter'],
                                                fields,
                                                serverctrls=serverctrls)

        _, records, msgid, serverctrls = self.ldap_connection.result3(msgid)
        self.pg_ctrl.cookie = [
            _ for _ in serverctrls
            if _.controlType == SimplePagedResultsControl.controlType
        ][0].cookie

        if not self.pg_ctrl.cookie:
            # disconnect, the page is the last one
            self.ldap_connection.unbind_s()

        return (self.clean_record(record[1]) for record in records
                if (record[0] and record[1]))
コード例 #5
0
def main(**kwargs):
    ldapuri = kwargs["<ldapuri>"]
    basedn = kwargs["<basedn>"]

    debug = kwargs["--debug"]
    verbose = kwargs["--verbose"]
    output_file = kwargs["--output"]
    schema = kwargs["--schema"]
    binddn = kwargs["--binddn"]
    password = kwargs["--password"]
    askpass = kwargs["--askpass"]
    starttls = kwargs["--starttls"]
    cafile = kwargs["--cafile"]
    passfile = kwargs["--passfile"]
    trace_level = int(kwargs["--trace-level"])
    timeout = int(kwargs["--timeout"])

    if debug:
        print(f"askpass: {askpass}")

    if askpass:
        password = getpass("Bind password: "******"displayName": (None, "=", "*"),
        "title": (None, "=", "*"),
    }

    attrlist, filterstr = get_attrlist_filterstr(schema, filters)

    ldap_conn = ldap.initialize(ldapuri, trace_level=trace_level)
    set_options(ldap_conn, ldap_opts)

    if starttls:
        ldap_conn.start_tls_s()

    if binddn is not None and password is not None:
        try:
            ldap_conn.simple_bind_s(binddn, password)
        except ldap.LDAPError as e:
            sys.exit(ldap_errmsg(e))

    serverctrls = [SimplePagedResultsControl(size=2147483647, cookie='')]

    try:
        result = ldap_conn.search_ext_s(
            basedn,
            ldap.SCOPE_SUBTREE,
            filterstr=filterstr,
            serverctrls=serverctrls,
            attrlist=attrlist,
        )
    except ldap.LDAPError as e:
        sys.exit(ldap_errmsg(e))

    if result is not None:
        with smart_open(output_file) as f:
            gen_orgchart(f, result_to_org(result), ORGCHART_TEMPLATE_STR)