1#! /bin/sh
2# $OpenLDAP$
3## This work is part of OpenLDAP Software <http://www.openldap.org/>.
4##
5## Copyright 2005-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
19case $BACKEND in ldif | null)
20          # LDIF lacks ACL support, NULL cannot hold dynamic entries
21        echo "Test does not support $BACKEND backend, test skipped"
22        exit 0
23esac
24
25if test $DDS = ddsno; then
26          echo "Dynamic Directory Services overlay not available, test skipped"
27          exit 0
28fi
29
30mkdir -p $TESTDIR $DBDIR1
31
32echo "Running slapadd to build slapd database..."
33. $CONFFILTER $BACKEND < $MCONF > $ADDCONF
34$SLAPADD -f $ADDCONF -l $LDIFORDERED
35RC=$?
36if test $RC != 0 ; then
37          echo "slapadd failed ($RC)!"
38          exit $RC
39fi
40
41echo "Running slapindex to index slapd database..."
42. $CONFFILTER $BACKEND < $DDSCONF > $CONF1
43$SLAPINDEX -f $CONF1
44RC=$?
45if test $RC != 0 ; then
46          echo "warning: slapindex failed ($RC)"
47          echo "  assuming no indexing support"
48fi
49
50echo "Starting slapd on TCP/IP port $PORT1..."
51$SLAPD -f $CONF1 -h $URI1 -d $LVL > $LOG1 2>&1 &
52PID=$!
53if test $WAIT != 0 ; then
54    echo PID $PID
55    read foo
56fi
57KILLPIDS="$PID"
58
59sleep 1
60
61echo "Testing slapd searching..."
62for i in 0 1 2 3 4 5; do
63          $LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
64                    '(objectclass=*)' > /dev/null 2>&1
65          RC=$?
66          if test $RC = 0 ; then
67                    break
68          fi
69          echo "Waiting 5 seconds for slapd to start..."
70          sleep 5
71done
72
73if test $RC != 0 ; then
74          echo "ldapsearch failed ($RC)!"
75          test $KILLSERVERS != no && kill -HUP $KILLPIDS
76          exit $RC
77fi
78
79cat /dev/null > $SEARCHOUT
80
81echo "Creating a dynamic entry..."
82$LDAPADD -D $MANAGERDN -w $PASSWD -H $URI1 \
83          >> $TESTOUT 2>&1 << EOMODS
84dn: cn=Dynamic Object,dc=example,dc=com
85objectClass: inetOrgPerson
86objectClass: dynamicObject
87cn: Dynamic Object
88sn: Object
89EOMODS
90RC=$?
91if test $RC != 0 ; then
92          echo "ldapadd failed ($RC)!"
93          test $KILLSERVERS != no && kill -HUP $KILLPIDS
94          exit $RC
95fi
96
97echo "Refreshing the newly created dynamic entry..."
98$LDAPEXOP -D $MANAGERDN -w $PASSWD -H $URI1 \
99          "refresh" "cn=Dynamic Object,dc=example,dc=com" "120" \
100          >> $TESTOUT 2>&1
101RC=$?
102if test $RC != 0 ; then
103          echo "ldapexop failed ($RC)!"
104          test $KILLSERVERS != no && kill -HUP $KILLPIDS
105          exit $RC
106fi
107
108echo "Modifying the newly created dynamic entry..."
109$LDAPMODIFY -D $MANAGERDN -w $PASSWD -H $URI1 \
110          >> $TESTOUT 2>&1 << EOMODS
111dn: cn=Dynamic Object,dc=example,dc=com
112changetype: modify
113add: userPassword
114userPassword: dynamic
115EOMODS
116RC=$?
117if test $RC != 0 ; then
118          echo "ldapadd failed ($RC)!"
119          test $KILLSERVERS != no && kill -HUP $KILLPIDS
120          exit $RC
121fi
122
123echo "Binding as the newly created dynamic entry..."
124$LDAPWHOAMI -H $URI1 \
125          -D "cn=Dynamic Object,dc=example,dc=com" -w dynamic
126RC=$?
127if test $RC != 0 ; then
128          echo "ldapwhoami failed ($RC)!"
129          test $KILLSERVERS != no && kill -HUP $KILLPIDS
130          exit $RC
131fi
132
133echo "Creating a dynamic entry subordinate to another..."
134$LDAPADD -D $MANAGERDN -w $PASSWD -H $URI1 \
135          >> $TESTOUT 2>&1 << EOMODS
136dn: cn=Subordinate Dynamic Object,cn=Dynamic Object,dc=example,dc=com
137objectClass: inetOrgPerson
138objectClass: dynamicObject
139cn: Subordinate Dynamic Object
140sn: Object
141userPassword: dynamic
142EOMODS
143RC=$?
144if test $RC != 0 ; then
145          echo "ldapadd failed ($RC)!"
146          test $KILLSERVERS != no && kill -HUP $KILLPIDS
147          exit $RC
148fi
149
150SEARCH=0
151
152SEARCH=`expr $SEARCH + 1`
153sleep $SLEEP0
154echo "# [$SEARCH] Searching the dynamic portion of the database..." >> $SEARCHOUT
155$LDAPSEARCH -S "" -b "$BASEDN" -H $URI1 \
156          '(objectClass=dynamicObject)' '*' entryTtl \
157          >> $SEARCHOUT 2>&1
158RC=$?
159if test $RC != 0 ; then
160          echo "ldapsearch failed ($RC)!"
161          test $KILLSERVERS != no && kill -HUP $KILLPIDS
162          exit $RC
163fi
164
165echo "Creating a static entry subordinate to a dynamic one (should fail)..."
166$LDAPADD -D $MANAGERDN -w $PASSWD -H $URI1 \
167          >> $TESTOUT 2>&1 << EOMODS
168dn: cn=Subordinate Static Object,cn=Dynamic Object,dc=example,dc=com
169objectClass: inetOrgPerson
170cn: Subordinate Static Object
171sn: Object
172userPassword: static
173EOMODS
174RC=$?
175case $RC in
1760)
177          echo "ldapadd should have failed ($RC)!"
178          test $KILLSERVERS != no && kill -HUP $KILLPIDS
179          exit -1
180          ;;
18119)
182          echo "ldapadd failed ($RC)"
183          ;;
184*)
185          echo "ldapadd failed ($RC)!"
186          test $KILLSERVERS != no && kill -HUP $KILLPIDS
187          exit $RC
188          ;;
189esac
190
191echo "Turning a static into a dynamic entry (should fail)..."
192$LDAPMODIFY -D $MANAGERDN -w $PASSWD -H $URI1 \
193          >> $TESTOUT 2>&1 << EOMODS
194dn: ou=People,dc=example,dc=com
195changetype: modify
196add: objectClass
197objectClass: dynamicObject
198EOMODS
199RC=$?
200case $RC in
2010)
202          echo "ldapmodify should have failed ($RC)!"
203          test $KILLSERVERS != no && kill -HUP $KILLPIDS
204          exit -1
205          ;;
20665)
207          echo "ldapmodify failed ($RC)"
208          ;;
209*)
210          echo "ldapmodify failed ($RC)!"
211          test $KILLSERVERS != no && kill -HUP $KILLPIDS
212          exit $RC
213          ;;
214esac
215
216echo "Turning a dynamic into a static entry (should fail)..."
217$LDAPMODIFY -D $MANAGERDN -w $PASSWD -H $URI1 \
218          >> $TESTOUT 2>&1 << EOMODS
219dn: cn=Dynamic Object,dc=example,dc=com
220changetype: modify
221delete: objectClass
222objectClass: dynamicObject
223EOMODS
224RC=$?
225case $RC in
2260)
227          echo "ldapmodify should have failed ($RC)!"
228          test $KILLSERVERS != no && kill -HUP $KILLPIDS
229          exit -1
230          ;;
23165)
232          echo "ldapmodify failed ($RC)"
233          ;;
234*)
235          echo "ldapmodify failed ($RC)!"
236          test $KILLSERVERS != no && kill -HUP $KILLPIDS
237          exit $RC
238          ;;
239esac
240
241echo "Renaming a dynamic entry..."
242$LDAPMODIFY -D $MANAGERDN -w $PASSWD -H $URI1 \
243          >> $TESTOUT 2>&1 << EOMODS
244dn: cn=Subordinate Dynamic Object,cn=Dynamic Object,dc=example,dc=com
245changetype: modrdn
246newrdn: cn=Renamed Dynamic Object
247deleteoldrdn: 1
248EOMODS
249RC=$?
250if test $RC != 0 ; then
251          echo "ldapmodrdn failed ($RC)!"
252          test $KILLSERVERS != no && kill -HUP $KILLPIDS
253          exit $RC
254fi
255
256SEARCH=`expr $SEARCH + 1`
257sleep $SLEEP0
258echo "# [$SEARCH] Searching the dynamic portion of the database..." >> $SEARCHOUT
259$LDAPSEARCH -S "" -b "$BASEDN" -H $URI1 \
260          '(objectClass=dynamicObject)' '*' entryTtl \
261          >> $SEARCHOUT 2>&1
262RC=$?
263if test $RC != 0 ; then
264          echo "ldapsearch failed ($RC)!"
265          test $KILLSERVERS != no && kill -HUP $KILLPIDS
266          exit $RC
267fi
268
269echo "Refreshing the initial dynamic entry to make it expire earlier than the subordinate..."
270$LDAPEXOP -D $MANAGERDN -w $PASSWD -H $URI1 \
271          "refresh" "cn=Dynamic Object,dc=example,dc=com" "1" \
272          >> $TESTOUT 2>&1
273RC=$?
274if test $RC != 0 ; then
275          echo "ldapexop failed ($RC)!"
276          test $KILLSERVERS != no && kill -HUP $KILLPIDS
277          exit $RC
278fi
279
280SLEEP=10
281echo "Waiting $SLEEP seconds to force a subordinate/superior expiration conflict..."
282sleep $SLEEP
283
284echo "Re-vitalizing the initial dynamic entry..."
285$LDAPEXOP -D $MANAGERDN -w $PASSWD -H $URI1 \
286          "refresh" "cn=Dynamic Object,dc=example,dc=com" "120" \
287          >> $TESTOUT 2>&1
288RC=$?
289if test $RC != 0 ; then
290          echo "ldapexop failed ($RC)!"
291          test $KILLSERVERS != no && kill -HUP $KILLPIDS
292          exit $RC
293fi
294
295echo "Re-renaming the subordinate dynamic entry (new superior)..."
296$LDAPMODIFY -D $MANAGERDN -w $PASSWD -H $URI1 \
297          >> $TESTOUT 2>&1 << EOMODS
298dn: cn=Renamed Dynamic Object,cn=Dynamic Object,dc=example,dc=com
299changetype: modrdn
300newrdn: cn=Renamed Dynamic Object
301deleteoldrdn: 1
302newsuperior: dc=example,dc=com
303EOMODS
304RC=$?
305if test $RC != 0 ; then
306          echo "ldapmodrdn failed ($RC)!"
307          test $KILLSERVERS != no && kill -HUP $KILLPIDS
308          exit $RC
309fi
310
311SEARCH=`expr $SEARCH + 1`
312sleep $SLEEP0
313echo "# [$SEARCH] Searching the dynamic portion of the database..." >> $SEARCHOUT
314$LDAPSEARCH -S "" -b "$BASEDN" -H $URI1 \
315          '(objectClass=dynamicObject)' '*' entryTtl \
316          >> $SEARCHOUT 2>&1
317RC=$?
318if test $RC != 0 ; then
319          echo "ldapsearch failed ($RC)!"
320          test $KILLSERVERS != no && kill -HUP $KILLPIDS
321          exit $RC
322fi
323
324echo "Deleting a dynamic entry..."
325$LDAPMODIFY -D $MANAGERDN -w $PASSWD -H $URI1 \
326          >> $TESTOUT 2>&1 << EOMODS
327dn: cn=Dynamic Object,dc=example,dc=com
328changetype: delete
329EOMODS
330RC=$?
331if test $RC != 0 ; then
332          echo "ldapdelete failed ($RC)!"
333          test $KILLSERVERS != no && kill -HUP $KILLPIDS
334          exit $RC
335fi
336
337SEARCH=`expr $SEARCH + 1`
338sleep $SLEEP0
339echo "# [$SEARCH] Searching the dynamic portion of the database..." >> $SEARCHOUT
340$LDAPSEARCH -S "" -b "$BASEDN" -H $URI1 \
341          '(objectClass=dynamicObject)' '*' entryTtl \
342          >> $SEARCHOUT 2>&1
343RC=$?
344if test $RC != 0 ; then
345          echo "ldapsearch failed ($RC)!"
346          test $KILLSERVERS != no && kill -HUP $KILLPIDS
347          exit $RC
348fi
349
350echo "Refreshing the remaining dynamic entry..."
351$LDAPEXOP -D $MANAGERDN -w $PASSWD -H $URI1 \
352          "refresh" "cn=Renamed Dynamic Object,dc=example,dc=com" "1" \
353          >> $TESTOUT 2>&1
354RC=$?
355if test $RC != 0 ; then
356          echo "ldapexop failed ($RC)!"
357          test $KILLSERVERS != no && kill -HUP $KILLPIDS
358          exit $RC
359fi
360
361SEARCH=`expr $SEARCH + 1`
362sleep $SLEEP0
363echo "# [$SEARCH] Searching the dynamic portion of the database..." >> $SEARCHOUT
364$LDAPSEARCH -S "" -b "$BASEDN" -H $URI1 \
365          '(objectClass=dynamicObject)' '*' entryTtl \
366          >> $SEARCHOUT 2>&1
367RC=$?
368if test $RC != 0 ; then
369          echo "ldapsearch failed ($RC)!"
370          test $KILLSERVERS != no && kill -HUP $KILLPIDS
371          exit $RC
372fi
373
374SLEEP=15
375echo "Waiting $SLEEP seconds for remaining entry to expire..."
376sleep $SLEEP
377
378SEARCH=`expr $SEARCH + 1`
379sleep $SLEEP0
380echo "# [$SEARCH] Searching the dynamic portion of the database..." >> $SEARCHOUT
381$LDAPSEARCH -S "" -b "$BASEDN" -H $URI1 \
382          '(objectClass=dynamicObject)' '*' entryTtl \
383          >> $SEARCHOUT 2>&1
384RC=$?
385if test $RC != 0 ; then
386          echo "ldapsearch failed ($RC)!"
387          test $KILLSERVERS != no && kill -HUP $KILLPIDS
388          exit $RC
389fi
390
391# Meeting
392MEETINGDN="cn=Meeting,ou=Groups,dc=example,dc=com"
393echo "Creating a meeting as $BJORNSDN..."
394$LDAPMODIFY -D "$BJORNSDN" -w bjorn -H $URI1 \
395          >> $TESTOUT 2>&1 << EOMODS
396dn: $MEETINGDN
397changetype: add
398objectClass: groupOfNames
399objectClass: dynamicObject
400cn: Meeting
401member: $BJORNSDN
402
403dn: $MEETINGDN
404changetype: modify
405add: member
406member: $JOHNDDN
407EOMODS
408RC=$?
409if test $RC != 0 ; then
410          echo "ldapmodify failed ($RC)!"
411          test $KILLSERVERS != no && kill -HUP $KILLPIDS
412          exit $RC
413fi
414
415echo "Refreshing the meeting as $BJORNSDN..."
416$LDAPEXOP -D "$BJORNSDN" -w bjorn -H $URI1 \
417          "refresh" "$MEETINGDN" "120" \
418          >> $TESTOUT 2>&1
419RC=$?
420if test $RC != 0 ; then
421          echo "ldapexop failed ($RC)!"
422          test $KILLSERVERS != no && kill -HUP $KILLPIDS
423          exit $RC
424fi
425
426echo "Joining the meeting as $BABSDN..."
427$LDAPMODIFY -D "$BABSDN" -w bjensen -H $URI1 \
428          >> $TESTOUT 2>&1 << EOMODS
429dn: $MEETINGDN
430changetype: modify
431add: member
432member: $BABSDN
433EOMODS
434RC=$?
435if test $RC != 0 ; then
436          echo "ldapmodify failed ($RC)!"
437          test $KILLSERVERS != no && kill -HUP $KILLPIDS
438          exit $RC
439fi
440
441echo "Trying to add a member as $BABSDN (should fail)..."
442$LDAPMODIFY -D "$BABSDN" -w bjensen -H $URI1 \
443          >> $TESTOUT 2>&1 << EOMODS
444dn: $MEETINGDN
445changetype: modify
446add: member
447member: $MELLIOTDN
448EOMODS
449RC=$?
450case $RC in
4510)
452          echo "ldapmodify should have failed ($RC)!"
453          test $KILLSERVERS != no && kill -HUP $KILLPIDS
454          exit -1
455          ;;
45650)
457          echo "ldapmodify failed ($RC)"
458          ;;
459*)
460          echo "ldapmodify failed ($RC)!"
461          test $KILLSERVERS != no && kill -HUP $KILLPIDS
462          exit $RC
463          ;;
464esac
465
466echo "Refreshing the meeting as $BABSDN..."
467$LDAPEXOP -D "$BABSDN" -w bjensen -H $URI1 \
468          "refresh" "$MEETINGDN" "180" \
469          >> $TESTOUT 2>&1
470RC=$?
471if test $RC != 0 ; then
472          echo "ldapexop failed ($RC)!"
473          test $KILLSERVERS != no && kill -HUP $KILLPIDS
474          exit $RC
475fi
476
477echo "Trying to refresh the meeting anonymously (should fail)..."
478$LDAPEXOP -H $URI1 \
479          "refresh" "$MEETINGDN" "240" \
480          >> $TESTOUT 2>&1
481RC=$?
482if test $RC = 0 ; then
483          echo "ldapexop should have failed ($RC)!"
484          test $KILLSERVERS != no && kill -HUP $KILLPIDS
485          exit -1
486fi
487
488echo "Trying to refresh the meeting as $JAJDN (should fail)..."
489$LDAPEXOP -D "$JAJDN" -w "jaj" -H $URI1 \
490          "refresh" "$MEETINGDN" "240" \
491          >> $TESTOUT 2>&1
492RC=$?
493if test $RC = 0 ; then
494          echo "ldapexop should have failed ($RC)!"
495          test $KILLSERVERS != no && kill -HUP $KILLPIDS
496          exit -1
497fi
498
499echo "Trying to delete the meeting as $BABSDN (should fail)..."
500$LDAPMODIFY -D "$BABSDN" -w bjensen -H $URI1 \
501          >> $TESTOUT 2>&1 << EOMODS
502dn: $MEETINGDN
503changetype: delete
504EOMODS
505RC=$?
506case $RC in
5070)
508          echo "ldapdelete should have failed ($RC)!"
509          test $KILLSERVERS != no && kill -HUP $KILLPIDS
510          exit -1
511          ;;
51250)
513          echo "ldapdelete failed ($RC)"
514          ;;
515*)
516          echo "ldapdelete failed ($RC)!"
517          test $KILLSERVERS != no && kill -HUP $KILLPIDS
518          exit $RC
519          ;;
520esac
521
522echo "Deleting the meeting as $BJORNSDN..."
523$LDAPMODIFY -D "$BJORNSDN" -w bjorn -H $URI1 \
524          >> $TESTOUT 2>&1 << EOMODS
525dn: $MEETINGDN
526changetype: delete
527EOMODS
528RC=$?
529if test $RC != 0 ; then
530          echo "ldapdelete failed ($RC)!"
531          test $KILLSERVERS != no && kill -HUP $KILLPIDS
532          exit $RC
533fi
534
535test $KILLSERVERS != no && kill -HUP $KILLPIDS
536
537LDIF=$DDSOUT
538
539# dds removes entryTtl and re-adds it, changing the order of attributes
540echo "Filtering ldapsearch results..."
541$LDIFFILTER -s a < $SEARCHOUT > $SEARCHFLT
542grep -i -v -e '^entryttl: ' < $SEARCHFLT > $SEARCHFLT2
543echo "Filtering original ldif used to create database..."
544$LDIFFILTER -s a < $LDIF > $LDIFFLT
545grep -i -v -e '^entryttl: ' < $LDIFFLT > $LDIFFLT2
546echo "Comparing filter output..."
547$CMP $SEARCHFLT2 $LDIFFLT2 > $CMPOUT
548
549if test $? != 0 ; then
550          echo "Comparison failed"
551          exit 1
552fi
553
554echo "Listing entryTtl values from ldapsearch results..."
555grep -i -e '^entryttl: ' < $SEARCHFLT | awk '{ print $2 }' > $SEARCHFLT2
556echo "Listing entryTtl values from original ldif used to create database..."
557grep -i -e '^entryttl: ' < $LDIFFLT | awk '{ print $2 }' > $LDIFFLT2
558
559if ! type paste >/dev/null 2>&1; then
560    echo "Cannot find 'paste' command, skipping entryTtl checks..."
561else
562    echo "Checking entryTtl appears to decrease with time..."
563    paste $SEARCHFLT2 $LDIFFLT2 | while read resultTTL savedTTL; do
564        if [ `expr $savedTTL - $resultTTL` -lt $SLEEP0 ]; then
565            echo "TTL has not reduced accordingly"
566            exit 1
567        fi
568    done
569fi
570
571echo ">>>>> Test succeeded"
572
573test $KILLSERVERS != no && wait
574
575exit 0
576