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 '$URI'$n`
123PROVIDERURI=`eval echo '$URIP'$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
180  starttls=critical
181olcMultiProvider: TRUE
182$INDEX2
183
184dn: olcOverlay=syncprov,olcDatabase={2}$BACKEND,cn=config
185objectClass: olcOverlayConfig
186objectClass: olcSyncProvConfig
187olcOverlay: syncprov
188
189dn: olcOverlay=accesslog,olcDatabase={2}$BACKEND,cn=config
190objectClass: olcOverlayConfig
191objectClass: olcAccessLogConfig
192olcOverlay: accesslog
193olcAccessLogDB: cn=log
194olcAccessLogOps: writes
195olcAccessLogSuccess: TRUE
196
197EOF
198$SLAPADD -F $CFDIR -n 0  -d-1< $TMP > $TESTOUT 2>&1
199PORT=`eval echo '$PORT'$n`
200echo "Starting server $n on TCP/IP port $PORT..."
201cd ${XDIR}${n}
202LOG=`eval echo '$LOG'$n`
203$SLAPD -F slapd.d -h $MYURI -d $LVL > $LOG 2>&1 &
204PID=$!
205if test $WAIT != 0 ; then
206    echo PID $PID
207    read foo
208fi
209KILLPIDS="$PID $KILLPIDS"
210cd $TESTWD
211
212echo "Using ldapsearch to check that server $n is running..."
213for i in 0 1 2 3 4 5; do
214          $LDAPSEARCH -s base -b "" -H $MYURI \
215                    'objectclass=*' > /dev/null 2>&1
216          RC=$?
217          if test $RC = 0 ; then
218                    break
219          fi
220          echo "Waiting 5 seconds for slapd to start..."
221          sleep 5
222done
223
224if test $RC != 0 ; then
225          echo "ldapsearch failed ($RC)!"
226          test $KILLSERVERS != no && kill -HUP $KILLPIDS
227          exit $RC
228fi
229
230if [ $n = 1 ]; then
231echo "Using ldapadd for context on server 1..."
232$LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD -f $LDIFORDEREDCP \
233          >> $TESTOUT 2>&1
234RC=$?
235if test $RC != 0 ; then
236          echo "ldapadd failed for server $n database ($RC)!"
237          test $KILLSERVERS != no && kill -HUP $KILLPIDS
238          exit $RC
239fi
240fi
241
242n=`expr $n + 1`
243done
244
245echo "Using ldapadd to populate server 1..."
246$LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD -f $LDIFORDEREDNOCP \
247          >> $TESTOUT 2>&1
248RC=$?
249if test $RC != 0 ; then
250          echo "ldapadd failed for server $n database ($RC)!"
251          test $KILLSERVERS != no && kill -HUP $KILLPIDS
252          exit $RC
253fi
254
255echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
256sleep $SLEEP1
257
258n=1
259while [ $n -le $MMR ]; do
260PORT=`expr $BASEPORT + $n`
261URI="ldap://${LOCALHOST}:$PORT/"
262
263echo "Using ldapsearch to read all the entries from server $n..."
264$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
265          'objectclass=*' > $TESTDIR/server$n.out 2>&1
266RC=$?
267
268if test $RC != 0 ; then
269          echo "ldapsearch failed at server $n ($RC)!"
270          test $KILLSERVERS != no && kill -HUP $KILLPIDS
271          exit $RC
272fi
273$LDIFFILTER < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
274n=`expr $n + 1`
275done
276
277n=2
278while [ $n -le $MMR ]; do
279echo "Comparing retrieved entries from server 1 and server $n..."
280$CMP $PROVIDERFLT $TESTDIR/server$n.flt > $CMPOUT
281
282if test $? != 0 ; then
283          echo "test failed - server 1 and server $n databases differ"
284          test $KILLSERVERS != no && kill -HUP $KILLPIDS
285          exit 1
286fi
287n=`expr $n + 1`
288done
289
290echo "Using ldapadd to populate server 2..."
291$LDAPADD -D "$MANAGERDN" -H $URI2 -w $PASSWD -f $LDIFADD1 \
292          >> $TESTOUT 2>&1
293RC=$?
294if test $RC != 0 ; then
295          echo "ldapadd failed for server 2 database ($RC)!"
296          test $KILLSERVERS != no && kill -HUP $KILLPIDS
297          exit $RC
298fi
299
300THEDN="cn=James A Jones 2,ou=Alumni Association,ou=People,dc=example,dc=com"
301sleep 1
302for i in 1 2 3; do
303          $LDAPSEARCH -S "" -b "$THEDN" -H $URI1 \
304                    -s base '(objectClass=*)' entryCSN > "${PROVIDEROUT}.$i" 2>&1
305          RC=$?
306
307          if test $RC = 0 ; then
308                    break
309          fi
310
311          if test $RC != 32 ; then
312                    echo "ldapsearch failed at replica ($RC)!"
313                    test $KILLSERVERS != no && kill -HUP $KILLPIDS
314                    exit $RC
315          fi
316
317          echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
318          sleep $SLEEP1
319done
320
321n=1
322while [ $n -le $MMR ]; do
323PORT=`expr $BASEPORT + $n`
324URI="ldap://${LOCALHOST}:$PORT/"
325
326echo "Using ldapsearch to read all the entries from server $n..."
327$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
328          'objectclass=*' > $TESTDIR/server$n.out 2>&1
329RC=$?
330
331if test $RC != 0 ; then
332          echo "ldapsearch failed at server $n ($RC)!"
333          test $KILLSERVERS != no && kill -HUP $KILLPIDS
334          exit $RC
335fi
336$LDIFFILTER < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
337n=`expr $n + 1`
338done
339
340n=2
341while [ $n -le $MMR ]; do
342echo "Comparing retrieved entries from server 1 and server $n..."
343$CMP $PROVIDERFLT $TESTDIR/server$n.flt > $CMPOUT
344
345if test $? != 0 ; then
346          echo "test failed - server 1 and server $n databases differ"
347          test $KILLSERVERS != no && kill -HUP $KILLPIDS
348          exit 1
349fi
350n=`expr $n + 1`
351done
352
353echo "Breaking replication between server 1 and 2..."
354n=1
355while [ $n -le $MMR ]; do
356o=`expr 3 - $n`
357MYURI=`eval echo '$URI'$n`
358PROVIDERURI=`eval echo '$URIP'$o`
359$LDAPMODIFY -D cn=config -H $MYURI -y $CONFIGPWF > $TESTOUT 2>&1 <<EOF
360dn: olcDatabase={2}$BACKEND,cn=config
361changetype: modify
362replace: olcSyncRepl
363olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
364  credentials=InvalidPw searchbase="$BASEDN" $SYNCTYPE
365  retry="3 +" timeout=3 logbase="cn=log"
366  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
367  syncdata=accesslog tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt
368  starttls=critical
369-
370replace: olcMultiProvider
371olcMultiProvider: TRUE
372
373EOF
374RC=$?
375if test $RC != 0 ; then
376          echo "ldapmodify failed for server $n config ($RC)!"
377          test $KILLSERVERS != no && kill -HUP $KILLPIDS
378          exit $RC
379fi
380n=`expr $n + 1`
381done
382
383echo "Using ldapmodify to force conflicts between server 1 and 2..."
384$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
385          >> $TESTOUT 2>&1 << EOF
386dn: $THEDN
387changetype: modify
388add: description
389description: Amazing
390
391EOF
392RC=$?
393if test $RC != 0 ; then
394          echo "ldapmodify failed for server 1 database ($RC)!"
395          test $KILLSERVERS != no && kill -HUP $KILLPIDS
396          exit $RC
397fi
398
399$LDAPMODIFY -D "$MANAGERDN" -H $URI2 -w $PASSWD \
400          >> $TESTOUT 2>&1 << EOF
401dn: $THEDN
402changetype: modify
403add: description
404description: Stupendous
405
406EOF
407RC=$?
408if test $RC != 0 ; then
409          echo "ldapmodify failed for server 2 database ($RC)!"
410          test $KILLSERVERS != no && kill -HUP $KILLPIDS
411          exit $RC
412fi
413
414$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
415          >> $TESTOUT 2>&1 << EOF
416dn: $THEDN
417changetype: modify
418delete: description
419description: Outstanding
420-
421add: description
422description: Mindboggling
423
424EOF
425RC=$?
426if test $RC != 0 ; then
427          echo "ldapmodify failed for server 1 database ($RC)!"
428          test $KILLSERVERS != no && kill -HUP $KILLPIDS
429          exit $RC
430fi
431
432$LDAPMODIFY -D "$MANAGERDN" -H $URI2 -w $PASSWD \
433          >> $TESTOUT 2>&1 << EOF
434dn: $THEDN
435changetype: modify
436delete: description
437description: OutStanding
438-
439add: description
440description: Bizarre
441
442EOF
443RC=$?
444if test $RC != 0 ; then
445          echo "ldapmodify failed for server 2 database ($RC)!"
446          test $KILLSERVERS != no && kill -HUP $KILLPIDS
447          exit $RC
448fi
449
450$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
451          >> $TESTOUT 2>&1 << EOF
452dn: $THEDN
453changetype: modify
454add: carLicense
455carLicense: 123-XYZ
456-
457add: employeeNumber
458employeeNumber: 32
459
460EOF
461RC=$?
462if test $RC != 0 ; then
463          echo "ldapmodify failed for server 1 database ($RC)!"
464          test $KILLSERVERS != no && kill -HUP $KILLPIDS
465          exit $RC
466fi
467
468$LDAPMODIFY -D "$MANAGERDN" -H $URI2 -w $PASSWD \
469          >> $TESTOUT 2>&1 << EOF
470dn: $THEDN
471changetype: modify
472add: employeeType
473employeeType: deadwood
474-
475add: employeeNumber
476employeeNumber: 64
477
478EOF
479RC=$?
480if test $RC != 0 ; then
481          echo "ldapmodify failed for server 2 database ($RC)!"
482          test $KILLSERVERS != no && kill -HUP $KILLPIDS
483          exit $RC
484fi
485
486$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
487          >> $TESTOUT 2>&1 << EOF
488dn: $THEDN
489changetype: modify
490replace: sn
491sn: Replaced later
492-
493replace: sn
494sn: Surname
495EOF
496RC=$?
497if test $RC != 0 ; then
498          echo "ldapmodify failed for server 1 database ($RC)!"
499          test $KILLSERVERS != no && kill -HUP $KILLPIDS
500          exit $RC
501fi
502
503echo "Restoring replication between server 1 and 2..."
504n=1
505while [ $n -le $MMR ]; do
506o=`expr 3 - $n`
507MYURI=`eval echo '$URI'$n`
508PROVIDERURI=`eval echo '$URIP'$o`
509$LDAPMODIFY -D cn=config -H $MYURI -y $CONFIGPWF > $TESTOUT 2>&1 <<EOF
510dn: olcDatabase={2}$BACKEND,cn=config
511changetype: modify
512replace: olcSyncRepl
513olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
514  credentials=$PASSWD searchbase="$BASEDN" $SYNCTYPE
515  retry="3 +" timeout=3 logbase="cn=log"
516  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
517  syncdata=accesslog tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt
518  starttls=critical
519-
520replace: olcMultiProvider
521olcMultiProvider: TRUE
522
523EOF
524RC=$?
525if test $RC != 0 ; then
526          echo "ldapmodify failed for server $n config ($RC)!"
527          test $KILLSERVERS != no && kill -HUP $KILLPIDS
528          exit $RC
529fi
530n=`expr $n + 1`
531done
532
533echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
534sleep $SLEEP1
535
536n=1
537while [ $n -le $MMR ]; do
538PORT=`expr $BASEPORT + $n`
539URI="ldap://${LOCALHOST}:$PORT/"
540
541echo "Using ldapsearch to read all the entries from server $n..."
542$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
543          'objectclass=*' > $TESTDIR/server$n.out 2>&1
544RC=$?
545
546if test $RC != 0 ; then
547          echo "ldapsearch failed at server $n ($RC)!"
548          test $KILLSERVERS != no && kill -HUP $KILLPIDS
549          exit $RC
550fi
551$LDIFFILTER -s a < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
552n=`expr $n + 1`
553done
554
555n=2
556while [ $n -le $MMR ]; do
557echo "Comparing retrieved entries from server 1 and server $n..."
558$CMP $PROVIDERFLT $TESTDIR/server$n.flt > $CMPOUT
559
560if test $? != 0 ; then
561          echo "test failed - server 1 and server $n databases differ"
562          test $KILLSERVERS != no && kill -HUP $KILLPIDS
563          exit 1
564fi
565n=`expr $n + 1`
566done
567
568test $KILLSERVERS != no && kill -HUP $KILLPIDS
569
570echo ">>>>> Test succeeded"
571
572test $KILLSERVERS != no && wait
573
574exit 0
575