directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Karasulu <>
Subject [ApacheDS] Problems with using nextInterceptor.xxxx()
Date Sun, 16 Oct 2005 08:24:03 GMT

After adding ACI guards for search() I started getting some 
IndexOutOfBoundsExceptions.  These were resulting from peek() calls by 
interceptors on an empty InvocationStack.  To sum up what's happening: 
the exceptions are resulting from calls to nextInterceptor.xxxx() within 
ACI tuple filters. 

Below is an in depth explanation of what's happening and why using 
nextInterceptor.xxxx() operations are *evil* ...

The search() method guards are implemented using a SearchResultFilter.  
This filter is used in conjunction with a 
SearchResultFilteringEnumeration which wraps the nexus returned 
enumeration.   It applies this filter to each candidate entry before it 
is returned to remove attributes or their values.  It also determines if 
the entry should be returned by the search at all.  I use the ACDFEngine 
obviously to perform access checks within the filter's accept() method. 

The search() method (and list() also) is very special in terms of 
interceptor handling.  Special, because both these operations produce 
NamingEnumerations.  The enumerations once returned by the proxy, are 
used to retrieve entries.  Calls to next() on enumerations invoke code 
that executes behind the nexus proxy even though the "interception" 
process is over.  Let me show the steps that lead to this 

1). A search() is invoked on a ServerDirContext
2). ServerDirContext transforms some arguments and forwards call to a 
search() method on the DirectoryPartitionNexusProxy
  (a) Proxy pushes a search operation Invocation onto InvocationStack: 
this Invocation object contains a handle to the JNDI context used to 
initiate the search() operation
  (b) Proxy then forwards the search() call to InterceptorChain
3). InterceptorChain after invoking search() on all interceptors finally 
calls search() on the DirectoryPartitionNexus which returns a 
4). While returning through all the interceptors in the chain, the 
NamingEnumeration returned by the nexus is wrapped by one or more 
interceptors using a SearchResultFilteringEnumeration.
5). The wrapped NamingEnumeration returns from the call to the 
6). The proxy then pops the Invocation stack (so the stack is empty)
7). Calls are made to the enumeration's next() method
  (a) accept() methods of SearchResultFilters are invoked.  These 
SearchResultFilters are usually defined as inner classes within an 
Interceptor and they have access to the Interceptor's members and methods.
  (b) accept() methods invoke the ACDFEngine to determine whether or not 
to return an entry, remove attributes, or just values from attributes
  (c) ACDFEngine calls nextInterceptor.xxxx() to do its job
  (d) Downstream interceptors peek() on the empty InvocationStack to 
produce IndexOutOfBoundsExceptions

What does all this mean in the end?  We cannot invoke 
nextInterceptor.xxxx() methods from within SearchResultFilter.accept() 
methods since they *can* execute when the stack is empty.  There are two 
choices for us:

1).  Call the nexus directly
2).  Call the nexus proxy

The first option is risky.  It does not take into account things managed 
by other interceptors like entries that are marked deleted but have yet 
to be deleted.  Or for example when operational attributes like 
modifyTimestamp are updated.  These would all have to be managed 
manually and there would be much code duplication defeating the purpose 
for these interceptors.

The second option is a PITA because we have to figure out the identity 
that we must execute the code as.  Sometimes it should be as the user 
that is performing the search and sometimes it should be as the admin to 
access sensitive internal server information.  If it is the admin then 
we have to authenticate as the admin or do we?  Perhaps admin access can 
be rigged in somehow without requiring authentication? See how this 
becomes a problem.

So do you have any ideas here?  I know this is a lot of stuff.  I'm just 
not doing too well with ideas at the moment. Hopefully you have a quick 
nice solution in mind already :-).


View raw message