예제 #1
0
    def _match_equal_to(search_base, attribute, value, candidates):
        matches = list()
        match_using_regex = False

        if "*" in value:
            match_using_regex = True
            #regex = check_escape(value)
            regex = value.replace('*', '.*')
            regex = "^{0}$".format(regex)

        for entry in candidates:
            dn = entry.get("dn")

            if not attribute in entry.get("attributes") \
                or not dn.endswith(search_base):

                continue

            values_from_directory = entry.get("attributes").get(attribute)
            if isinstance(values_from_directory, list):
                for item in values_from_directory:
                    if attribute == "objectGUID":
                        item = escape_bytes(item)

                    if match_using_regex:
                        m = re.match(regex, str(item), re.I)
                        if m:
                            entry["type"] = "searchResEntry"
                            matches.append(entry)
                    else:
                        if item == value:
                            entry["type"] = "searchResEntry"
                            matches.append(entry)

            else:
                if attribute == "objectGUID":
                    values_from_directory = escape_bytes(values_from_directory)
                if match_using_regex:
                    m = re.match(regex, str(values_from_directory), re.I)
                    if m:
                        entry["type"] = "searchResEntry"
                        matches.append(entry)
                else:
                    if str(value) == str(values_from_directory):
                        entry["type"] = "searchResEntry"
                        matches.append(entry)

        return matches
예제 #2
0
    def _match_equal_to(search_base, attribute, value, candidates):
        matches = list()
        match_using_regex = False

        if "*" in value:
            match_using_regex = True
            #regex = check_escape(value)
            regex = value.replace('*', '.*')
            regex = "^{0}$".format(regex)

        for entry in candidates:
            dn = entry.get("dn")

            if not attribute in entry.get("attributes") \
                or not dn.endswith(search_base):

                continue

            values_from_directory = entry.get("attributes").get(attribute)
            if isinstance(values_from_directory, list):
                for item in values_from_directory:
                    if attribute == "objectGUID":
                        item = escape_bytes(item)

                    if match_using_regex:
                        m = re.match(regex, str(item), re.I)
                        if m:
                            entry["type"] = "searchResEntry"
                            matches.append(entry)
                    else:
                        if item == value:
                            entry["type"] = "searchResEntry"
                            matches.append(entry)

            else:
                if attribute == "objectGUID":
                    values_from_directory = escape_bytes(values_from_directory)
                if match_using_regex:
                    m = re.match(regex, str(values_from_directory), re.I)
                    if m:
                        entry["type"] = "searchResEntry"
                        matches.append(entry)
                else:
                    if str(value) == str(values_from_directory):
                        entry["type"] = "searchResEntry"
                        matches.append(entry)

        return matches
예제 #3
0
    def test_search_exact_match_with_parentheses_in_filter(self):
        self.delete_at_teardown.append(
            add_user(self.connection,
                     testcase_id,
                     '(search)-3',
                     attributes={'givenName': 'givenname-3'}))
        result = self.connection.search(
            search_base=test_base,
            search_filter='(&(' + test_name_attr + '=' + testcase_id + '*)(' +
            test_name_attr + '=*' + escape_bytes(')') + '*))',
            attributes=[test_name_attr, 'sn'])
        if not self.connection.strategy.sync:
            response, _ = self.connection.get_response(result)
            json_response = self.connection.response_to_json(
                search_result=response)
        else:
            json_response = self.connection.response_to_json()
        json_entries = json.loads(json_response)['entries']

        self.assertEqual(len(json_entries), 1)
        if test_server_type == 'AD':
            self.assertEqual(json_entries[0]['attributes'][test_name_attr],
                             testcase_id + '(search)-3')
        else:
            self.assertEqual(json_entries[0]['attributes'][test_name_attr][0],
                             testcase_id + '(search)-3')
