Beispiel #1
0
 def get_listMembers(self, listname, search_base):
     memberlist = []
     with Connection(
             self.__ldap_server,
             self.__ldap_user,
             self.__ldap_password,
             auto_bind=True,
     ) as conn:
         bswlist = ObjectDef(["groupOfURLs"], conn)
         bswlist += "uniqueMember"
         bswmember = ObjectDef(["inetOrgPerson"], conn)
         r = Reader(conn, bswlist, search_base, "cn:=" + listname)
         r.search()
         for entry in r:
             # print(entry.entry_attributes_as_dict)
             # print(entry['uniqueMember'])
             for item in entry["uniqueMember"]:
                 # print(item.split(',')[0].split('=')[1])
                 r2 = Reader(
                     conn,
                     bswmember,
                     self.ldap_basedn,
                     "cn:=" + item.split(",")[0].split("=")[1],
                 )
                 r2.search()
                 for member in r2:
                     memberlist.append((
                         member["sn"][0] + "," + member["givenName"][0],
                         member["mail"][0],
                     ))
     return memberlist
Beispiel #2
0
 def get_groupMembers(self, groupname, search_base):
     memberlist = []
     with Connection(
             self.__ldap_server,
             self.__ldap_user,
             self.__ldap_password,
             auto_bind=True,
     ) as conn:
         bswmember = ObjectDef(["inetOrgPerson"], conn)
         bswgroup = ObjectDef(["groupOfUniqueNames"], conn)
         r = Reader(conn, bswgroup, search_base, "cn:=" + groupname)
         r.search()
         for entry in r:
             # print(entry.entry_attributes_as_dict)
             # print(entry['uniqueMember'])
             for item in entry["uniqueMember"]:
                 r2 = Reader(
                     conn,
                     bswmember,
                     self.ldap_basedn,
                     "cn:=" + item.split(",")[0].split("=")[1],
                 )
                 r2.search()
                 if len(r2) == 0:
                     add_members = self.get_groupMembers(
                         item.split(",")[0].split("=")[1], search_base)
                     memberlist.extend(add_members)
                 else:
                     for member in r2:
                         memberlist.append((
                             member["sn"][0] + "," + member["givenName"][0],
                             member["mail"][0],
                         ))
     return memberlist
Beispiel #3
0
 def __init__(self, obj):
     self.obj = obj
     self.query = []
     self.base_dn = obj.base_dn
     self.sub_tree = obj.sub_tree
     self.object_def = ObjectDef(obj.object_classes)
     self.operational_attributes = obj.operational_attributes
     self.components_in_and = True
Beispiel #4
0
    def test_search_with_dereference(self):
        reverse = lambda a, e: e[::-1]

        def raise_parentheses_rank(_, l):
            up = {'(': '[', ')': ']', '[': '{', ']': '}', '{': '<', '}': '>'}
            r = []
            for e in l:
                s = ''
                for c in e:
                    s += up[c] if c in up else c
                r.append(s)

            return r

        self.delete_at_teardown.append(
            add_user(self.connection, testcase_id, 'abstract-member-4'))
        self.delete_at_teardown.append(
            add_user(self.connection, testcase_id, 'abstract-member-5'))
        self.delete_at_teardown.append(
            add_user(self.connection, testcase_id, 'abstract-member-6'))
        self.delete_at_teardown.append(
            add_group(self.connection, testcase_id, 'abstract-group',
                      self.delete_at_teardown))
        ou = ObjectDef('inetOrgPerson')
        ou += AttrDef('cn', 'Common Name', post_query=reverse)
        ou += AttrDef('sn', 'Surname')
        ou += AttrDef('givenName',
                      'Given Name',
                      post_query=raise_parentheses_rank)
        ou += AttrDef('ACL')
        qu = 'Common Name: ' + testcase_id + 'abstract-member-*'
        ru = Reader(self.connection, ou, test_base, qu)
        lu = ru.search()
        self.assertEqual(len(lu), 3)

        og = ObjectDef('groupOfNames')
        og += AttrDef('member', dereference_dn=ou)
        og += 'cn'
        qg = 'cn := ' + testcase_id + 'abstract-group'
        rg = Reader(self.connection, og, test_base, qg)
        lg = rg.search()
        self.assertEqual(len(lg), 1)

        eg = lg[0]
        mg = eg.member
        self.assertEqual(len(mg), 3)
        ug = eg.member[0]
        self.assertTrue(
            str(ug.surname) in
            ['abstract-member-4', 'abstract-member-5', 'abstract-member-6'])
