Exemplo n.º 1
0
    def get_group_members(self, group_info):
        if not self.is_ad:
            members = []
            member_attrs = list(set(GROUP_MEMBER_MAP.values()))
            for member_attr in member_attrs:
                if member_attr in group_info:
                    m = group_info.get(member_attr, [])
                    if isinstance(m, basestring):
                        m = [m]
                    members.extend(m)
            return members
        else:
            group_dn = group_info['distinguishedName']
            group_info['dn'] = group_dn

            if self._cached_groups is None:
                self._cached_groups = self.get_groups(use_lookup_base=True)

            child_groups = self.get_children(group_dn)
            child_groups.append(group_dn)

            members = []
            member_attrs = list(set(GROUP_MEMBER_MAP.values()))
            for grp_dn in child_groups:
                grp = [g for g in self._cached_groups if g[0] == grp_dn][0]
                for member_attr in member_attrs:
                    if member_attr in grp[1]:
                        m = grp[1].get(member_attr, [])
                        if isinstance(m, basestring):
                            m = [m]
                        members.extend(m)
            return list(set(members))
Exemplo n.º 2
0
    def get_group_members(self, group_info):
        if not self.is_ad:
            members = []
            member_attrs = list(set(GROUP_MEMBER_MAP.values()))
            for member_attr in member_attrs:
                if member_attr in group_info:
                    m = group_info.get(member_attr, [])
                    if isinstance(m, basestring):
                        m = [m]
                    members.extend(m)
            return members
        else:
            group_dn = group_info['distinguishedName']
            group_info['dn'] = group_dn

            if self._cached_groups is None:
                self._cached_groups = self.get_groups()

            child_groups = self.get_children(group_dn)
            child_groups.append(group_dn)

            members = []
            member_attrs = list(set(GROUP_MEMBER_MAP.values()))
            for grp_dn in child_groups:
                grp = [g for g in self._cached_groups if g[0] == grp_dn][0]
                for member_attr in member_attrs:
                    if member_attr in grp[1]:
                        m = grp[1].get(member_attr, [])
                        if isinstance(m, basestring):
                            m = [m]
                        members.extend(m)
            return list(set(members))
Exemplo n.º 3
0
    def manage_editUserRoles(self, user_dn, role_dns=[], REQUEST=None):
        """ Edit the roles (groups) of a user """
        all_groups = self.getGroups(attr='dn')
        cur_groups = self.getGroups(dn=user_dn, attr='dn')
        operations = []
        luf = self.getLUF()

        user = self.getUserByDN(user_dn)
        if user is None:
            return

        for role_dn in role_dns:
            if role_dn not in all_groups:
                newgroup_type = 'groupOfUniqueNames'
                newgroup_member = GROUP_MEMBER_MAP.get(newgroup_type)
                newgroup_name = luf._delegate.explode_dn(role_dn, 1)[0]
                connection = luf._connect()
                attr_list = [ ('objectClass', ['top', newgroup_type])
                            , ('cn', newgroup_name)
                            , (newgroup_member, [user_dn, luf._binduid])
                            ]
                connection.add_s(role_dn, attr_list)


        for group in all_groups:
            if group in cur_groups and group not in role_dns:
                operations.append({ 'op'     : luf._delegate.DELETE
                                  , 'target' : group
                                  , 'type'   : luf.getGroupType(group)
                                  } )
            elif group in role_dns and group not in cur_groups:
                operations.append({ 'op'     : luf._delegate.ADD
                                  , 'target' : group
                                  , 'type'   : luf.getGroupType(group)
                                  } )

        if operations:
            connection = luf._connect()

            for to_do in operations:
                mod_list = ( ( to_do['op']
                             , GROUP_MEMBER_MAP.get(to_do['type'])
                             , user_dn
                             ), )
                try:
                    connection.modify_s(to_do['target'], mod_list)
                except Exception, e:
                    msg = str(e)

            msg = 'Roles changed for %s' % (user_dn)