예제 #4
0
파일: backends.py 프로젝트: dkoppel/ps1auth
    def get_user(self, user_id):
        from .models import PS1User
        """
        Get's The user object and attached ldap_user data.
        Will create the database entry if required.

        Keyword arguments:
        user_id -- a string or UUID object of samba4 objectGUID of a user.
        """
        try:
            guid = uuid.UUID(str(user_id))
        except ValueError:
            # Happens when we get passed an invalid or outdated user_id
            return None
        try:
            user = PS1User.objects.get(object_guid=str(guid))
        except PS1User.DoesNotExist:
            filter_string = '(objectGUID={})'.format(
                escape_bytes(guid.bytes_le))
            with get_ldap_connection() as c:
                c.search(settings.AD_BASEDN, filter_string, LEVEL)
                user_dn = c.response[0]['dn']
            user = PS1User(object_guid=str(guid))
            user.save()
        return user
예제 #5
0
    def _getDN(self, userId):
        """
        This function returns the DN of a userId.
        Therefor it evaluates the self.uidtype.

        :param userId: The userid of a user
        :type userId: string

        :return: The DN of the object.
        """
        dn = ""
        if self.uidtype.lower() == "dn":
            dn = userId
        else:
            if self.uidtype == "objectGUID":
                userId = uuid.UUID("{{{0!s}}}".format(userId)).bytes_le
                userId = escape_bytes(userId)
            # get the DN for the Object
            self._bind()
            filter = "(&{0!s}({1!s}={2!s}))".format(self.searchfilter, self.uidtype, userId)
            self.l.search(search_base=self.basedn,
                          search_scope=self.scope,
                          search_filter=filter,
                          attributes=self.userinfo.values())
            r = self.l.response
            r = self._trim_result(r)
            if len(r) > 1:  # pragma: no cover
                raise Exception("Found more than one object for uid {0!r}".format(userId))
            if len(r) == 1:
                dn = r[0].get("dn")

        return dn
예제 #6
0
    def _getDN(self, userId):
        """
        This function returns the DN of a userId.
        Therefor it evaluates the self.uidtype.

        :param userId: The userid of a user
        :type userId: string

        :return: The DN of the object.
        """
        dn = ""
        if self.uidtype.lower() == "dn":
            dn = userId
        else:
            if self.uidtype == "objectGUID":
                userId = uuid.UUID("{{{0!s}}}".format(userId)).bytes_le
                userId = escape_bytes(userId)
            # get the DN for the Object
            self._bind()
            filter = "(&{0!s}({1!s}={2!s}))".format(self.searchfilter, self.uidtype, userId)
            self.l.search(search_base=self.basedn,
                          search_scope=self.scope,
                          search_filter=filter,
                          attributes=self.userinfo.values())
            r = self.l.response
            r = self._trim_result(r)
            if len(r) > 1:  # pragma: no cover
                raise Exception("Found more than one object for uid {0!r}".format(userId))
            if len(r) == 1:
                dn = r[0].get("dn")

        return dn
예제 #7
0
 def test_search_string_guid(self):
     self.delete_at_teardown.append(
         add_user(self.connection,
                  testcase_id,
                  'sea-16',
                  attributes={'givenName': testcase_id + 'givenname-16'}))
     if test_server_type == 'EDIR':
         status, result, response, request = get_response_values(
             self.connection.search(search_base=test_base,
                                    search_filter='(givenname=' +
                                    testcase_id + 'givenname-16)',
                                    attributes=[
                                        test_name_attr, 'sn', 'guid'
                                    ]), self.connection)
     elif test_server_type == 'AD':  # not tested on AD yet
         status, result, response, request = get_response_values(
             self.connection.search(search_base=test_base,
                                    search_filter='(givenname=' +
                                    testcase_id + 'givenname-16)',
                                    attributes=[
                                        test_name_attr, 'sn', 'objectGuid'
                                    ]), self.connection)
     else:  # not tested on other kind of servers
         return
     self.assertEqual(result['description'], 'success')
     self.assertEqual(len(response), 1)
     if test_server_type == 'EDIR':
         if self.connection.check_names:
             status, result, response, request = get_response_values(
                 self.connection.search(
                     search_base=test_base,
                     search_filter='(guid=' +
                     response[0]['attributes']['guid'] + ')',
                     attributes=[test_name_attr, 'sn']), self.connection)
         else:
             status, result, response, request = get_response_values(
                 self.connection.search(
                     search_base=test_base,
                     search_filter='(guid=' + escape_bytes(
                         response[0]['raw_attributes']['guid'][0]) + ')',
                     attributes=[test_name_attr, 'sn']), self.connection)
     elif test_server_type == 'AD':  # not tested on AD yet
         status, result, response, request = get_response_values(
             self.connection.search(
                 search_base=test_base,
                 search_filter='(objectguid=' +
                 response[0]['attributes']['objectguid'] + ')',
                 attributes=[test_name_attr, 'sn']), self.connection)
     self.assertEqual(result['description'], 'success')
     self.assertEqual(len(response), 1)
     if test_server_type == 'EDIR':
         self.assertEqual(response[0]['attributes'][test_name_attr][0],
                          testcase_id + 'sea-16')
     elif test_server_type == 'AD':
         self.assertEqual(response[0]['attributes'][test_name_attr],
                          testcase_id + 'sea-16')
