Le 26/07/16 à 23:42, Mike Davis a écrit : > I've been trying to dig up some examples to implement a specific feature, > but am not really having much luck. Can you point me at some useful > resources to help me figure out my task? > > > > Here's what I am trying to accomplish. I have a groupOfUniqueNames. When a > uniqueMember is added, I want that user to be subject to a different > password policy than the rest of the users. I know how to specify a > specific password policy on a given user, but I want to make maintenance > just a factor of group membership. > > > > What I THINK I need to do is to create a trigger, possibly an > entryTriggerSpecification on the given groupOfUniqueNames. I'm not sure > how to specify that the trigger should be driven by add/delete of a > uniqueMember attribute. I'm also not sure how to define the trigger. > > > > I came across the presentation Ersin Er did at LDAPCon on ApacheDS back in > 2007. Unfortunately, with just the slides, there's not quite enough there > to get me moving, and that was not the current rev of the product.
This is definitively a complex task... I can understand how you feel in front of this pile of code :-) Let me give you some clues. - The best way to implement this feature would be to base it on the administrative model (ie, ACIs). That would require a huge refactoring of the way the Administrative model is working - something much needed, but here we are talking about 2 to 3 months of work-. - Triggers won't help that much either, because it would require some complete review of this part of the server. - there is a third way, simpler : define an interceptor. Interceptors are, in some way, equivalent to tomcat's valves.You can make them prcoess each operation focusing on teh fact that you are interested in. Typically, in your case, the Add, Modify, and Delete operations. The Add/Delete/Modify operations will have 1 thing to take care of : you have to update the entries so that the associated PP is updated at the same time than the groupOfUniqueNamesupdates. That are 3 different operations to implement, with an internal access to the backend in order to update the impacted entries. The best would be to have a look at an existing interceptor An Interceptor operation is typically executed this way : pre-action // do whatever you need before passing to the next interceptor call next() // call the next interceptor post-action // do whatever needed when back from the backend For instance, the CollectiveAttributeInterceptor add method : public void add( AddOperationContext addContext ) throws LdapException { checkAdd( addContext.getDn(), addContext.getEntry() ); next( addContext ); } Here, we first check if we can add the entry, and if so, continue with the next filter (ultimately, it will updated the database). We do't have post-action for this interceptor. The EventInterceptor has no pre-action, but a post-action : /** * {@inheritDoc} */ public void add( final AddOperationContext addContext ) throws LdapException { next( addContext ); List<RegistrationEntry> selecting = getSelectingRegistrations( addContext.getDn(), addContext.getEntry() ); if ( selecting.isEmpty() ) { return; } for ( final RegistrationEntry registration : selecting ) { if ( EventType.isAdd( registration.getCriteria().getEventMask() ) ) { fire( addContext, EventType.ADD, registration.getListener() ); } } } After the entry has been added in the database, we fire an event. Those are just samples, but I hope you get the idea. Once you have your interceptor coded, you will need to add it in the chain. In order to have it injected, and this is a bit tricky, it has to be in the classpath, and you need to change the configuration. The thing is that every interceptors are listed in the config file, and class loaded at startup. Here is teh content of the config file : dn: ou=interceptors,ads-directoryServiceId=default,ou=config ou: interceptors objectclass: organizationalUnit objectclass: top dn: ads-interceptorId=normalizationInterceptor,ou=interceptors,ads-directoryServiceId=default,ou=config objectclass: top objectclass: ads-base objectclass: ads-interceptor ads-interceptororder: 1 ads-interceptorclassname: org.apache.directory.server.core.normalization.NormalizationInterceptor ads-interceptorid: normalizationInterceptor ads-enabled: TRUE dn: ads-interceptorId=authenticationInterceptor,ou=interceptors,ads-directoryServiceId=default,ou=config objectclass: top objectclass: ads-base objectclass: ads-interceptor objectclass: ads-authenticationInterceptor ads-interceptororder: 2 ads-interceptorclassname: org.apache.directory.server.core.authn.AuthenticationInterceptor ads-interceptorid: authenticationInterceptor ads-enabled: TRUE ... dn: ads-interceptorId=referralInterceptor,ou=interceptors,ads-directoryServiceId=default,ou=config objectclass: top objectclass: ads-base objectclass: ads-interceptor ads-interceptororder: 3 ads-interceptorclassname: org.apache.directory.server.core.referral.ReferralInterceptor ads-interceptorid: referralInterceptor ads-enabled: TRUE ... Three important things : - the interceptors are ordered. It's important to keep the order as is, so if you want your interceptor to be put, say, before the referralInterceptor, you will have to set its ads-interceptororder to 3, and increment every other interceptors in teh config file - be sure that the ads-enabled flag is set to TRUE - have the ads-interceptorclassname refering to your interceptor's FQCN This is a primer, so feel free to ask for more.