1#! /bin/sh
2# $OpenLDAP$
3## This work is part of OpenLDAP Software <http://www.openldap.org/>.
4##
5## Copyright 1998-2011 The OpenLDAP Foundation.
6## All rights reserved.
7##
8## Redistribution and use in source and binary forms, with or without
9## modification, are permitted only as authorized by the OpenLDAP
10## Public License.
11##
12## A copy of this license is available in the file LICENSE in the
13## top-level directory of the distribution or, alternatively, at
14## <http://www.OpenLDAP.org/license.html>.
15
16echo "running defines.sh"
17. $SRCDIR/scripts/defines.sh
18
19if test $SYNCPROV = syncprovno; then 
20	echo "Syncrepl provider overlay not available, test skipped"
21	exit 0
22fi 
23
24CFPRO=$TESTDIR/cfpro.d
25CFCON=$TESTDIR/cfcon.d
26
27mkdir -p $TESTDIR $DBDIR1A $DBDIR1B $DBDIR2A $CFPRO $CFCON
28
29$SLAPPASSWD -g -n >$CONFIGPWF
30
31if test x"$SYNCMODE" = x ; then
32	SYNCMODE=rp
33fi
34case "$SYNCMODE" in
35	ro)
36		SYNCTYPE="type=refreshOnly interval=00:00:00:03"
37		;;
38	rp)
39		SYNCTYPE="type=refreshAndPersist"
40		;;
41	*)
42		echo "unknown sync mode $SYNCMODE"
43		exit 1;
44		;;
45esac
46
47#
48# Test replication of dynamic config with alternate slave config:
49# - start provider
50# - start consumer
51# - configure over ldap
52# - populate over ldap
53# - configure syncrepl over ldap
54# - retrieve database over ldap and compare against expected results
55#
56
57echo "Starting provider slapd on TCP/IP port $PORT1..."
58. $CONFFILTER $BACKEND $MONITORDB < $DYNAMICCONF > $CONFLDIF
59$SLAPADD -F $CFPRO -n 0 -l $CONFLDIF
60$SLAPD -F $CFPRO -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 &
61PID=$!
62if test $WAIT != 0 ; then
63    echo PID $PID
64    read foo
65fi
66KILLPIDS="$PID"
67
68sleep 1
69
70echo "Using ldapsearch to check that provider slapd is running..."
71for i in 0 1 2 3 4 5; do
72	$LDAPSEARCH -s base -b "" -H $URI1 \
73		'objectclass=*' > /dev/null 2>&1
74	RC=$?
75	if test $RC = 0 ; then
76		break
77	fi
78	echo "Waiting 5 seconds for slapd to start..."
79	sleep 5
80done
81
82if test $RC != 0 ; then
83	echo "ldapsearch failed ($RC)!"
84	test $KILLSERVERS != no && kill -HUP $KILLPIDS
85	exit $RC
86fi
87
88echo "Inserting syncprov overlay on provider..."
89if [ "$SYNCPROV" = syncprovmod ]; then
90	$LDAPADD -D cn=config -H $URI1 -y $CONFIGPWF <<EOF > $TESTOUT 2>&1
91dn: cn=module,cn=config
92objectClass: olcModuleList
93cn: module
94olcModulePath: ../servers/slapd/overlays
95olcModuleLoad: syncprov.la
96EOF
97	RC=$?
98	if test $RC != 0 ; then
99		echo "ldapadd failed for moduleLoad ($RC)!"
100		test $KILLSERVERS != no && kill -HUP $KILLPIDS
101		exit $RC
102	fi
103fi
104read CONFIGPW < $CONFIGPWF
105$LDAPMODIFY -D cn=config -H $URI1 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
106dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config
107changetype: add
108objectClass: olcOverlayConfig
109objectClass: olcSyncProvConfig
110olcOverlay: syncprov
111EOF
112RC=$?
113if test $RC != 0 ; then
114	echo "ldapmodify failed for syncprov config ($RC)!"
115	test $KILLSERVERS != no && kill -HUP $KILLPIDS
116	exit $RC
117fi
118
119# Slaves will not replicate the master's actual cn=config.
120# Instead, they will use an alternate DB so that they may be
121# configured differently from the master. This alternate DB
122# will also be a consumer for the real cn=schema,cn=config tree.
123# It has MirrorMode enabled so that it can be written directly
124# while being a slave of the main schema.
125echo "Configuring slave config DB on provider..."
126$LDAPMODIFY -D cn=config -H $URI1 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
127dn: cn=config
128changetype: modify
129add: olcServerID
130olcServerID: 1
131
132dn: olcDatabase={1}ldif,cn=config
133changetype: add
134objectClass: olcDatabaseConfig
135objectClass: olcLdifConfig
136olcDatabase: {1}ldif
137olcDbDirectory: $DBDIR1A
138olcSuffix: cn=config,cn=slave
139olcRootDN: cn=config,cn=slave
140olcRootPW: repsecret
141olcAccess: to * by dn.base="cn=config" write
142
143dn: olcOverlay=syncprov,olcDatabase={1}ldif,cn=config
144changetype: add
145objectClass: olcOverlayConfig
146objectClass: olcSyncProvConfig
147olcOverlay: syncprov
148
149dn: cn=config,cn=slave
150changetype: add
151objectClass: olcGlobal
152cn: slaveconfig
153
154dn: cn=schema,cn=config,cn=slave
155changetype: add
156objectClass: olcSchemaConfig
157cn: schema
158
159dn: olcDatabase={0}config,cn=config,cn=slave
160changetype: add
161objectClass: olcDatabaseConfig
162olcDatabase: {0}config
163olcRootPW: topsecret
164olcSyncrepl: {0}rid=001 provider=$URI1 binddn="cn=config,cn=slave"
165  bindmethod=simple credentials=repsecret searchbase="cn=config,cn=slave"
166  $SYNCTYPE retry="3 5 300 5" timeout=3 suffixmassage="cn=config"
167olcUpdateRef: $URI1
168
169dn: olcDatabase={1}ldif,cn=config
170changetype: modify
171add: olcSyncrepl
172olcSyncrepl: {0}rid=001 provider=$URI1 binddn="cn=config"
173  bindmethod=simple credentials=$CONFIGPW searchbase="cn=schema,cn=config"
174  $SYNCTYPE retry="3 5 300 5" timeout=3
175  suffixmassage="cn=schema,cn=config,cn=slave"
176-
177add: olcMirrorMode
178olcMirrorMode: TRUE
179
180EOF
181RC=$?
182if test $RC != 0 ; then
183	echo "ldapmodify failed for slave DB config ($RC)!"
184	test $KILLSERVERS != no && kill -HUP $KILLPIDS
185	exit $RC
186fi
187
188echo "Starting consumer slapd on TCP/IP port $PORT2..."
189$SLAPADD -F $CFCON -n 0 -l $CONFLDIF
190$SLAPD -F $CFCON -h $URI2 -d $LVL $TIMING > $LOG2 2>&1 &
191SLAVEPID=$!
192if test $WAIT != 0 ; then
193    echo SLAVEPID $SLAVEPID
194    read foo
195fi
196KILLPIDS="$KILLPIDS $SLAVEPID"
197
198sleep 1
199
200echo "Using ldapsearch to check that consumer slapd is running..."
201for i in 0 1 2 3 4 5; do
202	$LDAPSEARCH -s base -b "" -H $URI2 \
203		'objectclass=*' > /dev/null 2>&1
204	RC=$?
205	if test $RC = 0 ; then
206		break
207	fi
208	echo "Waiting 5 seconds for slapd to start..."
209	sleep 5
210done
211
212if test $RC != 0 ; then
213	echo "ldapsearch failed ($RC)!"
214	test $KILLSERVERS != no && kill -HUP $KILLPIDS
215	exit $RC
216fi
217
218echo "Configuring syncrepl on consumer..."
219$LDAPMODIFY -D cn=config -H $URI2 -y $CONFIGPWF <<EOF >>$TESTOUT 2>&1
220dn: olcDatabase={0}config,cn=config
221changetype: modify
222add: olcSyncRepl
223olcSyncRepl: rid=001 provider=$URI1 binddn="cn=config,cn=slave"
224  bindmethod=simple credentials=repsecret searchbase="cn=config,cn=slave"
225  $SYNCTYPE retry="3 5 300 5" timeout=3
226  suffixmassage="cn=config"
227-
228add: olcUpdateRef
229olcUpdateRef: $URI1
230EOF
231
232echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
233sleep $SLEEP1
234
235echo "Using ldapsearch to check that syncrepl received config changes..."
236RC=32
237for i in 0 1 2 3 4 5; do
238	RESULT=`$LDAPSEARCH -H $URI2 -D cn=config -y $CONFIGPWF \
239		-s base -b "olcDatabase={0}config,cn=config" \
240		'(olcUpdateRef=*)' 2>&1 | awk '/^dn:/ {print "OK"}'`
241	if test "x$RESULT" = "xOK" ; then
242		RC=0
243		break
244	fi
245	echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
246	sleep $SLEEP1
247done
248
249if test $RC != 0 ; then
250	echo "ldapsearch failed ($RC)!"
251	test $KILLSERVERS != no && kill -HUP $KILLPIDS
252	exit $RC
253fi
254
255echo "Adding schema and databases on provider..."
256$LDAPADD -D cn=config -H $URI1 -y $CONFIGPWF <<EOF >>$TESTOUT 2>&1
257include: file://$ABS_SCHEMADIR/core.ldif
258
259include: file://$ABS_SCHEMADIR/cosine.ldif
260
261include: file://$ABS_SCHEMADIR/inetorgperson.ldif
262
263include: file://$ABS_SCHEMADIR/openldap.ldif
264
265include: file://$ABS_SCHEMADIR/nis.ldif
266EOF
267RC=$?
268if test $RC != 0 ; then
269	echo "ldapadd failed for schema config ($RC)!"
270	test $KILLSERVERS != no && kill -HUP $KILLPIDS
271	exit $RC
272fi
273
274nullExclude="" nullOK=""
275test $BACKEND = null && nullExclude="# " nullOK="OK"
276
277if [ "$BACKENDTYPE" = mod ]; then
278	$LDAPADD -D cn=config -H $URI1 -y $CONFIGPWF <<EOF >>$TESTOUT 2>&1
279dn: cn=module,cn=config
280objectClass: olcModuleList
281cn: module
282olcModulePath: ../servers/slapd/back-$BACKEND
283olcModuleLoad: back_$BACKEND.la
284
285dn: cn=module,cn=config,cn=slave
286objectClass: olcModuleList
287cn: module
288olcModulePath: ../servers/slapd/back-$BACKEND
289olcModuleLoad: back_$BACKEND.la
290EOF
291	RC=$?
292	if test $RC != 0 ; then
293		echo "ldapadd failed for backend config ($RC)!"
294		test $KILLSERVERS != no && kill -HUP $KILLPIDS
295		exit $RC
296	fi
297fi
298
299$LDAPADD -D cn=config -H $URI1 -y $CONFIGPWF <<EOF >>$TESTOUT 2>&1
300dn: olcDatabase={2}$BACKEND,cn=config
301objectClass: olcDatabaseConfig
302${nullExclude}objectClass: olc${BACKEND}Config
303olcDatabase: {2}$BACKEND
304olcSuffix: $BASEDN
305${nullExclude}olcDbDirectory: $DBDIR1B
306olcRootDN: $MANAGERDN
307olcRootPW: $PASSWD
308olcSyncRepl: rid=002 provider=$URI1 binddn="$MANAGERDN" bindmethod=simple
309  credentials=$PASSWD searchbase="$BASEDN" $SYNCTYPE
310  retry="3 5 300 5" timeout=3
311olcUpdateRef: $URI1
312
313dn: olcOverlay=syncprov,olcDatabase={2}${BACKEND},cn=config
314changetype: add
315objectClass: olcOverlayConfig
316objectClass: olcSyncProvConfig
317olcOverlay: syncprov
318
319dn: olcDatabase={1}$BACKEND,cn=config,cn=slave
320objectClass: olcDatabaseConfig
321${nullExclude}objectClass: olc${BACKEND}Config
322olcDatabase: {1}$BACKEND
323olcSuffix: $BASEDN
324${nullExclude}olcDbDirectory: $DBDIR2A
325olcRootDN: $MANAGERDN
326olcRootPW: $PASSWD
327olcSyncRepl: rid=002 provider=$URI1 binddn="$MANAGERDN" bindmethod=simple
328  credentials=$PASSWD searchbase="$BASEDN" $SYNCTYPE
329  retry="3 5 300 5" timeout=3
330olcUpdateRef: $URI1
331
332EOF
333RC=$?
334if test $RC != 0 ; then
335	echo "ldapadd failed for database config ($RC)!"
336	test $KILLSERVERS != no && kill -HUP $KILLPIDS
337	exit $RC
338fi
339
340if test $INDEXDB = indexdb ; then
341	$LDAPMODIFY -D cn=config -H $URI1 -y $CONFIGPWF <<EOF >>$TESTOUT 2>&1
342dn: olcDatabase={2}$BACKEND,cn=config
343changetype: modify
344add: olcDbIndex
345olcDbIndex: objectClass,entryUUID,entryCSN eq
346olcDbIndex: cn,uid pres,eq,sub
347EOF
348	RC=$?
349	if test $RC != 0 ; then
350		echo "ldapadd modify for database config ($RC)!"
351		test $KILLSERVERS != no && kill -HUP $KILLPIDS
352		exit $RC
353	fi
354fi
355
356echo "Using ldapadd to populate provider..."
357$LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD -f $LDIFORDERED \
358	>> $TESTOUT 2>&1
359RC=$?
360if test $RC != 0 ; then
361	echo "ldapadd failed for database config ($RC)!"
362	test $KILLSERVERS != no && kill -HUP $KILLPIDS
363	exit $RC
364fi
365
366echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
367sleep $SLEEP1
368
369echo "Using ldapsearch to check that syncrepl received database changes..."
370RC=32
371for i in 0 1 2 3 4 5; do
372	RESULT=`$LDAPSEARCH -H $URI2 \
373		-s base -b "cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com" \
374		'(objectClass=*)' 2>&1 | awk '/^dn:/ {print "OK"}'`
375	if test "x$RESULT$nullOK" = "xOK" ; then
376		RC=0
377		break
378	fi
379	echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
380	sleep $SLEEP1
381done
382
383if test $RC != 0 ; then
384	echo "ldapsearch failed ($RC)!"
385	test $KILLSERVERS != no && kill -HUP $KILLPIDS
386	exit $RC
387fi
388
389echo "Using ldapsearch to read all the entries from the provider..."
390$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI1 -w $PASSWD  \
391	'objectclass=*' > $MASTEROUT 2>&1
392RC=$?
393
394if test $RC != 0 ; then
395	echo "ldapsearch failed at provider ($RC)!"
396	test $KILLSERVERS != no && kill -HUP $KILLPIDS
397	exit $RC
398fi
399
400echo "Using ldapsearch to read all the entries from the consumer..."
401$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI2 -w $PASSWD  \
402	'objectclass=*' > $SLAVEOUT 2>&1
403RC=$?
404
405if test $RC != 0 ; then
406	echo "ldapsearch failed at consumer ($RC)!"
407	test $KILLSERVERS != no && kill -HUP $KILLPIDS
408	exit $RC
409fi
410
411test $KILLSERVERS != no && kill -HUP $KILLPIDS
412
413echo "Filtering provider results..."
414$LDIFFILTER < $MASTEROUT > $MASTERFLT
415echo "Filtering consumer results..."
416$LDIFFILTER < $SLAVEOUT > $SLAVEFLT
417
418echo "Comparing retrieved entries from provider and consumer..."
419$CMP $MASTERFLT $SLAVEFLT > $CMPOUT
420
421if test $? != 0 ; then
422	echo "test failed - provider and consumer databases differ"
423	exit 1
424fi
425
426echo ">>>>> Test succeeded"
427
428test $KILLSERVERS != no && wait
429
430exit 0
431