Beispiel #5
0
    def get_definition(self,
                       object_class: Union[str, List[str]],
                       attributes: Iterable[str] = None) -> ObjectDef:
        """
        Get a new object class definition automatically from LDAP Schema.
        object definitions are save as cache for later use in connection.
        :param object_class: The LDAP objectClass type to define
        :param attributes: Extra LDAP attributes to include
        :return: ldap3 ObjectDef instance
        """
        # create definition if missing
        if object_class not in self.definitions:
            with LogExecutionTime(
                    f"Loading LDAP Schema definition for objectClass {object_class}"
            ):
                self.definitions[object_class] = ObjectDef(
                    object_class, self.connection)

        # add missing attributes
        if attributes:
            for attr in attributes:
                if attr not in self.definitions[object_class]:
                    self.definitions[object_class] += AttrDef(attr)

        return self.definitions[object_class]
Beispiel #6
0
 def list_ldap_users():
     users = dict()
     server = Server(Config.LDAP, use_ssl=True, get_info=ALL)
     person = ObjectDef('inetOrgPerson')
     try:
         with Connection(
             server=server,
             user=Config.LDAP_ADMIN,
             password=Config.LDAP_ADMIN_PASSWORD,
             auto_bind=True,
             receive_timeout=30,
         ) as conn:
             conn.search(
                 search_base="dc=edirepository,dc=org",
                 search_filter="(objectclass=person)",
                 attributes=["cn", "sn", "uid", "givenName", "mail"]
             )
             for e in sorted(conn.entries):
                 dn = e.entry_dn
                 user = {
                     "dn": e.entry_dn,
                     "cn": e.cn[0],
                     "sn": e.sn[0],
                     "givenName": e.givenName[0],
                     "mail": e.mail[0],
                 }
                 users[e.uid[0]] = user
     except Exception as e:
         logger.error(e)
     return users
    def test_find_entry_with_text_index_match(self):
        self.delete_at_teardown.append(
            add_user(self.connection, testcase_id, 'mat-1'))
        self.delete_at_teardown.append(
            add_user(self.connection, testcase_id, 'mat-2'))
        self.delete_at_teardown.append(
            add_user(self.connection, testcase_id, 'mat-3'))
        o = ObjectDef('inetOrgPerson')
        o += AttrDef('cn', 'Common Name')
        o += AttrDef('sn', 'Surname')
        o += AttrDef(test_multivalued_attribute, 'Given Name')

        query_text = 'Common Name:=' + testcase_id + 'mat-*'
        r = Reader(self.connection, o, test_base, query_text)

        results = r.search()
        self.assertEqual(len(results), 3)
        try:  # multiple matches
            e = r['match']
        except KeyError:
            pass

        e = r['-2']  # exact match
        self.assertTrue('mat-2' in e.entry_dn)

        try:
            e = r['no-match']  # no match
        except KeyError:
            pass
Beispiel #8
0
def profile():
    with Connection(server,
                    current_user.dn,
                    current_user.get_password(),
                    auto_bind=True) as conn:
        person = ObjectDef(["inetOrgPerson"], conn)
        r = Reader(conn, person, current_user.dn)
        r.search()
        # print(r[0].entry_attributes_as_dict)

    form = ProfileForm(request.form, obj=current_user)
    if request.method == "POST" and form.validate():
        w = Writer.from_cursor(r)
        # print(w[0].entry_attributes_as_dict)
        current_user.email = form.email.data
        current_user.vorname = form.vorname.data
        current_user.nachname = form.nachname.data
        w[0].givenName = current_user.vorname
        w[0].sn = current_user.nachname
        w[0].mail = current_user.email
        result = w[0].entry_commit_changes(refresh=True, controls=None)
        if result:
            flash(u"Profiländerung erfolgreich", "success")
            return redirect(url_for("index"))
        else:
            flash(u"Profiländerung nicht erfolgreich", "danger")
    return render_template(
        "/admin/changeprofile.html",
        form=form,
        user=current_user,
        title=u"Profiländerung",
    )
