1#! /bin/sh
2# $OpenLDAP$
3## This work is part of OpenLDAP Software <http://www.openldap.org/>.
4##
5## Copyright 2004-2011 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 $UNIQUE = uniqueno; then
20	echo "Attribute Uniqueness overlay not available, test skipped"
21	exit 0
22fi
23
24RCODEconstraint=19
25test $BACKEND = null && RCODEconstraint=0
26
27mkdir -p $TESTDIR $DBDIR1
28
29$SLAPPASSWD -g -n >$CONFIGPWF
30echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >$TESTDIR/configpw.conf
31
32echo "Running slapadd to build slapd database..."
33. $CONFFILTER $BACKEND $MONITORDB < $UNIQUECONF > $CONF1
34$SLAPADD -f $CONF1 -l $LDIFUNIQUE
35RC=$?
36if test $RC != 0 ; then
37	echo "slapadd failed ($RC)!"
38	exit $RC
39fi
40
41echo "Starting slapd on TCP/IP port $PORT1..."
42mkdir $TESTDIR/confdir
43$SLAPD -f $CONF1 -F $TESTDIR/confdir -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 &
44PID=$!
45if test $WAIT != 0 ; then
46    echo PID $PID
47    read foo
48fi
49KILLPIDS="$PID"
50
51sleep 1
52
53echo "Testing slapd attribute uniqueness operations..."
54for i in 0 1 2 3 4 5; do
55	$LDAPSEARCH -s base -b "$MONITOR" -h $LOCALHOST -p $PORT1 \
56		'objectclass=*' > /dev/null 2>&1
57	RC=$?
58	if test $RC = 0 ; then
59		break
60	fi
61	echo "Waiting 5 seconds for slapd to start..."
62	sleep 5
63done
64
65if test $RC != 0 ; then
66	echo "ldapsearch failed ($RC)!"
67	test $KILLSERVERS != no && kill -HUP $KILLPIDS
68	exit $RC
69fi
70
71echo "Adding a unique record..."
72$LDAPADD -D "$UNIQUEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
73	> /dev/null << EOTUNIQ1
74dn: uid=dave,ou=users,o=unique
75objectClass: inetOrgPerson
76uid: dave
77sn: nothere
78cn: dave
79businessCategory: otest
80carLicense: TEST
81departmentNumber: 42
82# NOTE: use special chars in attr value to be used
83# in internal searches ITS#4212
84displayName: Dave (ITS#4212)
85employeeNumber: 69
86employeeType: contractor
87givenName: Dave
88EOTUNIQ1
89RC=$?
90if test $RC != 0 ; then
91	echo "ldapadd failed ($RC)!"
92	test $KILLSERVERS != no && kill -HUP $KILLPIDS
93	exit $RC
94fi
95
96echo "Adding a non-unique record..."
97$LDAPADD -D "$UNIQUEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
98	 $TESTOUT 2>&1 << EOTUNIQ2
99dn: uid=bill,ou=users,o=unique
100objectClass: inetOrgPerson
101uid: bill
102sn: johnson
103cn: bill
104businessCategory: rtest
105carLicense: ABC123
106departmentNumber: 42
107displayName: Bill
108employeeNumber: 5150
109employeeType: contractor
110givenName: Bill
111EOTUNIQ2
112RC=$?
113if test $RC != $RCODEconstraint ; then
114	echo "unique check failed ($RC)!"
115	test $KILLSERVERS != no && kill -HUP $KILLPIDS
116	exit -1
117fi
118
119echo Dynamically retrieving initial configuration...
120$LDAPSEARCH -S "" -b olcOverlay='{0}'unique,olcDatabase='{1}'$BACKEND,cn=config -D cn=config -y $CONFIGPWF -h $LOCALHOST -p $PORT1 -LLL | tr -d \\r >$TESTDIR/initial-config.ldif
121cat <<EOF >$TESTDIR/initial-reference.ldif
122dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
123objectClass: olcOverlayConfig
124objectClass: olcUniqueConfig
125olcOverlay: {0}unique
126olcUniqueBase: o=unique
127olcUniqueAttribute: employeeNumber
128olcUniqueAttribute: displayName
129
130EOF
131diff $TESTDIR/initial-config.ldif $TESTDIR/initial-reference.ldif > /dev/null 2>&1
132RC=$?
133if test $RC != 0 ; then
134    echo "Initial configuration is not reported correctly."
135    test $KILLSERVERS != no && kill -HUP $KILLPIDS
136    exit -1
137fi
138
139echo Dynamically trying to add a URI with legacy attrs present...
140$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
141    > $TESTOUT 2>&1 <<EOF
142dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
143changetype: modify
144add: olcUniqueURI
145olcUniqueURI: ldap:///?employeeNumber,displayName?sub
146EOF
147RC=$?
148if test $RC != 80 ; then
149	echo "legacy and unique_uri allowed together"
150	test $KILLSERVERS != no && kill -HUP $KILLPIDS
151	exit -1
152fi
153
154echo Dynamically trying to add legacy ignored attrs with legacy attrs present...
155$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
156    > $TESTOUT 2>&1 <<EOF
157dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
158changetype: modify
159add: olcUniqueIgnore
160olcUniqueIgnore: objectClass
161EOF
162RC=$?
163if test $RC != 80 ; then
164	echo "legacy attrs and legacy ignore attrs allowed together"
165	test $KILLSERVERS != no && kill -HUP $KILLPIDS
166	exit -1
167fi
168
169echo Verifying initial configuration intact...
170$LDAPSEARCH -S "" -b olcOverlay='{0}'unique,olcDatabase='{1}'$BACKEND,cn=config -D cn=config -y $CONFIGPWF -h $LOCALHOST -p $PORT1 -LLL | tr -d \\r >$TESTDIR/initial-config-recheck.ldif
171diff $TESTDIR/initial-config-recheck.ldif $TESTDIR/initial-reference.ldif > /dev/null 2>&1
172RC=$?
173if test $RC != 0 ; then
174    echo "Initial configuration damaged by unsuccessful modifies."
175    test $KILLSERVERS != no && kill -HUP $KILLPIDS
176    exit -1
177fi
178
179echo Dynamically removing legacy base...
180$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
181    > $TESTOUT 2>&1 <<EOF
182dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
183changetype: modify
184delete: olcUniqueBase
185EOF
186RC=$?
187if test $RC != 0 ; then
188	echo "base removal failed"
189	test $KILLSERVERS != no && kill -HUP $KILLPIDS
190	exit -1
191fi
192
193echo Verifying base removal...
194$LDAPSEARCH -S "" -b olcOverlay='{0}'unique,olcDatabase='{1}'$BACKEND,cn=config -D cn=config -y $CONFIGPWF -h $LOCALHOST -p $PORT1 -LLL | tr -d \\r >$TESTDIR/baseremoval-config.ldif
195cat >$TESTDIR/baseremoval-reference.ldif <<EOF
196dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
197objectClass: olcOverlayConfig
198objectClass: olcUniqueConfig
199olcOverlay: {0}unique
200olcUniqueAttribute: employeeNumber
201olcUniqueAttribute: displayName
202
203EOF
204diff $TESTDIR/baseremoval-config.ldif $TESTDIR/baseremoval-reference.ldif > /dev/null 2>&1
205RC=$?
206if test $RC != 0 ; then
207    echo "Configuration damaged by base removal"
208    test $KILLSERVERS != no && kill -HUP $KILLPIDS
209    exit -1
210fi
211
212echo "Adding a non-unique record..."
213$LDAPADD -D "$UNIQUEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
214	 $TESTOUT 2>&1 << EOTUNIQ2
215dn: uid=bill,ou=users,o=unique
216objectClass: inetOrgPerson
217uid: bill
218sn: johnson
219cn: bill
220businessCategory: rtest
221carLicense: ABC123
222departmentNumber: 42
223displayName: Bill
224employeeNumber: 5150
225employeeType: contractor
226givenName: Bill
227EOTUNIQ2
228RC=$?
229if test $RC != $RCODEconstraint ; then
230	echo "unique check failed ($RC)!"
231	test $KILLSERVERS != no && kill -HUP $KILLPIDS
232	exit -1
233fi
234
235echo Trying a legacy base outside of the backend...
236$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
237    > $TESTOUT 2>&1 <<EOF
238dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
239changetype: modify
240add: olcUniqueBase
241olcUniqueBase: cn=config
242EOF
243RC=$?
244if test $RC != 80 ; then
245	echo "out of backend scope base allowed"
246	test $KILLSERVERS != no && kill -HUP $KILLPIDS
247	exit -1
248fi
249
250echo "Adding and removing attrs..."
251$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
252    > $TESTOUT 2>&1 <<EOF
253dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
254changetype: modify
255add: olcUniqueAttribute
256olcUniqueAttribute: description
257olcUniqueAttribute: telephoneNumber
258-
259delete: olcUniqueAttribute
260olcUniqueAttribute: displayName
261EOF
262RC=$?
263if test $RC != 0 ; then
264	echo "Unable to remove an attribute"
265	test $KILLSERVERS != no && kill -HUP $KILLPIDS
266	exit -1
267fi
268
269echo "Verifying we removed the right attr..."
270$LDAPADD -D "$UNIQUEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
271	 $TESTOUT 2>&1 << EOTUNIQ2
272dn: uid=bill,ou=users,o=unique
273objectClass: inetOrgPerson
274uid: bill
275sn: johnson
276cn: bill
277businessCategory: rtest
278carLicense: ABC123
279departmentNumber: 42
280displayName: Bill
281employeeNumber: 5150
282employeeType: contractor
283givenName: Bill
284EOTUNIQ2
285RC=$?
286if test $RC != $RCODEconstraint ; then
287	echo "olcUniqueAttribtue single deletion hit the wrong value"
288	test $KILLSERVERS != no && kill -HUP $KILLPIDS
289	exit -1
290fi
291
292echo Removing legacy config and adding URIs...
293$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
294    > $TESTOUT 2>&1 <<EOF
295dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
296changetype: modify
297delete: olcUniqueAttribute
298-
299add: olcUniqueURI
300olcUniqueURI: ldap:///?employeeNumber,displayName?sub
301olcUniqueURI: ldap:///?description?one
302EOF
303RC=$?
304if test $RC != 0 ; then
305	echo "Reconfiguration to URIs failed"
306	test $KILLSERVERS != no && kill -HUP $KILLPIDS
307	exit -1
308fi
309
310echo Dynamically retrieving second configuration...
311$LDAPSEARCH -S "" -b olcOverlay='{0}'unique,olcDatabase='{1}'$BACKEND,cn=config -D cn=config -y $CONFIGPWF -h $LOCALHOST -p $PORT1 -LLL | tr -d \\r >$TESTDIR/second-config.ldif
312cat >$TESTDIR/second-reference.ldif <<EOF
313dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
314objectClass: olcOverlayConfig
315objectClass: olcUniqueConfig
316olcOverlay: {0}unique
317olcUniqueURI: ldap:///?employeeNumber,displayName?sub
318olcUniqueURI: ldap:///?description?one
319
320EOF
321diff $TESTDIR/second-config.ldif $TESTDIR/second-reference.ldif > /dev/null 2>&1
322RC=$?
323if test $RC != 0 ; then
324    echo "Second configuration is not reported correctly."
325    test $KILLSERVERS != no && kill -HUP $KILLPIDS
326    exit -1
327fi
328
329echo "Adding a non-unique record..."
330$LDAPADD -D "$UNIQUEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
331	 $TESTOUT 2>&1 << EOTUNIQ2
332dn: uid=bill,ou=users,o=unique
333objectClass: inetOrgPerson
334uid: bill
335sn: johnson
336cn: bill
337businessCategory: rtest
338carLicense: ABC123
339departmentNumber: 42
340displayName: Bill
341employeeNumber: 5150
342employeeType: contractor
343givenName: Bill
344EOTUNIQ2
345RC=$?
346if test $RC != $RCODEconstraint ; then
347	echo "unique check failed ($RC)!"
348	test $KILLSERVERS != no && kill -HUP $KILLPIDS
349	exit -1
350fi
351
352echo Dynamically trying to add legacy base
353$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
354    > $TESTOUT 2>&1 <<EOF
355dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
356changetype: modify
357add: olcUniqueBase
358olcUniqueBase: o=unique
359EOF
360RC=$?
361if test $RC != 80 ; then
362	echo "legacy base allowed with URIs"
363	test $KILLSERVERS != no && kill -HUP $KILLPIDS
364	exit -1
365fi
366
367echo Dynamically trying to add legacy attrs
368$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
369    > $TESTOUT 2>&1 <<EOF
370dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
371changetype: modify
372add: olcUniqueAttribute
373olcUniqueAttribute: description
374EOF
375RC=$?
376if test $RC != 80 ; then
377	echo "legacy attributes allowed with URIs"
378	test $KILLSERVERS != no && kill -HUP $KILLPIDS
379	exit -1
380fi
381
382echo Dynamically trying to add legacy strictness
383$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
384    > $TESTOUT 2>&1 <<EOF
385dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
386changetype: modify
387add: olcUniqueStrict
388olcUniqueStrict: TRUE
389EOF
390RC=$?
391if test $RC != 80 ; then
392	echo "legacy strictness allowed with URIs"
393	test $KILLSERVERS != no && kill -HUP $KILLPIDS
394	exit -1
395fi
396
397#echo ----------------------
398echo Dynamically trying a bad filter...
399$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
400    > $TESTOUT 2>&1 <<EOF
401dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
402changetype: modify
403replace: olcUniqueURI
404olcUniqueURI: ldap:///?sn?sub?((cn=e*))
405EOF
406RC=$?
407if test $RC != 80 ; then
408	echo "bad filter allowed"
409	test $KILLSERVERS != no && kill -HUP $KILLPIDS
410	exit -1
411fi
412
413echo Verifying second configuration intact...
414$LDAPSEARCH -S "" -b olcOverlay='{0}'unique,olcDatabase='{1}'$BACKEND,cn=config -D cn=config -y $CONFIGPWF -h $LOCALHOST -p $PORT1 -LLL | tr -d \\r >$TESTDIR/second-config-recheck.ldif
415diff $TESTDIR/second-config-recheck.ldif $TESTDIR/second-reference.ldif > /dev/null 2>&1
416RC=$?
417if test $RC != 0 ; then
418    echo "Second configuration damaged by rejected modifies."
419    test $KILLSERVERS != no && kill -HUP $KILLPIDS
420    exit -1
421fi
422
423#echo ----------------------
424echo Dynamically reconfiguring to use different URIs...
425$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
426    > $TESTOUT 2>&1 <<EOF
427dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
428changetype: modify
429add: olcUniqueURI
430olcUniqueURI: ldap:///?sn?sub?(cn=e*)
431olcUniqueURI: ldap:///?uid?sub?(cn=edgar)
432-
433delete: olcUniqueURI
434olcUniqueURI: ldap:///?description?one
435EOF
436RC=$?
437if test $RC != 0 ; then
438	echo "unable to reconfigure"
439	test $KILLSERVERS != no && kill -HUP $KILLPIDS
440	exit -1
441fi
442
443echo Dynamically retrieving third configuration...
444$LDAPSEARCH -S "" -b olcOverlay='{0}'unique,olcDatabase='{1}'$BACKEND,cn=config -D cn=config -y $CONFIGPWF -h $LOCALHOST -p $PORT1 -LLL | tr -d \\r >$TESTDIR/third-config.ldif
445cat >$TESTDIR/third-reference.ldif <<EOF
446dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
447objectClass: olcOverlayConfig
448objectClass: olcUniqueConfig
449olcOverlay: {0}unique
450olcUniqueURI: ldap:///?employeeNumber,displayName?sub
451olcUniqueURI: ldap:///?sn?sub?(cn=e*)
452olcUniqueURI: ldap:///?uid?sub?(cn=edgar)
453
454EOF
455diff $TESTDIR/third-config.ldif $TESTDIR/third-reference.ldif > /dev/null 2>&1
456RC=$?
457if test $RC != 0 ; then
458    echo "Third configuration is not reported correctly."
459    test $KILLSERVERS != no && kill -HUP $KILLPIDS
460    exit -1
461fi
462
463echo "Adding a record unique in both domains if filtered..."
464
465$LDAPADD -D "$UNIQUEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
466	 $TESTOUT 2>&1 << EOF
467dn: uid=edgar,ou=users,o=unique
468objectClass: inetOrgPerson
469uid: edgar
470sn: johnson
471cn: edgar
472EOF
473
474RC=$?
475if test $RC != 0 ; then
476	echo "unique check failed ($RC)!"
477	test $KILLSERVERS != no && kill -HUP $KILLPIDS
478	exit -1
479fi
480
481echo "Adding a record unique in all domains because of filter conditions "
482$LDAPADD -D "$UNIQUEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
483	 $TESTOUT 2>&1 << EOF
484dn: uid=empty,ou=users,o=unique
485objectClass: inetOrgPerson
486uid: edgar
487cn: empty
488sn: empty
489EOF
490
491RC=$?
492if test $RC != 0 ; then
493	echo "spurious unique error ($RC)!"
494	test $KILLSERVERS != no && kill -HUP $KILLPIDS
495	exit -1
496fi
497
498
499echo "Adding a record unique in one domain, non-unique in the filtered domain..."
500
501$LDAPADD -D "$UNIQUEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
502	 $TESTOUT 2>&1 << EOF
503dn: uid=elvis,ou=users,o=unique
504objectClass: inetOrgPerson
505uid: elvis
506sn: johnson
507cn: elvis
508EOF
509
510RC=$?
511if test $RC != $RCODEconstraint ; then
512	echo "unique check failed ($RC)!"
513	test $KILLSERVERS != no && kill -HUP $KILLPIDS
514	exit -1
515fi
516
517#echo ----------------------
518echo Dynamically reconfiguring to use attribute-ignore URIs...
519$LDAPMODIFY -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF \
520    > $TESTOUT 2>&1 <<EOF
521dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
522changetype: modify
523replace: olcUniqueURI
524olcUniqueURI: ignore ldap:///?objectClass,uid,cn,sn?sub
525EOF
526RC=$?
527if test $RC != 0 ; then
528	echo "unable to reconfigure"
529	test $KILLSERVERS != no && kill -HUP $KILLPIDS
530	exit -1
531fi
532
533echo Dynamically retrieving fourth configuration...
534$LDAPSEARCH -S "" -b olcOverlay='{0}'unique,olcDatabase='{1}'$BACKEND,cn=config -D cn=config -y $CONFIGPWF -h $LOCALHOST -p $PORT1 -LLL | tr -d \\r >$TESTDIR/fourth-config.ldif
535cat >$TESTDIR/fourth-reference.ldif <<EOF
536dn: olcOverlay={0}unique,olcDatabase={1}$BACKEND,cn=config
537objectClass: olcOverlayConfig
538objectClass: olcUniqueConfig
539olcOverlay: {0}unique
540olcUniqueURI: ignore ldap:///?objectClass,uid,cn,sn?sub
541
542EOF
543diff $TESTDIR/fourth-config.ldif $TESTDIR/fourth-reference.ldif > /dev/null 2>&1
544RC=$?
545if test $RC != 0 ; then
546    echo "Fourth configuration is not reported correctly."
547    test $KILLSERVERS != no && kill -HUP $KILLPIDS
548    exit -1
549fi
550
551echo "Adding a record unique in the ignore-domain..."
552
553$LDAPADD -D "$UNIQUEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
554	 $TESTOUT 2>&1 << EOF
555dn: uid=elvis,ou=users,o=unique
556objectClass: inetOrgPerson
557uid: elvis
558sn: johnson
559cn: elvis
560description: left the building
561EOF
562
563RC=$?
564if test $RC != 0 ; then
565	echo "unique check failed ($RC)!"
566	test $KILLSERVERS != no && kill -HUP $KILLPIDS
567	exit -1
568fi
569
570echo "Adding a record non-unique in the ignore-domain..."
571
572$LDAPADD -D "$UNIQUEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
573	 $TESTOUT 2>&1 << EOF
574dn: uid=harry,ou=users,o=unique
575objectClass: inetOrgPerson
576uid: harry
577sn: johnson
578cn: harry
579description: left the building
580EOF
581
582RC=$?
583if test $RC != $RCODEconstraint ; then
584	echo "unique check failed ($RC)!"
585	test $KILLSERVERS != no && kill -HUP $KILLPIDS
586	exit -1
587fi
588
589test $KILLSERVERS != no && kill -HUP $KILLPIDS
590
591echo ">>>>> Test succeeded"
592
593test $KILLSERVERS != no && wait
594
595exit 0
596