Exemplo n.º 4
0
    def manage_editUserRoles(self, user_dn, role_dns=[], REQUEST=None):
        """ Edit the roles (groups) of a user """
        all_groups = self.getGroups(attr='dn')
        cur_groups = self.getGroups(dn=user_dn, attr='dn')
        operations = []
        luf = self.getLUF()

        user = self.getUserByDN(user_dn)
        if user is None:
            return

        for role_dn in role_dns:
            if role_dn not in all_groups:
                newgroup_type = 'groupOfUniqueNames'
                newgroup_member = GROUP_MEMBER_MAP.get(newgroup_type)
                newgroup_name = luf._delegate.explode_dn(role_dn, 1)[0]
                connection = luf._connect()
                attr_list = [('objectClass', ['top', newgroup_type]),
                             ('cn', newgroup_name),
                             (newgroup_member, [user_dn, luf._binduid])]
                connection.add_s(role_dn, attr_list)

        for group in all_groups:
            if group in cur_groups and group not in role_dns:
                operations.append({
                    'op': luf._delegate.DELETE,
                    'target': group,
                    'type': luf.getGroupType(group)
                })
            elif group in role_dns and group not in cur_groups:
                operations.append({
                    'op': luf._delegate.ADD,
                    'target': group,
                    'type': luf.getGroupType(group)
                })

        if operations:
            connection = luf._connect()

            for to_do in operations:
                mod_list = ((to_do['op'], GROUP_MEMBER_MAP.get(to_do['type']),
                             user_dn), )
                try:
                    connection.modify_s(to_do['target'], mod_list)
                except Exception, e:
                    msg = str(e)

            msg = 'Roles changed for %s' % (user_dn)
Exemplo n.º 5
0
    def getGroupedUsers(self, groups=None):
        """ Retrieve all users that in the groups i know about """
        all_dns = {}
        users = []
        luf = self.getLUF()
        possible_members = list(Set(GROUP_MEMBER_MAP.values()))

        if groups is None:
            groups = self.getGroups()

        for group_id, group_dn in groups:
            group_details = self.getGroupDetails(group_id)

            for attribute_name, dn_list in group_details:
                if attribute_name in possible_members:
                    for dn in dn_list:
                        all_dns[dn] = 1

        for dn in all_dns.keys():
            user = luf.getUserByDN(dn)

            if user is not None:
                users.append(user.__of__(self))

        return tuple(users)
Exemplo n.º 6
0
    def get_groups(self, use_lookup_base=False):
        """Return all LDAP groups below the adapted LDAPUserFolder's
        `groups_base` (or the `lookup_groups_base` if `use_lookup_base` is True).

        If defined, the `group_filter` property on the adapted LDAPUserFolder
        is used to further filter the results.
        """
        # Build a filter expression that matches objectClasses for all
        # possible group objectClasseses encountered in the wild

        possible_classes = ''
        for oc in GROUP_MEMBER_MAP.keys():
            # concatenate (objectClass=foo) pairs
            possible_classes += filter_format('(%s=%s)', ('objectClass', oc))

        # Build the final OR expression:
        # (|(objectClass=aaa)(objectClass=bbb)(objectClass=ccc))
        search_filter = '(|%s)' % possible_classes

        custom_filter = self.get_group_filter()
        search_filter = self._combine_filters(custom_filter, search_filter)

        if use_lookup_base:
            base_dn = getattr(
                self.context, 'lookup_groups_base', self.context.groups_base)
        else:
            base_dn = self.context.groups_base

        results = self.search(base_dn=base_dn, search_filter=search_filter)

        mapped_results = []
        for result in results:
            mapped_results.append(self.apply_schema_map(result))

        return mapped_results
Exemplo n.º 7
0
    def getGroupedUsers(self, groups=None):
        """ Retrieve all users that in the groups i know about """
        all_dns = {}
        users = []
        luf = self.getLUF()
        possible_members = list(Set(GROUP_MEMBER_MAP.values()))

        if groups is None:
            groups = self.getGroups()

        for group_id, group_dn in groups:
            group_details = self.getGroupDetails(group_id)

            for attribute_name, dn_list in group_details:
                if attribute_name in possible_members:
                    for dn in dn_list:
                        all_dns[dn] = 1

        for dn in all_dns.keys():
            user = luf.getUserByDN(dn)

            if user is not None:
                users.append(user.__of__(self))

        return tuple(users)
Exemplo n.º 8
0
    def get_groups(self):
        """Return all LDAP groups below the adapted LDAPUserFolder's
        groups_base.

        If defined, the `group_filter` property on the adapted LDAPUserFolder
        is used to further filter the results.
        """
        # Build a filter expression that matches objectClasses for all
        # possible group objectClasseses encountered in the wild

        possible_classes = ''
        for oc in GROUP_MEMBER_MAP.keys():
            # concatenate (objectClass=foo) pairs
            possible_classes += filter_format('(%s=%s)', ('objectClass', oc))

        # Build the final OR expression:
        # (|(objectClass=aaa)(objectClass=bbb)(objectClass=ccc))
        search_filter = '(|%s)' % possible_classes

        custom_filter = self.get_group_filter()
        if custom_filter not in [None, '']:
            search_filter = self._combine_filters(custom_filter, search_filter)

        results = self.search(base_dn=self.context.groups_base,
                              filter=search_filter)
        mapped_results = []
        for result in results:
            mapped_results.append(self.apply_schema_map(result))

        return mapped_results