Beispiel #9
0
    def test_match_dn_in_cursor(self):
        self.delete_at_teardown.append(
            add_user(self.connection, testcase_id, 'mat-1'))
        self.delete_at_teardown.append(
            add_user(self.connection, testcase_id, 'mat-2'))
        self.delete_at_teardown.append(
            add_user(self.connection, testcase_id, 'mat-3'))
        o = ObjectDef('inetOrgPerson')
        o += AttrDef('cn', 'Common Name')
        o += AttrDef('sn', 'Surname')
        o += AttrDef(test_multivalued_attribute, 'Given Name')

        query_text = 'Common Name:=' + testcase_id + 'mat-*'
        r = Reader(self.connection, o, test_base, query_text)

        results = r.search()
        self.assertEqual(len(results), 3)

        e = r.match_dn('mat')  # multiple matches
        self.assertEqual(len(e), 3)
        e = r.match_dn(
            '-3'
        )  # single match. there's domains with -20xx in their names, so use -3 to match
        self.assertEqual(len(e), 1)
        e = r.match_dn('no-match')  # no match
        self.assertEqual(len(e), 0)
Beispiel #10
0
    def __init__(self, server, user):
        self.server = server
        self.user = user

        self.person = ObjectDef(['top', 'organizationalPerson', 'user'])
        self.person += AttrDef('distinguishedName', key='dn')
        self.person += AttrDef('objectClass', key='object_class')
        self.person += AttrDef('cn', key='cn')
        self.person += AttrDef('sAMAccountName', key='username')
        self.person += AttrDef('givenName', key='first_name')
        self.person += AttrDef('sn', key='last_name')
        self.person += AttrDef('displayName', key='full_name')
        self.person += AttrDef('userPrincipalName', key='logon')
        self.person += AttrDef('mail', key='email')
        self.person += AttrDef('extensionName', key='email_canonical')
        self.person += AttrDef('userAccountControl', key='control')
        self.person += AttrDef('memberOf', key='groups')

        self.person += AttrDef(server.email_domain, key='email_domain')
        self.person += AttrDef(server.email_buzon_size, key='email_buzon_size')
        self.person += AttrDef(server.email_message_size,
                               key='email_message_size')

        self.person += AttrDef(server.internet_domain, key='internet_domain')
        self.person += AttrDef(server.internet_quota_type,
                               key='internet_quota_type')
        self.person += AttrDef(server.internet_quota_size,
                               key='internet_quota_size')
        self.person += AttrDef(server.internet_extra_quota_size,
                               key='internet_extra_quota_size')

        self.person += AttrDef(server.ftp_home, key='ftp_folder')
        self.person += AttrDef(server.ftp_size, key='ftp_size')

        self.query = 'username: {}'.format(self.user.username, )
Beispiel #11
0
    def user_factory(self, username: str, password: str, db) -> Optional[User]:
        connection = self._get_connection(username, password)

        # Attempting auth
        if not connection.bind():
            return None

        search_filter = config.LDAP_SEARCH_FILTER
        connection.search(self.base_dn, (search_filter % username))

        user_dn = connection.response[0]['dn']
        user_obj = ObjectDef('user', connection)

        reader = Reader(connection, user_obj, user_dn)
        reader.search()

        result = reader.entries[0]

        # Saving user to db
        user = User(username=username, name=str(result.name))
        user.save(db)

        UserLDAP(
            id=user.id,
            title=str(result.title),
            department=str(result.department),
            company=str(result.company),
        ).save(db)

        return user
