[ 
https://issues.apache.org/jira/browse/DIRSERVER-1844?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17241353#comment-17241353
 ] 

Emmanuel Lécharny commented on DIRSERVER-1844:
----------------------------------------------

Hi Ryan,

 

yes, I just pushed the 'member' branch there.

 

FTR, the 'memberOf' attribute is a virtual attribute, and it will require a bit 
of configuration. Typically, we would like to follow what OpenLDAP has 
implemented 
([slapo-memberof|[https://www.openldap.org/software/man.cgi?query=slapo-memberof&sektion=5&apropos=0&manpath=OpenLDAP+2.4-Release]).]
 This is clearly a bit too much to start withn, so let's devise what we really 
need to begin with.

 

The very first step would be to have something that works with the 
{{groupOfNames}} attribute. Every entry which DN is listed in the 
{{groupOfNames}} attribute values will be returned with a {{memberof}} 
attribute with the list of groups it belongs to. That requires a internal 
search when processing each entry during a search or a lookup.

The way the server is built makes it so that those entries are processed after 
the search/lookup request has been fully processed. That means we first fetch 
the entries from the backend, accordingly to the search request filter, and 
then we filter them one by one to apply some modifications (like removing 
attributes that aren't requested, adding some collective attributes on the fly, 
etc).

This is this filtering mechanism which is the key. It's done by class 
implementing the {{EntryFilter}} interface. You can have a look at such 
implementations:
 * {{AuthorizationFilter}}: check if the entry is to be returned based on the 
existing ACIs
 * {{CollectiveAttributeFilter}}: add some collective attrributes to the entry 
if needed
 * {{HideEntriesFilter}}: hide entries (like the subentries)
 * {{HideSubentriesFilter}}: hide subentries attributes
 * {{OperationalAttributeSearchFilter}}: process the operational attributes
 * {{SubordinatesSearchFilter}}: add the subordinate attributes (which tells 
how many parents and children an entry has)

All those filters are processed in the order they are added in the filter 
chain. For instance, the {{OperationalAttributeSearchFilter}} filter is added 
with this code :
{code:java}
public EntryFilteringCursor search( SearchOperationContext searchContext ) 
throws LdapException
{
    EntryFilteringCursor cursor = next( searchContext );        

    if ( searchContext.isAllOperationalAttributes()
            || ( ( searchContext.getReturningAttributes() != null ) && 
!searchContext.getReturningAttributes().isEmpty() ) )
    {
        if ( directoryService.isDenormalizeOpAttrsEnabled() )
        {
            cursor.addEntryFilter( denormalizingSearchFilter );
        }

        cursor.addEntryFilter( operationalAttributeSearchFilter );   <<<------ 
HERE
        cursor.addEntryFilter( subordinatesSearchFilter );
            
        return cursor;
    }

    return cursor;
}
 {code}
When we process the cursor in the main loop (ie in 
{{SearchRequestHandler.writeResults()}}), we read each entry from the resulting 
cursor, and for each one of them, we apply the filters.

In our case, what we need to do is to add such a filter so that when we process 
an entry, we to a search for a {{groupOfNames entry which }}{{member}} 
attribute has a value corresponding to the processed entry's DN. If so, we can 
then add the {{memberof}} attribute to this entry.

This is what the very basic first version of the implementation should do. IT 
WILL BE *VERY* INNEFICIENT. Imagine you have hundreds of entries to return, 
that means hundreds of search for the {{groupOfNames}} instances in the server, 
plus a check for potentially hundreds of DN in the {{member}} attribute, but at 
least it would do the job.

So bottom line, it's quite simple, you just need to create the interceptor 
(which you did), and add a filter class within it (like what we have in the 
{{CollectiveAttributeFilter}} class){{}}and implement the search into the 
{{accept}} method of this filter.

Going further would mean adding some caching mechanism to avoid doing such a 
search which is costly, and also make this interceptor configurable so that we 
can use another attribute that {{GroupOfnames}}.

 

Hope it helps !

> Add support for memberOf virtual attribute
> ------------------------------------------
>
>                 Key: DIRSERVER-1844
>                 URL: https://issues.apache.org/jira/browse/DIRSERVER-1844
>             Project: Directory ApacheDS
>          Issue Type: New Feature
>          Components: ldap
>    Affects Versions: 2.0.0.AM25
>            Reporter: Jay Danielsen
>            Priority: Major
>         Attachments: MemberOfInterceptor.java
>
>
> Several ldap servers support a reverse group membership lookup capability for 
> access control.
> using the rfc4519 groupOfNames objectclass/member attribute, and/or 
> groupOfUniqueNames objectclass/uniqueMember attribute.
> references:
> http://www.openldap.org/doc/admin24/overlays.html (Section 12.8. Reverse 
> Group Membership Maintenance)
> http://opendj.forgerock.org/doc/admin-guide/index/chap-groups.html (Working 
> with groups of entries)



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to