Hi folks,

Lately we've been thinking about disaster recovery and leveraging the change log to recover from partition corruption. We've also mixed into the fray the idea of building up a replica after a nascent server is added to a cluster.  We also spoke about applying the changes in the CL of one server to bring a fresh server to some previous state.

In all these cases, and a couple more below,
   
   - exporting then reimporting
   - connection pooling


there is a distinct need to preserve the identity information associated with the creatorsName and the modifiersName. In the above examples, the server internally must apply changes in the change log as the identity of the creator and modifier.  In most cases timestamps should also be preserved. Internally this is easy to do with ApacheDS' API. However it is not so easy when changes are coming from outside of the server.  For example when bringing a new replica into a cluster and loading it with entries it's very hard to preserve the values of these operational attributes.

Currest State
-------------------

Some leg work was done to be able to implement a "RunAs" capability in ApacheDS. An autorizedPrincipal property and effectivePrincipal was added to all operation contexts [0] via a base class.  The authenticatedPrincipal and yet another effectivePrincipal is accessible via the CoreSession [1]. The DefaultAuthorizationInterceptor [2] was indirectly modified via it's base class, BaseInterceptor [3], to leverage the effectivePrincipal.

There needs to be some clarification here as to what all this is about. A session must have an authenticated principal and my optionally have an authorized principal. The authenticated principal is the principal whose credentials were provided to bind after establishing the session.  The authorized principal is another identity associated with the session rather than with an individual request. There are, I believe, SASL mechanisms that would set this authorized principal. When this is the case, operations should be performed as the authorized user.  Hence the getEffectivePrincipal() method on the CoreSession checks if an authorized principal exists and returns that or in it's absence returns the authenticated principal.

AbstractOperationContext [0], also contains an authorized principal and has access to the CoreSession. These operation contexts represent requests being processed. Eventually with the proxied authorization control implemented, this authorized principal will be populated when the control is used to issue requests. The effectivePrincipal() method on OperationContexts will return the authorized principal when it is set at the request level. If it has not been set then the session.getEffectivePrincipal() value is returned by a context.

Need for Controls
-------------------------

There is really very little work that remains to implement this great control. It's great because it facilitates a single connection to issue requests as another user.  This is obviously a huge plus when dealing with connection pooling. But more importantly it's a plus when dealing with bringing a replica online and up to speed with the contents of it's peers in a cluster.  It will allow the a user with the proper authorization power to write entries to the DIT with the identity that was originally used to perform the operation hence preserving the creatorsName and the modifiersName.  This is important to do since these attributes can impact auditing, and access controls [4].

Likewise we should preserve modifyTimestamp and the createTimestamp operational attribute.  There is no specification for doing this as far as I know but a control which carries with it the timestamps to use can be very useful here.  Perhaps this is also something we can explore.

Now all these operationalAttributes have the directoryOperation USAGE and not distributedOperation or dSAOperation. This is somewhat confusing.  If the dSAOperation were used then that would tell us that these values can be different for each server.  If distributedOperation was used then it's something I would imagine would need to be the same across replicas.  Although confusing I think these operational attributes must line up across replicas in the cluster otherwise you have divergence.

Stored Procedures and Triggers
----------------------------------------------

When we get the SP and trigger story right, the RunAs code will come in very handy. For example, an administrator installs a trigger to fire a SP whenever an entry is deleted in some region of the DIT. The SP updates groups by removing references to the deleted entry.  The groups are protected from ACI to prevent anyone but the administrator to make changes.  When a normal user raises the trigger, that trigger will need to execute the SP with the authorization rights of the administrator.  The procedure will then execute as the administrator.

Summary
--------------

This control as well as another to support the preservation of timestamps is needed to do several things correctly.  Thankfully we already have some foundation to build on so their implementation would not be that involved.


Thanks,
Alex

-------------------
[0] - http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/interceptor/context/AbstractOperationContext.java?revision=702434&view=markup
[1] - http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/CoreSession.java?revision=725712&view=markup
[2] - http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authz/DefaultAuthorizationInterceptor.java?view=log
[3] - http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/interceptor/BaseInterceptor.java?revision=702434&view=markup
[4] - Nothing in ApacheDS exists yet to leverage the creatorsName or the modifiersName to conduct access decisions