Ejemplo n.º 1
0
    async def pagedsearch(self,
                          base,
                          query,
                          attributes,
                          search_scope=2,
                          size_limit=1000,
                          typesOnly=False,
                          derefAliases=0,
                          timeLimit=None,
                          controls=None):
        """
		Paged search is the same as the search operation and uses it under the hood. Adds automatic control to read all results in a paged manner.
		
		:param base: base tree on which the search should be performed
		:type base: str
		:param query: filter query that defines what should be searched for
		:type query: str
		:param attributes: a list of attributes to be included in the response
		:type attributes: List[str]
		:param search_scope: Specifies the search operation's scope. Default: 2 (Subtree)
		:type search_scope: int
		:param types_only: indicates whether the entries returned should include attribute types only or both types and values. Default: False (both)
		:type types_only: bool
		:param size_limit: Size limit of result elements per query. Default: 1000
		:type size_limit: int
		:param derefAliases: Specifies the behavior on how aliases are dereferenced. Default: 0 (never)
		:type derefAliases: int
		:param timeLimit: Maximum time the search should take. If time limit reached the server SHOULD return an error
		:type timeLimit: int
		:param controls: additional controls to be passed in the query
		:type controls: dict
		:return: Async generator which yields (`dict`, None) tuple on success or (None, `Exception`) on error
		:rtype: Iterator[(:class:`dict`, :class:`Exception`)]
		"""

        if self.status != MSLDAPClientStatus.RUNNING:
            yield None, Exception(
                'Connection not running! Probably encountered an error')
            return
        try:
            cookie = b''
            while True:

                ctrl_list_temp = [
                    Control({
                        'controlType':
                        b'1.2.840.113556.1.4.319',
                        'controlValue':
                        SearchControlValue({
                            'size': size_limit,
                            'cookie': cookie
                        }).dump()
                    })
                ]
                if controls is not None:
                    ctrl_list_temp.extend(controls)

                ctrs = Controls(ctrl_list_temp)

                async for res, err in self.search(base,
                                                  query,
                                                  attributes,
                                                  search_scope=search_scope,
                                                  size_limit=size_limit,
                                                  types_only=typesOnly,
                                                  derefAliases=derefAliases,
                                                  timeLimit=timeLimit,
                                                  controls=ctrs,
                                                  return_done=True):
                    if err is not None:
                        yield (None, err)
                        return

                    if 'resultCode' in res['protocolOp']:
                        for control in res['controls']:
                            if control[
                                    'controlType'] == b'1.2.840.113556.1.4.319':
                                try:
                                    cookie = SearchControlValue.load(
                                        control['controlValue']
                                    ).native['cookie']
                                except Exception as e:
                                    raise e
                                break
                        else:
                            raise Exception(
                                'SearchControl missing from server response!')
                    else:
                        yield (convert_result(res['protocolOp']), None)

                if cookie == b'':
                    break

        except Exception as e:
            yield (None, e)
Ejemplo n.º 2
0
    async def pagedsearch(self,
                          base,
                          filter,
                          attributes,
                          search_scope=2,
                          paged_size=1000,
                          typesOnly=False,
                          derefAliases=0,
                          timeLimit=None,
                          controls=None):
        if self.status != MSLDAPClientStatus.RUNNING:
            yield None, Exception(
                'Connection not running! Probably encountered an error')
            return
        try:
            cookie = b''
            while True:

                ctrl_list_temp = [
                    Control({
                        'controlType':
                        b'1.2.840.113556.1.4.319',
                        'controlValue':
                        SearchControlValue({
                            'size': paged_size,
                            'cookie': cookie
                        }).dump()
                    })
                ]
                if controls is not None:
                    ctrl_list_temp.extend(controls)

                ctrs = Controls(ctrl_list_temp)

                async for res, err in self.search(base,
                                                  filter,
                                                  attributes,
                                                  search_scope=search_scope,
                                                  paged_size=paged_size,
                                                  typesOnly=typesOnly,
                                                  derefAliases=derefAliases,
                                                  timeLimit=timeLimit,
                                                  controls=ctrs,
                                                  return_done=True):
                    if err is not None:
                        yield (None, err)
                        return

                    if 'resultCode' in res['protocolOp']:
                        for control in res['controls']:
                            if control[
                                    'controlType'] == b'1.2.840.113556.1.4.319':
                                try:
                                    cookie = SearchControlValue.load(
                                        control['controlValue']
                                    ).native['cookie']
                                except Exception as e:
                                    raise e
                                break
                        else:
                            raise Exception(
                                'SearchControl missing from server response!')
                    else:
                        yield (convert_result(res['protocolOp']), None)

                if cookie == b'':
                    break

        except Exception as e:
            yield (None, e)
