You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

Introduction

This page describes the way we generate reverse LDIF, for each operations. Reverse LDIF can be applied on a server in order to revert some changes done. The only condition is that they must be played in the exact reverse order.

Prerequisite

Each reverse LDIF must contains a revision number which identify uniquely its order : R-ldif-rev.

We should not store a revert LDIF if the operation has failed (for any reason).

Operations

Here are the operations we are considering :

Operation

AddRequest

DelRequest

ModifyRequest

ModifyDNRequest

AddRequest

Computing the revert LDIF for an AddRequest is easy : it's a DelRequest where we use the DN of the created entry.

An AddRequest contains those informations :

AddRequest ::= [APPLICATION 8] SEQUENCE {
    entry           LDAPDN,
    attributes      AttributeList }

AttributeList ::= SEQUENCE OF attribute Attribute

For the added entry :

dn: cn=test, dc=example, dc=com
objectclass: top
objectclass: person
cn: test
sn: This is a test

the reverse LDIF will be :

dn: cn=test, dc=example, dc=com
changetype: delete

DelRequest

To produce a revert LDIF for a DelRequest, we must first read the deleted attribute. We will create a Add Request based on the read deleted entry :

* read the entry to be deleted
* create a revert ldif AddRequest with this deleted entry
* delete the entry

Considering the existing entry :

dn: cn=test, dc=example, dc=com
objectclass: top
objectclass: person
cn: test
sn: This is a testcreatorsName:  dc=admin, ou=systemcreateTimestamp: 20071010150132ZmodifiersName:  dc=admin, ou=systemmodifyTimestamp:  20071010150133Z

 if we have a delRequest which ldif is :

dn: cn=test, dc=example, dc=com
changetype: delete

 the reversed ldif should be :

dn: cn=test, dc=example, dc=comchangetype: add
objectclass: top
objectclass: person
cn: test
sn: This is a test

There is still a question regarding the operational attributes : should we keep them ? How de we guarantee that the creatorName and createTimeStamp attributes are the original ones, instead of the one injected while creating the saved entry ? We will have some impact on the OperationaAttributesInterceptor...

To be able to build this reverse ldif, we need to read the previous entry before the deletion.

ModifyRequest

This is the most complex operation. The modification is applied on a specific entry, and can impact one or more attribute, one or more value, but it can't modify an attribute which is part iof the entry RDN.

We have three kind of modifications : add, delete and replace. They are applied in the order they are found in the Modify request, so the reverse LDIF must store them in reverse order too.

ModifyDNRequest

This request is used to move entries or to rename entries or to move and rename entries. Its counterpart in a ldif file is a 'changetype: moddn' or a 'changetype: modrdn' operation (moddn or modrdn are synonymous).

There are four cases :

  1. we don't change the superior and we don't delete the old RDN
  2. we don't change the superior and we delete the old RDN
  3. we change the superior and we don't delete the old RDN
  4. we change the superior and we delete the old RDN

The following table gives an example for each of those cases applied on the initial entry :

dn: cn=test, dc=example, dc=com
objectclass: top
objectclass: person
cn: test
sn: This is a test

The new superior will be 'ou=system'
the new RDN will be 'cn=joe'

case

deleteoldrdn

new superior

modifying ldif

resulting entry

reverse ldif

1

no

none

dn: cn=test, dc=example, dc=com
changetype: moddn
deleteoldrdn: 0
newrdn: cn=joe

dn: cn=joe, dc=example, dc=com
objectclass: top
objectclass: person
cn: test
cn: joe
sn: This is a test

dn: cn=joe, dc=example, dc=com
changetype: moddn
deleteoldrdn: 1
newrdn: cn=test 

1

yes

none

dn: cn=test, dc=example, dc=com
changetype: moddn
deleteoldrdn: 1
newrdn: cn=joe

dn: cn=joe, dc=example, dc=com
objectclass: top
objectclass: person
cn: test
cn: joe
sn: This is a test

dn: cn=joe, dc=example, dc=com
changetype: moddn
deleteoldrdn: 0
newrdn: cn=test  

1

no

ou=system

dn: cn=test, dc=example, dc=org
changetype: moddn
deleteoldrdn: 0
newrdn: cn=joe
newsuperior: ou=system

dn: cn=joe, ou=system
objectclass: top
objectclass: person
cn: test
cn: joe
sn: This is a test

dn: cn=joe, ou=system
changetype: moddn
deleteoldrdn: 1
newrdn: cn=test  
newsuperior: dc=example, dc=com

1

yes

ou=system

dn: cn=test, dc=example, dc=org
changetype: moddn
deleteoldrdn: 1
newrdn: cn=joe
newsuperior: ou=system

dn: cn=joe, ou=system
objectclass: top
objectclass: person
cn: test
cn: joe
sn: This is a test

dn: cn=joe, ou=system
changetype: moddn
deleteoldrdn: 0

newrdn: cn=test 
newsuperior: dc=example, dc=com

Computing the reverse LDIF for a ModifyDN request follows the algorithm :

reverseLdif.deleteOldRdn = true
if modifyDn.newSuperior not empty 
  then reverseLdif.newSuperior = modifyDn.dn minus the modifyDN.dn.getRDN
reverseLdif.newRdn = modifyDn.dn.getRDN

  • No labels