Beispiel #12
0
class Host():
    __def = ObjectDef(schema=_ldap, object_class=_cfg.hosts.objectclass)
    # attributes to request from LDAP
    __attr_name = _cfg.hosts.attr.name
    __attr_vars = _cfg.hosts.attr.var
    __attr = [__attr_name, __attr_vars]
    base = _cfg.hosts.base

    @classmethod
    def get_one(cls, name):
        """Fetch a single host (inventory host mode)."""

        reader = Reader(connection=_ldap,
                        query=cls.__attr_name + ":" + name,
                        base=cls.base,
                        object_def=cls.__def,
                        sub_tree=sub(_cfg.hosts))

        entries = reader.search(attributes=cls.__attr)
        return cls(entries[0])

    @classmethod
    def load_all(cls):
        by_name = {}
        by_dn = {}

        reader = Reader(connection=_ldap,
                        base=cls.base,
                        object_def=cls.__def,
                        sub_tree=sub(_cfg.hosts))

        entries = reader.search_paged(paged_size=_page_size,
                                      attributes=cls.__attr)
        for entry in entries:
            host = cls(entry)
            by_name[host.name] = host
            by_dn[host.dn] = host

        _log.info("Loaded %i hosts" % len(by_dn))
        return (by_name, by_dn)

    def __init__(self, entry):
        self.dn = entry.entry_dn

        # select a consistent name value, if there are several
        self.name = entry_name(entry, __class__.__attr_name)

        # parse vars values
        self.vars = {}
        for json_vars in entry[__class__.__attr_vars].values:
            self.vars.update(find_vars_in_attr(json_vars))

    def get_data(self):
        return self.vars

    def __str__(self):
        return "Host %s" % self.name
Beispiel #13
0
def check_oauthbase_exists(fix=True):
    """
    Check the oauth2 base DN exists, and if not, create it
    """
    conn = current_app.ldap3_login_manager.connection
    ou = ObjectDef('organizationalunit', conn)
    oauth2base = "%s,%s"%(current_app.config['LDAP_OAUTH2_CLIENT_DN'],
            current_app.config['LDAP_BASE_DN'])
    _check_dn_exists(oauth2base, ou, fix)
 def test_search_object(self):
     self.delete_at_teardown.append(
         add_user(self.connection, testcase_id, 'abstract-1'))
     o = ObjectDef(['inetorgPerson', 'person'], self.connection)
     r = Reader(self.connection, o, test_base,
                '(cn=' + testcase_id + 'abstract-1)')
     r.search()
     self.assertEqual(len(r), 1)
     self.assertEqual(r.entries[0].cn, testcase_id + 'abstract-1')
Beispiel #15
0
def check_userbase_exists(fix=True):
    """
    Check the User base DN exists, and if not, create it.
    """
    conn = current_app.ldap3_login_manager.connection
    ou = ObjectDef('organizationalunit', conn)
    userbase = "%s,%s"%(current_app.config['LDAP_USER_DN'],
            current_app.config['LDAP_BASE_DN'])
    _check_dn_exists(userbase, ou, fix)
Beispiel #16
0
    def _objectdef(cls):
        """
        Helper function to construct the objectdef at runtime.

        Subclasses MUST specify the objectClasses used in the
        `objectClasses` class attribute.
        """
        from ldap3 import ObjectDef
        conn = current_app.ldap3_login_manager.connection
        return ObjectDef(cls.objectClasses, conn)
Beispiel #17
0
    def __init__(cls, name, bases, ns):
        cls._attributes = dict()
        cls._object_def = ObjectDef(cls.object_classes)

        # loop through the namespace looking for LDAPAttribute instances
        for key, value in ns.items():
            if isinstance(value, LDAPAttribute):
                cls._attributes[key] = value
                attr_def = value.get_abstract_attr_def(key)
                cls._object_def.add(attr_def)
    def test_search_with_None_default(self):
        self.delete_at_teardown.append(add_user(self.connection, testcase_id, 'abs-12'))

        ou = ObjectDef('inetOrgPerson')
        ou += AttrDef('cn', 'CommonName')
        ou += AttrDef('employeeType', key='Employee', default=None)
        qu = 'CommonName := ' + testcase_id + 'abs-12'
        ru = Reader(self.connection, ou, test_base, qu)
        lu = ru.search()
        self.assertEqual(lu[0].employee.value, None)