예제 #8
0
 def get_ldap_group_membership(self, user_dn):
     """Retrieve django group ids that this user DN is a member of."""
     if not hasattr(self, '_group_cache'):
         r = LDAPGroup.objects.all().values_list('distinguished_name',
                                                 'obj')
         self._group_cache = dict(r)
     logger.debug(
         'Retrieving groups that {} is a member of'.format(user_dn))
     ldap_groups = self.smart_ldap_searcher.search(
         self.group_base,
         self.group_membership_filter.format(user_dn=escape_bytes(user_dn)),
         ldap3.SEARCH_SCOPE_WHOLE_SUBTREE, None)
     return (self._group_cache.get(i['dn']) for i in ldap_groups
             if i.get('dn'))
예제 #9
0
 def test_search_exact_match_with_parentheses_in_filter(self):
     self.delete_at_teardown.append(
         add_user(self.connection,
                  testcase_id,
                  '(search)-10',
                  attributes={'givenName': 'givenname-10'}))
     status, result, response, request = get_response_values(
         self.connection.search(
             search_base=test_base,
             search_filter='(' + test_name_attr + '=' + testcase_id + '*' +
             escape_bytes(')') + '*)',
             attributes=[test_name_attr, 'sn']), self.connection)
     entries = self.connection._get_entries(response, request)
     self.assertEqual(result['description'], 'success')
     self.assertEqual(len(entries), 1)
     self.assertEqual(entries[0][test_name_attr][0],
                      testcase_id + '(search)-10')
예제 #10
0
파일: models.py 프로젝트: deifius/ps1auth
    def ldap_user(self):
        if hasattr(self, '_ldap_user'):
            return self._ldap_user
        self._ldap_user = cache.get(self.object_guid)
        if not self._ldap_user:
            guid = uuid.UUID(self.object_guid)
            # certain byte sequences contain printable character that can
            # potentially be parseable by the query string.  Escape each byte as
            # hex to make sure this doesn't happen.
            #restrung = ''.join(['\\%02x' % ord(x) for x in guid.bytes_le])
            filter_string = '(objectGUID={})'.format(escape_bytes(guid.bytes_le))
            with get_ldap_connection() as c:
                c.search(settings.AD_BASEDN, filter_string, LEVEL, attributes = ALL_ATTRIBUTES)
                result = c.response

            if len(result) > 0:
                self._ldap_user = result[0]['attributes']
                cache.set(self.object_guid, self._ldap_user, 24 * 60 * 60 * 70)
        return self._ldap_user
예제 #11
0
 def test_search_exact_match_with_parentheses_in_filter(self):
     self.delete_at_teardown.append(
         add_user(self.connection,
                  testcase_id,
                  '(search)-10',
                  attributes={'givenName': 'givenname-10'}))
     result = self.connection.search(search_base=test_base,
                                     search_filter='(' + test_name_attr +
                                     '=' + testcase_id + '*' +
                                     escape_bytes(')') + '*)',
                                     attributes=[test_name_attr, 'sn'])
     if not self.connection.strategy.sync:
         response, result = self.connection.get_response(result)
     else:
         response = self.connection.response
         result = self.connection.result
     self.assertEqual(result['description'], 'success')
     self.assertEqual(len(response), 1)
     self.assertEqual(response[0]['attributes'][test_name_attr][0],
                      testcase_id + '(search)-10')
