blob: 1fb6936d747dee819394b92bbbbfd734e0762b59 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<document>
<properties>
<author email="akarasulu">akarasulu</author>
<title>ApacheDS - Interceptor Interactions</title>
</properties>
<body>
<p>
Interceptors will perform operations on behalf of the user/context making calls
against the proxy. Interceptors will often need to access or alter the DIT.
Interceptors have several options for DIT
access/alteration.</p>
<ol nesting="0">
<li>
operate directly against the
nexus</li>
<li>
operate against the nexus
proxy</li>
<li>
operate against the next Interceptor in the
chain</li>
<li>
operate against JNDI
interfaces</li>
<li>
operate against the nexus proxy with selective
bypass</li>
<li>
out of band support methods on
Interceptors</li>
</ol>
<p>
A combination of these approaches can be taken. Each one has side effects and
ramifications when used. We will discuss the ramifications of each option as it
relates to Interceptor interactions. Interceptor interactions (coupling)
undermine the overall goal of having orthogonal independent
services.</p>
<section heading="h2" name="Direct Operations Against the Nexus">
<p>
Direct operations against the system nexus retrieves or alters raw entries
stored within partitions. Sometimes this is absolutely necessary and sometimes
it could lead to serious
problems.</p>
<subsection heading="h3" name="Direct operations on the nexus bypass the Interceptor Mechanism">
<p>
Direct operations on the nexus bypass the Interceptor mechanism. No Invocation
object is pushed onto the InvocationStack, and no Interceptors intercept the
call. If the Interceptor code calling the nexus relies on pre or post
processing by any other Interceptor there will be a
problem.</p>
<p>
A good example is the reliance of upstream Interceptors on the Mitosis
replication Interceptor. Upstream Interceptors ironically don't even know of
the presence of the Mitosis Interceptor, nor that they rely on it. Mitosis does
not actually delete entries but marks them deleted. The Mitosis Interceptor
filters out deleted entries from searches and responds according with
NameNotFoundExceptions when other operations are performed on entries marked for
deletion. Interceptors before the Mitosis Interceptor don't have to worry about
whether or not an entry is deleted because this is handled already. This is not
the case for downstream Interceptors so positioning is critical. Direct access
to the nexus however bypasses the Mitosis Interceptor along with all others and
makes deleted entries
reappear.</p>
</subsection>
<subsection heading="h3" name="Raw access to partition entries may be required">
<p>
Raw access to partition entries should be done with extreme caution. But at
times this access may be absolutely necessary. The Interceptor, it's position
and the effects of bypassing other possibly unknown Interceptors must be taking
into
consideration.</p>
</subsection>
</section>
<section heading="h2" name="Operations on the Nexus Proxy">
<p>
Interceptors that have intercepted an operation, may use the proxy to perform
other operations. These other operations performed to satisfy the first
intercepted operation will also traverse the
InterceptorChain.</p>
<subsection heading="h3" name="There is a risk for infinate recursion">
<p>
The danger here is an infinite recursion. Let's suppose the first intercepted
operation, Invocation *A*, performs operations *A'* (that's A prime) and *B*
against the nexus. Invocation *A'* by the way is the same operation as the
intercepted operation but with different parameters. The same operation does not
mean the same Invocation. In this case *A'* may incur another set of Invocation
*A"* and *B'* all invoked within the same Interceptor. This chain reaction
could continue unabated to blow out the stack without
regulation.</p>
<p>
A good example of an Interceptor prone to an infinite recursion is the
AuthorizationService. It needs to lookup and search for other other entries to
determine access rights to perform operations. Those lookup and search
operations in turn trigger the AuthorizationService again to issue another set
of lookup and search operations and so on. An infinate recursion is the
result.</p>
<p>
If the AuthorizationService could call lookup and search on the nexus proxy
while bypassing itself then the recursion can be avoided. This raises the
question of whether or not sub-operations excecuted by Interceptors are really
considered to be performed by the user of the intercepted
call.</p>
</subsection>
<subsection heading="h3" name="Effects on the InvocationStack">
<p>
Calls against the nexus proxy are not presently possible. They can however be
enabled. The foreseeable mechanism would be to just call the proxy object of
the current intercepted operation. This could be done by peeking at the
InvocationStack to get a handle on the Invocation object for the current
operation. From there the calling Context can be accessed. An accessor in the
Context implementation can expose access to the nexus proxy
object.</p>
<p>
Calling this nexus proxy will push a new Invocation object on top of the current
operation's Invocation object. This is good even though the Context is used to
issue yet another Invocation. The key advantage though is that we can
diffentiate between the two Invocations even if the caller Context, operation
and the parameters are the
same.</p>
</subsection>
<subsection heading="h3" name="Identity Lock-in">
<p>
Because the same Context object is used, the identity performing the operation
is the same. This may be good and
bad.</p>
<p>
It's good because we are associating the sub-operations with the user performing
the primary operation. Although if we peek onto the stack the bottom most
Invocation tells us who the original Invocation was issued by. Even if
sub-operations are performed as another user like the super-user we can tell who
the original user was that this sub-operation was issued on behalf
of.</p>
<p>
There will be situations when we want a setUid like mechanism to access
protected information on behalf of the current user. Even if the current user
does not have access to protected resources, the Interceptor should be able to
access these resources to satisfy the current intercepted operation. Meaning
the Interceptor will need to perform operations as if it were the admin user to
satisfy an operation on behalf of the current user. Doing this is no simple
matter: authentication must be bypassed to enable an operation as the admin
user. Otherwise we would need access to the admin's credentials. Plus
re-authentication as the admin is unnecesary since the Interceptor is trusted
with admin rights. If we trust the Interceptor and give it the ability to
access the DIT as the admin, we must be sure this is done without compromising
security.</p>
<p>
Another alternative to access protected resources would be to disable access
controls for select sub-operations performed by an Interceptor. Perhaps even if
an operation's associated identity is unchanged, another parameter can be used
to provide access as another user. This would be a special cue to the
Authorization
subsystem.</p>
<p>
These limitations just show us that we're missing something in the design of the
Interceptor Mechanism. Whether we need to handle sub-operations with special
authorization measures, selectively bypass or require specific Interceptors
something is
required.</p>
</subsection>
</section>
</body>
</document>