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
23if test $ACCESSLOG = accesslogno; then
24	echo "Accesslog overlay not available, test skipped"
25	exit 0
26fi
27
28MMR=2
29
30XDIR=$TESTDIR/srv
31TMP=$TESTDIR/tmp
32
33mkdir -p $TESTDIR
34
35$SLAPPASSWD -g -n >$CONFIGPWF
36
37if test x"$SYNCMODE" = x ; then
38	SYNCMODE=rp
39fi
40case "$SYNCMODE" in
41	ro)
42		SYNCTYPE="type=refreshOnly interval=00:00:00:03"
43		;;
44	rp)
45		SYNCTYPE="type=refreshAndPersist interval=00:00:00:03"
46		;;
47	*)
48		echo "unknown sync mode $SYNCMODE"
49		exit 1;
50		;;
51esac
52
53#
54# Test delta-sync mmr
55# - start servers
56# - configure over ldap
57# - populate over ldap
58# - configure syncrepl over ldap
59# - break replication
60# - modify each server separately
61# - restore replication
62# - compare results
63#
64
65nullExclude=""
66test $BACKEND = null && nullExclude="# "
67
68KILLPIDS=
69
70echo "Initializing server configurations..."
71n=1
72while [ $n -le $MMR ]; do
73
74DBDIR=${XDIR}$n/db
75CFDIR=${XDIR}$n/slapd.d
76
77mkdir -p ${XDIR}$n $DBDIR.1 $DBDIR.2 $CFDIR
78
79o=`expr 3 - $n`
80cat > $TMP <<EOF
81dn: cn=config
82objectClass: olcGlobal
83cn: config
84olcServerID: $n
85
86EOF
87
88if [ "$SYNCPROV" = syncprovmod -o "$ACCESSLOG" = accesslogmod ]; then
89  cat <<EOF >> $TMP
90dn: cn=module,cn=config
91objectClass: olcModuleList
92cn: module
93olcModulePath: $TESTWD/../servers/slapd/overlays
94EOF
95  if [ "$SYNCPROV" = syncprovmod ]; then
96  echo "olcModuleLoad: syncprov.la" >> $TMP
97  fi
98  if [ "$ACCESSLOG" = accesslogmod ]; then
99  echo "olcModuleLoad: accesslog.la" >> $TMP
100  fi
101  echo "" >> $TMP
102fi
103
104if [ "$BACKENDTYPE" = mod ]; then
105cat <<EOF >> $TMP
106dn: cn=module,cn=config
107objectClass: olcModuleList
108cn: module
109olcModulePath: $TESTWD/../servers/slapd/back-$BACKEND
110olcModuleLoad: back_$BACKEND.la
111
112EOF
113fi
114MYURI=`eval echo '$URI'$n`
115PROVIDERURI=`eval echo '$URI'$o`
116if test $INDEXDB = indexdb ; then
117INDEX1="olcDbIndex: objectClass,entryCSN,reqStart,reqDN eq"
118INDEX2="olcDbIndex: objectClass,entryCSN,entryUUID eq"
119else
120INDEX1=
121INDEX2=
122fi
123cat >> $TMP <<EOF
124dn: cn=schema,cn=config
125objectclass: olcSchemaconfig
126cn: schema
127
128include: file://$ABS_SCHEMADIR/core.ldif
129
130include: file://$ABS_SCHEMADIR/cosine.ldif
131
132include: file://$ABS_SCHEMADIR/inetorgperson.ldif
133
134include: file://$ABS_SCHEMADIR/openldap.ldif
135
136include: file://$ABS_SCHEMADIR/nis.ldif
137
138dn: olcDatabase={0}config,cn=config
139objectClass: olcDatabaseConfig
140olcDatabase: {0}config
141olcRootPW:< file://$CONFIGPWF
142
143dn: olcDatabase={1}$BACKEND,cn=config
144objectClass: olcDatabaseConfig
145${nullExclude}objectClass: olc${BACKEND}Config
146olcDatabase: {1}$BACKEND
147olcSuffix: cn=log
148${nullExclude}olcDbDirectory: ${DBDIR}.1
149olcRootDN: $MANAGERDN
150$INDEX1
151
152dn: olcOverlay=syncprov,olcDatabase={1}$BACKEND,cn=config
153objectClass: olcOverlayConfig
154objectClass: olcSyncProvConfig
155olcOverlay: syncprov
156olcSpNoPresent: TRUE
157olcSpReloadHint: TRUE
158
159dn: olcDatabase={2}$BACKEND,cn=config
160objectClass: olcDatabaseConfig
161${nullExclude}objectClass: olc${BACKEND}Config
162olcDatabase: {2}$BACKEND
163olcSuffix: $BASEDN
164${nullExclude}olcDbDirectory: ${DBDIR}.2
165olcRootDN: $MANAGERDN
166olcRootPW: $PASSWD
167olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
168  credentials=$PASSWD searchbase="$BASEDN" $SYNCTYPE
169  retry="3 +" timeout=3 logbase="cn=log"
170  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
171  syncdata=accesslog
172olcMirrorMode: TRUE
173$INDEX2
174
175dn: olcOverlay=syncprov,olcDatabase={2}$BACKEND,cn=config
176objectClass: olcOverlayConfig
177objectClass: olcSyncProvConfig
178olcOverlay: syncprov
179
180dn: olcOverlay=accesslog,olcDatabase={2}$BACKEND,cn=config
181objectClass: olcOverlayConfig
182objectClass: olcAccessLogConfig
183olcOverlay: accesslog
184olcAccessLogDB: cn=log
185olcAccessLogOps: writes
186olcAccessLogSuccess: TRUE
187
188EOF
189$SLAPADD -F $CFDIR -n 0  -d-1< $TMP > $TESTOUT 2>&1
190PORT=`eval echo '$PORT'$n`
191echo "Starting server $n on TCP/IP port $PORT..."
192cd ${XDIR}${n}
193LOG=`eval echo '$LOG'$n`
194$SLAPD -F slapd.d -h $MYURI -d $LVL $TIMING > $LOG 2>&1 &
195PID=$!
196if test $WAIT != 0 ; then
197    echo PID $PID
198    read foo
199fi
200KILLPIDS="$PID $KILLPIDS"
201cd $TESTWD
202
203echo "Using ldapsearch to check that server $n is running..."
204for i in 0 1 2 3 4 5; do
205	$LDAPSEARCH -s base -b "" -H $MYURI \
206		'objectclass=*' > /dev/null 2>&1
207	RC=$?
208	if test $RC = 0 ; then
209		break
210	fi
211	echo "Waiting 5 seconds for slapd to start..."
212	sleep 5
213done
214
215if test $RC != 0 ; then
216	echo "ldapsearch failed ($RC)!"
217	test $KILLSERVERS != no && kill -HUP $KILLPIDS
218	exit $RC
219fi
220
221if [ $n = 1 ]; then
222echo "Using ldapadd for context on server 1..."
223$LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD -f $LDIFORDEREDCP \
224	>> $TESTOUT 2>&1
225RC=$?
226if test $RC != 0 ; then
227	echo "ldapadd failed for server $n database ($RC)!"
228	test $KILLSERVERS != no && kill -HUP $KILLPIDS
229	exit $RC
230fi
231fi
232
233n=`expr $n + 1`
234done
235
236echo "Using ldapadd to populate server 1..."
237$LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD -f $LDIFORDEREDNOCP \
238	>> $TESTOUT 2>&1
239RC=$?
240if test $RC != 0 ; then
241	echo "ldapadd failed for server $n database ($RC)!"
242	test $KILLSERVERS != no && kill -HUP $KILLPIDS
243	exit $RC
244fi
245
246echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
247sleep $SLEEP1
248
249n=1
250while [ $n -le $MMR ]; do
251PORT=`expr $BASEPORT + $n`
252URI="ldap://${LOCALHOST}:$PORT/"
253
254echo "Using ldapsearch to read all the entries from server $n..."
255$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
256	'objectclass=*' > $TESTDIR/server$n.out 2>&1
257RC=$?
258
259if test $RC != 0 ; then
260	echo "ldapsearch failed at server $n ($RC)!"
261	test $KILLSERVERS != no && kill -HUP $KILLPIDS
262	exit $RC
263fi
264$LDIFFILTER < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
265n=`expr $n + 1`
266done
267
268n=2
269while [ $n -le $MMR ]; do
270echo "Comparing retrieved entries from server 1 and server $n..."
271$CMP $MASTERFLT $TESTDIR/server$n.flt > $CMPOUT
272
273if test $? != 0 ; then
274	echo "test failed - server 1 and server $n databases differ"
275	test $KILLSERVERS != no && kill -HUP $KILLPIDS
276	exit 1
277fi
278n=`expr $n + 1`
279done
280
281echo "Using ldapadd to populate server 2..."
282$LDAPADD -D "$MANAGERDN" -H $URI2 -w $PASSWD -f $LDIFADD1 \
283	>> $TESTOUT 2>&1
284RC=$?
285if test $RC != 0 ; then
286	echo "ldapadd failed for server 2 database ($RC)!"
287	test $KILLSERVERS != no && kill -HUP $KILLPIDS
288	exit $RC
289fi
290
291THEDN="cn=James A Jones 2,ou=Alumni Association,ou=People,dc=example,dc=com"
292sleep 1
293for i in 1 2 3; do
294	$LDAPSEARCH -S "" -b "$THEDN" -H $URI1 \
295		-s base '(objectClass=*)' entryCSN > "${MASTEROUT}.$i" 2>&1
296	RC=$?
297
298	if test $RC = 0 ; then
299		break
300	fi
301
302	if test $RC != 32 ; then
303		echo "ldapsearch failed at slave ($RC)!"
304		test $KILLSERVERS != no && kill -HUP $KILLPIDS
305		exit $RC
306	fi
307
308	echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
309	sleep $SLEEP1
310done
311
312n=1
313while [ $n -le $MMR ]; do
314PORT=`expr $BASEPORT + $n`
315URI="ldap://${LOCALHOST}:$PORT/"
316
317echo "Using ldapsearch to read all the entries from server $n..."
318$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
319	'objectclass=*' > $TESTDIR/server$n.out 2>&1
320RC=$?
321
322if test $RC != 0 ; then
323	echo "ldapsearch failed at server $n ($RC)!"
324	test $KILLSERVERS != no && kill -HUP $KILLPIDS
325	exit $RC
326fi
327$LDIFFILTER < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
328n=`expr $n + 1`
329done
330
331n=2
332while [ $n -le $MMR ]; do
333echo "Comparing retrieved entries from server 1 and server $n..."
334$CMP $MASTERFLT $TESTDIR/server$n.flt > $CMPOUT
335
336if test $? != 0 ; then
337	echo "test failed - server 1 and server $n databases differ"
338	test $KILLSERVERS != no && kill -HUP $KILLPIDS
339	exit 1
340fi
341n=`expr $n + 1`
342done
343
344echo "Breaking replication between server 1 and 2..."
345n=1
346while [ $n -le $MMR ]; do
347o=`expr 3 - $n`
348MYURI=`eval echo '$URI'$n`
349PROVIDERURI=`eval echo '$URI'$o`
350$LDAPMODIFY -D cn=config -H $MYURI -y $CONFIGPWF > $TESTOUT 2>&1 <<EOF
351dn: olcDatabase={2}$BACKEND,cn=config
352changetype: modify
353replace: olcSyncRepl
354olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
355  credentials=InvalidPw searchbase="$BASEDN" $SYNCTYPE
356  retry="3 +" timeout=3 logbase="cn=log"
357  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
358  syncdata=accesslog
359-
360replace: olcMirrorMode
361olcMirrorMode: TRUE
362
363EOF
364RC=$?
365if test $RC != 0 ; then
366	echo "ldapmodify failed for server $n config ($RC)!"
367	test $KILLSERVERS != no && kill -HUP $KILLPIDS
368	exit $RC
369fi
370n=`expr $n + 1`
371done
372
373echo "Using ldapmodify to force conflicts between server 1 and 2..."
374$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
375	>> $TESTOUT 2>&1 << EOF
376dn: $THEDN
377changetype: modify
378add: description
379description: Amazing
380
381EOF
382RC=$?
383if test $RC != 0 ; then
384	echo "ldapmodify failed for server 1 database ($RC)!"
385	test $KILLSERVERS != no && kill -HUP $KILLPIDS
386	exit $RC
387fi
388
389$LDAPMODIFY -D "$MANAGERDN" -H $URI2 -w $PASSWD \
390	>> $TESTOUT 2>&1 << EOF
391dn: $THEDN
392changetype: modify
393add: description
394description: Stupendous
395
396EOF
397RC=$?
398if test $RC != 0 ; then
399	echo "ldapmodify failed for server 2 database ($RC)!"
400	test $KILLSERVERS != no && kill -HUP $KILLPIDS
401	exit $RC
402fi
403
404$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
405	>> $TESTOUT 2>&1 << EOF
406dn: $THEDN
407changetype: modify
408delete: description
409description: Outstanding
410-
411add: description
412description: Mindboggling
413
414EOF
415RC=$?
416if test $RC != 0 ; then
417	echo "ldapmodify failed for server 1 database ($RC)!"
418	test $KILLSERVERS != no && kill -HUP $KILLPIDS
419	exit $RC
420fi
421
422$LDAPMODIFY -D "$MANAGERDN" -H $URI2 -w $PASSWD \
423	>> $TESTOUT 2>&1 << EOF
424dn: $THEDN
425changetype: modify
426delete: description
427description: OutStanding
428-
429add: description
430description: Bizarre
431
432EOF
433RC=$?
434if test $RC != 0 ; then
435	echo "ldapmodify failed for server 2 database ($RC)!"
436	test $KILLSERVERS != no && kill -HUP $KILLPIDS
437	exit $RC
438fi
439
440$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
441	>> $TESTOUT 2>&1 << EOF
442dn: $THEDN
443changetype: modify
444add: carLicense
445carLicense: 123-XYZ
446-
447add: employeeNumber
448employeeNumber: 32
449
450EOF
451RC=$?
452if test $RC != 0 ; then
453	echo "ldapmodify failed for server 1 database ($RC)!"
454	test $KILLSERVERS != no && kill -HUP $KILLPIDS
455	exit $RC
456fi
457
458$LDAPMODIFY -D "$MANAGERDN" -H $URI2 -w $PASSWD \
459	>> $TESTOUT 2>&1 << EOF
460dn: $THEDN
461changetype: modify
462add: employeeType
463employeeType: deadwood
464-
465add: employeeNumber
466employeeNumber: 64
467
468EOF
469RC=$?
470if test $RC != 0 ; then
471	echo "ldapmodify failed for server 2 database ($RC)!"
472	test $KILLSERVERS != no && kill -HUP $KILLPIDS
473	exit $RC
474fi
475
476echo "Restoring replication between server 1 and 2..."
477n=1
478while [ $n -le $MMR ]; do
479o=`expr 3 - $n`
480MYURI=`eval echo '$URI'$n`
481PROVIDERURI=`eval echo '$URI'$o`
482$LDAPMODIFY -D cn=config -H $MYURI -y $CONFIGPWF > $TESTOUT 2>&1 <<EOF
483dn: olcDatabase={2}$BACKEND,cn=config
484changetype: modify
485replace: olcSyncRepl
486olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
487  credentials=$PASSWD searchbase="$BASEDN" $SYNCTYPE
488  retry="3 +" timeout=3 logbase="cn=log"
489  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
490  syncdata=accesslog
491-
492replace: olcMirrorMode
493olcMirrorMode: TRUE
494
495EOF
496RC=$?
497if test $RC != 0 ; then
498	echo "ldapmodify failed for server $n config ($RC)!"
499	test $KILLSERVERS != no && kill -HUP $KILLPIDS
500	exit $RC
501fi
502n=`expr $n + 1`
503done
504
505echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
506sleep $SLEEP1
507
508n=1
509while [ $n -le $MMR ]; do
510PORT=`expr $BASEPORT + $n`
511URI="ldap://${LOCALHOST}:$PORT/"
512
513echo "Using ldapsearch to read all the entries from server $n..."
514$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
515	'objectclass=*' > $TESTDIR/server$n.out 2>&1
516RC=$?
517
518if test $RC != 0 ; then
519	echo "ldapsearch failed at server $n ($RC)!"
520	test $KILLSERVERS != no && kill -HUP $KILLPIDS
521	exit $RC
522fi
523$LDIFFILTER -s $BACKEND=a < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
524n=`expr $n + 1`
525done
526
527n=2
528while [ $n -le $MMR ]; do
529echo "Comparing retrieved entries from server 1 and server $n..."
530$CMP $MASTERFLT $TESTDIR/server$n.flt > $CMPOUT
531
532if test $? != 0 ; then
533	echo "test failed - server 1 and server $n databases differ"
534	test $KILLSERVERS != no && kill -HUP $KILLPIDS
535	exit 1
536fi
537n=`expr $n + 1`
538done
539
540test $KILLSERVERS != no && kill -HUP $KILLPIDS
541
542echo ">>>>> Test succeeded"
543
544test $KILLSERVERS != no && wait
545
546exit 0
547