Exemplo n.º 9
0
    def getGroups(self, dn='*', attr=None):
        """ return group records i know about """
        group_list = []

        if self.groups_base:
            no_show = ('Anonymous', 'Authenticated', 'Shared')

            if dn == '*':
                group_classes = GROUP_MEMBER_MAP.keys()
                filt_list = [
                    filter_format('(%s=%s)', ('objectClass', g))
                    for g in group_classes
                ]
                group_filter = '(|%s)' % ''.join(filt_list)
            else:
                member_attrs = list(Set(GROUP_MEMBER_MAP.values()))
                filt_list = [
                    filter_format('(%s=%s)', (m_attr, dn))
                    for m_attr in member_attrs
                ]
                group_filter = '(|%s)' % ''.join(filt_list)
            luf = self.getLUF()

            res = luf._delegate.search(self.groups_base,
                                       self.groups_scope,
                                       group_filter,
                                       attrs=['dn', 'cn'])

            if res['size'] > 0:
                resultset = res['results']
                for i in range(res['size']):
                    dn = resultset[i].get('dn')
                    try:
                        cn = resultset[i].get('cn')[0]
                    except KeyError:  # NDS oddity
                        cn = luf._delegate.explode_dn(dn, 1)[0]

                    if attr is None:
                        group_list.append((cn, dn))
                    elif attr == 'cn':
                        group_list.append(cn)
                    elif attr == 'dn':
                        group_list.append(dn)

        return group_list
Exemplo n.º 10
0
    def getGroups(self, dn='*', attr=None):
        """ return group records i know about """
        group_list = []

        if self.groups_base:
            no_show = ('Anonymous', 'Authenticated', 'Shared')

            if dn == '*':
                group_classes = GROUP_MEMBER_MAP.keys()
                filt_list = [ filter_format('(%s=%s)', ('objectClass', g))
                                        for g in group_classes ]
                group_filter = '(|%s)' % ''.join(filt_list)
            else:
                member_attrs = list(Set(GROUP_MEMBER_MAP.values()))
                filt_list = [ filter_format('(%s=%s)', (m_attr, dn))
                                            for m_attr in member_attrs ]
                group_filter = '(|%s)' % ''.join(filt_list)
            luf = self.getLUF()

            res = luf._delegate.search( self.groups_base
                                      , self.groups_scope
                                      , group_filter
                                      , attrs=['dn', 'cn']
                                      )

            if res['size'] > 0:
                resultset = res['results']
                for i in range(res['size']):
                    dn = resultset[i].get('dn')
                    try:
                        cn = resultset[i].get('cn')[0]
                    except KeyError:    # NDS oddity
                        cn = luf._delegate.explode_dn(dn, 1)[0]

                    if attr is None:
                        group_list.append((cn, dn))
                    elif attr == 'cn':
                        group_list.append(cn)
                    elif attr == 'dn':
                        group_list.append(dn)

        return group_list
Exemplo n.º 11
0
def manage_editGroupRoles(self, user_dn, role_dns=[], REQUEST=None):
    """ Edit the roles (groups) of a group """
    from Products.LDAPUserFolder.utils import GROUP_MEMBER_MAP
    try:
        from Products.LDAPUserFolder.LDAPDelegate import ADD, DELETE
    except ImportError:
        # Support for LDAPUserFolder >= 2.6
        ADD = self._delegate.ADD
        DELETE = self._delegate.DELETE

    msg = ""

##    Log(LOG_DEBUG, "assigning", role_dns, "to", user_dn)
    all_groups = self.getGroups(attr='dn')
    cur_groups = self.getGroups(dn=user_dn, attr='dn')
    group_dns = []
    for group in role_dns:
        if group.find('=') == -1:
            group_dns.append('cn=%s,%s' % (group, self.groups_base))
        else:
            group_dns.append(group)

    if self._local_groups:
        if len(role_dns) == 0:
            del self._groups_store[user_dn]
        else:
            self._groups_store[user_dn] = role_dns

    else:
        for group in all_groups:
            member_attr = GROUP_MEMBER_MAP.get(self.getGroupType(group))

            if group in cur_groups and group not in group_dns:
                action = DELETE
            elif group in group_dns and group not in cur_groups:
                action = ADD
            else:
                action = None
            if action is not None:
                msg = self._delegate.modify(
                    group
                    , action
                    , {member_attr : [user_dn]}
                    )
