async def get_all_objectacl(self): """ Yields the security descriptor of all objects in the LDAP tree of the following types: Users, Computers, GPOs, OUs, Groups :return: Async generator which yields (`MSADSecurityInfo`, None) tuple on success or (None, `Exception`) on error :rtype: Iterator[(:class:`MSADSecurityInfo`, :class:`Exception`)] """ flags_value = SDFlagsRequest.DACL_SECURITY_INFORMATION | SDFlagsRequest.GROUP_SECURITY_INFORMATION | SDFlagsRequest.OWNER_SECURITY_INFORMATION req_flags = SDFlagsRequestValue({'Flags': flags_value}) ldap_filter = r'(|(objectClass=organizationalUnit)(objectCategory=groupPolicyContainer)(sAMAccountType=805306369)(objectClass=group)(sAMAccountType=805306368))' async for entry, err in self.pagedsearch(ldap_filter, attributes=['dn']): if err is not None: yield None, err return ldap_filter = r'(distinguishedName=%s)' % escape_filter_chars( entry['objectName']) attributes = MSADSecurityInfo.ATTRS controls = [('1.2.840.113556.1.4.801', True, req_flags.dump())] async for entry2, err in self.pagedsearch(ldap_filter, attributes, controls=controls): if err is not None: yield None, err return yield MSADSecurityInfo.from_ldap(entry2), None
async def get_tokengroups(self, dn): """ Yields SIDs of groups that the given DN is a member of. :return: Async generator which yields (`str`, None) tuple on success or (None, `Exception`) on error :rtype: Iterator[(:class:`str`, :class:`Exception`)] """ ldap_filter = r'(distinguishedName=%s)' % escape_filter_chars(dn) attributes = [b'tokenGroups'] async for entry, err in self._con.pagedsearch( dn, ldap_filter, attributes=attributes, size_limit=self.ldap_query_page_size, search_scope=BASE, ): if err is not None: yield None, err return #print(entry['attributes']) if 'tokenGroups' in entry['attributes']: for sid_data in entry['attributes']['tokenGroups']: yield sid_data, None
async def get_objectacl_by_dn( self, dn, flags=SDFlagsRequest.DACL_SECURITY_INFORMATION | SDFlagsRequest.GROUP_SECURITY_INFORMATION | SDFlagsRequest.OWNER_SECURITY_INFORMATION): """ Returns the full or partial Security Descriptor of the object specified by it's DN. The flags indicate which part of the security Descriptor to be returned. By default the full SD info is returned. :param object_dn: The object's DN :type object_dn: str :param flags: Flags indicate the data type to be returned. :type flags: :class:`SDFlagsRequest` :return: nTSecurityDescriptor attribute of the object as `bytes` and an `Exception` is there was any :rtype: (:class:`bytes`, :class:`Exception`) """ req_flags = SDFlagsRequestValue({'Flags': flags}) ldap_filter = r'(distinguishedName=%s)' % escape_filter_chars(dn) attributes = ['nTSecurityDescriptor'] controls = [('1.2.840.113556.1.4.801', True, req_flags.dump())] async for entry, err in self.pagedsearch(ldap_filter, attributes, controls=controls): if err is not None: return None, err return entry['attributes'].get('nTSecurityDescriptor'), None return None, None
async def get_all_schemaentry(self): """ Fetches all Schema entries under CN=Schema,CN=Configuration,... :return: Async generator which yields (`MSADSchemaEntry`, None) tuple on success or (None, `Exception`) on error :rtype: Iterator[(:class:`MSADSchemaEntry`, :class:`Exception`)] """ res = await self.get_tree_plot('CN=Schema,CN=Configuration,' + self._tree, level=1) for x in res: for dn in res[x]: async for entry, err in self._con.pagedsearch( dn, r'(distinguishedName=%s)' % escape_filter_chars(dn), attributes=[x.encode() for x in MSADSCHEMAENTRY_ATTRS], size_limit=self.ldap_query_page_size, search_scope=BASE, controls=None, ): if err is not None: yield None, err return yield MSADSchemaEntry.from_ldap(entry), None break else: yield None, None logger.debug('Finished polling for entries!')
async def get_objectacl_by_dn_p( self, dn, flags=SDFlagsRequest.DACL_SECURITY_INFORMATION | SDFlagsRequest.GROUP_SECURITY_INFORMATION | SDFlagsRequest.OWNER_SECURITY_INFORMATION): """ Returns the full or partial Security Descriptor of the object specified by it's DN. The flags indicate which part of the security Descriptor to be returned. By default the full SD info is returned. :param object_dn: The object's DN :type object_dn: str :param flags: Flags indicate the data type to be returned. :type flags: :class:`SDFlagsRequest` :return: :rtype: :class:`MSADSecurityInfo` """ req_flags = SDFlagsRequestValue({'Flags': flags}) ldap_filter = r'(distinguishedName=%s)' % escape_filter_chars(dn) attributes = MSADSecurityInfo.ATTRS controls = [('1.2.840.113556.1.4.801', True, req_flags.dump())] async for entry, err in self.pagedsearch(ldap_filter, attributes, controls=controls): if err is not None: yield None, err return yield MSADSecurityInfo.from_ldap(entry), None
async def get_group_by_dn(self, group_dn): """ Returns an `MSADGroup` object for the group specified by group_dn :param group_dn: The user's DN :type group_dn: str :return: tuple of `MSADGroup` and an `Exception` is there was any :rtype: (:class:`MSADGroup`, :class:`Exception`) """ ldap_filter = r'(&(objectClass=group)(distinguishedName=%s))' % escape_filter_chars( group_dn) async for entry, err in self.pagedsearch(ldap_filter, MSADGroup_ATTRS): if err is not None: return None, err return MSADGroup.from_ldap(entry), None
async def get_objectacl_by_dn(self, dn): """ Returns all ACL info for all AD objects """ flags_value = SDFlagsRequest.DACL_SECURITY_INFORMATION | SDFlagsRequest.GROUP_SECURITY_INFORMATION | SDFlagsRequest.OWNER_SECURITY_INFORMATION req_flags = SDFlagsRequestValue({'Flags': flags_value}) ldap_filter = r'(distinguishedName=%s)' % escape_filter_chars(dn) attributes = MSADSecurityInfo.ATTRS controls = [('1.2.840.113556.1.4.801', True, req_flags.dump())] async for entry in self.pagedsearch(ldap_filter, attributes, controls=controls): yield MSADSecurityInfo.from_ldap(entry)
async def get_objectsid_for_dn(self, dn): """ Fetches the objectsid for an object specified by `dn` :param dn: The object's distinguishedName :type dn: str :return: The SID of the pobject :rtype: (:class:`str`, :class:`Exception`) """ ldap_filter = r'(distinguishedName=%s)' % escape_filter_chars(dn) async for entry, err in self.pagedsearch(ldap_filter, ['objectSid']): if err is not None: return None, err return entry['attributes']['objectSid'], None
async def get_all_tokengroups(self): """ Yields all effective group membership information for all objects of the following type: Users, Groups, Computers :return: Async generator which yields (`dict`, None) tuple on success or (None, `Exception`) on error :rtype: Iterator[(:class:`dict`, :class:`Exception`)] """ ldap_filter = r'(|(sAMAccountType=805306369)(objectClass=group)(sAMAccountType=805306368))' async for entry, err in self.pagedsearch(ldap_filter, attributes=[ 'dn', 'cn', 'objectSid', 'objectClass', 'objectGUID' ]): if err is not None: yield None, err return if 'objectName' in entry: #print(entry['objectName']) async for entry2, err in self._con.pagedsearch( entry['objectName'], r'(distinguishedName=%s)' % escape_filter_chars(entry['objectName']), attributes=[b'tokenGroups'], size_limit=self.ldap_query_page_size, search_scope=BASE, ): #print(entry2) if err is not None: yield None, err break if 'tokenGroups' in entry2['attributes']: for token in entry2['attributes']['tokenGroups']: yield { 'cn': entry['attributes']['cn'], 'dn': entry['objectName'], 'guid': entry['attributes']['objectGUID'], 'sid': entry['attributes']['objectSid'], 'type': entry['attributes']['objectClass'][-1], 'token': token }, None
async def get_all_objectacl(self): """ bbbbbb """ flags_value = SDFlagsRequest.DACL_SECURITY_INFORMATION | SDFlagsRequest.GROUP_SECURITY_INFORMATION | SDFlagsRequest.OWNER_SECURITY_INFORMATION req_flags = SDFlagsRequestValue({'Flags': flags_value}) ldap_filter = r'(|(objectClass=organizationalUnit)(objectCategory=groupPolicyContainer)(sAMAccountType=805306369)(objectClass=group)(sAMAccountType=805306368))' async for entry in self.pagedsearch(ldap_filter, attributes=['dn']): ldap_filter = r'(distinguishedName=%s)' % escape_filter_chars( entry['objectName']) attributes = MSADSecurityInfo.ATTRS controls = [('1.2.840.113556.1.4.801', True, req_flags.dump())] async for entry2 in self.pagedsearch(ldap_filter, attributes, controls=controls): yield MSADSecurityInfo.from_ldap(entry2)
async def get_tokengroups(self, dn): """ returns the tokengroups attribute for a given DN """ ldap_filter = query_syntax_converter(r'(distinguishedName=%s)' % escape_filter_chars(dn)) attributes = [b'tokenGroups'] async for entry, err in self._con.pagedsearch( dn.encode(), ldap_filter, attributes=attributes, paged_size=self.ldap_query_page_size, search_scope=BASE, ): if err is not None: yield None, err break #print(entry['attributes']) if 'tokenGroups' in entry: for sid_data in entry['tokenGroups']: yield sid_data
async def get_all_tokengroups(self): """ returns the tokengroups attribute for a given DN """ ldap_filter = r'(|(sAMAccountType=805306369)(objectClass=group)(sAMAccountType=805306368))' async for entry in self.pagedsearch(ldap_filter, attributes=[ 'dn', 'cn', 'objectSid', 'objectClass', 'objectGUID' ]): if 'objectName' in entry: #print(entry['objectName']) async for entry2, err in self._con.pagedsearch( entry['objectName'].encode(), query_syntax_converter( r'(distinguishedName=%s)' % escape_filter_chars(entry['objectName'])), attributes=[b'tokenGroups'], paged_size=self.ldap_query_page_size, search_scope=BASE, ): #print(entry2) if err is not None: yield None, err break if 'tokenGroups' in entry2['attributes']: for token in entry2['attributes']['tokenGroups']: yield { 'cn': entry['attributes']['cn'], 'dn': entry['objectName'], 'guid': entry['attributes']['objectGUID'], 'sid': entry['attributes']['objectSid'], 'type': entry['attributes']['objectClass'][-1], 'token': token }
async def get_schemaentry(self, dn): """ Fetches one Schema entriy identified by dn :return: (`MSADSchemaEntry`, None) tuple on success or (None, `Exception`) on error :rtype: (:class:`MSADSchemaEntry`, :class:`Exception`) """ logger.debug('Polling Schema entry for %s' % dn) async for entry, err in self._con.pagedsearch( dn, r'(distinguishedName=%s)' % escape_filter_chars(dn), attributes=[x.encode() for x in MSADSCHEMAENTRY_ATTRS], size_limit=self.ldap_query_page_size, search_scope=BASE, controls=None, ): if err is not None: raise err return MSADSchemaEntry.from_ldap(entry), None else: return None, None logger.debug('Finished polling for entries!')
async def get_group_by_dn(self, dn): ldap_filter = r'(&(objectClass=group)(distinguishedName=%s))' % escape_filter_chars( dn) async for entry in self.pagedsearch(ldap_filter, ALL_ATTRIBUTES): yield MSADGroup.from_ldap(entry)