You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tb...@apache.org on 2006/12/12 16:24:14 UTC

svn commit: r486187 [7/49] - in /directory/trunks/triplesec: ./ admin-api/ admin-api/src/ admin-api/src/main/ admin-api/src/main/java/ admin-api/src/main/java/org/ admin-api/src/main/java/org/safehaus/ admin-api/src/main/java/org/safehaus/triplesec/ ad...

Added: directory/trunks/triplesec/admin-api/src/test/resources/server.ldif
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/test/resources/server.ldif?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/test/resources/server.ldif (added)
+++ directory/trunks/triplesec/admin-api/src/test/resources/server.ldif Tue Dec 12 07:23:31 2006
@@ -0,0 +1,485 @@
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you 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. 
+#  
+#   EXAMPLE.COM is freely and reserved for testing according to this RFC:
+#
+#   http://www.rfc-editor.org/rfc/rfc2606.txt
+#
+#
+
+#
+# This ACI allows brouse access to the root suffix and one level below that to anyone.
+# At this level there is nothing critical exposed.  Everything that matters is one or
+# more levels below this.
+#
+
+dn: cn=browseRootAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { maximum 1 }
+prescriptiveACI: { identificationTag "browseRoot", precedence 100, authenticationLevel none, itemOrUserFirst userFirst: { userClasses { allUsers }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantBrowse } } } } }
+
+dn: ou=Users, dc=example, dc=com
+objectclass: top
+objectclass: organizationalunit
+ou: Users
+
+#
+# This ACI allows users to modify a limited set of attributes in their own user
+# entry as well as read, compare those attributes.  The user's entry must be 
+# browseable and the DN must be returnable.
+#
+
+dn: cn=allowSelfModificationsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=users", maximum 1 }
+prescriptiveACI: { identificationTag "allowSelfModifications", precedence 14, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { thisEntry }, userPermissions  {  { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantModify, grantBrowse, grantRead, grantDiscloseOnError } }, { protectedItems {allAttributeValues {userPassword, krb5Key, givenName, cn, commonName, surName, sn, objectClass }}, grantsAndDenials { grantModify, grantAdd, grantRemove, grantRead, grantDiscloseOnError, grantCompare } } } } }
+
+#
+# This ACI allows users to access a limited set of attributes in their own user
+# entry as well as compare those attributes.  The user's entry must be browseable 
+# and the DN must be returnable.
+#
+
+dn: cn=allowSelfAccessAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=users", maximum 1 }
+prescriptiveACI: { identificationTag "allowSelfAccess", precedence 15, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { thisEntry }, userPermissions  {  { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantBrowse, grantRead, grantDiscloseOnError } }, { protectedItems {allAttributeValues {uid, userPassword, givenName, cn, commonName, surName, sn, objectClass, creatorsName, modifiersName, createTimestamp, modifyTimestamp, krb5AccountDisabled, description, apacheSamType }}, grantsAndDenials { grantRead, grantDiscloseOnError, grantCompare } } } } }
+
+dn: ou=Groups, dc=example, dc=com
+objectclass: top
+objectclass: organizationalunit
+ou: Groups
+
+dn: cn=superUsers, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: superUsers
+uniqueMember: uid=admin, ou=system
+
+dn: cn=userAdmins, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: userAdmin
+uniqueMember: uid=admin, ou=system
+
+dn: cn=applicationAdmins, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: applicationAdmin
+uniqueMember: uid=admin, ou=system
+
+dn: cn=groupAdmins, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: groupAdmin
+uniqueMember: uid=admin, ou=system
+
+#
+# This ACI allows members of the superUsers group to have full modify and read access
+# to the entire realm as does the system administrator principal: uid=admin, ou=system.
+#
+# The only thing these users cannot do is modify the system partition.  They are only
+# restricted to superUser rights within this realm partition
+#
+ 
+dn: cn=superUsersAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { }
+prescriptiveACI: { identificationTag "superUsersAci", precedence 20, authenticationLevel simple,  itemOrUserFirst userFirst: { userClasses { userGroup { "cn=superUsers,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues},  grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+#
+# This ACI allows members of the userAdmin group to have full modify and read access
+# to user accounts besides their own.  Hence they can administer users in the system.
+#
+ 
+dn: cn=userAdminsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=users", maximum 1 }
+prescriptiveACI: { identificationTag "userAdminsAci", precedence 16, authenticationLevel simple,  itemOrUserFirst userFirst: { userClasses { userGroup { "cn=userAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues},  grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+
+#
+# This ACI allows members of the applicationAdmin group to have full modify and read access
+# to all applications in the realm.  Adding users to this group is like a wild card for 
+# application access.
+#
+ 
+dn: cn=applicationAdminsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=applications" }
+prescriptiveACI: { identificationTag "applicationAdminsAci", precedence 17, authenticationLevel simple,  itemOrUserFirst userFirst: { userClasses { userGroup { "cn=applicationAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues},  grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+
+#
+# This ACI allows members of the groupAdmins group to have full modify and read access
+# to all groups in the realm other than the superUsers, userAdmins, groupAdmins, and the 
+# applicationAdmins groups.
+#
+# The rational behind this is to prevent these users from changing their or other
+# users' access rights for the entire system by modifying their membership in these 
+# groups. Making someone a groupAdmin should not open the door to their ability to
+# grant themselves or others system wide administrative abilities.
+#
+# Really the groupAdmins group is intended for users that have the ability to manage 
+# group membership in specific application administration groups and that's all.  
+# These types of admins should not have the right to promote others to system level
+# administrators or complete super users.
+#
+ 
+dn: cn=groupAdminsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=groups", specificExclusions { chopBefore: "cn=userAdmins", chopBefore: "cn=groupAdmins", chopBefore: "cn=applicationAdmins", chopBefore: "cn=superUsers" } }
+prescriptiveACI: { identificationTag "groupAdminsAci", precedence 18, authenticationLevel simple,  itemOrUserFirst userFirst: { userClasses { userGroup { "cn=groupAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues},  grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+dn: uid=akarasulu, ou=Users, dc=example,dc=com
+cn: Alex Karasulu
+sn: Karasulu
+givenname: Alex
+objectclass: top
+objectclass: uidObject
+objectclass: person
+objectclass: organizationalPerson
+objectclass: extensibleObject
+objectclass: inetOrgPerson
+objectclass: krb5Principal
+objectclass: krb5KDCEntry
+objectclass: safehausProfile
+ou: Directory
+ou: Users
+l: Jacksonville
+uid: akarasulu
+krb5PrincipalName: akarasulu@EXAMPLE.COM
+krb5KeyVersionNumber: 0
+mail: akarasulu@example.com
+telephonenumber: +1 904 982 6882
+facsimiletelephonenumber: +1 904 982 6883
+roomnumber: 666
+apacheSamType: 7
+safehausUid: akarasulu
+safehausRealm: EXAMPLE.COM
+safehausLabel: example realm
+safehausFactor: 27304238
+safehausSecret:: aaaabbbbccccdddd
+safehausFailuresInEpoch: 0
+safehausResynchCount: -1
+safehausInfo: test account
+safehausTokenPin: 1234
+safehausNotifyBy: sms
+userpassword: maxwell
+
+dn: uid=lockedout, ou=Users, dc=example,dc=com
+cn: Risky
+sn: Lockedout
+givenname: Unlucky
+objectclass: top
+objectclass: uidObject
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: krb5Principal
+objectclass: krb5KDCEntry
+objectclass: safehausProfile
+ou: Directory
+ou: Users
+l: DummyCity
+uid: lockedout
+krb5PrincipalName: lockedout@EXAMPLE.COM
+krb5KeyVersionNumber: 0
+mail: lockedout@example.com
+telephonenumber: +1 904 982 6882
+facsimiletelephonenumber: +1 904 982 6883
+roomnumber: 699
+safehausUid: lockedout
+safehausRealm: EXAMPLE.COM
+safehausLabel: example realm
+safehausFactor: 101347012
+safehausSecret:: (Q-H23BQ#SDsdkf3o&81923r
+safehausFailuresInEpoch: 20
+safehausResynchCount: -1
+safehausInfo: unlucky account
+safehausTokenPin: 1234
+safehausNotifyBy: sms
+userpassword: asdfasdf
+
+dn: uid=erodriguez, ou=Users, dc=example,dc=com
+cn: Enrique Rodriguez
+sn: Rodriguez
+givenname: Enrique
+objectclass: top
+objectclass: uidObject
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: krb5Principal
+objectclass: krb5KDCEntry
+objectclass: safehausProfile
+ou: Directory
+ou: Users
+l: Boston
+uid: erodriguez
+krb5PrincipalName: erodriguez@EXAMPLE.COM
+krb5KeyVersionNumber: 0
+mail: erodriguez@example.com
+telephonenumber: +1 408 555 9187
+facsimiletelephonenumber: +1 408 555 8473
+roomnumber: 667
+safehausUid: erodriguez
+safehausRealm: EXAMPLE.COM
+safehausLabel: example realm
+safehausFactor: 917483720127847
+safehausSecret:: xcJqp45S80e8fahs&@rq1I98awg8)^*
+safehausFailuresInEpoch: 0
+safehausResynchCount: -1
+safehausInfo: test account
+safehausTokenPin: 1234
+safehausNotifyBy: sms
+userpassword: noices
+
+dn: uid=krbtgt, ou=Users, dc=example,dc=com
+cn: Kerberos Server
+sn: Server
+givenname: Kerberos
+objectclass: top
+objectclass: uidObject
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: krb5Principal
+objectclass: krb5KDCEntry
+ou: Directory
+ou: Users
+l: Boston
+uid: krbtgt
+krb5PrincipalName: krbtgt/EXAMPLE.COM@EXAMPLE.COM
+krb5KeyVersionNumber: 0
+mail: erodriguez@example.com
+telephonenumber: +1 408 555 9187
+facsimiletelephonenumber: +1 408 555 8473
+roomnumber: 667
+userpassword: kahuna
+
+dn: uid=hostssh, ou=Users, dc=example,dc=com
+cn: SSH Service
+sn: Service
+givenname: SSH
+objectclass: top
+objectclass: uidObject
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: krb5Principal
+objectclass: krb5KDCEntry
+ou: Directory
+ou: Users
+l: Boston
+uid: hostssh
+krb5PrincipalName: host/www.example.com@EXAMPLE.COM
+krb5KeyVersionNumber: 0
+mail: erodriguez@example.com
+telephonenumber: +1 408 555 9187
+facsimiletelephonenumber: +1 408 555 8473
+roomnumber: 667
+userpassword: randall
+
+dn: uid=hostssh2, ou=Users, dc=example,dc=com
+cn: SSH Service
+sn: Service
+givenname: SSH
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: krb5Principal
+objectclass: krb5KDCEntry
+ou: Directory
+ou: Users
+l: Boston
+uid: hostssh
+krb5PrincipalName: host/kerberos.example.com@EXAMPLE.COM
+krb5KeyVersionNumber: 0
+mail: erodriguez@example.com
+telephonenumber: +1 408 555 9187
+facsimiletelephonenumber: +1 408 555 8473
+roomnumber: 667
+userpassword: randall
+
+dn: ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: organizationalunit
+ou: applications
+
+dn: appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyApplication
+appName: mockApplication
+userPassword:: dGVzdGluZw==
+
+dn: ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: organizationalUnit
+ou: permissions
+
+dn: permName=mockPerm0,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm0
+
+dn: permName=mockPerm1,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm1
+
+dn: permName=mockPerm2,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm2
+
+dn: permName=mockPerm3,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm3
+
+dn: permName=mockPerm4,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm4
+
+dn: permName=mockPerm5,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm5
+
+dn: permName=mockPerm6,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm6
+
+dn: permName=mockPerm7,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm7
+
+dn: permName=mockPerm8,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm8
+
+dn: permName=mockPerm9,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm9
+
+dn: ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: organizationalUnit
+ou: roles
+
+dn: roleName=mockRole0,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: policyRole
+objectClass: top
+roleName: mockRole0
+
+dn: roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyRole
+grants: mockPerm0
+roleName: mockRole1
+
+dn: roleName=mockRole2,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyRole
+grants: mockPerm1
+roleName: mockRole2
+
+dn: roleName=mockRole3,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyRole
+grants: mockPerm3
+grants: mockPerm2
+roleName: mockRole3
+
+dn: roleName=mockRole4,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyRole
+grants: mockPerm9
+grants: mockPerm7
+grants: mockPerm6
+grants: mockPerm5
+grants: mockPerm4
+roleName: mockRole4
+
+dn: ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: organizationalUnit
+ou: profiles
+
+dn: profileId=mockProfile0,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyProfile
+user: akarasulu
+profileId: mockProfile0
+
+dn: profileId=mockProfile1,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyProfile
+roles: mockRole2
+roles: mockRole1
+user: akarasulu
+profileId: mockProfile1
+
+dn: profileId=mockProfile2,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyProfile
+grants: mockPerm0
+roles: mockRole2
+user: akarasulu
+profileId: mockProfile2
+
+dn: profileId=mockProfile3,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyProfile
+grants: mockPerm7
+grants: mockPerm0
+roles: mockRole3
+user: akarasulu
+profileId: mockProfile3
+
+dn: profileId=mockProfile4,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyProfile
+denials: mockPerm7
+grants: mockPerm0
+roles: mockRole4
+roles: mockRole3
+user: akarasulu
+profileId: mockProfile4
+

Added: directory/trunks/triplesec/admin-api/src/test/resources/server.xml
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/test/resources/server.xml?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/test/resources/server.xml (added)
+++ directory/trunks/triplesec/admin-api/src/test/resources/server.xml Tue Dec 12 07:23:31 2006
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
+  "http://www.springframework.org/dtd/spring-beans.dtd">
+
+<beans>
+  <bean id="environment" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
+    <property name="properties">
+      <props>
+        <prop key="java.naming.security.authentication">simple</prop>
+        <prop key="java.naming.security.principal">uid=admin,ou=system</prop>
+        <prop key="java.naming.security.credentials">secret</prop>
+        <prop key="java.naming.provider.url">dc=example,dc=com</prop>
+        <prop key="java.naming.factory.state">org.safehaus.triplesec.store.ProfileStateFactory</prop>
+        <prop key="java.naming.factory.object">org.safehaus.triplesec.store.ProfileObjectFactory</prop>
+
+        <prop key="kdc.primary.realm">EXAMPLE.COM</prop>
+        <prop key="kdc.principal">krbtgt/EXAMPLE.COM@EXAMPLE.COM</prop>
+        <prop key="kdc.encryption.types">des-cbc-md5 des3-cbc-sha1 des3-cbc-md5 des-cbc-md4 des-cbc-crc</prop>
+        <prop key="kdc.entryBaseDn">ou=users,dc=example,dc=com</prop>
+        <prop key="kdc.java.naming.security.credentials">secret</prop>
+
+        <prop key="changepw.entryBaseDn">ou=users,dc=example,dc=com</prop>
+        <prop key="changepw.java.naming.security.credentials">secret</prop>
+        <prop key="changepw.principal">kadmin/changepw@EXAMPLE.COM</prop>
+
+        <!-- All times are in minutes -->
+        <prop key="kdc.allowable.clockskew">5</prop>
+        <prop key="kdc.tgs.maximum.ticket.lifetime">1440</prop>
+        <prop key="kdc.tgs.maximum.renewable.lifetime">10080</prop>
+        <prop key="kdc.pa.enc.timestamp.required">true</prop>
+        <prop key="kdc.tgs.empty.addresses.allowed">true</prop>
+        <prop key="kdc.tgs.forwardable.allowed">true</prop>
+        <prop key="kdc.tgs.proxiable.allowed">true</prop>
+        <prop key="kdc.tgs.postdate.allowed">true</prop>
+        <prop key="kdc.tgs.renewable.allowed">true</prop>
+
+        <prop key="safehaus.entry.basedn">ou=Users,dc=example,dc=com</prop>
+        <prop key="safehaus.load.testdata">true</prop>
+        <prop key="kerberos.sam.type.7">org.safehaus.triplesec.verifier.hotp.DefaultHotpSamVerifier</prop>
+      </props>
+    </property>
+  </bean>
+
+  <bean id="configuration" class="org.safehaus.triplesec.configuration.MutableTriplesecStartupConfiguration">
+    <property name="workingDirectory"><value>partitions</value></property>
+    <property name="allowAnonymousAccess"><value>false</value></property>
+    <property name="accessControlEnabled"><value>true</value></property>
+    <property name="ldapPort"><value>10389</value></property>
+    <property name="enableKerberos"><value>true</value></property>
+    <property name="enableNtp"><value>false</value></property>
+    <property name="enableChangePassword"><value>true</value></property>
+
+    <!-- Uncomment below to have the server load entries on startup!        -->
+    <!-- ldifDirectory property can point to a relative file, directory or  -->
+    <!-- can point to an absolute path to either using the URL path         -->
+    <!-- notation: i.e. file:///Users/jack/apacheds/ldifs                   -->
+
+    <!-- Entries will optionally be filtered using LdifLoadFilters in the   -->
+    <!-- order specified.  The included Krb5KdcEntryFilter will filter      -->
+    <!-- kerberos principals creating keys for them using their             -->
+    <!-- userPassword attribute if present.                                 -->
+
+    <!-- If missing the Triplesec server will use LDIF files under the conf -->
+    <!-- directory where it has been installed.                             -->
+
+    <!--
+    <property name="ldifDirectory">
+      <value>example.ldif</value>
+    </property>
+    -->
+    <property name="ldifFilters">
+      <list>
+        <bean class="org.apache.directory.server.protocol.shared.store.Krb5KdcEntryFilter"/>
+      </list>
+    </property>
+
+    <property name="activationConfiguration">
+      <bean class="org.safehaus.triplesec.configuration.ActivationConfiguration">
+        <property name="enableDecoyMidlet"><value>true</value></property>
+        <property name="otpLength"><value>6</value></property>
+        <property name="midletNameAttribute"><value>midletNameAttribute</value></property>
+      </bean>  
+    </property>    
+    
+    <property name="smsConfiguration">
+      <bean class="org.safehaus.triplesec.configuration.SmsConfiguration">
+        <property name="smsUsername"><value>hauskeys</value></property>
+        <property name="smsPassword"><value>secret</value></property>
+        <property name="smsAccountName"><value>demo</value></property>
+        <property name="smsTransportUrl"><value>http://www.nbroadcasting.com/customers/messages/Sender.asp</value></property>
+      </bean>  
+    </property>    
+    
+    <property name="smtpConfiguration">
+      <bean class="org.safehaus.triplesec.configuration.SmtpConfiguration">
+        <property name="smtpAuthenticate"><value>false</value></property>
+        <!-- uncomment and set above property if authentication is required by mail server
+             <property name="smtpUsername"><value>hauskeys</value></property>
+             <property name="smtpPassword"><value>secret</value></property>
+             -->
+             <property name="smtpHost"><value>localhost</value></property>
+             <property name="smtpSubject"><value>Triplesec Account Activated</value></property>
+             <property name="smtpFrom"><value>dev@safehaus.org</value></property>
+           </bean>  
+         </property>    
+         
+    <property name="contextPartitionConfigurations">
+      <set>
+        <ref bean="examplePartitionConfiguration"/>
+      </set>
+    </property>
+    <property name="bootstrapSchemas">
+      <set>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CorbaSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CoreSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CosineSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.ApacheSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.CollectiveSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.InetorgpersonSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.JavaSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.Krb5kdcSchema"/>
+        <bean class="org.apache.directory.server.core.schema.bootstrap.SystemSchema"/>
+        <bean class="org.safehaus.triplesec.store.schema.SafehausSchema"/>
+      </set>
+    </property>
+    
+    <property name="extendedOperationHandlers">
+      <list>
+        <bean class="org.apache.directory.server.ldap.support.extended.GracefulShutdownHandler"/>
+        <bean class="org.apache.directory.server.ldap.support.extended.LaunchDiagnosticUiHandler"/>
+      </list>
+    </property>  
+
+    <property name="interceptorConfigurations">
+      <list>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>normalizationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.normalization.NormalizationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>authenticationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.authn.AuthenticationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>referralService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.referral.ReferralService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>authorizationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.authz.AuthorizationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>defaultAuthorizationService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.authz.DefaultAuthorizationService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>exceptionService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.exception.ExceptionService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>schemaService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.schema.SchemaService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>subentryService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.subtree.SubentryService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>operationalAttributeService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.operational.OperationalAttributeService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>collectiveAttributeService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.collective.CollectiveAttributeService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>eventService</value></property>
+          <property name="interceptor">
+            <bean class="org.apache.directory.server.core.event.EventService" />
+          </property>
+        </bean>
+        <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+          <property name="name"><value>policyProtectionService</value></property>
+          <property name="interceptor">
+            <bean class="org.safehaus.triplesec.store.interceptor.PolicyProtectionInterceptor" />
+          </property>
+        </bean>
+      </list>
+    </property>
+  </bean>
+  
+  <bean id="examplePartitionConfiguration" class="org.apache.directory.server.core.configuration.MutablePartitionConfiguration">
+    <property name="name"><value>example</value></property>
+    <property name="suffix"><value>dc=example,dc=com</value></property>
+    <property name="indexedAttributes">
+      <set>
+        <value>objectClass</value>
+        <value>ou</value>
+        <value>dc</value>
+        <value>uid</value>
+        <value>profileId</value>
+        <value>roles</value>
+        <value>grants</value>
+        <value>denials</value>
+        <value>krb5PrincipalName</value>
+      </set>
+    </property>
+    <property name="contextEntry">
+      <value>
+        objectClass: top
+        objectClass: domain
+        objectClass: extensibleObject
+        dc: example
+        administrativeRole: accessControlSpecificArea
+        administrativeRole: collectiveAttributeSpecificArea
+      </value>
+    </property>
+  </bean>
+
+  <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
+    <property name="customEditors">
+      <map>
+        <entry key="javax.naming.directory.Attributes">
+          <bean class="org.apache.directory.server.core.configuration.AttributesPropertyEditor"/>
+        </entry>
+      </map>
+   </property>
+  </bean>
+</beans>

Added: directory/trunks/triplesec/admin-api/todo.txt
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/todo.txt?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/todo.txt (added)
+++ directory/trunks/triplesec/admin-api/todo.txt Tue Dec 12 07:23:31 2006
@@ -0,0 +1,3 @@
+need to:
+
+ o cleanup doco

Added: directory/trunks/triplesec/changelog/README.txt
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/README.txt?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/README.txt (added)
+++ directory/trunks/triplesec/changelog/README.txt Tue Dec 12 07:23:31 2006
@@ -0,0 +1,15 @@
+
+   Example: Interceptor 
+ Objective: Demonstrate ApacheDS embedded configuration with LDAP service,
+            extra partition, and a custom interceptor for a changelog/audit
+            trail. 
+  To Build: mvn compile
+    To Run: mvn test
+   Summary: The purpose of this demolet is to show how custom interceptors 
+            can be used in apacheds by building a custom interceptor for 
+            keeping a change log.
+      Tips: This is a cumulative example and requires all the other examples
+            except for the kerberos example.  Take a look inside server-work
+            to see the changes.log file for this interceptor.  Tail -f the
+            file and start changing the directory.
+

Added: directory/trunks/triplesec/changelog/pom.xml
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/pom.xml?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/pom.xml (added)
+++ directory/trunks/triplesec/changelog/pom.xml Tue Dec 12 07:23:31 2006
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+
+-->
+
+<project>
+  <parent>
+    <groupId>org.safehaus.triplesec</groupId>
+    <artifactId>build</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>triplesec-changelog</artifactId>
+  <name>TripleSec Changelog Subsystem</name>
+  <packaging>jar</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-core</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-server-jndi</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>nlog4j</artifactId>
+      <version>1.2.25</version>
+    </dependency>
+  </dependencies>
+
+  <!-- <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>test</phase>
+            <configuration>
+              <tasks>
+                <java fork="true"
+                      classname="org.safehaus.triplesec.changelog.LdapChangeLogApplication">
+                  <classpath>
+                    <path refid="maven.compile.classpath"/>
+                    <path refid="maven.test.classpath"/>
+                    <path refid="maven.dependency.classpath"/>
+                  </classpath>
+                </java>
+              </tasks>
+            </configuration>
+            <goals>
+              <goal>run</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build> -->
+
+</project>

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/interceptor/ChangelogService.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/interceptor/ChangelogService.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/interceptor/ChangelogService.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/interceptor/ChangelogService.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,506 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.interceptor;
+
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.ModificationItem;
+
+import org.apache.directory.server.core.DirectoryServiceConfiguration;
+import org.apache.directory.server.core.configuration.InterceptorConfiguration;
+import org.apache.directory.server.core.interceptor.BaseInterceptor;
+import org.apache.directory.server.core.interceptor.NextInterceptor;
+import org.apache.directory.server.core.invocation.InvocationStack;
+import org.apache.directory.server.core.jndi.ServerContext;
+import org.apache.directory.server.core.schema.AttributeTypeRegistry;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.util.DateUtils;
+import org.apache.directory.shared.ldap.util.NamespaceTools;
+import org.safehaus.triplesec.changelog.beta.model.AddChangeEvent;
+import org.safehaus.triplesec.changelog.beta.model.ChangeEvent;
+import org.safehaus.triplesec.changelog.beta.model.DeleteChangeEvent;
+import org.safehaus.triplesec.changelog.beta.model.ModifyChangeEvent;
+import org.safehaus.triplesec.changelog.beta.model.ModifyDnChangeEvent;
+import org.safehaus.triplesec.changelog.beta.model.ModifyRdnChangeEvent;
+import org.safehaus.triplesec.changelog.beta.model.StringAttribute;
+import org.safehaus.triplesec.changelog.beta.support.AttributeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * An interceptor which maintains a change log as it intercepts changes to the
+ * directory. It maintains an embedded DB for writing Changelog Event records.
+ * 
+ * @author <a href="mailto:ersiner@safehaus.org">Ersin Er</a>
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ */
+public class ChangelogService extends BaseInterceptor implements Runnable
+{
+    
+    private static final Logger log = LoggerFactory.getLogger( ChangelogService.class );
+
+    private static String dbProtocol = "jdbc:derby:";
+
+    private static String dbName = "changelogDb";
+
+    private static String dbTable = "changelogTable";
+
+    private static String dbUserName = "user1";
+
+    private static String dbPassword = "user1";
+
+    /** the single db connection */
+    private Connection conn = null;
+
+    /** queue of changelog events awaiting serialization to the db */
+    private LinkedList queue = new LinkedList();
+
+    /** a handle on the attributeType registry to determine the binary nature of attributes */
+    private AttributeTypeRegistry registry = null;
+
+    /** determines if this service has been activated */
+    private boolean isActive = false;
+
+    /** thread used to asynchronously write change logs to db */
+    private Thread writer = null;
+    
+    /** time to wait before automatically waking up the writer thread */
+    private static final long WAIT_TIMEOUT_MILLIS = 1000;
+
+
+    // -----------------------------------------------------------------------
+    // Overridden init() and destroy() methods
+    // -----------------------------------------------------------------------
+
+    public void init( DirectoryServiceConfiguration dsConfig, InterceptorConfiguration iConfig ) throws NamingException
+    {
+        super.init( dsConfig, iConfig );
+
+        // Initialize the DB backend for logging
+        initDb();
+
+        // Get a handle on the attribute registry to check if attributes are binary
+        registry = dsConfig.getGlobalRegistries().getAttributeTypeRegistry();
+
+        log.info( "# -----------------------------------------------------------------------------" );
+        log.info( "# Initializing changelog service: " + DateUtils.getGeneralizedTime() );
+        log.info( "# -----------------------------------------------------------------------------" );
+
+        writer = new Thread( this );
+        isActive = true;
+        writer.start();
+    }
+
+
+    public void destroy()
+    {
+        // Gracefully stop writer thread and push remaining enqueued buffers ourselves
+        isActive = false;
+        do
+        {
+            // Let's notify the writer thread to make it die faster
+            synchronized ( queue )
+            {
+                queue.notifyAll();
+            }
+
+            // Sleep tiny bit waiting for the writer to die
+            try
+            {
+                Thread.sleep( 50 );
+            }
+            catch ( InterruptedException e )
+            {
+                log.error( "Failed to sleep while waiting for writer to die", e );
+            }
+        }
+        while ( writer.isAlive() );
+
+        // Ok lock down queue and start draining it
+        synchronized ( queue )
+        {
+            while ( ! queue.isEmpty() )
+            {
+                ChangeEvent changeEvent = ( ChangeEvent ) queue.getFirst();
+                if ( changeEvent != null )
+                {
+                    writeChangeEventToDb( changeEvent );
+                }
+            }
+        }
+
+        shutdownDb();
+
+        log.info( "# -----------------------------------------------------------------------------" );
+        log.info( "# Deactivating changelog service: " + DateUtils.getGeneralizedTime() );
+        log.info( "# -----------------------------------------------------------------------------" );
+
+        super.destroy();
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Implementation for Runnable.run() for writer Thread
+    // -----------------------------------------------------------------------
+
+    public void run()
+    {
+        while ( isActive )
+        {
+            ChangeEvent changeEvent = null;
+
+            // Grab semphore to queue and dequeue from it
+            synchronized ( queue )
+            {
+                try
+                {
+                    queue.wait( WAIT_TIMEOUT_MILLIS );
+                }
+                catch ( InterruptedException e )
+                {
+                    log.error( "Failed to to wait() on queue", e );
+                }
+
+                // replacing following jdk 1.5 poll() function with equivalent 1.4 functions
+                // changeEvent = ( ChangeEvent ) queue.poll();
+                if ( queue.size() == 0 )
+                {
+                    changeEvent = null;
+                }
+                else
+                {
+                    changeEvent = ( ChangeEvent ) queue.removeFirst();
+                }
+
+                queue.notifyAll();
+            }
+
+            // Do writing outside of synch block to allow other threads to enqueue
+            if ( changeEvent != null )
+            {
+                writeChangeEventToDb( changeEvent );
+            }
+        }
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Overridden (only change inducing) intercepted methods
+    // -----------------------------------------------------------------------
+
+    public void add( NextInterceptor next, LdapDN nDn, Attributes entry ) throws NamingException
+    {
+        next.add( nDn, entry );
+
+        if ( ! isActive )
+        {
+            return;
+        }
+
+        AddChangeEvent changeEvent = new AddChangeEvent( 0, nDn.getUpName(), getPrincipalName(), 
+            new Date(), AttributeUtils.attributesToStringAttributeList( entry, registry ) );
+        
+        // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+        synchronized ( queue )
+        {
+            queue.addLast( changeEvent );
+            queue.notifyAll();
+        }
+    }
+
+
+    public void delete( NextInterceptor next, LdapDN nDn ) throws NamingException
+    {
+        next.delete( nDn );
+
+        if ( ! isActive )
+        {
+            return;
+        }
+
+        DeleteChangeEvent changeEvent = new DeleteChangeEvent( 0, nDn.toString(), getPrincipalName(), new Date() ); 
+        
+        // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+        synchronized ( queue )
+        {
+            queue.addLast( changeEvent );
+            queue.notifyAll();
+        }
+    }
+
+
+    public void modify( NextInterceptor next, LdapDN nDn, int modOp, Attributes mods ) throws NamingException
+    {
+        /**
+         * TODO: We need to deep copy here (before invoking the next
+         * interceptor) attributes that are being deleted or replaced. They
+         * should be gathered from the DIT while we do not have them passed
+         * here. BTW, logging this detailed information can also be necessary
+         * for "rollback support".
+         * 
+         * This issue is also valid for other similar operations.
+         */
+
+        next.modify( nDn, modOp, mods );
+
+        if ( ! isActive )
+        {
+            return;
+        }
+        
+        List strAttributes = AttributeUtils.attributesToStringAttributeList( mods, registry );
+        ModifyChangeEvent changeEvent = new ModifyChangeEvent( 0, nDn.toString(), getPrincipalName(), new Date() );
+        changeEvent.addModificationAttributes( modOp, strAttributes );
+        
+        // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+        synchronized ( queue )
+        {
+            queue.addLast( changeEvent );
+            queue.notifyAll();
+        }
+
+    }
+
+
+    public void modify( NextInterceptor next, LdapDN nDn, ModificationItem[] mods ) throws NamingException
+    {
+
+        next.modify( nDn, mods );
+
+        if ( ! isActive )
+        {
+            return;
+        }
+
+        ModifyChangeEvent changeEvent = new ModifyChangeEvent( 0, nDn.toString(), getPrincipalName(), new Date() );
+        
+        for (int i = 0; i < mods.length; i++ )
+        {
+            StringAttribute strAttribute = AttributeUtils.attributeToStringAttribute( mods[i].getAttribute(), registry );
+            changeEvent.addModificationAttribute( mods[i].getModificationOp(), strAttribute );
+        }
+
+        // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+        synchronized ( queue )
+        {
+            queue.addLast( changeEvent );
+            queue.notifyAll();
+        }
+    }
+    
+    
+    public void modifyRn( NextInterceptor next, LdapDN name, String newRn, boolean deleteOldRn ) throws NamingException
+    {
+        
+        next.modifyRn( name, newRn, deleteOldRn );
+        
+        if ( ! isActive )
+        {
+            return;
+        }
+        
+        ModifyRdnChangeEvent changeEvent = new ModifyRdnChangeEvent( 
+            0,
+            name.toString(), 
+            getPrincipalName(), 
+            new Date(), 
+            newRn, 
+            deleteOldRn);
+
+        // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+        synchronized ( queue )
+        {
+            queue.addLast( changeEvent );
+            queue.notifyAll();
+        }       
+        
+    }
+    
+    
+    public void move( NextInterceptor next, LdapDN oldName, LdapDN newParentName, String newRn, boolean deleteOldRn ) throws NamingException
+    {
+        
+        next.move( oldName, newParentName, newRn, deleteOldRn );
+
+        if ( ! isActive )
+        {
+            return;
+        }
+
+        String newDn = newRn + "," + newParentName;
+        ModifyDnChangeEvent changeEvent = new ModifyDnChangeEvent( 
+            0,
+            oldName.toString(), 
+            getPrincipalName(), 
+            new Date(), 
+            newDn, 
+            deleteOldRn );
+
+        // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+        synchronized ( queue )
+        {
+            queue.addLast( changeEvent );
+            queue.notifyAll();
+        }
+        
+    }
+      
+    
+    public void move( NextInterceptor next, LdapDN oldName, LdapDN newParentName ) throws NamingException
+    {
+        next.move( oldName, newParentName );
+        
+        if ( ! isActive )
+        {
+            return;
+        }
+        
+        String newDn = NamespaceTools.getRdn( oldName.toString() ) + "," + newParentName;
+        ModifyDnChangeEvent changeEvent = new ModifyDnChangeEvent( 
+            0,
+            oldName.toString(), 
+            getPrincipalName(), 
+            new Date(), 
+            newDn, 
+            false );
+        
+        // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+        synchronized ( queue )
+        {
+            queue.addLast( changeEvent );
+            queue.notifyAll();
+        }
+    }
+     
+
+    // -----------------------------------------------------------------------
+    // Private utility methods used by interceptor methods
+    // -----------------------------------------------------------------------
+
+    /**
+     * Gets the DN of the user currently bound to the server executing this
+     * operation. If the user is anonymous "" is returned.
+     * 
+     * @return the DN of the user executing the current intercepted operation
+     * @throws NamingException
+     *             if we cannot access the interceptor stack
+     */
+    private String getPrincipalName() throws NamingException
+    {
+        
+        ServerContext ctx = ( ServerContext ) InvocationStack.getInstance().peek().getCaller();
+        return ctx.getPrincipal().getName();
+        
+    }
+    
+
+    // -----------------------------------------------------------------------
+    // Private utility methods for DB access
+    // -----------------------------------------------------------------------
+
+    private void initDb() throws NamingException
+    {
+
+        Properties props = new Properties();
+        props.put( "user", dbUserName );
+        props.put( "password", dbPassword );
+
+        try
+        {
+            conn = DriverManager.getConnection( dbProtocol + dbName, props );
+        }
+        catch ( SQLException e )
+        {
+            NamingException ne = new NamingException();
+            ne.setRootCause( e );
+            throw ne;
+        }
+
+    }
+
+
+    private void writeChangeEventToDb( ChangeEvent changeEvent )
+    {
+        
+        PreparedStatement insertStatement = null;
+
+        try
+        {
+            insertStatement = conn.prepareStatement( "insert into " + dbTable + " values (DEFAULT, ?, ?, ?, ?, ?)" );
+            insertStatement.setInt( 1, changeEvent.getEventType() );
+            insertStatement.setString( 2, changeEvent.getAffectedEntryName() );
+            insertStatement.setString( 3, changeEvent.getPrincipalName() );
+            insertStatement.setTimestamp( 4, new Timestamp( changeEvent.getEventTime().getTime() ) );
+            insertStatement.setString( 5, changeEvent.getEventMessage() );
+            insertStatement.execute();
+        }
+        catch ( SQLException e )
+        {
+            log.error( "Failed to create the record insertion SQL prepared statement: " + e );
+        }
+        finally
+        {
+            if ( insertStatement != null )
+            {
+                try
+                {
+                    insertStatement.close();
+                }
+                catch ( SQLException e )
+                {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    private void shutdownDb()
+    {
+        
+        if ( conn == null )
+        {
+            return;
+        }
+
+        try
+        {
+            conn.close();
+        }
+        catch ( SQLException e )
+        {
+            log.error( "Cannot close DB connection: " + e );
+            e.printStackTrace();
+        }
+
+    }
+
+}

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/AddChangeEvent.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/AddChangeEvent.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/AddChangeEvent.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/AddChangeEvent.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,62 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.safehaus.triplesec.changelog.beta.support.ChangeEventType;
+
+/**
+ * @author <a href="mailto:ersiner@safehaus.org">Ersin Er</a>
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ */
+public class AddChangeEvent extends BaseChangeEvent
+{
+    private List attributes = new ArrayList();
+
+    public AddChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime )
+    {
+        super( id, ChangeEventType.ADD_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime );
+    }
+    
+    public AddChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime, List attributes )
+    {
+        super( id, ChangeEventType.ADD_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime );
+        addAttributes( attributes );
+    }
+
+    public String getEventMessage()
+    {
+        return attributes.toString();
+    }
+    
+    public void addAttributes( List attributes )
+    {
+        this.attributes.addAll( attributes );
+    }
+    
+    public List getAttributes()
+    {
+        return attributes;
+    }
+
+}

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/BaseChangeEvent.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/BaseChangeEvent.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/BaseChangeEvent.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/BaseChangeEvent.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,120 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.model;
+
+import java.util.Date;
+
+import org.safehaus.triplesec.changelog.beta.support.ChangeEventType;
+
+/**
+ * A base implementation for {@link org.safehaus.triplesec.changelog.beta.model.ChangeEvent}
+ * 
+ * @author <a href="mailto:ersiner@safehaus.org">Ersin Er</a>
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ */
+public class BaseChangeEvent implements ChangeEvent
+{
+    private int id;
+    private int changeEventType;
+    private String affectedEntryName;
+    private String changeEventPrincipal;
+    private Date changeEventTime;
+
+
+    public BaseChangeEvent( int id, int changeEventType, String affectedEntryName, String changeEventPrincipal, Date changeEventTime)
+    {
+        this.id = id;
+        this.changeEventType = changeEventType;
+        this.affectedEntryName = affectedEntryName;
+        this.changeEventPrincipal = changeEventPrincipal;
+        this.changeEventTime = changeEventTime;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.safehaus.triplesec.changelog.model.ChangeEvent#getEventMessage()
+     */
+    public String getEventMessage()
+    {
+        return "";
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.safehaus.triplesec.changelog.model.ChangeEvent#getEventTime()
+     */
+    public Date getEventTime()
+    {
+        return changeEventTime;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.safehaus.triplesec.changelog.model.ChangeEvent#getEventType()
+     */
+    public int getEventType()
+    {
+        return changeEventType;
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.safehaus.triplesec.changelog.model.ChangeEvent#getNameOfAffectedEntry()
+     */
+    public String getAffectedEntryName()
+    {
+        return affectedEntryName;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.safehaus.triplesec.changelog.model.ChangeEvent#getPrincipleName()
+     */
+    public String getPrincipalName()
+    {
+        return changeEventPrincipal;
+    }
+
+
+    public String getEventTypeName()
+    {
+        return ChangeEventType.getChangeEventTypeNameByIntEnum( getEventType() );
+    }
+
+
+    public int getEventId()
+    {
+        return id;
+    }
+
+
+    public String getAffectedEntryShortName()
+    {
+        if ( affectedEntryName.length() > 40  )
+        {
+            return affectedEntryName.subSequence(0, 35).toString() + "...";    
+        }
+        else
+        {
+            return affectedEntryName;
+        }
+    }
+
+}

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ChangeEvent.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ChangeEvent.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ChangeEvent.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ChangeEvent.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.model;
+
+import java.util.Date;
+
+/**
+ * Represents a change-type LDAP operation with invocation time and
+ * principle.
+ * 
+ * @author <a href="mailto:ersiner@safehaus.org">Ersin Er</a>
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ */
+public interface ChangeEvent
+{
+    /**
+     * Returns the unique id of the change event.
+     * 
+     * @return The unique id of the change event
+     */
+    public int getEventId();
+    
+    
+    /**
+     * Returns the type of the change event as an integer.
+     * 
+     * @return The type of the change event as an integer
+     */
+    public int getEventType();
+    
+    /**
+     * Returns the type of the change event as a string.
+     * 
+     * @return The type of the change event as a string
+     */
+    public String getEventTypeName();
+    
+    /**
+     * Returns the distinguished name of the entry being affected.
+     * 
+     * @return The distinguished name of the entry being affected
+     */
+    public String getAffectedEntryName();
+    
+    /**
+     * Returns a short form of the distinguished name of the entry being affected.
+     * 
+     * @return A short for of the distinguished name of the entry being affected
+     */
+    public String getAffectedEntryShortName();
+    
+    /**
+     * Returns a detailed message about the change event.
+     * 
+     * @return Detailed message about the change event
+     */
+    public String getEventMessage();
+    
+    /**
+     * Returns the time when the change event generated.
+     * 
+     * @return The time when the change event generated
+     */
+    public Date getEventTime();
+    
+    /**
+     * Returns the name of the principle caused the change event
+     * to be generated because of operation it invoked.
+     * 
+     * @return The name of the principle in effect
+     */
+    public String getPrincipalName();
+}

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/DeleteChangeEvent.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/DeleteChangeEvent.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/DeleteChangeEvent.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/DeleteChangeEvent.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,44 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.model;
+
+import java.util.Date;
+
+import org.safehaus.triplesec.changelog.beta.support.ChangeEventType;
+
+/**
+ * @author <a href="mailto:ersiner@safehaus.org">Ersin Er</a>
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ */
+public class DeleteChangeEvent extends BaseChangeEvent
+{
+
+    public DeleteChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime )
+    {
+        super( id, ChangeEventType.DELETE_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime );
+    }
+        
+
+    public String getEventMessage()
+    {
+        return getAffectedEntryName();
+    }
+
+}

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyChangeEvent.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyChangeEvent.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyChangeEvent.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyChangeEvent.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,140 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.safehaus.triplesec.changelog.beta.support.AttributeModificationType;
+import org.safehaus.triplesec.changelog.beta.support.ChangeEventType;
+
+/**
+ * @author <a href="mailto:ersiner@safehaus.org">Ersin Er</a>
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ */
+public class ModifyChangeEvent extends BaseChangeEvent
+{
+    private List addedAttributes = new ArrayList();
+    private List removedAttributes = new ArrayList();
+    private List replacedAttributes = new ArrayList();
+    private Map modifications = new HashMap();
+    
+    /** Refecence types used for as keys for the attribute modification map */
+    private static Integer ADD_ATTRIBUTE_MODIFICATION_OBJECT = new Integer( AttributeModificationType.ADD_ATTRIBUTE_MODIFICATION );
+    private static Integer REMOVE_ATTRIBUTE_MODIFICATION_OBJECT = new Integer( AttributeModificationType.REMOVE_ATTRIBUTE_MODIFICATION );
+    private static Integer REPLACE_ATTRIBUTE_MODIFICATION_OBJECT = new Integer( AttributeModificationType.REPLACE_ATTRIBUTE_MODIFICATION );
+
+    public ModifyChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime )
+    {
+        super( id, ChangeEventType.MODIFY_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime );
+        
+        modifications.put( ADD_ATTRIBUTE_MODIFICATION_OBJECT, addedAttributes );
+        modifications.put( REMOVE_ATTRIBUTE_MODIFICATION_OBJECT, removedAttributes );
+        modifications.put( REPLACE_ATTRIBUTE_MODIFICATION_OBJECT, replacedAttributes );
+    }
+    
+    public void addModificationAttribute( int modType, StringAttribute attribute )
+    {
+        switch ( modType )
+        {
+            case AttributeModificationType.ADD_ATTRIBUTE_MODIFICATION:
+                addedAttributes.add( attribute );
+                break;
+            case AttributeModificationType.REMOVE_ATTRIBUTE_MODIFICATION:
+                removedAttributes.add( attribute );
+                break;
+            case AttributeModificationType.REPLACE_ATTRIBUTE_MODIFICATION:
+                replacedAttributes.add( attribute );
+                break;
+            default:
+                throw new IllegalArgumentException( "Unmatched Attribute Modification Type: " + modType );
+        }
+    }
+    
+    public void addModificationAttributes( int modType, List stringAttributes )
+    {
+        Iterator it = stringAttributes.iterator();
+        while ( it.hasNext() )
+        {
+            addModificationAttribute( modType, (StringAttribute) it.next() );
+        }
+    }
+    
+    public List getAddedAttributes()
+    {
+        return addedAttributes;
+    }
+    
+    public List getRemovedAttributes()
+    {
+        return removedAttributes;
+    }
+    
+    public List getReplacedAttributes()
+    {
+        return replacedAttributes;
+    }
+    
+    public boolean anyAddedAttributeExists()
+    {
+        return addedAttributes.size() > 0;
+    }
+    
+    public boolean anyRemovedAttributeExists()
+    {
+        return removedAttributes.size() > 0;
+    }
+    
+    public boolean anyReplacedAttributeExists()
+    {
+        return replacedAttributes.size() > 0;
+    }
+
+    public String getEventMessage()
+    {
+        StringBuffer buffer = new StringBuffer();
+        
+        if ( anyAddedAttributeExists() )
+        {
+            buffer.append( "added:: " );
+            buffer.append( getAddedAttributes().toString() );
+            buffer.append( "\n" );
+        }
+        if ( anyRemovedAttributeExists() )
+        {
+            buffer.append( "removed:: " );
+            buffer.append( getRemovedAttributes().toString() );
+            buffer.append( "\n" );
+        }
+        if ( anyReplacedAttributeExists() )
+        {
+            buffer.append( "replaced:: " );
+            buffer.append( getReplacedAttributes().toString() );
+            buffer.append( "\n" );
+        }
+        
+        return buffer.toString();
+    }
+    
+}

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyDnChangeEvent.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyDnChangeEvent.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyDnChangeEvent.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyDnChangeEvent.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,70 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.model;
+
+import java.util.Date;
+
+import org.safehaus.triplesec.changelog.beta.support.ChangeEventType;
+
+/**
+ * @author ersin
+ *
+ */
+public class ModifyDnChangeEvent extends BaseChangeEvent
+{
+    private String newDn;
+    private boolean deleteOldRdn;
+    
+    
+    public ModifyDnChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime, String newDn, boolean deleteOldRdn )
+    {
+        super( id, ChangeEventType.MODDN_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime );
+        this.newDn = newDn;
+        this.deleteOldRdn = deleteOldRdn;
+    }
+    
+
+    /**
+     * @return Returns the deleteOldRdn.
+     */
+    public boolean isDeleteOldRdn()
+    {
+        return deleteOldRdn;
+    }
+
+
+    /**
+     * @return Returns the newDn.
+     */
+    public String getNewDn()
+    {
+        return newDn;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.safehaus.triplesec.changelog.model.BaseChangeEvent#getEventMessage()
+     */
+    public String getEventMessage()
+    {
+        return "dn moved to " + newDn;
+    }
+
+}

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyRdnChangeEvent.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyRdnChangeEvent.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyRdnChangeEvent.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyRdnChangeEvent.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,70 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.model;
+
+import java.util.Date;
+
+import org.safehaus.triplesec.changelog.beta.support.ChangeEventType;
+
+/**
+ * @author ersin
+ *
+ */
+public class ModifyRdnChangeEvent extends BaseChangeEvent
+{
+    private String newRdn;
+    private boolean deleteOldRdn;
+    
+    
+    public ModifyRdnChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime, String newRdn, boolean deleteOldRdn )
+    {
+        super( id, ChangeEventType.MODRDN_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime );
+        this.newRdn = newRdn;
+        this.deleteOldRdn = deleteOldRdn;
+    }
+    
+
+    /**
+     * @return Returns the deleteOldRdn.
+     */
+    public boolean isDeleteOldRdn()
+    {
+        return deleteOldRdn;
+    }
+
+
+    /**
+     * @return Returns the newRdn.
+     */
+    public String getNewRdn()
+    {
+        return newRdn;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.safehaus.triplesec.changelog.model.BaseChangeEvent#getEventMessage()
+     */
+    public String getEventMessage()
+    {
+        return "rdn moved to " + newRdn;
+    }
+
+}

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/StringAttribute.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/StringAttribute.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/StringAttribute.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/StringAttribute.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,93 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:ersiner@safehaus.org">Ersin Er</a>
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ */
+public class StringAttribute
+{
+    private String id;
+    private List values = new ArrayList();
+    
+    public StringAttribute( String id )
+    {
+        this.id = id;
+    }
+    
+    public StringAttribute( String id, String value )
+    {
+        this( id );
+        addValue( value );
+    }
+    
+    public StringAttribute( String id, List values )
+    {
+        this( id );
+        addValues( values );
+    }
+    
+
+    public String getId()
+    {
+        return id;
+    }
+
+
+    public List getValues()
+    {
+        return values;
+    }
+
+
+    public void addValue( String value )
+    {
+        values.add( value );
+    }
+
+
+    public void addValues( List values )
+    {
+        // TODO: Need some safity check here
+        values.addAll( values );
+    }
+    
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+        Iterator it = values.iterator();
+        
+        while ( it.hasNext() )
+        {
+            buffer.append( id );
+            buffer.append( ": " );
+            buffer.append( it.next() );
+            buffer.append( ", " );
+        }
+        
+        return buffer.toString();
+    }
+
+}

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeModificationType.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeModificationType.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeModificationType.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeModificationType.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,72 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.support;
+
+import javax.naming.directory.DirContext;
+
+/**
+ * @author <a href="mailto:ersiner@safehaus.org">Ersin Er</a>
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ */
+public abstract class AttributeModificationType
+{
+	public static final int ADD_ATTRIBUTE_MODIFICATION = DirContext.ADD_ATTRIBUTE;
+	public static final int REMOVE_ATTRIBUTE_MODIFICATION = DirContext.REMOVE_ATTRIBUTE;
+	public static final int REPLACE_ATTRIBUTE_MODIFICATION = DirContext.REPLACE_ATTRIBUTE;
+
+	public static String getAttributeModificationTypeNameByIntEnum( int intType )
+	{
+		switch ( intType )
+		{
+			case ADD_ATTRIBUTE_MODIFICATION:
+				return "add";
+			case REMOVE_ATTRIBUTE_MODIFICATION:
+				return "remove";
+			case REPLACE_ATTRIBUTE_MODIFICATION:
+				return "replace";
+			default:
+                throw new IllegalArgumentException( "Unmatched Attribute Modification Type: " + intType );
+        }
+	}
+    
+	public static int getIntEnumAttributeModicafitionTypeByName( String name )
+    {
+        if ( name.equals( "add" ) )
+        {
+            return ADD_ATTRIBUTE_MODIFICATION;
+        }
+        else if ( name.equals( "remove" ) )
+        {
+            return REMOVE_ATTRIBUTE_MODIFICATION;
+        }
+        else if ( name.equals( "replace" ) )
+        {
+            return REPLACE_ATTRIBUTE_MODIFICATION;
+        }
+        else
+        {
+            throw new IllegalArgumentException( "Unmatched Attribute Modification Type Name: " + name );
+        }
+    }
+    
+    private AttributeModificationType()
+    {
+    }
+}

Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeUtils.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeUtils.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeUtils.java (added)
+++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeUtils.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,101 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.safehaus.triplesec.changelog.beta.support;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+
+import org.apache.directory.server.core.schema.AttributeTypeRegistry;
+import org.apache.directory.shared.ldap.util.Base64;
+import org.safehaus.triplesec.changelog.beta.model.StringAttribute;
+
+public class AttributeUtils
+{
+    
+    public static List attributesToStringAttributeList( Attributes attributes, AttributeTypeRegistry registry ) throws NamingException
+    {
+        List stringAttributes = new ArrayList();
+        NamingEnumeration attributeEnum = attributes.getAll();
+
+        while ( attributeEnum.hasMore() )
+        {            
+            StringAttribute strAttribute = attributeToStringAttribute( (Attribute) attributeEnum.next(), registry );
+            stringAttributes.add( strAttribute );
+        }
+        return stringAttributes;
+        
+    }
+
+
+    public static StringAttribute attributeToStringAttribute( Attribute attr, AttributeTypeRegistry registry ) throws NamingException
+    {
+        
+        String id = ( String ) attr.getID();
+        int size = attr.size();
+        
+        boolean isBinary = ! registry.lookup( id ).getSyntax().isHumanReadible();
+        
+        StringAttribute strAttribute = new StringAttribute( id );
+
+        if ( isBinary )
+        {
+            for ( int ii = 0; ii < size; ii++ )
+            {
+                Object value = attr.get( ii );
+                String encoded;
+                if ( value instanceof String )
+                {
+                    encoded = ( String ) value;
+                    try
+                    {
+                        encoded = new String( Base64.encode( encoded.getBytes( "UTF-8" ) ) );
+                    }
+                    catch ( UnsupportedEncodingException e )
+                    {
+                        //log.error( "Cannot convert to UTF-8: " + encoded, e );
+                    }
+                }
+                else
+                {
+                    encoded = new String( Base64.encode( ( byte[] ) attr.get( ii ) ) );
+                }
+                strAttribute.addValue( encoded );
+            }
+        }
+        else
+        {
+            for ( int ii = 0; ii < size; ii++ )
+            {
+                strAttribute.addValue( (String) attr.get( ii ) );
+            }
+        }
+
+        return strAttribute;
+        
+    }
+
+
+}