##                Log(LOG_DEBUG, "group", group, "subgroup", user_dn, "result", msg)

    if msg:
        raise RuntimeError, msg
def manage_editGroupRoles(self, user_dn, role_dns=[], REQUEST=None):
    """ Edit the roles (groups) of a group """
    from Products.LDAPUserFolder.utils import GROUP_MEMBER_MAP
    try:
        from Products.LDAPUserFolder.LDAPDelegate import ADD, DELETE
    except ImportError:
        # Support for LDAPUserFolder >= 2.6
        ADD = self._delegate.ADD
        DELETE = self._delegate.DELETE

    msg = ""

    ##    Log(LOG_DEBUG, "assigning", role_dns, "to", user_dn)
    all_groups = self.getGroups(attr='dn')
    cur_groups = self.getGroups(dn=user_dn, attr='dn')
    group_dns = []
    for group in role_dns:
        if group.find('=') == -1:
            group_dns.append('cn=%s,%s' % (group, self.groups_base))
        else:
            group_dns.append(group)

    if self._local_groups:
        if len(role_dns) == 0:
            del self._groups_store[user_dn]
        else:
            self._groups_store[user_dn] = role_dns

    else:
        for group in all_groups:
            member_attr = GROUP_MEMBER_MAP.get(self.getGroupType(group))

            if group in cur_groups and group not in group_dns:
                action = DELETE
            elif group in group_dns and group not in cur_groups:
                action = ADD
            else:
                action = None
            if action is not None:
                msg = self._delegate.modify(group, action,
                                            {member_attr: [user_dn]})


##                Log(LOG_DEBUG, "group", group, "subgroup", user_dn, "result", msg)

    if msg:
        raise RuntimeError, msg
Exemplo n.º 13
0
    def getGroupDetails(self, encoded_cn):
        """ Return all group details """
        result = []
        cn = urllib.unquote(encoded_cn)
        luf = self.getLUF()

        res = luf._delegate.search(self.groups_base, self.groups_scope,
                                   '(cn=%s)' % cn,
                                   list(Set(GROUP_MEMBER_MAP.values())))

        if res['exception']:
            result = (('Exception', res['exception']), )
        elif res['size'] > 0:
            result = res['results'][0].items()
            result.sort()

        return tuple(result)
Exemplo n.º 14
0
    def getUsersByRole(self, acl_folder, groups=None):
        """ Return all those users that are in a group """
        all_dns = {}
        res = []
        res_append = res.append
        member_attrs = GROUP_MEMBER_MAP.values()

        if groups is None:  return ()

        for group_id, group_dn in groups:
            dn = self.getRootDN(acl_folder)
            scope = self.getGroupScope(acl_folder)
            result = self.delegate.search(dn, scope, filter_format('(cn=%s)', (group_id,)), ['uniqueMember', 'member'])
            for val in result['results']:
                for dn in val['uniqueMember']:
                    info = self.delegate.search(base=dn, scope=ldap.SCOPE_BASE)
                    [ res_append(i) for i in info['results'] ]
            return res
Exemplo n.º 15
0
    def getUsersByRole(self, acl_folder, groups=None):
        """ Return all those users that are in a group """
        all_dns = {}
        res = []
        res_append = res.append
        member_attrs = GROUP_MEMBER_MAP.values()

        if groups is None:  return ()

        for group_id, group_dn in groups:
            dn = self.getRootDN(acl_folder)
            scope = self.getGroupScope(acl_folder)
            result = self.delegate.search(dn, scope, filter_format('(cn=%s)', (group_id,)), ['uniqueMember', 'member'])
            for val in result['results']:
                for dn in val['uniqueMember']:
                    info = self.delegate.search(base=dn, scope=ldap.SCOPE_BASE)
                    [ res_append(i) for i in info['results'] ]
            return res