Beispiel #19
0
 def test_search_object(self):
     self.delete_at_teardown.append(
         add_user(self.connection, testcase_id, 'abstract-1'))
     o = ObjectDef(['inetorgPerson', 'person'], self.connection)
     r = Reader(self.connection, o, test_base,
                '(cn=' + testcase_id + 'abstract-1)')
     r.search(attributes='cn'
              )  # AD returns operationError for reading some atributes
     self.assertEqual(len(r), 1)
     self.assertEqual(r.entries[0].cn, testcase_id + 'abstract-1')
    def test_create_query_filter_single_attribute_multiple_value(self):
        o = ObjectDef()
        o += AttrDef('cn', 'Common Name')

        query_text = '|Common Name:=john;=Bob'
        r = Reader(self.connection, o, test_base, query_text)

        r._create_query_filter()

        self.assertEqual('(|(cn=Bob)(cn=john))', r.query_filter)
    def test_create_query_filter_single_attribute_single_value(self):
        o = ObjectDef()
        o += AttrDef('cn', 'Common Name')

        query_text = 'Common Name:John'
        r = Reader(self.connection, o, test_base, query_text)

        r._create_query_filter()

        self.assertEqual('(cn=John)', r.query_filter)
Beispiel #22
0
def check_group_base_exists(fix=True):
    """
    Check the Group base DN exists, and if not, create it.
    """
    conn = current_app.ldap3_login_manager.connection
    ou = ObjectDef("organizationalunit", conn)
    groupbase = "%s,%s" % (
        current_app.config["LDAP_GROUP_DN"],
        current_app.config["LDAP_BASE_DN"],
    )
    _check_dn_exists(groupbase, ou, fix)
def process_outbound_entry(queue_entry, ldap_connection):
    """ Processes queue_entry and apply changes to the LDAP user/group.

    Args:
        queue_entry: (dict) A outbound_queue table entry. The mandatory keys in
            the dict are:
                {
                    "data": (dict containing current state of LDAP object)
                    "data_type": (str)
                }
        ldap_connection: (ldap Connection object) A bound ldap connection object.
    Returns:
        write_confirmation: (bool) Returns True if a change to LDAP occurred,
            returns False if no LDAP changes occurred
    """
    distinguished_name = get_distinguished_name(queue_entry)
    data_type = queue_entry["data_type"]
    if data_type == "group":
        sawtooth_entry_filtered = outbound_group_filter(queue_entry["data"], "ldap")
    elif data_type == "user":
        # Outbound AD user changes is currently not supported
        return False

    object_def = ObjectDef(data_type, ldap_connection)
    reader_cursor = Reader(ldap_connection, object_def, distinguished_name)
    reader_cursor.search()
    writer_cursor = Writer.from_cursor(reader_cursor)

    if reader_cursor.entries:
        LOGGER.debug("Updating AD %s: %s", data_type, distinguished_name)
        validated_entry = validate_update_entry(sawtooth_entry_filtered, data_type)

        # Grab current state of user/group in LDAP
        ldap_resource = writer_cursor[0]

        # Update AD user/group
        for ad_attribute in validated_entry:
            ldap_current_value = ldap_resource[ad_attribute].value

            if ad_attribute != "distinguishedName" and validated_entry[ad_attribute]:
                # Convert member list to list if value is a string
                if ad_attribute == "member" and isinstance(ldap_current_value, str):
                    ldap_current_value = [ldap_current_value]

                # Sort lists for comparison
                if isinstance(ldap_current_value, list):
                    ldap_current_value.sort()
                    validated_entry[ad_attribute].sort()
                if ldap_current_value != validated_entry[ad_attribute]:
                    ldap_resource[ad_attribute] = validated_entry[ad_attribute]
        return ldap_resource.entry_commit_changes()

    LOGGER.debug("AD %s %s was not found.", data_type, distinguished_name)
    return False
