summaryrefslogtreecommitdiffstats
path: root/contrib/slapd-modules/datamorph/tests
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/slapd-modules/datamorph/tests')
-rw-r--r--contrib/slapd-modules/datamorph/tests/Rules.mk23
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/config.ldif108
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/datamorph.conf49
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test.ldif434
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test001-01-same-attr.ldif3
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test001-02-same-index.ldif4
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test001-02a-same-index.ldif4
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test001-03-invalid-attr.ldif3
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test002-config.ldif9
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test002-entry.ldif31
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test002-fail.ldif23
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test002-transformed-rdn.ldif5
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test003-config.ldif30
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test003-out.ldif125
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test005-01-fail.ldif5
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test005-02-fail.ldif5
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test005-03-fail.ldif5
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test005-03a-fail.ldif5
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test005-04-fail.ldif10
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test005-04a-fail.ldif6
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test005-changes.ldif30
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test005-out.ldif212
-rw-r--r--contrib/slapd-modules/datamorph/tests/data/test007-config.ldif30
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/run229
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/scripts/all102
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/scripts/common.sh152
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/scripts/test001-config248
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/scripts/test002-add-delete147
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/scripts/test003-search106
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/scripts/test004-compare62
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/scripts/test005-modify89
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/scripts/test006-modrdn52
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/scripts/test007-transformed-replication296
-rwxr-xr-xcontrib/slapd-modules/datamorph/tests/scripts/test008-ignored-replication299
34 files changed, 2941 insertions, 0 deletions
diff --git a/contrib/slapd-modules/datamorph/tests/Rules.mk b/contrib/slapd-modules/datamorph/tests/Rules.mk
new file mode 100644
index 0000000..c25c1d2
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/Rules.mk
@@ -0,0 +1,23 @@
+sp := $(sp).x
+dirstack_$(sp) := $(d)
+d := $(dir)
+
+.PHONY: test
+
+CLEAN += clients servers tests/progs tests/schema tests/testdata tests/testrun
+
+test: all clients servers tests/progs
+
+test:
+ cd tests; \
+ SRCDIR=$(abspath $(LDAP_SRC)) \
+ LDAP_BUILD=$(abspath $(LDAP_BUILD)) \
+ TOPDIR=$(abspath $(SRCDIR)) \
+ LIBTOOL=$(abspath $(LIBTOOL)) \
+ $(abspath $(SRCDIR))/tests/run all
+
+servers clients tests/progs:
+ ln -s $(abspath $(LDAP_BUILD))/$@ $@
+
+d := $(dirstack_$(sp))
+sp := $(basename $(sp))
diff --git a/contrib/slapd-modules/datamorph/tests/data/config.ldif b/contrib/slapd-modules/datamorph/tests/data/config.ldif
new file mode 100644
index 0000000..91f2e60
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/config.ldif
@@ -0,0 +1,108 @@
+dn: cn=datamorph,cn=schema,cn=config
+changetype: add
+objectClass: olcSchemaConfig
+olcAttributeTypes: ( 1.3.6.1.4.1.4203.666.11.12.123.1
+ NAME 'enumerated'
+ DESC 'Enumerated attribute'
+ EQUALITY fixedSizeIntegerMatch
+ ORDERING fixedSizeIntegerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.4203.666.11.12.1.2 )
+olcAttributeTypes: ( 1.3.6.1.4.1.4203.666.11.12.123.2
+ NAME 'number'
+ DESC 'Integer attribute'
+ EQUALITY fixedSizeIntegerMatch
+ ORDERING fixedSizeIntegerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.4203.666.11.12.1.3 )
+olcAttributeTypes: ( 1.3.6.1.4.1.4203.666.11.12.123.3
+ NAME 'signed'
+ DESC 'Signed integer attribute'
+ EQUALITY fixedSizeSignedIntegerMatch
+ ORDERING fixedSizeSignedIntegerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.4203.666.11.12.1.4 )
+olcObjectClasses: ( 1.3.6.1.4.1.4203.666.11.12.123.4
+ NAME 'transformedObject'
+ DESC 'Testing objectclass'
+ SUP top AUXILIARY
+ MAY ( enumerated $ number $ signed ) )
+
+dn: olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectClass: olcOverlayConfig
+objectclass: olcDatamorphConfig
+
+# a basic enum
+dn: olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnum
+
+dn: olcDatamorphValue=bjensen,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 1
+
+dn: olcDatamorphValue=bjorn,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 11
+
+dn: olcDatamorphValue=dots,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 12
+
+dn: olcDatamorphValue=jaj,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 13
+
+dn: olcDatamorphValue=jjones,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 14
+
+dn: olcDatamorphValue=jdoe,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 10
+
+dn: olcDatamorphValue=jen,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 101
+
+dn: olcDatamorphValue=johnd,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 20
+
+dn: olcDatamorphValue=melliot,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 51
+
+dn: olcDatamorphValue=uham,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 31
+
+dn: olcDatamorphValue=\5Cno \22name\22,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 200
+
+# an interval
+dn: olcDatamorphAttribute=signed,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphInteger
+olcDatamorphIntegerBytes: 2
+olcDatamorphIntegerSigned: TRUE
+olcDatamorphIntegerLowerBound: -20000
+olcDatamorphIntegerUpperBound: 30000
+
+# an number interval (essentially TRUE/FALSE)
+dn: olcDatamorphAttribute=number,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphInteger
+olcDatamorphIntegerBytes: 1
+olcDatamorphIntegerUpperBound: 1
+olcDatamorphIntegerSigned: FALSE
diff --git a/contrib/slapd-modules/datamorph/tests/data/datamorph.conf b/contrib/slapd-modules/datamorph/tests/data/datamorph.conf
new file mode 100644
index 0000000..7cc4899
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/datamorph.conf
@@ -0,0 +1,49 @@
+overlay datamorph
+
+# they depend on the syntaxes defined by the overlay
+attributetype ( 1.3.6.1.4.1.4203.666.11.12.123.1 NAME 'enumerated'
+ DESC 'Enumerated attribute'
+ EQUALITY fixedSizeIntegerMatch
+ ORDERING fixedSizeIntegerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.4203.666.11.12.1.2 )
+
+attributetype ( 1.3.6.1.4.1.4203.666.11.12.123.2 NAME 'number'
+ DESC 'Integer attribute'
+ EQUALITY fixedSizeIntegerMatch
+ ORDERING fixedSizeIntegerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.4203.666.11.12.1.3 )
+
+attributetype ( 1.3.6.1.4.1.4203.666.11.12.123.3 NAME 'signed'
+ DESC 'Signed integer attribute'
+ EQUALITY fixedSizeSignedIntegerMatch
+ ORDERING fixedSizeSignedIntegerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.4203.666.11.12.1.4 )
+
+objectclass ( 1.3.6.1.4.1.4203.666.11.12.123.4 NAME 'transformedObject'
+ DESC 'Testing objectclass'
+ SUP top AUXILIARY
+ MAY ( enumerated $ number $ signed ) )
+
+datamorph eNuM enumerated
+datamorph_value 1 bjensen
+datamorph_value 11 bjorn
+datamorph_value 12 dots
+datamorph_value "13" jaj
+datamorph_value 14 jjones
+datamorph_value 10 jdoe
+datamorph_value 101 jen
+datamorph_value 20 johnd
+datamorph_value 51 "melliot"
+datamorph_value 31 uham
+datamorph_value 200 "\\no \"name\""
+
+datamorph int signed
+datamorph_size 2
+datamorph_signed TRUE
+datamorph_lower_bound -20000
+datamorph_upper_bound 30000
+
+datamorph iNT number
+datamorph_size 1
+datamorph_signed no
+datamorph_upper_bound 1
diff --git a/contrib/slapd-modules/datamorph/tests/data/test.ldif b/contrib/slapd-modules/datamorph/tests/data/test.ldif
new file mode 100644
index 0000000..67971f3
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test.ldif
@@ -0,0 +1,434 @@
+#LEAD COMMENT
+dn: dc=example,dc=com
+#EMBEDDED COMMENT
+objectClass: top
+objectClass: organization
+objectClass: domainRelatedObject
+objectClass: dcobject
+dc: example
+l: Anytown, Michigan
+st: Michigan
+o: Example, Inc.
+o: EX
+o: Ex.
+description: The Example, Inc. at Anytown
+postalAddress: Example, Inc. $ 535 W. William St. $ Anytown, MI 48109 $ US
+telephoneNumber: +1 313 555 1817
+associatedDomain: example.com
+
+dn: ou=People,dc=example,dc=com
+objectClass: organizationalUnit
+objectClass: extensibleObject
+ou: People
+uidNumber: 0
+gidNumber: 0
+signed:: sm4=
+number:: AA==
+
+dn: ou=Groups,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Groups
+
+dn: ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Alumni Association
+
+dn: ou=Information Technology Division,ou=People,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Information Technology Division
+description:: aMODwoPDgsKCw4PCgsOCwotFVlZQw4PCg8OCwoPDg8KCw4LCv0zDg8KDw4LCgsOD
+ woLDgsKKT8ODwoPDgsKDw4PCgsOCwqs6w4PCg8OCwoLDg8KCw4LCjUQkw4PCg8OCwoLDg8KCw4LCi
+ 01QUcODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoLDg8KCw4LCik/Dg8KDw4
+ LCgsODwoLDgsKLRCQoZitEJMODwoPDgsKCw4PCgsOCwrfDg8KDw4LCg8ODwoLDgsKIw4PCg8OCwoP
+ Dg8KCw4LCgcODwoPDgsKDw4PCgsOCwqHDg8KDw4LCgsODwoLDgsKLRCQkZitEJMODwoPDgsKCw4PC
+ gsOCwrfDg8KDw4LCg8ODwoLDgsKQw4PCg8OCwoPDg8KCw4LCisODwoPDgsKCw4PCgsOCwotFUVZqU
+ MODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCg8ODwoLDgsKAw4PCg8OCwoLDg8KCw4LCik85dCTDg8KDw4
+ LCgsODwoLDgsKFQ8ODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4L
+ Cvzl0JMODwoPDgsKCw4PCgsOCwoXDg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4LCv8ODwoPD
+ gsKDw4PCgsOCwr/Dg8KDw4LCgsODwoLDgsKLRCTDg8KDw4LCgsODwoLDgsKDw4PCg8OCwoLDg8KCw
+ 4LCuMODwoPDgsKDw4PCgsOCwoR0Q8ODwoPDgsKCw4PCgsOCwoM9w4PCg8OCwoPDg8KCw4LChMODwo
+ PDgsKDw4PCgsOCwoFOdTrDg8KDw4LCg8ODwoLDgsKHw4PCg8OCwoPDg8KCw4LChMODwoPDgsKDw4P
+ CgsOCwoFOw4PCg8OCwoPDg8KCw4LCqMODwoPDgsKDw4PCgsOCwrtHw4PCg8OCwoLDg8KCw4LChcOD
+ woPDgsKDw4PCgsOCwoDDg8KDw4LCgsODwoLDgsK4dMODwoPDgsKDw4PCgsOCwqjDg8KDw4LCg8ODw
+ oLDgsKtR8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCiMODwo
+ PDgsKDw4PCgsOCwr9SfGrDg8KDw4LCgsODwoLDgsKLQGgxw4PCg8OCwoPDg8KCw4LCoWhQw4PCg8O
+ CwoPDg8KCw4LCv8ODwoPDgsKDw4PCgsOCwoDDg8KDw4LCgsODwoLDgsKKT8ODwoPDgsKCw4PCgsOC
+ wotEJDDDg8KDw4LCgsODwoLDgsKFw4PCg8OCwoPDg8KCw4LCgHTDg8KDw4LCgsODwoLDgsKDw4PCg
+ 8OCwoPDg8KCw4LCuHXDg8KDw4LCgsODwoLDgsKLRCRqw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4
+ PCgsOCwojDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKCw4PCgsOCwpPDg8K
+ Dw4LCg8ODwoLDgsKQXV9eW8ODwoPDgsKCw4PCgsOCwoPDg8KDw4LCg8ODwoLDgsKEw4PCg8OCwoPD
+ g8KCw4LCgsODwoPDgsKDw4PCgsOCwozDg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoPDg8KCw4LCjMODw
+ oPDgsKDw4PCgsOCwozDg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKDw4PCgs
+ OCwoxWV8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgsKxw4PCg8OCwoLDg8KCw4LCi3wkw4P
+ Cg8OCwoLDg8KCw4LCjcODwoPDgsKCw4PCgsOCwofDg8KDw4LCg8ODwoLDgsKof8ODwoPDgsKDw4PC
+ gsOCwr/Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoLDg8KCw4LCg8ODwoPDgsKDw4PCgsOCwrh5w4PCg
+ 8OCwoLDg8KCw4LChzQzw4PCg8OCwoPDg8KCw4LCicODwoPDgsKCw4PCgsOCworDg8KDw4LCgsODwo
+ LDgsKIw4PCg8OCwoLDg8KCw4LCuDFBw4PCg8OCwoPDg8KCw4LCvyTDg8KDw4LCgsODwoLDgsKNdDF
+ Bw4PCg8OCwoLDg8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsKCw4PCgsOCwrhfXsODwoPD
+ gsKDw4PCgsOCwoLDg8KDw4LCgsODwoLDgsK4X17Dg8KDw4LCg8ODwoLDgsKCw4PCg8OCwoLDg8KCw
+ 4LCi8ODwoPDgsKDw4PCgsOCwo7Dg8KDw4LCgsODwoLDgsKBw4PCg8OCwoPDg8KCw4LCv8ODwoPDgs
+ KCw4PCgsOCwoTDg8KDw4LCgsODwoLDgsKAdcODwoPDgsKDw4PCgsOCwqhtw4PCg8OCwoLDg8KCw4L
+ ChcODwoPDgsKDw4PCgsOCwoDDg8KDw4LCgsODwoLDgsKEw4PCg8OCwoPDg8KCw4LCsMODwoPDgsKC
+ w4PCgsOCwrhfXsODwoPDgsKDw4PCgsOCwoLDg8KDw4LCg8ODwoLDgsKow4PCg8OCwoLDg8KCw4LCt
+ sODwoPDgsKDw4PCgsOCwq7Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKCw4
+ PCgsOCwoPDg8KDw4LCg8ODwoLDgsKoZsODwoPDgsKCw4PCgsOCwoPDg8KDw4LCg8ODwoLDgsK4w4P
+ Cg8OCwoLDg8KCw4LCh8ODwoPDgsKDw4PCgsOCwpUzw4PCg8OCwoPDg8KCw4LCicODwoPDgsKCw4PC
+ gsOCworDg8KDw4LCgsODwoLDgsKISDJBw4PCg8OCwoPDg8KCw4LCvyTDg8KDw4LCgsODwoLDgsKNN
+ DJBw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgsKOw4PCg8OCwo
+ PDg8KCw4LCv8ODwoPDgsKCw4PCgsOCwpDDg8KDw4LCg8ODwoLDgsKIw4PCg8OCwoLDg8KCw4LCi8O
+ DwoPDgsKDw4PCgsOCwojDg8KDw4LCg8ODwoLDgsKow4PCg8OCwoPDg8KCw4LCnEzDg8KDw4LCgsOD
+ woLDgsKLSEBmw4PCg8OCwoLDg8KCw4LCg3lwdSTDg8KDw4LCgsODwoLDgsKBw4PCg8OCwoPDg8KCw
+ 4LCv8ODwoPDgsKCw4PCgsOCwobDg8KDw4LCgsODwoLDgsKAw4PCg8OCwoLDg8KCw4LChMODwoPDgs
+ KCw4PCgsOCwp/Dg8KDw4LCgsODwoLDgsKBw4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKCw4PCgsOCwoj
+ Dg8KDw4LCgsODwoLDgsKAw4PCg8OCwoLDg8KCw4LChMODwoPDgsKCw4PCgsOCwpPDg8KDw4LCgsOD
+ woLDgsKBw4PCg8OCwoPDg8KCw4LCv1rDg8KDw4LCgsODwoLDgsKAw4PCg8OCwoLDg8KCw4LChMODw
+ oPDgsKCw4PCgsOCwodqw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKCw4PCgsOCwoBqaMODwoPDgsKCw4
+ PCgsOCwpBQw4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKDIMODwoPDgsKCw4PCgsOCwopPw4PCg8OCwoL
+ Dg8KCw4LChcODwoPDgsKDw4PCgsOCwoDDg8KDw4LCgsODwoLDgsKOacODwoPDgsKCw4PCgsOCwrhf
+ XsODwoPDgsKDw4PCgsOCwoLDg8KDw4LCgsODwoLDgsK4X17Dg8KDw4LCg8ODwoLDgsKCw4PCg8OCw
+ oLDg8KCw4LCgcODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCgsODwoLDgsKGw4PCg8OCwoLDg8KCw4LCgM
+ ODwoPDgsKCw4PCgsOCwoRJw4PCg8OCwoLDg8KCw4LCgcODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCgsO
+ DwoLDgsKIw4PCg8OCwoLDg8KCw4LCgMODwoPDgsKCw4PCgsOCwoQ9w4PCg8OCwoLDg8KCw4LCgcOD
+ woPDgsKDw4PCgsOCwr9aw4PCg8OCwoLDg8KCw4LCgMODwoPDgsKCw4PCgsOCwoQxw4PCg8OCwoLDg
+ 8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsKCw4PCgsOCwoM9w4PCg8OCwoPDg8KCw4LCm0
+ 7Dg8KDw4LCgsODwoLDgsKEw4PCg8OCwoLDg8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsK
+ Cw4PCgsOCwrhfXsODwoPDgsKDw4PCgsOCwoLDg8KDw4LCgsODwoLDgsK4X17Dg8KDw4LCg8ODwoLD
+ gsKCw4PCg8OCwoLDg8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsKCw4PCgsOCwrhfXsODw
+ oPDgsKDw4PCgsOCwoLDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4PCgs
+ OCwo7Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoLDg8KCw4LCkMODwoPDgsKDw4PCgsOCwojDg8KDw4L
+ CgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCiMODwoPDgsKDw4PCgsOCwqjDg8KDw4LCg8ODwoLDgsK+
+ S8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgsKww4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKDw
+ 4PCgsOCwoTDg8KDw4LCgsODwoLDgsKKT1DDg8KDw4LCg8ODwoLDgsKoRsODwoPDgsKCw4PCgsOCwo
+ vDg8KDw4LCg8ODwoLDgsK4w4PCg8OCwoLDg8KCw4LChcODwoPDgsKDw4PCgsOCwrZ0Y8ODwoPDgsK
+ Cw4PCgsOCwoXDg8KDw4LCg8ODwoLDgsK/dF/Dg8KDw4LCgsODwoLDgsKhdHpPw4PCg8OCwoLDg8KC
+ w4LCi8ODwoPDgsKDw4PCgsOCwo5Qw4PCg8OCwoPDg8KCw4LCqC1Jw4PCg8OCwoLDg8KCw4LChcODw
+ oPDgsKDw4PCgsOCwoB1RMODwoPDgsKCw4PCgsOCwqFwek/Dg8KDw4LCgsODwoLDgsKLw4PCg8OCwo
+ PDg8KCw4LCj1DDg8KDw4LCg8ODwoLDgsKoScODwoPDgsKCw4PCgsOCwoXDg8KDw4LCg8ODwoLDgsK
+ AdTPDg8KDw4LCgsODwoLDgsKhbHpPw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4PCgsOCwo5Qw4PC
+ g8OCwoPDg8KCw4LCqEnDg8KDw4LCgsODwoLDgsKFw4PCg8OCwoPDg8KCw4LCgHXDg8KDw4LCgsODw
+ oLDgsKhaHpPw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4PCgsOCwo9Qw4PCg8OCwoPDg8KCw4LCqM
+ ODwoPDgsKDw4PCgsOCwrpIw4PCg8OCwoLDg8KCw4LChcODwoPDgsKDw4PCgsOCwoB1M8ODwoPDgsK
+ Dw4PCgsOCwoBfXsODwoPDgsKDw4PCgsOCwoLDg8KDw4LCgsODwoLDgsK4X17Dg8KDw4LCg8ODwoLD
+ gsKCw4PCg8OCwoLDg8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgjPDg8KDw4LCg8ODwoLDgsKAX17Dg
+ 8KDw4LCg8ODwoLDgsKCw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4PCgsOCwo7Dg8KDw4LCg8ODwo
+ LDgsKoJ8ODwoPDgsKDw4PCgsOCwq3Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4LCv8ODwoP
+ DgsKCw4PCgsOCwoPDg8KDw4LCg8ODwoLDgsK4aHU5w4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKCw4PC
+ gsOCwovDg8KDw4LCg8ODwoLDgsKOw4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKCw4PCgsOCwpDDg8KDw
+ 4LCg8ODwoLDgsKIw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgs
+ KIw4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKCw4PCgsOCwpLDg8KDw4LCg8ODwoLDgsKEw4PCg8OCwoL
+ Dg8KCw4LChcODwoPDgsKDw4PCgsOCwoB0IcODwoPDgsKCw4PCgsOCwovDg8KDw4LCgsODwoLDgsKA
+ w4PCg8OCwoPDg8KCw4LCtMODwoPDgsKCw4PCgsOCwoXDg8KDw4LCg8ODwoLDgsKAdGbDg8KDw4LCg
+ sODwoLDgsKLQGY9dGY9dTPDg8KDw4LCg8ODwoLDgsKAX17Dg8KDw4LCg8ODwoLDgsKCw4PCg8OCwo
+ LDg8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsKCw4PCgsOCwrhfXsODwoPDgsKDw4PCgsO
+ CwoIzw4PCg8OCwoPDg8KCw4LCgF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsKCw4PCgsOCwovDg8KD
+ w4LCg8ODwoLDgsK/Ri9BUC9BRi9BWi9BZC9BWzBBZC9BZTBBZC9BZC9BbzBBZC9BeTBBw4PCg8OCw
+ oLDg8KCw4LCgzBBMUFhMUFrMUE=
+description:: UF7Dg8KDw4LCg8ODwoLDgsKCw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKDw4PCgsOC
+ wozDg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKDw4PCgsOCwozDg8KDw4LCg
+ 8ODwoLDgsKMw4PCg8OCwoPDg8KCw4LCqFDDg8KDw4LCg8ODwoLDgsKpRsODwoPDgsKDw4PCgsOCwo
+ zDg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKDw4PCgsOCwozDg8KDw4LCg8O
+ DwoLDgsKMw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKCw4PCgsOCwotEJCDDg8KDw4LCgsODwoLDgsKD
+ w4PCg8OCwoPDg8KCw4LCrMODwoPDgsKCw4PCgsOCwotUJCRTw4PCg8OCwoLDg8KCw4LCi1wkJFbDg
+ 8KDw4LCgsODwoLDgsKJTCRXVVBSU8ODwoPDgsKDw4PCgsOCwqjDg8KDw4LCg8ODwoLDgsKdT8ODwo
+ PDgsKCw4PCgsOCwoN8JDB1w4PCg8OCwoPDg8KCw4LCh8ODwoPDgsKDw4PCgsOCwoDDg8KDw4LCg8O
+ DwoLDgsKBTsODwoPDgsKDw4PCgsOCwqktw4PCg8OCwoLDg8KCw4LCg3wkMHTDg8KDw4LCgsODwoLD
+ gsKDfCQww4PCg8OCwoLDg8KCw4LChTPDg8KDw4LCg8ODwoLDgsK2OTXDg8KDw4LCg8ODwoLDgsKAw
+ 4PCg8OCwoPDg8KCw4LCgU7Dg8KDw4LCgsODwoLDgsKEIMODwoPDgsKCw4PCgsOCwqFIw4PCg8OCwo
+ PDg8KCw4LChU7Dg8KDw4LCgsODwoLDgsKJNcODwoPDgsKDw4PCgsOCwoDDg8KDw4LCg8ODwoLDgsK
+ BTsODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgsKIw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKD
+ w4PCgsOCwr9TXMODwoPDgsKCw4PCgsOCwolEJDvDg8KDw4LCg8ODwoLDgsKGw4PCg8OCwoLDg8KCw
+ 4LChMODwoPDgsKCw4PCgsOCwpHDg8KDw4LCgsODwoLDgsKNRCTDg8KDw4LCgsODwoLDgsKLIEjDg8
+ KDw4LCg8ODwoLDgsKFTlDDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCv1Ngw4PCg8OCwoL
+ Dg8KCw4LCi8ODwoPDgsKDw4PCgsOCwpjDg8KDw4LCgsODwoLDgsKFw4PCg8OCwoPDg8KCw4LCm3Rx
+ w4PCg8OCwoLDg8KCw4LCizvDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCi8ODwoPDgsKDw
+ 4PCgsOCwr9XaMODwoPDgsKCw4PCgsOCwolEJDvDg8KDw4LCg8ODwoLDgsKGdGLDg8KDw4LCgsODwo
+ LDgsKLf2zDg8KDw4LCgsODwoLDgsKNRCTDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCi1D
+ Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4LCl8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8OD
+ woLDgsKow4PCg8OCwoLDg8KCw4LChcODwoPDgsKDw4PCgsOCwq10SmgoT03Dg8KDw4LCgsODwoLDg
+ sKLw4PCg8OCwoPDg8KCw4LCjcODwoPDgsKDw4PCgsOCwqggTMODwoPDgsKCw4PCgsOCwoXDg8KDw4
+ LCg8ODwoLDgsKAdDrDg8KDw4LCgsODwoLDgsKNRCTDg8KDw4LCgsODwoLDgsKLTSBQUcODwoPDgsK
+ Dw4PCgsOCwr/Dg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoLDg8KCw4LCik/Dg8KDw4LCgsODwoLDgsKL
+ RCQoZitEJCDDg8KDw4LCgsODwoLDgsK3w4PCg8OCwoPDg8KCw4LCiMODwoPDgsKDw4PCgsOCwoHDg
+ 8KDw4LCg8ODwoLDgsKhw4PCg8OCwoLDg8KCw4LCi0QkJGYrRCTDg8KDw4LCgsODwoLDgsK3w4PCg8
+ OCwoPDg8KCw4LCkMODwoPDgsKDw4PCgsOCworDg8KDw4LCgsODwoLDgsKLRSBRVmpQw4PCg8OCwoP
+ Dg8KCw4LCv8ODwoPDgsKDw4PCgsOCwoDDg8KDw4LCgsODwoLDgsKKTzl0JHXDg8KDw4LCgsODwoLD
+ gsKhOXQkw4PCg8OCwoLDg8KCw4LChW/Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4LCv8ODw
+ oPDgsKDw4PCgsOCwr/Dg8KDw4LCgsODwoLDgsKhRMODwoPDgsKDw4PCgsOCwoVOw4PCg8OCwoLDg8
+ KCw4LCi8ODwoPDgsKDw4PCgsOCwojDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCv1Ncw4P
+ Cg8OCwoLDg8KCw4LCiUQkw4PCg8OCwoLDg8KCw4LChcODwoPDgsKDw4PCgsOCwoDDg8KDw4LCgsOD
+ woLDgsKEw4PCg8OCwoPDg8KCw4LCtjPDg8KDw4LCg8ODwoLDgsK2w4PCg8OCwoLDg8KCw4LCjUQkw
+ 4PCg8OCwoLDg8KCw4LCiyBEw4PCg8OCwoPDg8KCw4LChU5Qw4PCg8OCwoLDg8KCw4LCi8ODwoPDgs
+ KDw4PCgsOCwr9TYMODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgsK4w4PCg8OCwoLDg8KCw4L
+ ChcODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCgsODwoLDgsKEw4PCg8OCwoPDg8KCw4LCkMODwoPDgsKC
+ w4PCgsOCwovDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCj8ODwoPDgsKDw4PCgsOCwr9Ta
+ MODwoPDgsKCw4PCgsOCwolEJDvDg8KDw4LCg8ODwoLDgsKGw4PCg8OCwoLDg8KCw4LChMODwoPDgs
+ KCw4PCgsOCwr3Dg8KDw4LCgsODwoLDgsKNRCTDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4L
+ Cj1DDg8KDw4LCg8ODwoLDgsK/U2zDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCqMODwoPD
+ gsKCw4PCgsOCwoXDg8KDw4LCg8ODwoLDgsKtw4PCg8OCwoLDg8KCw4LChMODwoPDgsKCw4PCgsOCw
+ p9oMMODwoPDgsKDw4PCgsOCwolMw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4PCgsOCwo3Dg8KDw4
+ LCg8ODwoLDgsKow4PCg8OCwoPDg8KCw4LCq0vDg8KDw4LCgsODwoLDgsKFw4PCg8OCwoPDg8KCw4L
+ CgMODwoPDgsKCw4PCgsOCwoTDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoLDg8KCw4LCi0QkOcODwoPD
+ gsKCw4PCgsOCwrDDg8KDw4LCg8ODwoLDgsKEdEU5w4PCg8OCwoLDg8KCw4LCtTR0PcODwoPDgsKCw
+ 4PCgsOCwovDg8KDw4LCg8ODwoLDgsKNw4PCg8OCwoPDg8KCw4LCqMODwoPDgsKDw4PCgsOCwo5Lw4
+ PCg8OCwoLDg8KCw4LCi0AgUMODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCgsODwoLDgsKsw4PCg8OCwoL
+ Dg8KCw4LCik/Dg8KDw4LCgsODwoLDgsKFw4PCg8OCwoPDg8KCw4LCgHUow4PCg8OCwoLDg8KCw4LC
+ i8ODwoPDgsKDw4PCgsOCwo3Dg8KDw4LCgsODwoLDgsKJw4PCg8OCwoLDg8KCw4LCtTTDg8KDw4LCg
+ 8ODwoLDgsKow4PCg8OCwoPDg8KCw4LCl8ODwoPDgsKDw4PCgsOCwrtWw4PCg8OCwoLDg8KCw4LCi8
+ ODwoPDgsKDw4PCgsOCwo3Dg8KDw4LCg8ODwoLDgsKow4PCg8OCwoLDg8KCw4LCnw==
+
+dn: cn=All Staff,ou=Groups,dc=example,dc=com
+member: cn=Manager,dc=example,dc=com
+member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=exam
+ ple,dc=com
+member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc
+ =com
+member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=exa
+ mple,dc=com
+member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=exampl
+ e,dc=com
+owner: cn=Manager,dc=example,dc=com
+cn: All Staff
+description: Everyone in the sample data
+objectClass: groupofnames
+
+dn: cn=Alumni Assoc Staff,ou=Groups,dc=example,dc=com
+member: cn=Manager,dc=example,dc=com
+member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
+member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
+owner: cn=Manager,dc=example,dc=com
+description: All Alumni Assoc Staff
+cn: Alumni Assoc Staff
+objectClass: groupofnames
+
+dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
+ dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Barbara Jensen
+cn: Babs Jensen
+sn:: IEplbnNlbiA=
+uid: bjensen
+title: Mythical Manager, Research Systems
+postalAddress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Anyt
+ own, MI 48103-4943
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+userPassword:: YmplbnNlbg==
+mail: bjensen@mailgw.example.com
+homePostalAddress: 123 Wesley $ Anytown, MI 48103
+description: Mythical manager of the rsdd unix project
+drink: water
+homePhone: +1 313 555 2333
+pager: +1 313 555 3233
+facsimileTelephoneNumber: +1 313 555 2274
+telephoneNumber: +1 313 555 9022
+enumerated:: AQ==
+
+dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc
+ =com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Bjorn Jensen
+cn: Biiff Jensen
+sn: Jensen
+uid: bjorn
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+userPassword:: Ympvcm4=
+homePostalAddress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
+drink: Iced Tea
+description: Hiker, biker
+title: Director, Embedded Systems
+postalAddress: Info Tech Division $ 535 W. William St. $ Anytown, MI 48103
+mail: bjorn@mailgw.example.com
+homePhone: +1 313 555 5444
+pager: +1 313 555 4474
+facsimileTelephoneNumber: +1 313 555 2177
+telephoneNumber: +1 313 555 0355
+enumerated:: Cw==
+
+dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Dorothy Stevens
+cn: Dot Stevens
+sn: Stevens
+uid: dots
+title: Secretary, UM Alumni Association
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+drink: Lemonade
+homePostalAddress: 377 White St. Apt. 3 $ Anytown, MI 48104
+description: Very tall
+facsimileTelephoneNumber: +1 313 555 3223
+telephoneNumber: +1 313 555 3664
+mail: dots@mail.alumni.example.com
+homePhone: +1 313 555 0454
+enumerated:: DA==
+
+dn: cn=ITD Staff,ou=Groups,dc=example,dc=com
+owner: cn=Manager,dc=example,dc=com
+description: All ITD Staff
+cn: ITD Staff
+objectClass: groupofuniquenames
+uniqueMember: cn=Manager,dc=example,dc=com
+uniqueMember: cn=Bjorn Jensen,OU=Information Technology Division,ou=People,dc=
+ example,dc=com
+uniqueMember: cn=James A Jones 2,ou=Information Technology Division,ou=People,
+ dc=example,dc=com
+uniqueMember: cn=John Doe,ou=Information Technology Division,ou=People,dc=exam
+ ple,dc=com
+
+dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: James A Jones 1
+cn: James Jones
+cn: Jim Jones
+sn: Jones
+uid: jaj
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+userPassword:: amFq
+homePostalAddress: 3882 Beverly Rd. $ Anytown, MI 48105
+homePhone: +1 313 555 4772
+description: Outstanding
+title: Mad Cow Researcher, UM Alumni Association
+pager: +1 313 555 3923
+mail: jaj@mail.alumni.example.com
+facsimileTelephoneNumber: +1 313 555 4332
+telephoneNumber: +1 313 555 0895
+enumerated:: DQ==
+
+dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=example
+ ,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: James A Jones 2
+cn: James Jones
+cn: Jim Jones
+sn: Doe
+uid: jjones
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 933 Brooks $ Anytown, MI 48104
+homePhone: +1 313 555 8838
+title: Senior Manager, Information Technology Division
+description: Not around very much
+mail: jjones@mailgw.example.com
+postalAddress: Info Tech Division $ 535 W William $ Anytown, MI 48103
+pager: +1 313 555 2833
+facsimileTelephoneNumber: +1 313 555 8688
+telephoneNumber: +1 313 555 7334
+enumerated:: Dg==
+
+dn: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Jane Doe
+cn: Jane Alverson
+sn: Doe
+uid: jdoe
+title: Programmer Analyst, UM Alumni Association
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 123 Anystreet $ Anytown, MI 48104
+drink: diet coke
+description: Enthusiastic
+mail: jdoe@woof.net
+homePhone: +1 313 555 5445
+pager: +1 313 555 1220
+facsimileTelephoneNumber: +1 313 555 2311
+telephoneNumber: +1 313 555 4774
+enumerated:: Cg==
+
+dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Jennifer Smith
+cn: Jen Smith
+sn: Smith
+uid: jen
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+drink: Sam Adams
+homePostalAddress: 1000 Maple #44 $ Anytown, MI 48103
+title: Telemarketer, UM Alumni Association
+mail: jen@mail.alumni.example.com
+homePhone: +1 313 555 2333
+pager: +1 313 555 6442
+facsimileTelephoneNumber: +1 313 555 2756
+telephoneNumber: +1 313 555 8232
+enumerated:: ZQ==
+
+dn: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: John Doe
+cn: Jonathon Doe
+sn: Doe
+uid: johnd
+postalAddress: ITD $ 535 W. William $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 912 East Bllvd $ Anytown, MI 48104
+title: System Administrator, Information Technology Division
+description: overworked!
+mail: johnd@mailgw.example.com
+homePhone: +1 313 555 3774
+pager: +1 313 555 6573
+facsimileTelephoneNumber: +1 313 555 4544
+telephoneNumber: +1 313 555 9394
+enumerated:: FA==
+
+dn: cn=Manager,dc=example,dc=com
+objectClass: person
+cn: Manager
+cn: Directory Manager
+cn: Dir Man
+sn: Manager
+description: Manager of the directory
+userPassword:: c2VjcmV0
+
+dn: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Mark Elliot
+cn: Mark A Elliot
+sn: Elliot
+uid: melliot
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 199 Outer Drive $ Ypsilanti, MI 48198
+homePhone: +1 313 555 0388
+drink: Gasoline
+title: Director, UM Alumni Association
+mail: melliot@mail.alumni.example.com
+pager: +1 313 555 7671
+facsimileTelephoneNumber: +1 313 555 7762
+telephoneNumber: +1 313 555 4177
+enumerated:: Mw==
+
+dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Ursula Hampster
+sn: Hampster
+uid: uham
+title: Secretary, UM Alumni Association
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 123 Anystreet $ Anytown, MI 48104
+mail: uham@mail.alumni.example.com
+homePhone: +1 313 555 8421
+pager: +1 313 555 2844
+facsimileTelephoneNumber: +1 313 555 9700
+telephoneNumber: +1 313 555 5331
+enumerated:: Hw==
+
diff --git a/contrib/slapd-modules/datamorph/tests/data/test001-01-same-attr.ldif b/contrib/slapd-modules/datamorph/tests/data/test001-01-same-attr.ldif
new file mode 100644
index 0000000..b9ba88f
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test001-01-same-attr.ldif
@@ -0,0 +1,3 @@
+dn: olcDatamorphAttribute=enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnum
diff --git a/contrib/slapd-modules/datamorph/tests/data/test001-02-same-index.ldif b/contrib/slapd-modules/datamorph/tests/data/test001-02-same-index.ldif
new file mode 100644
index 0000000..1dac5dc
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test001-02-same-index.ldif
@@ -0,0 +1,4 @@
+dn: olcDatamorphValue=nope,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 1
diff --git a/contrib/slapd-modules/datamorph/tests/data/test001-02a-same-index.ldif b/contrib/slapd-modules/datamorph/tests/data/test001-02a-same-index.ldif
new file mode 100644
index 0000000..f31ab0a
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test001-02a-same-index.ldif
@@ -0,0 +1,4 @@
+dn: olcDatamorphValue={0}bjensen,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIndex
+olcDatamorphIndex: 11
diff --git a/contrib/slapd-modules/datamorph/tests/data/test001-03-invalid-attr.ldif b/contrib/slapd-modules/datamorph/tests/data/test001-03-invalid-attr.ldif
new file mode 100644
index 0000000..01f21c2
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test001-03-invalid-attr.ldif
@@ -0,0 +1,3 @@
+dn: olcDatamorphAttribute=uid,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnum
diff --git a/contrib/slapd-modules/datamorph/tests/data/test002-config.ldif b/contrib/slapd-modules/datamorph/tests/data/test002-config.ldif
new file mode 100644
index 0000000..2aed906
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test002-config.ldif
@@ -0,0 +1,9 @@
+dn: olcDatamorphValue=gjensen,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: add
+objectclass: olcDatamorphEnumValue
+olcDatamorphIndex: 55
+
+dn: olcDatamorphAttribute={1}signed,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+delete: olcDatamorphIntegerUpperBound
+olcDatamorphIntegerUpperBound: 30000
diff --git a/contrib/slapd-modules/datamorph/tests/data/test002-entry.ldif b/contrib/slapd-modules/datamorph/tests/data/test002-entry.ldif
new file mode 100644
index 0000000..0df14c4
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test002-entry.ldif
@@ -0,0 +1,31 @@
+dn: cn=Gern Jensen,ou=Information Technology Division,ou=People,dc=example,dc=
+ com
+changetype: add
+objectClass: testPerson
+objectClass: transformedObject
+cn: Gern Jensen
+sn: Jensen
+uid: gjensen
+title: Chief Investigator, ITD
+postalAddress: ITD $ 535 W. William St $ Anytown, MI 48103
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+drink: Coffee
+homePostalAddress: 844 Brown St. Apt. 4 $ Anytown, MI 48104
+description: Very odd
+facsimileTelephonenumber: +1 313 555 7557
+telephoneNumber: +1 313 555 8343
+mail: gjensen@mailgw.example.com
+homePhone: +1 313 555 8844
+testTime: 20050304001801.234Z
+enumerated: gjensen
+
+dn: ou=New Unit,dc=example,dc=com
+changetype: add
+objectClass: organizationalUnit
+objectClass: extensibleObject
+ou: New Unit
+uidNumber: 32345
+gidNumber: 1
+signed: 32345
+number: 1
+
diff --git a/contrib/slapd-modules/datamorph/tests/data/test002-fail.ldif b/contrib/slapd-modules/datamorph/tests/data/test002-fail.ldif
new file mode 100644
index 0000000..f834997
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test002-fail.ldif
@@ -0,0 +1,23 @@
+dn: uid=bjensen+cn=Barbara Jensen+enumerated=bjensen,ou=Information Technology Division,ou=People,dc=example,
+ dc=com
+changetype: add
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Barbara Jensen
+cn: Babs Jensen
+sn:: IEplbnNlbiA=
+uid: bjensen
+title: Mythical Manager, Research Systems
+postalAddress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Anyt
+ own, MI 48103-4943
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+userPassword:: YmplbnNlbg==
+mail: bjensen@mailgw.example.com
+homePostalAddress: 123 Wesley $ Anytown, MI 48103
+description: Mythical manager of the rsdd unix project
+drink: water
+homePhone: +1 313 555 2333
+pager: +1 313 555 3233
+facsimileTelephoneNumber: +1 313 555 2274
+telephoneNumber: +1 313 555 9022
+
diff --git a/contrib/slapd-modules/datamorph/tests/data/test002-transformed-rdn.ldif b/contrib/slapd-modules/datamorph/tests/data/test002-transformed-rdn.ldif
new file mode 100644
index 0000000..cbcb14a
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test002-transformed-rdn.ldif
@@ -0,0 +1,5 @@
+dn: ou=New Unit,dc=www+number=1,dc=example,dc=com
+changetype: add
+objectClass: organizationalUnit
+ou: New Unit
+
diff --git a/contrib/slapd-modules/datamorph/tests/data/test003-config.ldif b/contrib/slapd-modules/datamorph/tests/data/test003-config.ldif
new file mode 100644
index 0000000..f74717c
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test003-config.ldif
@@ -0,0 +1,30 @@
+dn: olcDatamorphValue={2}dots,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIndex
+olcDatamorphIndex: 110
+
+dn: olcDatamorphValue={3}jaj,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIndex
+olcDatamorphIndex: 12
+
+dn: olcDatamorphValue={4}jjones,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIndex
+olcDatamorphIndex: 13
+
+dn: olcDatamorphValue={2}dots,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIndex
+olcDatamorphIndex: 14
+
+dn: olcDatamorphAttribute={1}signed,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIntegerSigned
+olcDatamorphIntegerSigned: FALSE
+-
+replace: olcDatamorphIntegerUpperBound
+olcDatamorphIntegerUpperBound: 50000
+-
+replace: olcDatamorphIntegerLowerBound
+olcDatamorphIntegerLowerBound: 50
diff --git a/contrib/slapd-modules/datamorph/tests/data/test003-out.ldif b/contrib/slapd-modules/datamorph/tests/data/test003-out.ldif
new file mode 100644
index 0000000..3dbd8bc
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test003-out.ldif
@@ -0,0 +1,125 @@
+# List regular entries
+dn: dc=example,dc=com
+objectClass: top
+objectClass: organization
+objectClass: domainRelatedObject
+objectClass: dcobject
+dc: example
+l: Anytown, Michigan
+st: Michigan
+o: Example, Inc.
+o: EX
+o: Ex.
+description: The Example, Inc. at Anytown
+postalAddress: Example, Inc. $ 535 W. William St. $ Anytown, MI 48109 $ US
+telephoneNumber: +1 313 555 1817
+associatedDomain: example.com
+
+dn: ou=Groups,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Groups
+
+
+# List entries with transformed attributes
+dn: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: John Doe
+cn: Jonathon Doe
+sn: Doe
+uid: johnd
+postalAddress: ITD $ 535 W. William $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 912 East Bllvd $ Anytown, MI 48104
+title: System Administrator, Information Technology Division
+description: overworked!
+mail: johnd@mailgw.example.com
+homePhone: +1 313 555 3774
+pager: +1 313 555 6573
+facsimileTelephoneNumber: +1 313 555 4544
+telephoneNumber: +1 313 555 9394
+enumerated: johnd
+
+dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc
+ =com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Bjorn Jensen
+cn: Biiff Jensen
+sn: Jensen
+uid: bjorn
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+userPassword:: Ympvcm4=
+homePostalAddress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
+drink: Iced Tea
+description: Hiker, biker
+title: Director, Embedded Systems
+postalAddress: Info Tech Division $ 535 W. William St. $ Anytown, MI 48103
+mail: bjorn@mailgw.example.com
+homePhone: +1 313 555 5444
+pager: +1 313 555 4474
+facsimileTelephoneNumber: +1 313 555 2177
+telephoneNumber: +1 313 555 0355
+enumerated: bjorn
+
+dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
+ dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Barbara Jensen
+cn: Babs Jensen
+sn:: IEplbnNlbiA=
+uid: bjensen
+title: Mythical Manager, Research Systems
+postalAddress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Anyt
+ own, MI 48103-4943
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+userPassword:: YmplbnNlbg==
+mail: bjensen@mailgw.example.com
+homePostalAddress: 123 Wesley $ Anytown, MI 48103
+description: Mythical manager of the rsdd unix project
+drink: water
+homePhone: +1 313 555 2333
+pager: +1 313 555 3233
+facsimileTelephoneNumber: +1 313 555 2274
+telephoneNumber: +1 313 555 9022
+enumerated: bjensen
+
+dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=example
+ ,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: James A Jones 2
+cn: James Jones
+cn: Jim Jones
+sn: Doe
+uid: jjones
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 933 Brooks $ Anytown, MI 48104
+homePhone: +1 313 555 8838
+title: Senior Manager, Information Technology Division
+description: Not around very much
+mail: jjones@mailgw.example.com
+postalAddress: Info Tech Division $ 535 W William $ Anytown, MI 48103
+pager: +1 313 555 2833
+facsimileTelephoneNumber: +1 313 555 8688
+telephoneNumber: +1 313 555 7334
+enumerated: jjones
+
+
+# Search for transformed attributes listing only those
+dn: ou=People,dc=example,dc=com
+signed: -19858
+
+dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
+ dc=com
+enumerated: bjensen
+
+
+# Search for transformed attributes after reconfiguring mapping
+dn: ou=People,dc=example,dc=com
+signed: 45678
+
+dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+enumerated: jaj
+
diff --git a/contrib/slapd-modules/datamorph/tests/data/test005-01-fail.ldif b/contrib/slapd-modules/datamorph/tests/data/test005-01-fail.ldif
new file mode 100644
index 0000000..694aacc
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test005-01-fail.ldif
@@ -0,0 +1,5 @@
+# invalid enum value
+dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+changetype: modify
+replace: enumerated
+enumerated: 2dots
diff --git a/contrib/slapd-modules/datamorph/tests/data/test005-02-fail.ldif b/contrib/slapd-modules/datamorph/tests/data/test005-02-fail.ldif
new file mode 100644
index 0000000..1ce687f
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test005-02-fail.ldif
@@ -0,0 +1,5 @@
+# enums are case sensitive
+dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+changetype: modify
+replace: enumerated
+enumerated: Dots
diff --git a/contrib/slapd-modules/datamorph/tests/data/test005-03-fail.ldif b/contrib/slapd-modules/datamorph/tests/data/test005-03-fail.ldif
new file mode 100644
index 0000000..54bb9b5
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test005-03-fail.ldif
@@ -0,0 +1,5 @@
+# value does not exist in entry
+dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+changetype: modify
+delete: enumerated
+enumerated: uham
diff --git a/contrib/slapd-modules/datamorph/tests/data/test005-03a-fail.ldif b/contrib/slapd-modules/datamorph/tests/data/test005-03a-fail.ldif
new file mode 100644
index 0000000..601d895
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test005-03a-fail.ldif
@@ -0,0 +1,5 @@
+# value does not exist in entry
+dn: ou=People,dc=example,dc=com
+changetype: modify
+delete: signed
+signed: 2
diff --git a/contrib/slapd-modules/datamorph/tests/data/test005-04-fail.ldif b/contrib/slapd-modules/datamorph/tests/data/test005-04-fail.ldif
new file mode 100644
index 0000000..d97effc
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test005-04-fail.ldif
@@ -0,0 +1,10 @@
+# a value outside the bounds
+dn: ou=People,dc=example,dc=com
+changetype: modify
+replace: signed
+signed: 2
+-
+replace: number
+number: -1
+-
+
diff --git a/contrib/slapd-modules/datamorph/tests/data/test005-04a-fail.ldif b/contrib/slapd-modules/datamorph/tests/data/test005-04a-fail.ldif
new file mode 100644
index 0000000..63b3263
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test005-04a-fail.ldif
@@ -0,0 +1,6 @@
+# a value outside the bounds
+dn: ou=People,dc=example,dc=com
+changetype: modify
+replace: signed
+signed: 32000
+-
diff --git a/contrib/slapd-modules/datamorph/tests/data/test005-changes.ldif b/contrib/slapd-modules/datamorph/tests/data/test005-changes.ldif
new file mode 100644
index 0000000..17a72da
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test005-changes.ldif
@@ -0,0 +1,30 @@
+dn: ou=People,dc=example,dc=com
+changetype: modify
+replace: signed
+signed: -1
+-
+replace: number
+number: 1
+-
+
+dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+changetype: modify
+replace: enumerated
+enumerated: jaj
+-
+
+dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com
+changetype: modify
+add: enumerated
+enumerated: bjorn
+enumerated: uham
+-
+
+dn: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc=com
+changetype: modify
+delete: enumerated
+enumerated: johnd
+-
+add: enumerated
+enumerated: melliot
+-
diff --git a/contrib/slapd-modules/datamorph/tests/data/test005-out.ldif b/contrib/slapd-modules/datamorph/tests/data/test005-out.ldif
new file mode 100644
index 0000000..4c8c360
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test005-out.ldif
@@ -0,0 +1,212 @@
+# Test1: list entries that should have been changed by ldapmodify
+dn: ou=People,dc=example,dc=com
+objectClass: organizationalUnit
+objectClass: extensibleObject
+ou: People
+uidNumber: 0
+gidNumber: 0
+signed: -1
+number: 1
+
+dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
+ dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Barbara Jensen
+cn: Babs Jensen
+sn:: IEplbnNlbiA=
+uid: bjensen
+title: Mythical Manager, Research Systems
+postalAddress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Anyt
+ own, MI 48103-4943
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+userPassword:: YmplbnNlbg==
+mail: bjensen@mailgw.example.com
+homePostalAddress: 123 Wesley $ Anytown, MI 48103
+description: Mythical manager of the rsdd unix project
+drink: water
+homePhone: +1 313 555 2333
+pager: +1 313 555 3233
+facsimileTelephoneNumber: +1 313 555 2274
+telephoneNumber: +1 313 555 9022
+enumerated: bjensen
+enumerated: bjorn
+enumerated: uham
+
+dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc
+ =com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Bjorn Jensen
+cn: Biiff Jensen
+sn: Jensen
+uid: bjorn
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+userPassword:: Ympvcm4=
+homePostalAddress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
+drink: Iced Tea
+description: Hiker, biker
+title: Director, Embedded Systems
+postalAddress: Info Tech Division $ 535 W. William St. $ Anytown, MI 48103
+mail: bjorn@mailgw.example.com
+homePhone: +1 313 555 5444
+pager: +1 313 555 4474
+facsimileTelephoneNumber: +1 313 555 2177
+telephoneNumber: +1 313 555 0355
+enumerated: bjorn
+
+dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Dorothy Stevens
+cn: Dot Stevens
+sn: Stevens
+uid: dots
+title: Secretary, UM Alumni Association
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+drink: Lemonade
+homePostalAddress: 377 White St. Apt. 3 $ Anytown, MI 48104
+description: Very tall
+facsimileTelephoneNumber: +1 313 555 3223
+telephoneNumber: +1 313 555 3664
+mail: dots@mail.alumni.example.com
+homePhone: +1 313 555 0454
+enumerated: jaj
+
+dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: James A Jones 1
+cn: James Jones
+cn: Jim Jones
+sn: Jones
+uid: jaj
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+userPassword:: amFq
+homePostalAddress: 3882 Beverly Rd. $ Anytown, MI 48105
+homePhone: +1 313 555 4772
+description: Outstanding
+title: Mad Cow Researcher, UM Alumni Association
+pager: +1 313 555 3923
+mail: jaj@mail.alumni.example.com
+facsimileTelephoneNumber: +1 313 555 4332
+telephoneNumber: +1 313 555 0895
+enumerated: jaj
+
+dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=example
+ ,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: James A Jones 2
+cn: James Jones
+cn: Jim Jones
+sn: Doe
+uid: jjones
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 933 Brooks $ Anytown, MI 48104
+homePhone: +1 313 555 8838
+title: Senior Manager, Information Technology Division
+description: Not around very much
+mail: jjones@mailgw.example.com
+postalAddress: Info Tech Division $ 535 W William $ Anytown, MI 48103
+pager: +1 313 555 2833
+facsimileTelephoneNumber: +1 313 555 8688
+telephoneNumber: +1 313 555 7334
+enumerated: jjones
+
+dn: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Jane Doe
+cn: Jane Alverson
+sn: Doe
+uid: jdoe
+title: Programmer Analyst, UM Alumni Association
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 123 Anystreet $ Anytown, MI 48104
+drink: diet coke
+description: Enthusiastic
+mail: jdoe@woof.net
+homePhone: +1 313 555 5445
+pager: +1 313 555 1220
+facsimileTelephoneNumber: +1 313 555 2311
+telephoneNumber: +1 313 555 4774
+enumerated: jdoe
+
+dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Jennifer Smith
+cn: Jen Smith
+sn: Smith
+uid: jen
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+drink: Sam Adams
+homePostalAddress: 1000 Maple #44 $ Anytown, MI 48103
+title: Telemarketer, UM Alumni Association
+mail: jen@mail.alumni.example.com
+homePhone: +1 313 555 2333
+pager: +1 313 555 6442
+facsimileTelephoneNumber: +1 313 555 2756
+telephoneNumber: +1 313 555 8232
+enumerated: jen
+
+dn: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: John Doe
+cn: Jonathon Doe
+sn: Doe
+uid: johnd
+postalAddress: ITD $ 535 W. William $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 912 East Bllvd $ Anytown, MI 48104
+title: System Administrator, Information Technology Division
+description: overworked!
+mail: johnd@mailgw.example.com
+homePhone: +1 313 555 3774
+pager: +1 313 555 6573
+facsimileTelephoneNumber: +1 313 555 4544
+telephoneNumber: +1 313 555 9394
+enumerated: melliot
+
+dn: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Mark Elliot
+cn: Mark A Elliot
+sn: Elliot
+uid: melliot
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 199 Outer Drive $ Ypsilanti, MI 48198
+homePhone: +1 313 555 0388
+drink: Gasoline
+title: Director, UM Alumni Association
+mail: melliot@mail.alumni.example.com
+pager: +1 313 555 7671
+facsimileTelephoneNumber: +1 313 555 7762
+telephoneNumber: +1 313 555 4177
+enumerated: melliot
+
+dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
+objectClass: OpenLDAPperson
+objectClass: transformedObject
+cn: Ursula Hampster
+sn: Hampster
+uid: uham
+title: Secretary, UM Alumni Association
+postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
+seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
+homePostalAddress: 123 Anystreet $ Anytown, MI 48104
+mail: uham@mail.alumni.example.com
+homePhone: +1 313 555 8421
+pager: +1 313 555 2844
+facsimileTelephoneNumber: +1 313 555 9700
+telephoneNumber: +1 313 555 5331
+enumerated: uham
+
diff --git a/contrib/slapd-modules/datamorph/tests/data/test007-config.ldif b/contrib/slapd-modules/datamorph/tests/data/test007-config.ldif
new file mode 100644
index 0000000..3820831
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/data/test007-config.ldif
@@ -0,0 +1,30 @@
+dn: olcDatamorphValue={2}dots,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIndex
+olcDatamorphIndex: 110
+
+dn: olcDatamorphValue={4}jjones,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIndex
+olcDatamorphIndex: 14
+
+dn: olcDatamorphValue={3}jaj,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIndex
+olcDatamorphIndex: 13
+
+dn: olcDatamorphValue={2}dots,olcDatamorphAttribute={0}enumerated,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIndex
+olcDatamorphIndex: 12
+
+dn: olcDatamorphAttribute={1}signed,olcOverlay={0}datamorph,olcDatabase={1}@BACKEND@,cn=config
+changetype: modify
+replace: olcDatamorphIntegerSigned
+olcDatamorphIntegerSigned: TRUE
+-
+replace: olcDatamorphIntegerLowerBound
+olcDatamorphIntegerLowerBound: -20000
+-
+replace: olcDatamorphIntegerUpperBound
+olcDatamorphIntegerUpperBound: 30000
diff --git a/contrib/slapd-modules/datamorph/tests/run b/contrib/slapd-modules/datamorph/tests/run
new file mode 100755
index 0000000..6a38431
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/run
@@ -0,0 +1,229 @@
+#!/bin/sh
+## $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 1998-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+##
+## ACKNOWLEDGEMENTS:
+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
+
+USAGE="$0 [-b <backend>] [-c] [-k] [-l #] [-p] [-s {ro|rp}] [-u] [-w] <script>"
+
+TOPSRCDIR="${SRCDIR-$LDAP_SRC}"
+SRCDIR="${TOPSRCDIR}/tests"
+eval `grep EGREP_CMD= ${LDAP_BUILD}/tests/run`
+eval `$EGREP_CMD -e '^LN_S=' ${LDAP_BUILD}/tests/run`
+
+export SRCDIR TOPSRCDIR LN_S EGREP_CMD
+
+. "${SRCDIR}/scripts/defines.sh"
+
+BACKEND=
+CLEAN=no
+WAIT=0
+KILLSERVERS=yes
+PRESERVE=${PRESERVE-no}
+SYNCMODE=${SYNCMODE-rp}
+USERDATA=no
+LOOP=1
+COUNTER=1
+
+while test $# -gt 0 ; do
+ case "$1" in
+ -b | -backend)
+ BACKEND="$2"
+ shift; shift ;;
+
+ -c | -clean)
+ CLEAN=yes
+ shift ;;
+
+ -k | -kill)
+ KILLSERVERS=no
+ shift ;;
+ -l | -loop)
+ NUM="`echo $2 | sed 's/[0-9]//g'`"
+ if [ -z "$NUM" ]; then
+ LOOP=$2
+ else
+ echo "Loop variable not an int: $2"
+ echo "$USAGE"; exit 1
+ fi
+ shift ;
+ shift ;;
+
+ -p | -preserve)
+ PRESERVE=yes
+ shift ;;
+
+ -s | -syncmode)
+ case "$2" in
+ ro | rp)
+ SYNCMODE="$2"
+ ;;
+ *)
+ echo "unknown sync mode $2"
+ echo "$USAGE"; exit 1
+ ;;
+ esac
+ shift; shift ;;
+
+ -u | -userdata)
+ USERDATA=yes
+ shift ;;
+
+ -w | -wait)
+ WAIT=1
+ shift ;;
+
+ -)
+ shift
+ break ;;
+
+ -*)
+ echo "$USAGE"; exit 1
+ ;;
+
+ *)
+ break ;;
+ esac
+done
+
+eval `$EGREP_CMD -e '^AC' ${LDAP_BUILD}/tests/run`
+export `$EGREP_CMD -e '^AC' ${LDAP_BUILD}/tests/run | sed 's/=.*//'`
+
+if test -z "$BACKEND" ; then
+ for b in mdb ; do
+ if eval "test \"\$AC_$b\" != no" ; then
+ BACKEND=$b
+ break
+ fi
+ done
+ if test -z "$BACKEND" ; then
+ echo "No suitable default database backend configured" >&2
+ exit 1
+ fi
+fi
+
+BACKENDTYPE=`eval 'echo $AC_'$BACKEND`
+if test "x$BACKENDTYPE" = "x" ; then
+ BACKENDTYPE="unknown"
+fi
+
+# Backend features. indexdb: indexing and unchecked limit.
+# maindb: main storage backend. Currently index,limits,mode,paged results.
+INDEXDB=noindexdb MAINDB=nomaindb
+case $BACKEND in
+ mdb) INDEXDB=indexdb MAINDB=maindb ;;
+ ndb) INDEXDB=indexdb ;;
+esac
+
+export BACKEND BACKENDTYPE INDEXDB MAINDB \
+ WAIT KILLSERVERS PRESERVE SYNCMODE USERDATA \
+ SRCDIR
+
+if test $# = 0 ; then
+ echo "$USAGE"; exit 1
+fi
+
+# need defines.sh for the definitions of the directories
+. $SRCDIR/scripts/defines.sh
+
+SCRIPTDIR="${TOPDIR}/tests/scripts"
+
+export SCRIPTDIR
+
+SCRIPTNAME="$1"
+shift
+
+if test -x "${SCRIPTDIR}/${SCRIPTNAME}" ; then
+ SCRIPT="${SCRIPTDIR}/${SCRIPTNAME}"
+elif test -x "`echo ${SCRIPTDIR}/test*-${SCRIPTNAME}`"; then
+ SCRIPT="`echo ${SCRIPTDIR}/test*-${SCRIPTNAME}`"
+elif test -x "`echo ${SCRIPTDIR}/${SCRIPTNAME}-*`"; then
+ SCRIPT="`echo ${SCRIPTDIR}/${SCRIPTNAME}-*`"
+else
+ echo "run: ${SCRIPTNAME} not found (or not executable)"
+ exit 1;
+fi
+
+if test ! -r ${DATADIR}/test.ldif ; then
+ ${LN_S} ${SRCDIR}/data ${DATADIR}
+fi
+if test ! -r ${SCHEMADIR}/core.schema ; then
+ ${LN_S} ${TOPSRCDIR}/servers/slapd/schema ${SCHEMADIR}
+fi
+if test ! -r ./data; then
+ ${LN_S} ${TOPDIR}/tests/data ./
+fi
+
+if test -d ${TESTDIR} ; then
+ if test $PRESERVE = no ; then
+ echo "Cleaning up test run directory leftover from previous run."
+ /bin/rm -rf ${TESTDIR}
+ elif test $PRESERVE = yes ; then
+ echo "Cleaning up only database directories leftover from previous run."
+ /bin/rm -rf ${TESTDIR}/db.*
+ fi
+fi
+if test $BACKEND = ndb ; then
+ mysql --user root <<EOF
+ drop database if exists db_1;
+ drop database if exists db_2;
+ drop database if exists db_3;
+ drop database if exists db_4;
+ drop database if exists db_5;
+ drop database if exists db_6;
+EOF
+fi
+mkdir -p ${TESTDIR}
+
+if test $USERDATA = yes ; then
+ if test ! -d userdata ; then
+ echo "User data directory (userdata) does not exist."
+ exit 1
+ fi
+ cp -R userdata/* ${TESTDIR}
+fi
+
+# disable LDAP initialization
+LDAPNOINIT=true; export LDAPNOINIT
+
+echo "Running ${SCRIPT} for ${BACKEND}..."
+while [ $COUNTER -le $LOOP ]; do
+ if [ $LOOP -gt 1 ]; then
+ echo "Running $COUNTER of $LOOP iterations"
+ fi
+ $SCRIPT $*
+ RC=$?
+
+ if test $CLEAN = yes ; then
+ echo "Cleaning up test run directory from this run."
+ /bin/rm -rf ${TESTDIR}
+ echo "Cleaning up symlinks."
+ /bin/rm -f ${DATADIR} ${SCHEMADIR}
+ fi
+
+ if [ $RC -ne 0 ]; then
+ if [ $LOOP -gt 1 ]; then
+ echo "Failed after $COUNTER of $LOOP iterations"
+ fi
+ exit $RC
+ else
+ COUNTER=`expr $COUNTER + 1`
+ if [ $COUNTER -le $LOOP ]; then
+ echo "Cleaning up test run directory from this run."
+ /bin/rm -rf ${TESTDIR}
+ fi
+ fi
+done
+exit $RC
diff --git a/contrib/slapd-modules/datamorph/tests/scripts/all b/contrib/slapd-modules/datamorph/tests/scripts/all
new file mode 100755
index 0000000..d6d6dc7
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/scripts/all
@@ -0,0 +1,102 @@
+#! /bin/sh
+# $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 1998-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+
+. $SRCDIR/scripts/defines.sh
+
+TB="" TN=""
+if test -t 1 ; then
+ TB=`$SHTOOL echo -e "%B" 2>/dev/null`
+ TN=`$SHTOOL echo -e "%b" 2>/dev/null`
+fi
+
+FAILCOUNT=0
+SKIPCOUNT=0
+SLEEPTIME=10
+
+echo ">>>>> Executing all LDAP tests for $BACKEND"
+
+if [ -n "$NOEXIT" ]; then
+ echo "Result Test" > $TESTWD/results
+fi
+
+for CMD in ${SCRIPTDIR}/test*; do
+ case "$CMD" in
+ *~) continue;;
+ *.bak) continue;;
+ *.orig) continue;;
+ *.sav) continue;;
+ *) test -f "$CMD" || continue;;
+ esac
+
+ # remove cruft from prior test
+ if test $PRESERVE = yes ; then
+ /bin/rm -rf $TESTDIR/db.*
+ else
+ /bin/rm -rf $TESTDIR
+ fi
+ if test $BACKEND = ndb ; then
+ mysql --user root <<EOF
+ drop database if exists db_1;
+ drop database if exists db_2;
+ drop database if exists db_3;
+ drop database if exists db_4;
+ drop database if exists db_5;
+ drop database if exists db_6;
+EOF
+ fi
+
+ BCMD=`basename $CMD`
+ if [ -x "$CMD" ]; then
+ echo ">>>>> Starting ${TB}$BCMD${TN} for $BACKEND..."
+ $CMD
+ RC=$?
+ if test $RC -eq 0 ; then
+ echo ">>>>> $BCMD completed ${TB}OK${TN} for $BACKEND."
+ else
+ echo ">>>>> $BCMD ${TB}failed${TN} for $BACKEND"
+ FAILCOUNT=`expr $FAILCOUNT + 1`
+
+ if [ -n "$NOEXIT" ]; then
+ echo "Continuing."
+ else
+ echo "(exit $RC)"
+ exit $RC
+ fi
+ fi
+ else
+ echo ">>>>> Skipping ${TB}$BCMD${TN} for $BACKEND."
+ SKIPCOUNT=`expr $SKIPCOUNT + 1`
+ RC="-"
+ fi
+
+ if [ -n "$NOEXIT" ]; then
+ echo "$RC $BCMD" >> $TESTWD/results
+ fi
+
+# echo ">>>>> waiting $SLEEPTIME seconds for things to exit"
+# sleep $SLEEPTIME
+ echo ""
+done
+
+if [ -n "$NOEXIT" ]; then
+ if [ "$FAILCOUNT" -gt 0 ]; then
+ cat $TESTWD/results
+ echo "$FAILCOUNT tests for $BACKEND ${TB}failed${TN}. Please review the test log."
+ else
+ echo "All executed tests for $BACKEND ${TB}succeeded${TN}."
+ fi
+fi
+
+echo "$SKIPCOUNT tests for $BACKEND were ${TB}skipped${TN}."
diff --git a/contrib/slapd-modules/datamorph/tests/scripts/common.sh b/contrib/slapd-modules/datamorph/tests/scripts/common.sh
new file mode 100755
index 0000000..a468732
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/scripts/common.sh
@@ -0,0 +1,152 @@
+#! /bin/sh
+## $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 2016-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+##
+## ACKNOWLEDGEMENTS:
+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
+
+OVERLAY_CONFIG=${OVERLAY_CONFIG-data/config.ldif}
+
+mkdir -p $TESTDIR $DBDIR1
+
+mkdir $TESTDIR/confdir
+. $CONFFILTER $BACKEND $MONITORDB < $CONF > $CONF1
+
+$SLAPPASSWD -g -n >$CONFIGPWF
+echo "database config" >>$CONF1
+echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >>$CONF1
+
+echo "Starting slapd on TCP/IP port $PORT1 for configuration..."
+$SLAPD -f $CONF1 -F $TESTDIR/confdir -h $URI1 -d $LVL > $LOG1 2>&1 &
+PID=$!
+if test $WAIT != 0 ; then
+ echo PID $PID
+ read foo
+fi
+KILLPIDS="$PID"
+
+sleep $SLEEP0
+
+for i in 0 1 2 3 4 5; do
+ $LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
+ 'objectclass=*' > /dev/null 2>&1
+ RC=$?
+ if test $RC = 0 ; then
+ break
+ fi
+ echo "Waiting ${SLEEP1} seconds for slapd to start..."
+ sleep ${SLEEP1}
+done
+
+$LDAPSEARCH -D cn=config -H $URI1 -y $CONFIGPWF \
+ -s base -b 'cn=module{0},cn=config' 1.1 >$TESTOUT 2>&1
+RC=$?
+case $RC in
+0)
+ $LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1 <<EOMOD
+dn: cn=module{0},cn=config
+changetype: modify
+add: olcModuleLoad
+olcModuleLoad: `pwd`/../datamorph.la
+EOMOD
+ ;;
+32)
+ $LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1 <<EOMOD
+dn: cn=module,cn=config
+changetype: add
+objectClass: olcModuleList
+olcModuleLoad: `pwd`/../datamorph.la
+EOMOD
+ ;;
+*)
+ echo "Failed testing for module load entry"
+ exit $RC;
+ ;;
+esac
+
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Loading test datamorph configuration..."
+. $CONFFILTER $BACKEND $MONITORDB < $OVERLAY_CONFIG | \
+$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ > $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+if test $INDEXDB = indexdb ; then
+ echo "Configure indexing for transformed attributes..."
+ $LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1 <<EOMOD
+dn: olcDatabase={1}$BACKEND,cn=config
+changetype: modify
+add: olcDbIndex
+olcDbIndex: enumerated pres,eq
+olcDbIndex: number pres,eq
+olcDbIndex: signed pres,eq
+EOMOD
+ RC=$?
+ if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ fi
+else
+ echo "Skipping indexing setup for this database"
+fi
+
+echo "Stopping slapd on TCP/IP port $PORT1..."
+kill -HUP $KILLPIDS
+KILLPIDS=""
+sleep $SLEEP0
+
+echo "Running slapadd to build slapd database..."
+$SLAPADD -F $TESTDIR/confdir -l data/test.ldif
+RC=$?
+if test $RC != 0 ; then
+ echo "slapadd failed ($RC)!"
+ exit $RC
+fi
+
+echo "Starting slapd on TCP/IP port $PORT1..."
+$SLAPD -F $TESTDIR/confdir -h $URI1 -d $LVL >> $LOG1 2>&1 &
+PID=$!
+if test $WAIT != 0 ; then
+ echo PID $PID
+ read foo
+fi
+KILLPIDS="$PID"
+
+sleep $SLEEP0
+
+for i in 0 1 2 3 4 5; do
+ $LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
+ 'objectclass=*' > /dev/null 2>&1
+ RC=$?
+ if test $RC = 0 ; then
+ break
+ fi
+ echo "Waiting ${SLEEP1} seconds for slapd to start..."
+ sleep ${SLEEP1}
+done
diff --git a/contrib/slapd-modules/datamorph/tests/scripts/test001-config b/contrib/slapd-modules/datamorph/tests/scripts/test001-config
new file mode 100755
index 0000000..c4bfdf0
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/scripts/test001-config
@@ -0,0 +1,248 @@
+#! /bin/sh
+## $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 2016-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+##
+## ACKNOWLEDGEMENTS:
+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
+
+echo "running defines.sh"
+. $SRCDIR/scripts/defines.sh
+
+. ${SCRIPTDIR}/common.sh
+
+echo "Applying invalid changes to config (should fail)..."
+for CHANGE in data/test001-*.ldif; do
+ echo "... $CHANGE"
+ . $CONFFILTER $BACKEND $MONITORDB < $CHANGE | \
+ $LDAPMODIFY -D cn=config -H $URI1 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+ RC=$?
+ case $RC in
+ 0)
+ echo "ldapmodify should have failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+ ;;
+ 80)
+ echo "ldapmodify failed ($RC)"
+ ;;
+ *)
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ ;;
+ esac
+done
+
+# We run this search after the changes above and before restart so we can also
+# check the reconfiguration attempts actually had no side effects
+echo "Saving search output before server restart..."
+echo "# search output from dynamically configured server..." >> $SERVER6OUT
+$LDAPSEARCH -b "$BASEDN" -H $URI1 \
+ >> $SERVER6OUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Stopping slapd on TCP/IP port $PORT1..."
+kill -HUP $KILLPIDS
+KILLPIDS=""
+sleep $SLEEP0
+echo "Starting slapd on TCP/IP port $PORT1..."
+$SLAPD -F $TESTDIR/confdir -h $URI1 -d $LVL >> $LOG1 2>&1 &
+PID=$!
+if test $WAIT != 0 ; then
+ echo PID $PID
+ read foo
+fi
+KILLPIDS="$PID"
+
+sleep $SLEEP0
+
+for i in 0 1 2 3 4 5; do
+ $LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
+ 'objectclass=*' > /dev/null 2>&1
+ RC=$?
+ if test $RC = 0 ; then
+ break
+ fi
+ echo "Waiting ${SLEEP1} seconds for slapd to start..."
+ sleep ${SLEEP1}
+done
+
+echo "Testing slapd.conf support..."
+mkdir $TESTDIR/conftest $DBDIR2
+. $CONFFILTER $BACKEND $MONITORDB < $CONFTWO \
+ | sed -e '/^argsfile.*/a\
+moduleload ../datamorph.la' \
+ -e '/database.*monitor/i\
+include data/datamorph.conf' \
+ > $CONF2
+echo "database config" >>$CONF2
+echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >>$CONF2
+
+$SLAPADD -f $CONF2 -l data/test.ldif
+RC=$?
+if test $RC != 0 ; then
+ echo "slapadd failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Starting slapd on TCP/IP port $PORT2..."
+$SLAPD -f $CONF2 -h $URI2 -d $LVL >> $LOG2 2>&1 &
+PID=$!
+if test $WAIT != 0 ; then
+ echo PID $PID
+ read foo
+fi
+
+sleep $SLEEP0
+
+for i in 0 1 2 3 4 5; do
+ $LDAPSEARCH -s base -b "$MONITOR" -H $URI2 \
+ 'objectclass=*' > /dev/null 2>&1
+ RC=$?
+ if test $RC = 0 ; then
+ break
+ fi
+ echo "Waiting ${SLEEP1} seconds for slapd to start..."
+ sleep ${SLEEP1}
+done
+
+echo "# search output from server running from slapd.conf..." >> $SERVER2OUT
+$LDAPSEARCH -b "$BASEDN" -H $URI2 \
+ >> $SERVER2OUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Stopping slapd on TCP/IP port $PORT2..."
+kill -HUP $PID
+
+$SLAPD -Tt -f $CONF2 -F $TESTDIR/conftest -d $LVL >> $LOG3 2>&1
+
+echo "Starting slapd on TCP/IP port $PORT2..."
+$SLAPD -F $TESTDIR/conftest -h $URI2 -d $LVL >> $LOG3 2>&1 &
+PID=$!
+if test $WAIT != 0 ; then
+ echo PID $PID
+ read foo
+fi
+KILLPIDS="$KILLPIDS $PID"
+
+sleep $SLEEP0
+
+for i in 0 1 2 3 4 5; do
+ $LDAPSEARCH -s base -b "$MONITOR" -H $URI2 \
+ 'objectclass=*' > /dev/null 2>&1
+ RC=$?
+ if test $RC = 0 ; then
+ break
+ fi
+ echo "Waiting ${SLEEP1} seconds for slapd to start..."
+ sleep ${SLEEP1}
+done
+
+echo "Gathering overlay configuration from both servers..."
+echo "# overlay configuration from dynamically configured server..." >> $SERVER1OUT
+$LDAPSEARCH -D cn=config -H $URI1 -y $CONFIGPWF \
+ -b "olcOverlay={0}datamorph,olcDatabase={1}$BACKEND,cn=config" \
+ | sed -e "s/ {[0-9]*}/ /" -e "s/={[0-9]*}/=/g" \
+ >> $SERVER1OUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "# overlay configuration from server configured from slapd.conf..." >> $SERVER3OUT
+$LDAPSEARCH -D cn=config -H $URI2 -y $CONFIGPWF \
+ -b "olcOverlay={0}datamorph,olcDatabase={1}$BACKEND,cn=config" \
+ | sed -e "s/ {[0-9]*}/ /" -e "s/={[0-9]*}/=/g" \
+ >> $SERVER3OUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+# We've already filtered out the ordering markers, now sort the entries
+echo "Filtering ldapsearch results..."
+$LDIFFILTER -s e < $SERVER3OUT > $SERVER3FLT
+echo "Filtering expected entries..."
+$LDIFFILTER -s e < $SERVER1OUT > $SERVER1FLT
+echo "Comparing filter output..."
+$CMP $SERVER3FLT $SERVER1FLT > $CMPOUT
+
+if test $? != 0 ; then
+ echo "Comparison failed"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+fi
+
+rm $SERVER1OUT $SERVER3OUT
+
+echo "Comparing search output on both servers..."
+echo "# search output from dynamically configured server..." >> $SERVER1OUT
+$LDAPSEARCH -b "$BASEDN" -H $URI1 \
+ >> $SERVER1OUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "# search output from server configured from slapd.conf..." >> $SERVER3OUT
+$LDAPSEARCH -b "$BASEDN" -H $URI2 \
+ >> $SERVER3OUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+test $KILLSERVERS != no && kill -HUP $KILLPIDS
+
+echo "Filtering ldapsearch results..."
+$LDIFFILTER -s e < $SERVER1OUT > $SERVER1FLT
+$LDIFFILTER -s e < $SERVER2OUT > $SERVER2FLT
+$LDIFFILTER -s e < $SERVER3OUT > $SERVER3FLT
+echo "Filtering expected entries..."
+$LDIFFILTER -s e < $SERVER6OUT > $SERVER6FLT
+echo "Comparing filter output..."
+$CMP $SERVER6FLT $SERVER1FLT > $CMPOUT && \
+$CMP $SERVER6FLT $SERVER2FLT > $CMPOUT && \
+$CMP $SERVER6FLT $SERVER3FLT > $CMPOUT
+
+if test $? != 0 ; then
+ echo "Comparison failed"
+ exit 1
+fi
+
+echo ">>>>> Test succeeded"
+
+test $KILLSERVERS != no && wait
+
+exit 0
diff --git a/contrib/slapd-modules/datamorph/tests/scripts/test002-add-delete b/contrib/slapd-modules/datamorph/tests/scripts/test002-add-delete
new file mode 100755
index 0000000..f947d09
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/scripts/test002-add-delete
@@ -0,0 +1,147 @@
+#! /bin/sh
+## $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 2016-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+##
+## ACKNOWLEDGEMENTS:
+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
+
+echo "running defines.sh"
+. $SRCDIR/scripts/defines.sh
+
+. ${SCRIPTDIR}/common.sh
+
+echo "Adding entries (should fail this time)..."
+$LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
+ -c -f data/test002-entry.ldif >> $TESTOUT 2>&1
+RC=$?
+case $RC in
+0)
+ echo "ldapmodify should have failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+ ;;
+19)
+ echo "ldapmodify failed ($RC)"
+ ;;
+*)
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ ;;
+esac
+
+echo "Adding other entries (should fail)..."
+$LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
+ -f data/test002-fail.ldif >> $TESTOUT 2>&1
+RC=$?
+case $RC in
+0)
+ echo "ldapmodify should have failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+ ;;
+19)
+ echo "ldapmodify failed ($RC)"
+ ;;
+*)
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ ;;
+esac
+
+$LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
+ -f data/test002-transformed-rdn.ldif >> $TESTOUT 2>&1
+RC=$?
+case $RC in
+0)
+ echo "ldapmodify should have failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+ ;;
+32)
+ echo "ldapmodify failed ($RC)"
+ ;;
+*)
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ ;;
+esac
+
+echo "Configuring new value..."
+. $CONFFILTER $BACKEND $MONITORDB < data/test002-config.ldif | \
+$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Adding some of the entries again..."
+$LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
+ -f data/test002-entry.ldif >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Saving search output..."
+$LDAPSEARCH -H $URI1 -b "$BASEDN" \
+ "(|(cn=Gern Jensen)(ou=New Unit))" \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Removing entry..."
+$LDAPDELETE -D $MANAGERDN -H $URI1 -w $PASSWD \
+ "cn=Gern Jensen,ou=Information Technology Division,ou=People,$BASEDN" \
+ "ou=New Unit,$BASEDN" \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapdelete failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+test $KILLSERVERS != no && kill -HUP $KILLPIDS
+
+LDIF=data/test002-entry.ldif
+
+echo "Filtering ldapsearch results..."
+$LDIFFILTER -s ae < $SEARCHOUT > $SEARCHFLT
+echo "Filtering expected entries..."
+$LDIFFILTER -s ae < $LDIF | grep -v '^changetype:' > $LDIFFLT
+echo "Comparing filter output..."
+$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
+
+if test $? != 0 ; then
+ echo "Comparison failed"
+ exit 1
+fi
+
+echo ">>>>> Test succeeded"
+
+test $KILLSERVERS != no && wait
+
+exit 0
diff --git a/contrib/slapd-modules/datamorph/tests/scripts/test003-search b/contrib/slapd-modules/datamorph/tests/scripts/test003-search
new file mode 100755
index 0000000..9afe677
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/scripts/test003-search
@@ -0,0 +1,106 @@
+#! /bin/sh
+## $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 2016-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+##
+## ACKNOWLEDGEMENTS:
+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
+
+echo "running defines.sh"
+. $SRCDIR/scripts/defines.sh
+
+. ${SCRIPTDIR}/common.sh
+
+echo "Testing searches against regular entries..."
+echo "# Testing searches against regular entries..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI1 "(|(ou=Groups)(st=*))" \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Testing searches listing transformed attributes..."
+echo >> $SEARCHOUT
+echo "# Testing searches listing transformed attributes..." >> $SEARCHOUT
+$LDAPSEARCH -b "ou=Information Technology Division,ou=People,$BASEDN" -s one \
+ -H $URI1 >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Testing searches filtering on transformed attributes..."
+echo >> $SEARCHOUT
+echo "# Testing searches filtering on transformed attributes..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI1 \
+ "(|(enumerated=bjensen)(&(signed=-19858)(signed<=0)(signed>=-20000)))" \
+ enumerated signed \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Reconfiguring transformation definition..."
+. $CONFFILTER $BACKEND $MONITORDB < data/test003-config.ldif | \
+$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Testing searches filtering on the new values..."
+echo >> $SEARCHOUT
+echo "# Testing searches filtering on the new values..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI1 \
+ "(|(enumerated=not a value)(enumerated=jaj)(&(signed=45678)(!(signed>=50000))(signed>=44444)))" \
+ enumerated signed \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+test $KILLSERVERS != no && kill -HUP $KILLPIDS
+
+LDIF=data/test003-out.ldif
+
+echo "Filtering ldapsearch results..."
+$LDIFFILTER -s e < $SEARCHOUT > $SEARCHFLT
+echo "Filtering expected entries..."
+$LDIFFILTER -s e < $LDIF > $LDIFFLT
+echo "Comparing filter output..."
+$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
+
+if test $? != 0 ; then
+ echo "Comparison failed"
+ exit 1
+fi
+
+echo ">>>>> Test succeeded"
+
+test $KILLSERVERS != no && wait
+
+exit 0
diff --git a/contrib/slapd-modules/datamorph/tests/scripts/test004-compare b/contrib/slapd-modules/datamorph/tests/scripts/test004-compare
new file mode 100755
index 0000000..d4b535b
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/scripts/test004-compare
@@ -0,0 +1,62 @@
+#! /bin/sh
+## $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 2016-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+##
+## ACKNOWLEDGEMENTS:
+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
+
+echo "running defines.sh"
+. $SRCDIR/scripts/defines.sh
+
+. ${SCRIPTDIR}/common.sh
+
+echo "Comparing a regular entry..."
+$LDAPCOMPARE -H $URI1 \
+ "cn=Mark Elliot,ou=Alumni Association,ou=People,$BASEDN" \
+ "cn:Mark Elliot" >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 6 && test $RC,$BACKEND != 5,null ; then
+ echo "ldapcompare failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+fi
+
+echo "Comparing a transformed enum entry..."
+$LDAPCOMPARE -H $URI1 \
+ "cn=Jane Doe,ou=Alumni Association,ou=People,$BASEDN" \
+ "enumerated:jdoe" >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 6 && test $RC,$BACKEND != 5,null ; then
+ echo "ldapcompare failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+fi
+
+echo "Comparing a transformed interval entry..."
+$LDAPCOMPARE -H $URI1 "ou=People,$BASEDN" \
+ "signed:-19858" >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 6 && test $RC,$BACKEND != 5,null ; then
+ echo "ldapcompare failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+fi
+
+test $KILLSERVERS != no && kill -HUP $KILLPIDS
+
+echo ">>>>> Test succeeded"
+
+test $KILLSERVERS != no && wait
+
+exit 0
diff --git a/contrib/slapd-modules/datamorph/tests/scripts/test005-modify b/contrib/slapd-modules/datamorph/tests/scripts/test005-modify
new file mode 100755
index 0000000..94cf1c0
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/scripts/test005-modify
@@ -0,0 +1,89 @@
+#! /bin/sh
+## $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 2016-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+##
+## ACKNOWLEDGEMENTS:
+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
+
+echo "running defines.sh"
+. $SRCDIR/scripts/defines.sh
+
+. ${SCRIPTDIR}/common.sh
+
+echo "Modifying entry..."
+$LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
+ -f data/test005-changes.ldif >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Applying invalid changes (should fail)..."
+for CHANGE in data/test005-*fail.ldif; do
+ echo "... $CHANGE"
+ $LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
+ -f $CHANGE >> $TESTOUT 2>&1
+ RC=$?
+ case $RC in
+ 0)
+ echo "ldapmodify should have failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+ ;;
+ 16|19)
+ echo "ldapmodify failed ($RC)"
+ ;;
+ *)
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ ;;
+ esac
+done
+
+echo "Reading affected entries back..."
+echo "# Reading affected entries back..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI1 \
+ '(|(objectClass=OpenLDAPperson)(ou=people))' \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+test $KILLSERVERS != no && kill -HUP $KILLPIDS
+
+LDIF=data/test005-out.ldif
+
+echo "Filtering ldapsearch results..."
+$LDIFFILTER -s e < $SEARCHOUT > $SEARCHFLT
+echo "Filtering expected entries..."
+$LDIFFILTER -s e < $LDIF > $LDIFFLT
+echo "Comparing filter output..."
+$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
+
+if test $? != 0 ; then
+ echo "Comparison failed"
+ exit 1
+fi
+
+echo ">>>>> Test succeeded"
+
+test $KILLSERVERS != no && wait
+
+exit 0
diff --git a/contrib/slapd-modules/datamorph/tests/scripts/test006-modrdn b/contrib/slapd-modules/datamorph/tests/scripts/test006-modrdn
new file mode 100755
index 0000000..56e2f2a
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/scripts/test006-modrdn
@@ -0,0 +1,52 @@
+#! /bin/sh
+## $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 2016-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+##
+## ACKNOWLEDGEMENTS:
+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
+
+echo "running defines.sh"
+. $SRCDIR/scripts/defines.sh
+
+. ${SCRIPTDIR}/common.sh
+
+echo "Renaming an entry to add new value (should fail)..."
+$LDAPMODRDN -D $MANAGERDN -H $URI1 -w $PASSWD \
+ "cn=Mark Elliot,ou=Alumni Association,ou=People,$BASEDN" \
+ "cn=Mark Elliot+enumerated=melliot" \
+ >> $TESTOUT 2>&1
+RC=$?
+case $RC in
+0)
+ echo "ldapmodrdn should have failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+ ;;
+19)
+ echo "ldapmodrdn failed ($RC)"
+ ;;
+*)
+ echo "ldapmodrdn failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ ;;
+esac
+
+test $KILLSERVERS != no && kill -HUP $KILLPIDS
+
+echo ">>>>> Test succeeded"
+
+test $KILLSERVERS != no && wait
+
+exit 0
diff --git a/contrib/slapd-modules/datamorph/tests/scripts/test007-transformed-replication b/contrib/slapd-modules/datamorph/tests/scripts/test007-transformed-replication
new file mode 100755
index 0000000..5b2ea4d
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/scripts/test007-transformed-replication
@@ -0,0 +1,296 @@
+#! /bin/sh
+## $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 2016-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+##
+## ACKNOWLEDGEMENTS:
+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
+
+echo "running defines.sh"
+. $SRCDIR/scripts/defines.sh
+
+if test "$SYNCPROV" = syncprovno; then
+ echo "Syncrepl provider overlay not available, test skipped"
+ exit 0
+fi
+
+. ${SCRIPTDIR}/common.sh
+
+if test "$SYNCPROV" = syncprovmod; then
+ $LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ > $TESTOUT 2>&1 <<EOMOD
+dn: cn=module,cn=config
+changetype: add
+objectClass: olcModuleList
+olcModuleLoad: $LDAP_BUILD/servers/slapd/overlays/syncprov.la
+EOMOD
+
+ RC=$?
+ if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ fi
+fi
+
+mkdir $DBDIR4 $TESTDIR/confdir-consumer
+
+echo "Starting consumer slapd on TCP/IP port $PORT4..."
+. $CONFFILTER $BACKEND $MONITORDB < $P1SRCONSUMERCONF > $CONF4
+
+echo "database config" >>$CONF4
+echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >>$CONF4
+
+$SLAPD -f $CONF4 -F $TESTDIR/confdir-consumer -h $URI4 -d $LVL > $LOG4 2>&1 &
+CONSUMERPID=$!
+if test $WAIT != 0 ; then
+ echo CONSUMERPID $CONSUMERPID
+ read foo
+fi
+KILLPIDS="$KILLPIDS $CONSUMERPID"
+
+sleep $SLEEP0
+
+echo "Setting up overlay on consumer..."
+$LDAPMODIFY -v -D cn=config -H $URI4 -y $CONFIGPWF \
+ > $TESTOUT 2>&1 <<EOMOD
+dn: cn=module,cn=config
+changetype: add
+objectClass: olcModuleList
+olcModuleLoad: `pwd`/../datamorph.la
+EOMOD
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Configuring syncprov on provider..."
+$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ > $TESTOUT 2>&1 <<EOMOD
+dn: olcOverlay=syncprov,olcDatabase={1}$BACKEND,cn=config
+changetype: add
+objectclass: olcSyncProvConfig
+EOMOD
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+. $CONFFILTER $BACKEND $MONITORDB < $OVERLAY_CONFIG | \
+$LDAPMODIFY -v -D cn=config -H $URI4 -y $CONFIGPWF \
+ > $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+for i in 0 1 2 3 4 5; do
+ $LDAPSEARCH -s base -b "$BASEDN" -H $URI4 \
+ 'objectclass=*' > /dev/null 2>&1
+ RC=$?
+ if test $RC = 0 ; then
+ break
+ fi
+ echo "Waiting ${SLEEP1} seconds for consumer to start replication..."
+ sleep ${SLEEP1}
+done
+
+echo "Waiting ${SLEEP1} seconds for consumer to finish replicating..."
+sleep ${SLEEP1}
+
+echo "Testing searches against regular replicated entries..."
+echo "# Testing searches against regular replicated entries..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI4 "(|(ou=Groups)(st=*))" \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Testing searches listing replicated transformed attributes..."
+echo >> $SEARCHOUT
+echo "# Testing searches listing replicated transformed attributes..." >> $SEARCHOUT
+$LDAPSEARCH -b "ou=Information Technology Division,ou=People,$BASEDN" \
+ -s one -H $URI4 \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Testing searches filtering on replicated transformed attributes..."
+echo >> $SEARCHOUT
+echo "# Testing searches filtering on replicated transformed attributes..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI4 \
+ "(|(enumerated=bjensen)(&(signed=-19858)(signed<=0)(signed>=-20000)))" \
+ enumerated signed \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Reconfiguring transformation definition..."
+. $CONFFILTER $BACKEND $MONITORDB < data/test003-config.ldif | \
+$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+. $CONFFILTER $BACKEND $MONITORDB < data/test003-config.ldif | \
+$LDAPMODIFY -v -D cn=config -H $URI4 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Testing searches filtering on the new replicated values..."
+echo >> $SEARCHOUT
+echo "# Testing searches filtering on the new replicated values..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI4 \
+ "(|(enumerated=not a value)(enumerated=jaj)(&(signed=45678)(!(signed>=50000))(signed>=44444)))" \
+ enumerated signed \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+LDIF=data/test003-out.ldif
+
+echo "Filtering ldapsearch results..."
+$LDIFFILTER -s e < $SEARCHOUT > $SEARCHFLT
+echo "Filtering expected entries..."
+$LDIFFILTER -s e < $LDIF > $LDIFFLT
+echo "Comparing filter output..."
+$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
+
+if test $? != 0 ; then
+ echo "Comparison failed"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+fi
+
+rm $SEARCHOUT
+
+echo "Reverting part of the above configuration for remainder of the test..."
+. $CONFFILTER $BACKEND $MONITORDB < data/test007-config.ldif | \
+$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+. $CONFFILTER $BACKEND $MONITORDB < data/test007-config.ldif | \
+$LDAPMODIFY -v -D cn=config -H $URI4 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Modifying entry..."
+$LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
+ -f data/test005-changes.ldif >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Applying invalid changes (should fail)..."
+for CHANGE in data/test005-*fail.ldif; do
+ echo "... $CHANGE"
+ $LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
+ -f $CHANGE >> $TESTOUT 2>&1
+ RC=$?
+ case $RC in
+ 0)
+ echo "ldapmodify should have failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+ ;;
+ 16|19)
+ echo "ldapmodify failed ($RC)"
+ ;;
+ *)
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ ;;
+ esac
+done
+
+echo "Waiting ${SLEEP1} seconds for consumer to finish replicating..."
+sleep ${SLEEP1}
+
+echo "Reading affected entries back..."
+echo "# Reading affected entries back..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI1 \
+ '(|(objectClass=OpenLDAPperson)(ou=people))' \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+test $KILLSERVERS != no && kill -HUP $KILLPIDS
+
+LDIF=data/test005-out.ldif
+
+echo "Filtering ldapsearch results..."
+$LDIFFILTER -s e < $SEARCHOUT > $SEARCHFLT
+echo "Filtering expected entries..."
+$LDIFFILTER -s e < $LDIF > $LDIFFLT
+echo "Comparing filter output..."
+$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
+
+if test $? != 0 ; then
+ echo "Comparison failed"
+ exit 1
+fi
+
+echo ">>>>> Test succeeded"
+
+test $KILLSERVERS != no && wait
+
+exit 0
diff --git a/contrib/slapd-modules/datamorph/tests/scripts/test008-ignored-replication b/contrib/slapd-modules/datamorph/tests/scripts/test008-ignored-replication
new file mode 100755
index 0000000..a1fcb71
--- /dev/null
+++ b/contrib/slapd-modules/datamorph/tests/scripts/test008-ignored-replication
@@ -0,0 +1,299 @@
+#! /bin/sh
+## $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 2016-2022 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+##
+## ACKNOWLEDGEMENTS:
+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
+
+echo "running defines.sh"
+. $SRCDIR/scripts/defines.sh
+
+if test "$SYNCPROV" = syncprovno; then
+ echo "Syncrepl provider overlay not available, test skipped"
+ exit 0
+fi
+
+. ${SCRIPTDIR}/common.sh
+
+if test "$SYNCPROV" = syncprovmod; then
+ $LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ > $TESTOUT 2>&1 <<EOMOD
+dn: cn=module,cn=config
+changetype: add
+objectClass: olcModuleList
+olcModuleLoad: $LDAP_BUILD/servers/slapd/overlays/syncprov.la
+EOMOD
+
+ RC=$?
+ if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ fi
+fi
+
+mkdir $DBDIR4 $TESTDIR/confdir-consumer
+
+echo "Starting consumer slapd on TCP/IP port $PORT4..."
+. $CONFFILTER $BACKEND $MONITORDB < $P1SRCONSUMERCONF > $CONF4
+
+echo "database config" >>$CONF4
+echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >>$CONF4
+
+$SLAPD -f $CONF4 -F $TESTDIR/confdir-consumer -h $URI4 -d $LVL > $LOG4 2>&1 &
+CONSUMERPID=$!
+if test $WAIT != 0 ; then
+ echo CONSUMERPID $CONSUMERPID
+ read foo
+fi
+KILLPIDS="$KILLPIDS $CONSUMERPID"
+
+sleep $SLEEP0
+
+echo "Setting up overlay on consumer..."
+$LDAPMODIFY -v -D cn=config -H $URI4 -y $CONFIGPWF \
+ > $TESTOUT 2>&1 <<EOMOD
+dn: cn=module,cn=config
+changetype: add
+objectClass: olcModuleList
+olcModuleLoad: `pwd`/../datamorph.la
+EOMOD
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Configuring syncprov on provider..."
+$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ > $TESTOUT 2>&1 <<EOMOD
+dn: olcOverlay={0}syncprov,olcDatabase={1}$BACKEND,cn=config
+changetype: add
+objectclass: olcSyncProvConfig
+EOMOD
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+. $CONFFILTER $BACKEND $MONITORDB < $OVERLAY_CONFIG | \
+$LDAPMODIFY -v -D cn=config -H $URI4 -y $CONFIGPWF \
+ > $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+for i in 0 1 2 3 4 5; do
+ $LDAPSEARCH -s base -b "$BASEDN" -H $URI4 \
+ 'objectclass=*' > /dev/null 2>&1
+ RC=$?
+ if test $RC = 0 ; then
+ break
+ fi
+ echo "Waiting ${SLEEP1} seconds for consumer to start replication..."
+ sleep ${SLEEP1}
+done
+
+echo "Waiting ${SLEEP1} seconds for consumer to finish replicating..."
+sleep ${SLEEP1}
+
+echo "Testing searches against regular replicated entries..."
+echo "# Testing searches against regular replicated entries..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI4 "(|(ou=Groups)(st=*))" \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Testing searches listing replicated transformed attributes..."
+echo >> $SEARCHOUT
+echo "# Testing searches listing replicated transformed attributes..." >> $SEARCHOUT
+$LDAPSEARCH -b "ou=Information Technology Division,ou=People,$BASEDN" -s one \
+ -H $URI4 \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Testing searches filtering on replicated transformed attributes..."
+echo >> $SEARCHOUT
+echo "# Testing searches filtering on replicated transformed attributes..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI4 \
+ "(|(enumerated=bjensen)(&(signed=-19858)(signed<=0)(signed>=-20000)))" \
+ enumerated signed \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Reconfiguring transformation definition..."
+. $CONFFILTER $BACKEND $MONITORDB < data/test003-config.ldif | \
+sed 's/{0}datamorph/{1}datamorph/' | \
+$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+. $CONFFILTER $BACKEND $MONITORDB < data/test003-config.ldif | \
+$LDAPMODIFY -v -D cn=config -H $URI4 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Testing searches filtering on the new replicated values..."
+echo >> $SEARCHOUT
+echo "# Testing searches filtering on the new replicated values..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI4 \
+ "(|(enumerated=not a value)(enumerated=jaj)(&(signed=45678)(!(signed>=50000))(signed>=44444)))" \
+ enumerated signed \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+LDIF=data/test003-out.ldif
+
+echo "Filtering ldapsearch results..."
+$LDIFFILTER -s e < $SEARCHOUT > $SEARCHFLT
+echo "Filtering expected entries..."
+$LDIFFILTER -s e < $LDIF > $LDIFFLT
+echo "Comparing filter output..."
+$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
+
+if test $? != 0 ; then
+ echo "Comparison failed"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+fi
+
+rm $SEARCHOUT
+
+echo "Reverting part of the above configuration for remainder of the test..."
+. $CONFFILTER $BACKEND $MONITORDB < data/test007-config.ldif | \
+sed 's/{0}datamorph/{1}datamorph/' | \
+$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+. $CONFFILTER $BACKEND $MONITORDB < data/test007-config.ldif | \
+$LDAPMODIFY -v -D cn=config -H $URI4 -y $CONFIGPWF \
+ >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Modifying entry..."
+$LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
+ -f data/test005-changes.ldif >> $TESTOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Applying invalid changes (should fail)..."
+for CHANGE in data/test005-*fail.ldif; do
+ echo "... $CHANGE"
+ $LDAPMODIFY -D $MANAGERDN -H $URI1 -w $PASSWD \
+ -f $CHANGE >> $TESTOUT 2>&1
+ RC=$?
+ case $RC in
+ 0)
+ echo "ldapmodify should have failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit 1
+ ;;
+ 16|19)
+ echo "ldapmodify failed ($RC)"
+ ;;
+ *)
+ echo "ldapmodify failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+ ;;
+ esac
+done
+
+echo "Waiting ${SLEEP1} seconds for consumer to finish replicating..."
+sleep ${SLEEP1}
+
+echo "Reading affected entries back..."
+echo "# Reading affected entries back..." >> $SEARCHOUT
+$LDAPSEARCH -b "$BASEDN" -H $URI1 \
+ '(|(objectClass=OpenLDAPperson)(ou=people))' \
+ >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+test $KILLSERVERS != no && kill -HUP $KILLPIDS
+
+LDIF=data/test005-out.ldif
+
+echo "Filtering ldapsearch results..."
+$LDIFFILTER -s e < $SEARCHOUT > $SEARCHFLT
+echo "Filtering expected entries..."
+$LDIFFILTER -s e < $LDIF > $LDIFFLT
+echo "Comparing filter output..."
+$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
+
+
+if test $? != 0 ; then
+ echo "Comparison failed"
+ exit 1
+fi
+
+echo ">>>>> Test succeeded"
+
+test $KILLSERVERS != no && wait
+
+exit 0