예제 #1
0
파일: client.py 프로젝트: youda313/msldap
    async def set_objectacl_by_dn(
        self,
        object_dn,
        data,
        flags=SDFlagsRequest.DACL_SECURITY_INFORMATION
        | SDFlagsRequest.GROUP_SECURITY_INFORMATION
        | SDFlagsRequest.OWNER_SECURITY_INFORMATION):
        """
		Updates the security descriptor of the LDAP object
		
		:param object_dn: The object's DN
		:type object_dn: str
		:param data: The actual data as bytearray to be updated in the Security Descriptor of the specified object 
		:type data: bytes
		:param flags: Flags indicate the data type to be updated.
		:type flags: :class:`SDFlagsRequest`
		:return: A tuple of (True, None) on success or (False, Exception) on error. 
		:rtype: tuple

		"""

        req_flags = SDFlagsRequestValue({'Flags': flags})
        controls = [
            Control({
                'controlType': b'1.2.840.113556.1.4.801',
                'controlValue': req_flags.dump(),
                'criticality': True,
            })
        ]

        changes = {'nTSecurityDescriptor': [('replace', [data])]}
        return await self._con.modify(object_dn, changes, controls=controls)
예제 #2
0
파일: client.py 프로젝트: mmg1/msldap
    async def pagedsearch(self, ldap_filter, attributes, controls=None):
        """
		Performs a paged search on the AD, using the filter and attributes as a normal query does.
		Needs to connect to the server first!

		Parameters:
			ldap_filter (str): LDAP query filter
			attributes (list): Attributes list to recieve in the result
			controls (obj): Additional control dict
		
		Returns:
			generator
		"""
        logger.debug('Paged search, filter: %s attributes: %s' %
                     (ldap_filter, ','.join(attributes)))
        if self._con.status != MSLDAPClientStatus.RUNNING:
            if self._con.status == MSLDAPClientStatus.ERROR:
                print('There was an error in the connection!')
                return
            elif self._con.status == MSLDAPClientStatus.ERROR:
                print('Theconnection is in stopped state!')
                return

        if self._tree is None:
            raise Exception('BIND first!')
        t = []
        for x in attributes:
            t.append(x.encode())
        attributes = t
        ldap_filter = query_syntax_converter(ldap_filter)

        t = []
        if controls is not None:
            for control in controls:
                t.append(
                    Control({
                        'controlType': control[0].encode(),
                        'criticality': control[1],
                        'controlValue': control[2]
                    }))

        controls = t

        async for entry, err in self._con.pagedsearch(
                self._tree.encode(),
                ldap_filter,
                attributes=attributes,
                paged_size=self.ldap_query_page_size,
                controls=controls):

            if err is not None:
                raise err
            if entry['objectName'] == '' and entry['attributes'] == '':
                #searchresref...
                continue
            #print('et %s ' % entry)
            yield entry
예제 #3
0
파일: client.py 프로젝트: youda313/msldap
    async def modify(self, dn, changes, controls=None):
        """
		Performs the modify operation.
		
		:param dn: The DN of the object whose attributes are to be modified
		:type dn: str
		:param changes: Describes the changes to be made on the object. Must be a dictionary of the following format: {'attribute': [('change_type', [value])]}
		:type changes: dict
		:param controls: additional controls to be passed in the query
		:type controls: dict
		:return: A tuple of (True, None) on success or (False, Exception) on error. 
		:rtype: (:class:`bool`, :class:`Exception`)
		"""
        if controls is None:
            controls = []
        controls_conv = []
        for control in controls:
            controls_conv.append(Control(control))
        return await self._con.modify(dn, changes, controls=controls_conv)
예제 #4
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)
예제 #5
0
파일: client.py 프로젝트: youda313/msldap
    async def pagedsearch(self, query, attributes, controls=None):
        """
		Performs a paged search on the AD, using the filter and attributes as a normal query does.
			!The LDAP connection MUST be active before invoking this function!

		:param query: LDAP query filter
		:type query: str
		:param attributes: List of requested attributes
		:type attributes: List[str]
		:param controls: additional controls to be passed in the query
		:type controls: dict
		:param level: Recursion level
		:type level: int

		:return: Async generator which yields (`dict`, None) tuple on success or (None, `Exception`) on error
		:rtype: Iterator[(:class:`dict`, :class:`Exception`)]

		"""
        logger.debug('Paged search, filter: %s attributes: %s' %
                     (query, ','.join(attributes)))
        if self._con.status != MSLDAPClientStatus.RUNNING:
            if self._con.status == MSLDAPClientStatus.ERROR:
                print('There was an error in the connection!')
                return
            elif self._con.status == MSLDAPClientStatus.ERROR:
                print('Theconnection is in stopped state!')
                return

        if self._tree is None:
            raise Exception('BIND first!')
        t = []
        for x in attributes:
            t.append(x.encode())
        attributes = t

        t = []
        if controls is not None:
            for control in controls:
                t.append(
                    Control({
                        'controlType': control[0].encode(),
                        'criticality': control[1],
                        'controlValue': control[2]
                    }))

        controls = t

        async for entry, err in self._con.pagedsearch(
                self._tree,
                query,
                attributes=attributes,
                size_limit=self.ldap_query_page_size,
                controls=controls):

            if err is not None:
                yield None, err
                return
            if entry['objectName'] == '' and entry['attributes'] == '':
                #searchresref...
                continue
            #print('et %s ' % entry)
            yield entry, None
예제 #6
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)