Beispiel #24
0
    def test_search_with_default(self):
        self.delete_at_teardown.append(
            add_user(self.connection, testcase_id, 'abstract-member-10'))

        ou = ObjectDef('inetOrgPerson')
        ou += AttrDef('cn', 'CommonName')
        ou += AttrDef('employeeType', key='Employee', default='not employed')
        qu = 'CommonName := ' + testcase_id + 'abstract-member-10'
        ru = Reader(self.connection, ou, test_base, qu)
        lu = ru.search()
        self.assertEqual(str(lu[0].employee), 'not employed')
Beispiel #25
0
            def get_def_(names):
                """
                Lit les définitions de classes LDAP afin de lister tous les
                attributs devant être extraits.

                :param names: la liste des noms de classes LDAP
                :return: une définition contenant tous les attributs \
                        correspondant aux classes listées
                :raises FatalError: une classe LDAP listée n'a pas pu être \
                        trouvée
                """
                (first, rest) = (names[0], names[1:])
                try:
                    from ldap3 import ObjectDef
                    dfn = ObjectDef(first, ldap_conn)
                    for other in rest:
                        for attr in ObjectDef(other, ldap_conn):
                            dfn += attr
                except KeyError as e:
                    raise FatalError('Classe LDAP {} inconnue'.format(str(e)))
                return dfn
    def test_create_query_filter(self):
        o = ObjectDef()
        o += AttrDef('cn', 'Common Name')
        o += AttrDef('sn', 'Surname')
        o += AttrDef('givenName', 'Given Name')

        query_text = '|Common Name:=john;Bob, Surname:=smith'
        r = Reader(self.connection, o, test_base, query_text)

        r._create_query_filter()

        self.assertEqual('(&(sn=smith)(|(cn=Bob)(cn=john)))', r.query_filter)
Beispiel #27
0
 def search_for_users(basedn):
     server = Server(IDIR_URL, get_info=ALL)
     #objectClass
     conn = Connection(server,
                       user=current_app.config["LDAP_IDIR_USERNAME"],
                       password=current_app.config["LDAP_IDIR_PASSWORD"],
                       authentication=NTLM,
                       auto_bind=True)
     obj_user = ObjectDef('user', conn)
     r = Reader(conn, obj_user, basedn)
     r.search()
     return [x.entry_attributes_as_dict for x in r]
Beispiel #28
0
    def test_validate_query_filter(self):
        o = ObjectDef()
        o += AttrDef('cn', 'Common Name')
        o += AttrDef('sn', 'Surname')
        o += AttrDef('givenName', 'Given Name')

        query_text = '|Common Name:=john;=Bob, Surname:=smith'
        r = Reader(self.connection, o, test_base, query_text)

        r._validate_query()

        self.assertEqual('Surname: =smith, |CommonName: =Bob;=john', r.validated_query)
Beispiel #29
0
 def get_lists(self, search_base):
     ldap_lists = []
     with Connection(
             self.__ldap_server,
             self.__ldap_user,
             self.__ldap_password,
             auto_bind=True,
     ) as conn:
         r = Reader(conn, ObjectDef(["groupOfURLs"], conn), search_base)
         r.search()
         for entry in r.entries:
             ldap_lists.append(entry.entry_dn)
     return ldap_lists
def main():
    server = Server('ipa.demo1.freeipa.org', get_info=ALL)
    conn = Connection(
        server,
        'uid=admin,cn=users,cn=accounts,dc=demo1,dc=freeipa,dc=org',
        'Secret123',
        auto_bind=True)
    person = ObjectDef('person', conn)
    r = Reader(conn, person, 'ou=ldap3-tutorial,dc=demo1,dc=freeipa,dc=org')
    print(r)
    print('************')
    person += 'uid'
    print(r)