Exemplo n.º 16
0
    def getGroupDetails(self, encoded_cn):
        """ Return all group details """
        result = []
        cn = urllib.unquote(encoded_cn)
        luf = self.getLUF()

        res = luf._delegate.search( self.groups_base
                                  , self.groups_scope
                                  , '(cn=%s)' % cn
                                  , list(Set(GROUP_MEMBER_MAP.values()))
                                  )

        if res['exception']:
            result = (('Exception', res['exception']),)
        elif res['size'] > 0:
            result = res['results'][0].items()
            result.sort()

        return tuple(result)
Exemplo n.º 17
0
    def get_groups(self, use_lookup_base=False):
        """Return all LDAP groups below the adapted LDAPUserFolder's
        `groups_base` (or the `lookup_groups_base` if `use_lookup_base` is True).

        If defined, the `group_filter` property on the adapted LDAPUserFolder
        is used to further filter the results.
        """
        # Build a filter expression that matches objectClasses for all
        # possible group objectClasseses encountered in the wild

        possible_classes = ''
        for oc in GROUP_MEMBER_MAP.keys():
            # concatenate (objectClass=foo) pairs
            possible_classes += filter_format('(%s=%s)', ('objectClass', oc))

        # Build the final OR expression:
        # (|(objectClass=aaa)(objectClass=bbb)(objectClass=ccc))
        search_filter = '(|%s)' % possible_classes

        custom_filter = self.get_group_filter()
        search_filter = self._combine_filters(custom_filter, search_filter)

        if use_lookup_base:
            base_dn = getattr(
                self.context, 'lookup_groups_base', self.context.groups_base)
        else:
            base_dn = self.context.groups_base

        results = self.search(base_dn=base_dn, filter=search_filter)

        mapped_results = []
        for result in results:
            dn, entry = result
            if dn is None:
                # This is likely a referral to be hunted down by
                # client-chasing. We don't support those.
                logger.info('Skipping referral: %r' % (result, ))
                continue
            mapped_results.append(self.apply_schema_map(result))

        return mapped_results
Exemplo n.º 18
0
    def getUsersByRole(self, acl_folder, groups=None):
        """ Return all those users that are in a group """
        all_dns = {}
        res = []
        res_append = res.append
        member_attrs = GROUP_MEMBER_MAP.values()

        if groups is None:
            return ()

        for group_id, group_dn in groups:
            dn = self.getRootDN(acl_folder)
            scope = self.getGroupScope(acl_folder)
            delegate = self.get_ldap_delegate()
            result = delegate.search(dn, scope, filter_format("(cn=%s)", (group_id,)), ["uniqueMember", "member"])
            for val in result["results"]:
                for dn in val["uniqueMember"]:
                    p_username = self._user_id_from_dn(dn)
                    info = self.get_source_user_info(p_username)
                    res_append(info)
        return res
Exemplo n.º 19
0
    def getUsersByRole(self, acl_folder, groups=None):
        """ Return all those users that are in a group """
        all_dns = {}
        res = []
        res_append = res.append
        member_attrs = GROUP_MEMBER_MAP.values()

        if groups is None: return ()

        for group_id, group_dn in groups:
            dn = self.getRootDN(acl_folder)
            scope = self.getGroupScope(acl_folder)
            delegate = self.get_ldap_delegate()
            result = delegate.search(dn, scope,
                                     filter_format('(cn=%s)', (group_id, )),
                                     ['uniqueMember', 'member'])
            for val in result['results']:
                for dn in val['uniqueMember']:
                    p_username = self._user_id_from_dn(dn)
                    info = self.get_source_user_info(p_username)
                    res_append(info)
        return res