예제 #12
0
 def test_search_exact_match_with_escaped_parentheses_in_filter(self):
     self.delete_at_teardown.append(
         add_user(self.connection,
                  testcase_id,
                  '(s)-12',
                  attributes={'givenName': 'givenname-12'}))
     status, result, response, request = get_response_values(
         self.connection.search(
             search_base=test_base,
             search_filter='(' + test_name_attr + '=' + testcase_id + '*' +
             escape_bytes(')') + '*)',
             attributes=[test_name_attr, 'sn']), self.connection)
     self.assertEqual(result['description'], 'success')
     self.assertEqual(len(response), 1)
     if test_server_type == 'AD':
         self.assertEqual(response[0]['attributes'][test_name_attr],
                          testcase_id + '(s)-12')
     else:
         self.assertEqual(response[0]['attributes'][test_name_attr][0],
                          testcase_id + '(s)-12')
예제 #13
0
    def getUserInfo(self, userId):
        """
        This function returns all user info for a given userid/object.

        :param userId: The userid of the object
        :type userId: string
        :return: A dictionary with the keys defined in self.userinfo
        :rtype: dict
        """
        ret = {}
        self._bind()

        if self.uidtype.lower() == "dn":
            # encode utf8, so that also german ulauts work in the DN
            self.l.search(search_base=to_utf8(userId),
                          search_scope=self.scope,
                          search_filter="(&" + self.searchfilter + ")",
                          attributes=self.userinfo.values())
        else:
            if self.uidtype == "objectGUID":
                userId = uuid.UUID("{{{0!s}}}".format(userId)).bytes_le
                userId = escape_bytes(userId)
            filter = "(&{0!s}({1!s}={2!s}))".format(self.searchfilter,
                                                    self.uidtype, userId)
            self.l.search(search_base=self.basedn,
                          search_scope=self.scope,
                          search_filter=filter,
                          attributes=self.userinfo.values())

        r = self.l.response
        r = self._trim_result(r)
        if len(r) > 1:  # pragma: no cover
            raise Exception(
                "Found more than one object for uid {0!r}".format(userId))

        for entry in r:
            attributes = entry.get("attributes")
            ret = self._ldap_attributes_to_user_object(attributes)

        return ret
예제 #14
0
    def getUserInfo(self, userId):
        """
        This function returns all user info for a given userid/object.

        :param userId: The userid of the object
        :type userId: string
        :return: A dictionary with the keys defined in self.userinfo
        :rtype: dict
        """
        ret = {}
        self._bind()

        if self.uidtype.lower() == "dn":
            # encode utf8, so that also german ulauts work in the DN
            self.l.search(search_base=to_utf8(userId),
                          search_scope=self.scope,
                          search_filter="(&" + self.searchfilter + ")",
                          attributes=self.userinfo.values())
        else:
            if self.uidtype == "objectGUID":
                userId = uuid.UUID("{{{0!s}}}".format(userId)).bytes_le
                userId = escape_bytes(userId)
            filter = "(&{0!s}({1!s}={2!s}))".format(self.searchfilter, self.uidtype, userId)
            self.l.search(search_base=self.basedn,
                              search_scope=self.scope,
                              search_filter=filter,
                              attributes=self.userinfo.values())

        r = self.l.response
        r = self._trim_result(r)
        if len(r) > 1:  # pragma: no cover
            raise Exception("Found more than one object for uid {0!r}".format(userId))

        for entry in r:
            attributes = entry.get("attributes")
            ret = self._ldap_attributes_to_user_object(attributes)

        return ret
