You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Alex Karasulu <ao...@bellsouth.net> on 2005/10/16 10:24:03 UTC
[ApacheDS] Problems with using nextInterceptor.xxxx()
Trustin,
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
IndexOutOfBoundsException:
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
NamingEnumeration
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
InterceptorChain
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 :-).
Thanks,
Alex
Re: [ApacheDS] Problems with using nextInterceptor.xxxx()
Posted by Trustin Lee <tr...@gmail.com>.
Hi Alex,
2005/10/16, Alex Karasulu <ao...@bellsouth.net>:
>
> 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
> IndexOutOfBoundsException:
>
> 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
> NamingEnumeration
> 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
> InterceptorChain
> 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
I understood it fully thanks to your great explanation.
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.
Yes, it is risky and should be performed only when it is required without
questions.
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.
Yes, we can modify the users identity temporarilly. In case of search, I
think it is a right way to go.
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 :-).
I'll modify DirectoryService (or DirectoryServiceConfiguration) to provide
more getter methods such as getProxiedPartitionNexus() besides
getJndiContext(). WDYT?
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/