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
16# This script tests a bug where syncprov used on a glue database
17# with a subordinate syncrepl consumer database looses a read-lock
18# on the glue suffix entry when a modification is received on the
19# syncrepl consumer.  The bug is only triggered when there is an
20# active syncrepl consumers of the glue suffix entry.
21
22echo "running defines.sh"
23. $SRCDIR/scripts/defines.sh
24
25if test $SYNCPROV = syncprovno; then
26          echo "Syncrepl provider overlay not available, test skipped"
27          exit 0
28fi
29
30PRODDIR=$TESTDIR/prod
31PRO2DIR=$TESTDIR/pro2
32CONSDIR=$TESTDIR/cons
33CFPROD=$PRODDIR/slapd.d
34CFPRO2=$PRO2DIR/slapd.d
35CFCONS=$CONSDIR/slapd.d
36
37mkdir -p $TESTDIR
38mkdir -p $PRODDIR $CFPROD $PRODDIR/db $PRODDIR/ou1
39mkdir -p $PRO2DIR $CFPRO2 $PRO2DIR/db
40mkdir -p $CONSDIR $CFCONS $CONSDIR/db
41
42cd $TESTDIR
43
44KILLPIDS=
45
46$SLAPPASSWD -g -n >$CONFIGPWF
47
48if test x"$SYNCMODE" = x ; then
49          SYNCMODE=rp
50fi
51case "$SYNCMODE" in
52          ro)
53                    SYNCTYPE="type=refreshOnly interval=00:00:00:03"
54                    ;;
55          rp)
56                    SYNCTYPE="type=refreshAndPersist"
57                    ;;
58          *)
59                    echo "unknown sync mode $SYNCMODE"
60                    exit 1;
61                    ;;
62esac
63
64echo "Initializing provider configurations..."
65$SLAPADD -F $CFPROD -n 0 <<EOF
66dn: cn=config
67objectClass: olcGlobal
68cn: config
69olcServerID: 1
70
71dn: olcDatabase={0}config,cn=config
72objectClass: olcDatabaseConfig
73olcDatabase: {0}config
74olcRootPW:< file://$CONFIGPWF
75
76EOF
77
78echo "Initializing provider2 configurations..."
79$SLAPADD -F $CFPRO2 -n 0 <<EOF
80dn: cn=config
81objectClass: olcGlobal
82cn: config
83
84dn: olcDatabase={0}config,cn=config
85objectClass: olcDatabaseConfig
86olcDatabase: {0}config
87olcRootPW:< file://$CONFIGPWF
88
89EOF
90
91$SLAPADD -F $CFCONS -n 0 <<EOF
92dn: cn=config
93objectClass: olcGlobal
94cn: config
95
96dn: olcDatabase={0}config,cn=config
97objectClass: olcDatabaseConfig
98olcDatabase: {0}config
99olcRootPW:< file://$CONFIGPWF
100EOF
101
102echo "Starting provider slapd on TCP/IP port $PORT1..."
103cd $PRODDIR
104$SLAPD -F slapd.d -h $URI1 -d $LVL > $LOG1 2>&1 &
105PID=$!
106if test $WAIT != 0 ; then
107    echo PID $PID
108    read foo
109fi
110KILLPIDS="$KILLPIDS $PID"
111cd $TESTWD
112sleep 1
113echo "Using ldapsearch to check that provider slapd is running..."
114for i in 0 1 2 3 4 5; do
115          $LDAPSEARCH -s base -b "" -H $URI1 \
116                    'objectclass=*' > /dev/null 2>&1
117          RC=$?
118          if test $RC = 0 ; then
119                    break
120          fi
121          echo "Waiting 5 seconds for slapd to start..."
122          sleep 5
123done
124if test $RC != 0 ; then
125          echo "ldapsearch failed ($RC)!"
126          test $KILLSERVERS != no && kill -HUP $KILLPIDS
127          exit $RC
128fi
129
130echo "Starting provider2 slapd on TCP/IP port $PORT2..."
131cd $PRO2DIR
132$SLAPD -F slapd.d -h $URI2 -d $LVL > $LOG2 2>&1 &
133PID=$!
134if test $WAIT != 0 ; then
135    echo PID $PID
136    read foo
137fi
138KILLPIDS="$KILLPIDS $PID"
139cd $TESTWD
140sleep 1
141echo "Using ldapsearch to check that provider slapd is running..."
142for i in 0 1 2 3 4 5; do
143          $LDAPSEARCH -s base -b "" -H $URI2 \
144                    'objectclass=*' > /dev/null 2>&1
145          RC=$?
146          if test $RC = 0 ; then
147                    break
148          fi
149          echo "Waiting 5 seconds for slapd to start..."
150          sleep 5
151done
152if test $RC != 0 ; then
153          echo "ldapsearch failed ($RC)!"
154          test $KILLSERVERS != no && kill -HUP $KILLPIDS
155          exit $RC
156fi
157
158echo "Starting consumer slapd on TCP/IP port $PORT3..."
159cd $CONSDIR
160$SLAPD -F slapd.d -h $URI3 -d $LVL > $LOG3 2>&1 &
161PID=$!
162if test $WAIT != 0 ; then
163    echo PID $PID
164    read foo
165fi
166KILLPIDS="$KILLPIDS $PID"
167cd $TESTWD
168sleep 1
169echo "Using ldapsearch to check that consumer slapd is running..."
170for i in 0 1 2 3 4 5; do
171          $LDAPSEARCH -s base -b "" -H $URI3 \
172                    'objectclass=*' > /dev/null 2>&1
173          RC=$?
174          if test $RC = 0 ; then
175                    break
176          fi
177          echo "Waiting 5 seconds for slapd to start..."
178          sleep 5
179done
180if test $RC != 0 ; then
181          echo "ldapsearch failed ($RC)!"
182          test $KILLSERVERS != no && kill -HUP $KILLPIDS
183          exit $RC
184fi
185
186for uri in $URI1 $URI2 $URI3; do
187          echo "Adding schema on $uri..."
188          $LDAPADD -D cn=config -H $uri -y $CONFIGPWF <<EOF > $TESTOUT 2>&1
189include: file://$ABS_SCHEMADIR/core.ldif
190
191include: file://$ABS_SCHEMADIR/cosine.ldif
192
193include: file://$ABS_SCHEMADIR/inetorgperson.ldif
194
195include: file://$ABS_SCHEMADIR/openldap.ldif
196
197include: file://$ABS_SCHEMADIR/nis.ldif
198EOF
199          RC=$?
200          if test $RC != 0 ; then
201                    echo "ldapadd failed for schema config ($RC)!"
202                    test $KILLSERVERS != no && kill -HUP $KILLPIDS
203                    exit $RC
204          fi
205
206          [ "$BACKENDTYPE" = mod ] || continue
207
208          echo "Adding backend module on $uri..."
209          $LDAPADD -D cn=config -H $uri -y $CONFIGPWF <<EOF >>$TESTOUT 2>&1
210dn: cn=module,cn=config
211objectClass: olcModuleList
212cn: module
213olcModulePath: $TESTWD/../servers/slapd/back-$BACKEND
214olcModuleLoad: back_$BACKEND.la
215EOF
216          RC=$?
217          if test $RC != 0 ; then
218                    echo "ldapadd failed for backend module ($RC)!"
219                    test $KILLSERVERS != no && kill -HUP $KILLPIDS
220                    exit $RC
221          fi
222done
223
224echo "Adding databases on provider..."
225if [ "$SYNCPROV" = syncprovmod ]; then
226          $LDAPADD -D cn=config -H $URI1 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
227dn: cn=module,cn=config
228objectClass: olcModuleList
229cn: module
230olcModulePath: $TESTWD/../servers/slapd/overlays
231olcModuleLoad: syncprov.la
232
233EOF
234          RC=$?
235          if test $RC != 0 ; then
236                    echo "ldapadd failed for moduleLoad ($RC)!"
237                    test $KILLSERVERS != no && kill -HUP $KILLPIDS
238                    exit $RC
239          fi
240fi
241
242nullExclude="" nullOK=""
243test $BACKEND = null && nullExclude="# " nullOK="OK"
244
245$LDAPADD -D cn=config -H $URI1 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
246dn: olcDatabase={1}$BACKEND,cn=config
247objectClass: olcDatabaseConfig
248${nullExclude}objectClass: olc${BACKEND}Config
249olcDatabase: {1}$BACKEND
250${nullExclude}olcDbDirectory: $PRODDIR/db
251olcSuffix: $BASEDN
252olcRootDN: $MANAGERDN
253olcRootPW: $PASSWD
254
255EOF
256RC=$?
257if test $RC != 0 ; then
258          echo "ldapadd failed for provider database config1 ($RC)!"
259          test $KILLSERVERS != no && kill -HUP $KILLPIDS
260          exit $RC
261fi
262
263$LDAPADD -D cn=config -H $URI1 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
264dn: olcOverlay={0}glue,olcDatabase={1}$BACKEND,cn=config
265objectClass: olcOverlayConfig
266olcOverlay: {0}glue
267
268dn: olcOverlay={1}syncprov,olcDatabase={1}$BACKEND,cn=config
269objectClass: olcOverlayConfig
270objectClass: olcSyncProvConfig
271olcOverlay: {1}syncprov
272
273dn: olcDatabase={1}$BACKEND,cn=config
274objectClass: olcDatabaseConfig
275${nullExclude}objectClass: olc${BACKEND}Config
276olcDatabase: {1}$BACKEND
277${nullExclude}olcDbDirectory: $PRODDIR/ou1
278olcSubordinate: TRUE
279olcSuffix: ou=ou1,$BASEDN
280olcRootDN: $MANAGERDN
281
282EOF
283RC=$?
284if test $RC != 0 ; then
285          echo "ldapadd failed for provider database config ($RC)!"
286          test $KILLSERVERS != no && kill -HUP $KILLPIDS
287          exit $RC
288fi
289
290echo "Adding databases on provider2..."
291if [ "$SYNCPROV" = syncprovmod ]; then
292          $LDAPADD -D cn=config -H $URI2 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
293dn: cn=module,cn=config
294objectClass: olcModuleList
295cn: module
296olcModulePath: $TESTWD/../servers/slapd/overlays
297olcModuleLoad: syncprov.la
298
299EOF
300          RC=$?
301          if test $RC != 0 ; then
302                    echo "ldapadd failed for moduleLoad ($RC)!"
303                    test $KILLSERVERS != no && kill -HUP $KILLPIDS
304                    exit $RC
305          fi
306fi
307
308$LDAPADD -D cn=config -H $URI2 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
309dn: olcDatabase={1}$BACKEND,cn=config
310objectClass: olcDatabaseConfig
311${nullExclude}objectClass: olc${BACKEND}Config
312olcDatabase: {1}$BACKEND
313${nullExclude}olcDbDirectory: $PRO2DIR/db
314olcSuffix: $BASEDN
315olcRootDN: $MANAGERDN
316olcRootPW: $PASSWD
317
318dn: olcOverlay={0}syncprov,olcDatabase={1}$BACKEND,cn=config
319objectClass: olcOverlayConfig
320objectClass: olcSyncProvConfig
321olcOverlay: {0}syncprov
322
323EOF
324RC=$?
325if test $RC != 0 ; then
326          echo "ldapadd failed for provider database config ($RC)!"
327          test $KILLSERVERS != no && kill -HUP $KILLPIDS
328          exit $RC
329fi
330
331echo "Adding databases on consumer..."
332$LDAPADD -D cn=config -H $URI3 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
333dn: olcDatabase={1}$BACKEND,cn=config
334objectClass: olcDatabaseConfig
335${nullExclude}objectClass: olc${BACKEND}Config
336olcDatabase: {1}$BACKEND
337${nullExclude}olcDbDirectory: $CONSDIR/db
338olcSuffix: $BASEDN
339olcRootDN: $MANAGERDN
340
341EOF
342RC=$?
343if test $RC != 0 ; then
344          echo "ldapadd failed for consumer database config ($RC)!"
345          test $KILLSERVERS != no && kill -HUP $KILLPIDS
346          exit $RC
347fi
348
349echo "Populating provider..."
350$LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD <<EOF >> $TESTOUT 2>&1
351dn: dc=example,dc=com
352objectClass: top
353objectClass: organization
354objectClass: dcObject
355dc: example
356o: Example, Inc
357
358dn: ou=ou1,dc=example,dc=com
359objectClass: top
360objectClass: organizationalUnit
361ou: ou1
362
363EOF
364RC=$?
365if test $RC != 0 ; then
366          echo "ldapadd failed to populate provider entry ($RC)!"
367          test $KILLSERVERS != no && kill -HUP $KILLPIDS
368          exit $RC
369fi
370
371echo "Populating provider2..."
372$LDAPADD -D "$MANAGERDN" -H $URI2 -w $PASSWD <<EOF >> $TESTOUT 2>&1
373dn: dc=example,dc=com
374objectClass: top
375objectClass: organization
376objectClass: dcObject
377dc: example
378o: Example, Inc
379
380dn: ou=ou1,dc=example,dc=com
381objectClass: top
382objectClass: organizationalUnit
383ou: ou1
384
385EOF
386RC=$?
387if test $RC != 0 ; then
388          echo "ldapadd failed to populate provider entry ($RC)!"
389          test $KILLSERVERS != no && kill -HUP $KILLPIDS
390          exit $RC
391fi
392
393echo "Adding syncrepl on provider..."
394$LDAPMODIFY -D cn=config -H $URI1 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
395dn: olcDatabase={1}$BACKEND,cn=config
396changetype: modify
397add: olcSyncRepl
398olcSyncRepl: rid=1 provider=$URI2 searchbase="ou=ou1,$BASEDN"
399  binddn="$MANAGERDN" bindmethod=simple credentials=$PASSWD
400  $SYNCTYPE retry="3 5 300 5" timeout=1
401
402EOF
403RC=$?
404if test $RC != 0 ; then
405          echo "ldapmodify failed to add syncrepl consumer ($RC)!"
406          test $KILLSERVERS != no && kill -HUP $KILLPIDS
407          exit $RC
408fi
409
410echo "Adding syncrepl consumer on consumer..."
411$LDAPMODIFY -D cn=config -H $URI3 -y $CONFIGPWF <<EOF >> $TESTOUT 2>&1
412dn: olcDatabase={1}$BACKEND,cn=config
413changetype: modify
414add: olcSyncRepl
415olcSyncRepl: rid=1 provider=$URI1 searchbase="$BASEDN"
416  binddn="$MANAGERDN" bindmethod=simple credentials=$PASSWD
417  $SYNCTYPE retry="3 5 300 5" timeout=1
418
419EOF
420RC=$?
421if test $RC != 0 ; then
422          echo "ldapmodify failed to add syncrepl consumer ($RC)!"
423          test $KILLSERVERS != no && kill -HUP $KILLPIDS
424          exit $RC
425fi
426
427echo "Using ldapsearch to check that consumer received changes..."
428RC=32
429for i in 0 1 2 3 4 5; do
430          RESULT=`$LDAPSEARCH -H $URI3 \
431                    -s base -b "ou=ou1,$BASEDN" \
432                    '(objectClass=*)' 2>&1 | awk '/^dn:/ {print "OK"}'`
433          if test "x$RESULT$nullOK" = "xOK" ; then
434                    RC=0
435                    break
436          fi
437          echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
438          sleep $SLEEP1
439done
440if test $RC != 0 ; then
441          echo "ldapsearch failed ($RC)!"
442          test $KILLSERVERS != no && kill -HUP $KILLPIDS
443          exit $RC
444fi
445
446echo "Using ldapmodify to modify provider2..."
447$LDAPADD -D "$MANAGERDN" -H $URI2 -w $PASSWD <<EOF >> $TESTOUT 2>&1
448dn: ou=ou1,dc=example,dc=com
449changetype: modify
450add: description
451description: Modify1
452
453EOF
454RC=$?
455if test $RC != 0 ; then
456          echo "ldapmodify failed ($RC)!"
457          test $KILLSERVERS != no && kill -HUP $KILLPIDS
458          exit $RC
459fi
460
461sleep 1
462
463echo "Using ldapsearch to check that consumer received changes..."
464RC=32
465for i in 0 1 2 3 4 5; do
466          RESULT=`$LDAPSEARCH -H $URI3 \
467                    -s base -b "ou=ou1,$BASEDN" \
468                    '(description=Modify1)' 2>&1 | awk '/^dn:/ {print "OK"}'`
469          if test "x$RESULT$nullOK" = "xOK" ; then
470                    RC=0
471                    break
472          fi
473          echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
474          sleep $SLEEP1
475done
476if test $RC != 0 ; then
477          echo "ldapsearch failed ($RC)!"
478          test $KILLSERVERS != no && kill -HUP $KILLPIDS
479          exit $RC
480fi
481
482echo "Using ldapmodify to modify glue suffix on provider..."
483$LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD <<EOF >> $TESTOUT 2>&1
484dn: dc=example,dc=com
485changetype: modify
486add: description
487description: Test1
488
489EOF
490RC=$?
491if test $RC != 0 ; then
492          echo "ldapadd failed to modify suffix ($RC)!"
493          test $KILLSERVERS != no && kill -HUP $KILLPIDS
494          exit $RC
495fi
496
497test $KILLSERVERS != no && kill -HUP $KILLPIDS
498test "$lock_bug" = 2          && exit 2
499
500echo ">>>>> Test succeeded"
501
502exit 0
503