Exemplo n.º 20
0
    def getAdditionalRoles(self, user, already_added=()):
        """ extend the user roles """
        my_path = self.absolute_url(1)
        add_role_dict = {}
        if user is None:
            return []

        if self.recurse == 1:
            self_path = self.getPhysicalPath()
            other_satellites = self.superValues('LDAPUserSatellite')
            other_satellites.reverse()

            for sat in other_satellites:
                if sat.getPhysicalPath() != self_path:
                    add_role_list = sat.getAdditionalRoles(user, already_added)
                    newly_added = {}

                    for add_role in add_role_list:
                        newly_added[add_role] = 1

                    for add_role in already_added:
                        newly_added[add_role] = 1

                    already_added = tuple(newly_added.keys())

        luf = self.getLUF()
        user_id = user.getId()
        user_expiration = user._created + luf.getCacheTimeout('authenticated')

        if ( self._cache('users').has_key(user_id) and
             self._cache('expiration').get(user_id, 0) >= user_expiration ):
            logger.debug('Used cached user "%s"' % user_id)
            return self._cache('users').get(user_id)

        if self.groups_base:   # We were given a search base, so search there
            user_dn = user.getUserDN()
            member_attrs = list(Set(GROUP_MEMBER_MAP.values()))
            filt_list = [ filter_format('(%s=%s)', (m_attr, user_dn))
                                        for m_attr in member_attrs ]
            group_filter = '(|%s)' % ''.join(filt_list)

            res = luf._delegate.search( self.groups_base
                                      , self.groups_scope
                                      , group_filter
                                      , attrs = ['dn', 'cn']
                                      )

            if res['size'] > 0:
                resultset = res['results']
                for i in range(res['size']):
                    dn = resultset[i].get('dn')
                    try:
                        cn = resultset[i].get('cn')[0]
                    except KeyError:    # NDS oddity
                        cn = luf._delegate.explode_dn(dn, 1)[0]

                    add_role_dict[cn] = 1

        for add_role in already_added:
            add_role_dict[add_role] = 1
        already_added = ()

        if self.groups_map:     # We have a group mapping, so map away
            user_roles = list(user.getRoles())
            roles = user_roles[:]
            roles.extend(add_role_dict.keys())
            roles.extend(list(user._getLDAPGroups()))

            for role in roles:
                mapped_roles = self.groups_map.get(role, [])
                for mapped_role in mapped_roles:
                    if mapped_role and mapped_role not in user_roles:
                        add_role_dict[mapped_role] = 1

        added_roles = add_role_dict.keys()

        if added_roles:
            add_roles = ', '.join(added_roles)
            logger.debug('Added roles "%s" to user "%s"' % (add_roles, user_id))

        self._cacheRoles(user_id, added_roles, user_expiration)

        return added_roles
Exemplo n.º 21
0
    def getAdditionalRoles(self, user, already_added=()):
        """ extend the user roles """
        my_path = self.absolute_url(1)
        add_role_dict = {}
        if user is None:
            return []

        if self.recurse == 1:
            self_path = self.getPhysicalPath()
            other_satellites = self.superValues('LDAPUserSatellite')
            other_satellites.reverse()

            for sat in other_satellites:
                if sat.getPhysicalPath() != self_path:
                    add_role_list = sat.getAdditionalRoles(user, already_added)
                    newly_added = {}

                    for add_role in add_role_list:
                        newly_added[add_role] = 1

                    for add_role in already_added:
                        newly_added[add_role] = 1

                    already_added = tuple(newly_added.keys())

        luf = self.getLUF()
        user_id = user.getId()
        user_expiration = user._created + luf.getCacheTimeout('authenticated')

        if (self._cache('users').has_key(user_id) and
                self._cache('expiration').get(user_id, 0) >= user_expiration):
            logger.debug('Used cached user "%s"' % user_id)
            return self._cache('users').get(user_id)

        if self.groups_base:  # We were given a search base, so search there
            user_dn = user.getUserDN()
            member_attrs = list(Set(GROUP_MEMBER_MAP.values()))
            filt_list = [
                filter_format('(%s=%s)', (m_attr, user_dn))
                for m_attr in member_attrs
            ]
            group_filter = '(|%s)' % ''.join(filt_list)

            res = luf._delegate.search(self.groups_base,
                                       self.groups_scope,
                                       group_filter,
                                       attrs=['dn', 'cn'])

            if res['size'] > 0:
                resultset = res['results']
                for i in range(res['size']):
                    dn = resultset[i].get('dn')
                    try:
                        cn = resultset[i].get('cn')[0]
                    except KeyError:  # NDS oddity
                        cn = luf._delegate.explode_dn(dn, 1)[0]

                    add_role_dict[cn] = 1

        for add_role in already_added:
            add_role_dict[add_role] = 1
        already_added = ()

        if self.groups_map:  # We have a group mapping, so map away
            user_roles = list(user.getRoles())
            roles = user_roles[:]
            roles.extend(add_role_dict.keys())
            roles.extend(list(user._getLDAPGroups()))

            for role in roles:
                mapped_roles = self.groups_map.get(role, [])
                for mapped_role in mapped_roles:
                    if mapped_role and mapped_role not in user_roles:
                        add_role_dict[mapped_role] = 1

        added_roles = add_role_dict.keys()

        if added_roles:
            add_roles = ', '.join(added_roles)
            logger.debug('Added roles "%s" to user "%s"' %
                         (add_roles, user_id))

        self._cacheRoles(user_id, added_roles, user_expiration)

        return added_roles