Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 53297 invoked from network); 19 Sep 2005 01:22:24 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 19 Sep 2005 01:22:24 -0000 Received: (qmail 97155 invoked by uid 500); 19 Sep 2005 01:22:23 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 97124 invoked by uid 500); 19 Sep 2005 01:22:23 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 97107 invoked by uid 99); 19 Sep 2005 01:22:23 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 18 Sep 2005 18:22:23 -0700 X-ASF-Spam-Status: No, hits=-9.8 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Sun, 18 Sep 2005 18:22:32 -0700 Received: (qmail 53266 invoked by uid 65534); 19 Sep 2005 01:22:21 -0000 Message-ID: <20050919012220.53265.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r290038 - in /directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz: AuthorizationService.java TupleCache.java Date: Mon, 19 Sep 2005 01:22:20 -0000 To: commits@directory.apache.org From: akarasulu@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: akarasulu Date: Sun Sep 18 18:22:16 2005 New Revision: 290038 URL: http://svn.apache.org/viewcvs?rev=290038&view=rev Log: changes ... o created cache which responds to add, delete and modify events o cache also initializes itself by searching for all access control subentries within all namingContexts of the server o completes DIREVE-258 here http://issues.apache.org/jira/browse/DIREVE-258 o completes DIREVE-259 here http://issues.apache.org/jira/browse/DIREVE-259 Added: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/TupleCache.java (with props) Modified: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/AuthorizationService.java Modified: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/AuthorizationService.java URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/AuthorizationService.java?rev=290038&r1=290037&r2=290038&view=diff ============================================================================== --- directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/AuthorizationService.java (original) +++ directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/AuthorizationService.java Sun Sep 18 18:22:16 2005 @@ -18,6 +18,15 @@ import org.apache.ldap.server.interceptor.BaseInterceptor; +import org.apache.ldap.server.interceptor.NextInterceptor; +import org.apache.ldap.server.jndi.ContextFactoryConfiguration; +import org.apache.ldap.server.configuration.InterceptorConfiguration; +import org.apache.ldap.server.partition.ContextPartitionNexus; + +import javax.naming.Name; +import javax.naming.NamingException; +import javax.naming.directory.Attributes; +import javax.naming.directory.ModificationItem; /** @@ -28,4 +37,46 @@ */ public class AuthorizationService extends BaseInterceptor { + private ContextPartitionNexus nexus; + private TupleCache cache; + + + public void init( ContextFactoryConfiguration factoryCfg, InterceptorConfiguration cfg ) throws NamingException + { + super.init( factoryCfg, cfg ); + + nexus = factoryCfg.getPartitionNexus(); + cache = new TupleCache( factoryCfg ); + } + + + public void add( NextInterceptor next, String upName, Name normName, Attributes entry ) throws NamingException + { + next.add( upName, normName, entry ); + cache.subentryAdded( upName, normName, entry ); + } + + + public void delete( NextInterceptor next, Name name ) throws NamingException + { + Attributes entry = nexus.lookup( name ); + next.delete( name ); + cache.subentryDeleted( name, entry ); + } + + + public void modify( NextInterceptor next, Name name, int modOp, Attributes mods ) throws NamingException + { + Attributes entry = nexus.lookup( name ); + next.modify( name, modOp, mods ); + cache.subentryModified( name, modOp, mods, entry ); + } + + + public void modify( NextInterceptor next, Name name, ModificationItem[] mods ) throws NamingException + { + Attributes entry = nexus.lookup( name ); + next.modify( name, mods ); + cache.subentryModified( name, mods, entry ); + } } Added: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/TupleCache.java URL: http://svn.apache.org/viewcvs/directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/TupleCache.java?rev=290038&view=auto ============================================================================== --- directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/TupleCache.java (added) +++ directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/TupleCache.java Sun Sep 18 18:22:16 2005 @@ -0,0 +1,213 @@ +/* + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.ldap.server.authz; + + +import org.apache.ldap.server.partition.ContextPartitionNexus; +import org.apache.ldap.server.schema.ConcreteNameComponentNormalizer; +import org.apache.ldap.server.jndi.ContextFactoryConfiguration; +import org.apache.ldap.common.exception.LdapSchemaViolationException; +import org.apache.ldap.common.exception.LdapInvalidAttributeValueException; +import org.apache.ldap.common.message.ResultCodeEnum; +import org.apache.ldap.common.acl.ACIItemParser; +import org.apache.ldap.common.acl.ACIItem; +import org.apache.ldap.common.name.LdapName; +import org.apache.ldap.common.filter.ExprNode; +import org.apache.ldap.common.filter.SimpleNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.naming.directory.*; +import javax.naming.Name; +import javax.naming.NamingException; +import javax.naming.NamingEnumeration; +import java.util.*; +import java.text.ParseException; + + +/** + * A cache for tuple sets which responds to specific events to perform + * cache house keeping as access control subentries are added, deleted + * and modified. + * + * @author Apache Directory Project + * @version $Rev$ + */ +public class TupleCache +{ + /** the attribute id for prescriptive aci: prescriptiveACI */ + private static final String ACI_ATTR = "prescriptiveACI"; + /** the attribute id for an object class: objectClass */ + private static final String OC_ATTR = "objectClass"; + /** the object class for access control subentries: accessControlSubentry */ + private static final String ACSUBENTRY_OC = "accessControlSubentry"; + + /** the logger for this class */ + private static final Logger log = LoggerFactory.getLogger( TupleCache.class ); + + /** cloned startup environment properties we use for subentry searching */ + private final Hashtable env; + /** a map of strings to ACITuple collections */ + private final Map tuples = new HashMap(); + /** a handle on the partition nexus */ + private final ContextPartitionNexus nexus; + /** a normalizing ACIItem parser */ + private final ACIItemParser aciParser; + + + /** + * Creates a ACITuple cache. + * + * @param factoryCfg the context factory configuration for the server + */ + public TupleCache( ContextFactoryConfiguration factoryCfg ) throws NamingException + { + this.nexus = factoryCfg.getPartitionNexus(); + aciParser = new ACIItemParser( new ConcreteNameComponentNormalizer( + factoryCfg.getGlobalRegistries().getAttributeTypeRegistry() ) ); + env = ( Hashtable ) factoryCfg.getEnvironment().clone(); + initialize(); + } + + + private void initialize() throws NamingException + { + // search all naming contexts for access control subentenries + // generate ACITuple Arrays for each subentry + // add that subentry to the hash + Iterator suffixes = nexus.listSuffixes( true ); + while ( suffixes.hasNext() ) + { + String suffix = ( String ) suffixes.next(); + Name baseDn = new LdapName( suffix ); + ExprNode filter = new SimpleNode( OC_ATTR, ACSUBENTRY_OC, SimpleNode.EQUALITY ); + SearchControls ctls = new SearchControls(); + ctls.setSearchScope( SearchControls.SUBTREE_SCOPE ); + NamingEnumeration results = nexus.search( baseDn, env, filter, ctls ); + while ( results.hasMore() ) + { + SearchResult result = ( SearchResult ) results.next(); + String subentryDn = result.getName(); + Attribute aci = result.getAttributes().get( ACI_ATTR ); + if ( aci == null ) + { + log.warn( "Found accessControlSubentry '" + subentryDn + "' without any " + ACI_ATTR ); + continue; + } + + subentryAdded( subentryDn, new LdapName( subentryDn ), result.getAttributes() ); + } + results.close(); + } + } + + + private boolean hasPrescriptiveACI( Attributes entry ) throws NamingException + { + // only do something if the entry contains prescriptiveACI + Attribute aci = entry.get( ACI_ATTR ); + if ( aci == null && entry.get( OC_ATTR ).contains( ACSUBENTRY_OC ) ) + { + // should not be necessary because of schema interceptor but schema checking + // can be turned off and in this case we must protect against being able to + // add access control information to anything other than an AC subentry + throw new LdapSchemaViolationException( "", ResultCodeEnum.OBJECTCLASSVIOLATION ); + } + else if ( aci == null ) + { + return false; + } + return true; + } + + + public void subentryAdded( String upName, Name normName, Attributes entry ) throws NamingException + { + // only do something if the entry contains prescriptiveACI + Attribute aci = entry.get( ACI_ATTR ); + if ( ! hasPrescriptiveACI( entry ) ) + { + return; + } + + List entryTuples = new ArrayList(); + for ( int ii = 0; ii < aci.size(); ii++ ) + { + ACIItem item = null; + + try + { + aciParser.parse( ( String ) aci.get( ii ) ); + } + catch ( ParseException e ) + { + String msg = "ACIItem parser failure on '"+item+"': " + e.getMessage(); + log.error( msg, e ); + throw new LdapInvalidAttributeValueException( msg, ResultCodeEnum.INVALIDATTRIBUTESYNTAX ); + } + + entryTuples.addAll( item.toTuples() ); + } + tuples.put( normName.toString(), entryTuples ); + } + + + public void subentryDeleted( Name normName, Attributes entry ) throws NamingException + { + if ( ! hasPrescriptiveACI( entry ) ) + { + return; + } + + tuples.remove( normName.toString() ); + } + + + public void subentryModified( Name normName, ModificationItem[] mods, Attributes entry ) throws NamingException + { + if ( ! hasPrescriptiveACI( entry ) ) + { + return; + } + + boolean isAciModified = false; + for ( int ii = 0; ii < mods.length; ii++ ) + { + isAciModified |= mods[ii].getAttribute().contains( ACI_ATTR ); + } + if ( isAciModified ) + { + subentryDeleted( normName, entry ); + subentryAdded( normName.toString(), normName, entry ); + } + } + + + public void subentryModified( Name normName, int modOp, Attributes mods, Attributes entry ) throws NamingException + { + if ( ! hasPrescriptiveACI( entry ) ) + { + return; + } + + if ( mods.get( ACI_ATTR ) != null ) + { + subentryDeleted( normName, entry ); + subentryAdded( normName.toString(), normName, entry ); + } + } +} Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/ldap/server/authz/TupleCache.java ------------------------------------------------------------------------------ svn:eol-style = native