예제 #15
0
파일: models.py 프로젝트: dkoppel/ps1auth
    def ldap_user(self):
        if hasattr(self, '_ldap_user'):
            return self._ldap_user
        self._ldap_user = cache.get(self.object_guid)
        if not self._ldap_user:
            guid = uuid.UUID(self.object_guid)
            # certain byte sequences contain printable character that can
            # potentially be parseable by the query string.  Escape each byte as
            # hex to make sure this doesn't happen.
            #restrung = ''.join(['\\%02x' % ord(x) for x in guid.bytes_le])
            filter_string = '(objectGUID={})'.format(
                escape_bytes(guid.bytes_le))
            with get_ldap_connection() as c:
                c.search(settings.AD_BASEDN,
                         filter_string,
                         LEVEL,
                         attributes=ALL_ATTRIBUTES)
                result = c.response

            if len(result) > 0:
                self._ldap_user = result[0]['attributes']
                cache.set(self.object_guid, self._ldap_user, 24 * 60 * 60 * 70)
        return self._ldap_user
예제 #16
0
    def get_user(self, user_id):
        from .models import PS1User
        """
        Get's The user object and attached ldap_user data.
        Will create the database entry if required.

        Keyword arguments:
        user_id -- a string or UUID object of samba4 objectGUID of a user.
        """
        try:
            guid = uuid.UUID(str(user_id))
        except ValueError:
            # Happens when we get passed an invalid or outdated user_id
            return None
        try:
            user = PS1User.objects.get(object_guid=str(guid))
        except PS1User.DoesNotExist:
            filter_string = '(objectGUID={})'.format(escape_bytes(guid.bytes_le))
            with get_ldap_connection() as c:
                c.search(settings.AD_BASEDN, filter_string, LEVEL)
                user_dn = c.response[0]['dn']
            user = PS1User(object_guid=str(guid))
            user.save()
        return user
예제 #17
0
 def escaped(query):
     return escape_bytes(query)
예제 #18
0
 def escaped(query):
     return escape_bytes(query)
예제 #19
0
def _convert_objectGUID(item):
    item = uuid.UUID("{{{0!s}}}".format(item)).bytes_le
    item = escape_bytes(item)
    return item
예제 #20
0
 def get_ldap_group_membership(self, user_dn):
     """Retrieve django group ids that this user DN is a member of."""
     if not hasattr(self, '_group_cache'):
         r = LDAPGroup.objects.all().values_list('distinguished_name', 'obj')
         self._group_cache = dict(r)
     logger.debug('Retrieving groups that {} is a member of'.format(user_dn))
     ldap_groups = self.smart_ldap_searcher.search(self.group_base, self.group_membership_filter.format(user_dn=escape_bytes(user_dn)), ldap3.SEARCH_SCOPE_WHOLE_SUBTREE, None)
     return (self._group_cache.get(i['dn']) for i in ldap_groups if i.get('dn'))
예제 #21
0
 def guid_to_search(cls, guid):
     return escape_bytes(uuid.UUID(guid).bytes_le)
 def test_search_exact_match_with_parentheses_in_filter(self):
     result = self.connection.search(search_base=test_base, search_filter='(' + test_name_attr + '=*' + escape_bytes(')') + '*)', attributes=[test_name_attr, 'sn'])
     if not isinstance(result, bool):
         response, result = self.connection.get_response(result)
     else:
         response = self.connection.response
         result = self.connection.result
     self.assertEqual(result['description'], 'success')
     self.assertEqual(len(response), 1)
     self.assertEqual(response[0]['attributes']['cn'][0], 'test-search-(parentheses)')
예제 #23
0
def _convert_objectGUID(item):
    item = uuid.UUID("{{{0!s}}}".format(item)).bytes_le
    item = escape_bytes(item)
    return item
