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