Ejemplo n.º 3
0
    async def search(self,
                     base,
                     query,
                     attributes,
                     search_scope=2,
                     size_limit=1000,
                     types_only=False,
                     derefAliases=0,
                     timeLimit=None,
                     controls=None,
                     return_done=False):
        """
		Performs the search operation.
		
		:param base: base tree on which the search should be performed
		:type base: str
		:param query: filter query that defines what should be searched for
		:type query: str
		:param attributes: a list of attributes to be included in the response
		:type attributes: List[str]
		:param search_scope: Specifies the search operation's scope. Default: 2 (Subtree)
		:type search_scope: int
		:param types_only: indicates whether the entries returned should include attribute types only or both types and values. Default: False (both)
		:type types_only: bool
		:param size_limit: Size limit of result elements per query. Default: 1000
		:type size_limit: int
		:param derefAliases: Specifies the behavior on how aliases are dereferenced. Default: 0 (never)
		:type derefAliases: int
		:param timeLimit: Maximum time the search should take. If time limit reached the server SHOULD return an error
		:type timeLimit: int
		:param controls: additional controls to be passed in the query
		:type controls: dict
		:param return_done: Controls wether the final 'done' LDAP message should be returned, or just the actual results
		:type return_done: bool

		:return: Async generator which yields (`LDAPMessage`, None) tuple on success or (None, `Exception`) on error
		:rtype: Iterator[(:class:`LDAPMessage`, :class:`Exception`)]
		"""
        if self.status != MSLDAPClientStatus.RUNNING:
            yield None, Exception(
                'Connection not running! Probably encountered an error')
            return
        try:
            if timeLimit is None:
                timeLimit = 600  #not sure

            flt = query_syntax_converter(query)

            searchreq = {
                'baseObject': base.encode(),
                'scope': search_scope,
                'derefAliases': derefAliases,
                'sizeLimit': size_limit,
                'timeLimit': timeLimit,
                'typesOnly': types_only,
                'filter': flt,
                'attributes': attributes,
            }

            br = {'searchRequest': SearchRequest(searchreq)}
            msg = {'protocolOp': protocolOp(br)}
            if controls is not None:
                msg['controls'] = controls

            msg_id = await self.send_message(msg)

            while True:
                results = await self.recv_message(msg_id)
                for message in results:
                    msg_type = message['protocolOp'].name
                    message = message.native
                    if msg_type == 'searchResDone':
                        #print(message)
                        #print('BREAKING!')
                        if return_done is True:
                            yield (message, None)
                        break

                    elif msg_type == 'searchResRef':
                        #TODO: Check if we need to deal with this further
                        continue

                    if return_done is True:
                        yield (message, None)
                    else:
                        yield (convert_result(message['protocolOp']), None)
                else:
                    continue

                break

        except Exception as e:
            yield (None, e)
Ejemplo n.º 4
0
    async def search(self,
                     base,
                     filter,
                     attributes,
                     search_scope=2,
                     paged_size=1000,
                     typesOnly=False,
                     derefAliases=0,
                     timeLimit=None,
                     controls=None,
                     return_done=False):
        """
		This function is a generator!!!!! Dont just call it but use it with "async for"
		"""
        if self.status != MSLDAPClientStatus.RUNNING:
            yield None, Exception(
                'Connection not running! Probably encountered an error')
            return
        try:
            if timeLimit is None:
                timeLimit = 600  #not sure

            searchreq = {
                'baseObject': base,
                'scope': search_scope,
                'derefAliases': derefAliases,
                'sizeLimit': paged_size,
                'timeLimit': timeLimit,
                'typesOnly': typesOnly,
                'filter': filter,
                'attributes': attributes,
            }

            br = {'searchRequest': SearchRequest(searchreq)}
            msg = {'protocolOp': protocolOp(br)}
            if controls is not None:
                msg['controls'] = controls

            msg_id = await self.send_message(msg)

            while True:
                results = await self.recv_message(msg_id)
                for message in results:
                    msg_type = message['protocolOp'].name
                    message = message.native
                    if msg_type == 'searchResDone':
                        #print(message)
                        #print('BREAKING!')
                        if return_done is True:
                            yield (message, None)
                        break

                    elif msg_type == 'searchResRef':
                        #TODO: Check if we need to deal with this further
                        continue

                    if return_done is True:
                        yield (message, None)
                    else:
                        yield (convert_result(message['protocolOp']), None)
                else:
                    continue

                break

        except Exception as e:
            yield (None, e)