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