예제 #24
0
    def test_search_exact_match_with_parentheses_in_filter(self):
        self.delete_at_teardown.append(add_user(self.connection, testcase_id, '(search)-3', attributes={'givenName': 'givenname-3'}))
        result = self.connection.search(search_base=test_base, search_filter='(&(' + test_name_attr + '=' + testcase_id + '*)(' + test_name_attr + '=*' + escape_bytes(')') + '*))', attributes=[test_name_attr, 'sn'])
        if not self.connection.strategy.sync:
            response, _ = self.connection.get_response(result)
            json_response = self.connection.response_to_json(search_result=response)
        else:
            json_response = self.connection.response_to_json()
        json_entries = json.loads(json_response)['entries']

        self.assertEqual(len(json_entries), 1)
        if test_server_type == 'AD':
            self.assertEqual(json_entries[0]['attributes'][test_name_attr], testcase_id + '(search)-3')
        else:
            self.assertEqual(json_entries[0]['attributes'][test_name_attr][0], testcase_id + '(search)-3')
예제 #25
0
 def test_search_exact_match_with_parentheses_in_filter(self):
     self.delete_at_teardown.append(add_user(self.connection, testcase_id, '(search)-10', attributes={'givenName': 'givenname-10'}))
     result = self.connection.search(search_base=test_base, search_filter='(' + test_name_attr + '=' + testcase_id + '*' + escape_bytes(')') + '*)', attributes=[test_name_attr, 'sn'])
     if not self.connection.strategy.sync:
         response, result = self.connection.get_response(result)
         entries = self.connection._get_entries(response)
     else:
         result = self.connection.result
         entries = self.connection.entries
     self.assertEqual(result['description'], 'success')
     self.assertEqual(len(entries), 1)
     self.assertEqual(entries[0][test_name_attr][0], testcase_id + '(search)-10')
예제 #26
0
MY_BASE = 'cn=Users, dc=ad2012, dc=LAB'
MY_ADMIN = 'cn=Giovanni, cn=Users, dc=AD2012, dc=LAB'
MY_PASSWORD = '******'
MY_USER = '******'

# establish a connection to the AD Server
print('Trying to connect to ' + MY_SERVER + ' with user ' + MY_ADMIN)
s = Server(MY_SERVER, use_ssl=True)
c = Connection(s, MY_ADMIN, MY_PASSWORD)
if c.bind():
    print('Searching for object GUID for user ' + MY_USER)
    if c.search(MY_BASE, '(cn=%s)' % MY_USER, attributes=['objectGuid']):
        print('Entry ' + c.response[0]['dn'] + ' found')
        if c.response[0]['attributes']['objectGuid']:
            guid = c.response[0]['attributes']['objectGuid']
            escaped_guid = escape_bytes(UUID(guid).bytes_le)
            print('Object GUID for %s is %s. Its escaped bytes value is %s' %
                  (MY_USER, guid, escaped_guid))
            print('Searching for guid ' + guid)
            if c.search(MY_BASE,
                        '(objectGuid=%s)' % escaped_guid,
                        attributes=['samAccountName', 'objectGUID']):
                print('Found user %s with object GUID %s' %
                      (c.response[0]['attributes']['samAccountName'],
                       c.response[0]['attributes']['objectGuid']))
            else:
                print('ObjectGuid ' + guid + ' not found')
        else:
            print('objectGuid not found for ' + MY_USER)
    else:
        print(MY_USER + ' not found')
예제 #27
0
def trim_objectGUID(userId):
    userId = uuid.UUID("{{{0!s}}}".format(userId)).bytes_le
    userId = escape_bytes(userId)
    return userId
예제 #28
0
파일: ldap.py 프로젝트: lwycool/EEH
from .base import BaseDriver
from ldap3 import Connection
from ldap3.utils.conv import escape_bytes

ldap_escape = lambda s: escape_bytes(s.encode())


class Driver(BaseDriver):
    connection = None

    def __init__(self, config, domains=[], **kwargs):
        self.config = config

        self.user_base = config["user base"]
        self.user_query = config["user query"]
        self.user_name_attribute = config["user name attribute"]
        self.user_mail_attribute = config["user mail attribute"]

        self.group_base = config["group base"]
        self.group_query = config["group query"]
        self.group_member_attribute = config["group member attribute"]

        self.domains = domains

    def get_connection(self, c=None):
        if c is None:
            return Connection(self.config["server"], self.config["binddn"],
                              self.config["password"], True)
        else:
            return c