1 /* at.c - routines for dealing with attribute types */
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
17 #include "portable.h"
18
19 #include <stdio.h>
20
21 #include <ac/ctype.h>
22 #include <ac/errno.h>
23 #include <ac/socket.h>
24 #include <ac/string.h>
25 #include <ac/time.h>
26
27 #include "slap.h"
28
29
30 const char *
at_syntax(AttributeType * at)31 at_syntax(
32 AttributeType *at )
33 {
34 for ( ; at != NULL; at = at->sat_sup ) {
35 if ( at->sat_syntax_oid ) {
36 return at->sat_syntax_oid;
37 }
38 }
39
40 assert( 0 );
41
42 return NULL;
43 }
44
45 int
is_at_syntax(AttributeType * at,const char * oid)46 is_at_syntax(
47 AttributeType *at,
48 const char *oid )
49 {
50 const char *syn_oid = at_syntax( at );
51
52 if ( syn_oid ) {
53 return strcmp( syn_oid, oid ) == 0;
54 }
55
56 return 0;
57 }
58
is_at_subtype(AttributeType * sub,AttributeType * sup)59 int is_at_subtype(
60 AttributeType *sub,
61 AttributeType *sup )
62 {
63 for( ; sub != NULL; sub = sub->sat_sup ) {
64 if( sub == sup ) return 1;
65 }
66
67 return 0;
68 }
69
70 struct aindexrec {
71 struct berval air_name;
72 AttributeType *air_at;
73 };
74
75 static Avlnode *attr_index = NULL;
76 static Avlnode *attr_cache = NULL;
77 static LDAP_STAILQ_HEAD(ATList, AttributeType) attr_list
78 = LDAP_STAILQ_HEAD_INITIALIZER(attr_list);
79
80 /* Last hardcoded attribute registered */
81 AttributeType *at_sys_tail;
82
83 int at_oc_cache;
84
85 static int
attr_index_cmp(const void * v_air1,const void * v_air2)86 attr_index_cmp(
87 const void *v_air1,
88 const void *v_air2 )
89 {
90 const struct aindexrec *air1 = v_air1;
91 const struct aindexrec *air2 = v_air2;
92 int i = air1->air_name.bv_len - air2->air_name.bv_len;
93 if (i) return i;
94 return (strcasecmp( air1->air_name.bv_val, air2->air_name.bv_val ));
95 }
96
97 static int
attr_index_name_cmp(const void * v_type,const void * v_air)98 attr_index_name_cmp(
99 const void *v_type,
100 const void *v_air )
101 {
102 const struct berval *type = v_type;
103 const struct aindexrec *air = v_air;
104 int i = type->bv_len - air->air_name.bv_len;
105 if (i) return i;
106 return (strncasecmp( type->bv_val, air->air_name.bv_val, type->bv_len ));
107 }
108
109 AttributeType *
at_find(const char * name)110 at_find( const char *name )
111 {
112 struct berval bv;
113
114 bv.bv_val = (char *)name;
115 bv.bv_len = strlen( name );
116
117 return at_bvfind( &bv );
118 }
119
120 AttributeType *
at_bvfind(struct berval * name)121 at_bvfind( struct berval *name )
122 {
123 struct aindexrec *air;
124
125 if ( attr_cache ) {
126 air = ldap_avl_find( attr_cache, name, attr_index_name_cmp );
127 if ( air ) return air->air_at;
128 }
129
130 air = ldap_avl_find( attr_index, name, attr_index_name_cmp );
131
132 if ( air ) {
133 if ( air->air_at->sat_flags & SLAP_AT_DELETED ) {
134 air = NULL;
135 } else if (( slapMode & SLAP_TOOL_MODE ) && at_oc_cache ) {
136 ldap_avl_insert( &attr_cache, (caddr_t) air,
137 attr_index_cmp, ldap_avl_dup_error );
138 }
139 }
140
141 return air != NULL ? air->air_at : NULL;
142 }
143
144 int
at_append_to_list(AttributeType * sat,AttributeType *** listp)145 at_append_to_list(
146 AttributeType *sat,
147 AttributeType ***listp )
148 {
149 AttributeType **list;
150 AttributeType **list1;
151 int size;
152
153 list = *listp;
154 if ( !list ) {
155 size = 2;
156 list = ch_calloc(size, sizeof(AttributeType *));
157 if ( !list ) {
158 return -1;
159 }
160 } else {
161 size = 0;
162 list1 = *listp;
163 while ( *list1 ) {
164 size++;
165 list1++;
166 }
167 size += 2;
168 list1 = ch_realloc(list, size*sizeof(AttributeType *));
169 if ( !list1 ) {
170 return -1;
171 }
172 list = list1;
173 }
174 list[size-2] = sat;
175 list[size-1] = NULL;
176 *listp = list;
177 return 0;
178 }
179
180 int
at_delete_from_list(int pos,AttributeType *** listp)181 at_delete_from_list(
182 int pos,
183 AttributeType ***listp )
184 {
185 AttributeType **list;
186 AttributeType **list1;
187 int i;
188 int j;
189
190 if ( pos < 0 ) {
191 return -2;
192 }
193 list = *listp;
194 for ( i=0; list[i]; i++ )
195 ;
196 if ( pos >= i ) {
197 return -2;
198 }
199 for ( i=pos, j=pos+1; list[j]; i++, j++ ) {
200 list[i] = list[j];
201 }
202 list[i] = NULL;
203 /* Tell the runtime this can be shrunk */
204 list1 = ch_realloc(list, (i+1)*sizeof(AttributeType **));
205 if ( !list1 ) {
206 return -1;
207 }
208 *listp = list1;
209 return 0;
210 }
211
212 int
at_find_in_list(AttributeType * sat,AttributeType ** list)213 at_find_in_list(
214 AttributeType *sat,
215 AttributeType **list )
216 {
217 int i;
218
219 if ( !list ) {
220 return -1;
221 }
222 for ( i=0; list[i]; i++ ) {
223 if ( sat == list[i] ) {
224 return i;
225 }
226 }
227 return -1;
228 }
229
230 static void
at_delete_names(AttributeType * at)231 at_delete_names( AttributeType *at )
232 {
233 char **names = at->sat_names;
234
235 if (!names) return;
236
237 while (*names) {
238 struct aindexrec tmpair, *air;
239
240 ber_str2bv( *names, 0, 0, &tmpair.air_name );
241 tmpair.air_at = at;
242 air = (struct aindexrec *)ldap_avl_delete( &attr_index,
243 (caddr_t)&tmpair, attr_index_cmp );
244 assert( air != NULL );
245 ldap_memfree( air );
246 names++;
247 }
248 }
249
250 /* Mark the attribute as deleted, remove from list, and remove all its
251 * names from the AVL tree. Leave the OID in the tree.
252 */
253 void
at_delete(AttributeType * at)254 at_delete( AttributeType *at )
255 {
256 at->sat_flags |= SLAP_AT_DELETED;
257
258 LDAP_STAILQ_REMOVE(&attr_list, at, AttributeType, sat_next);
259
260 at_delete_names( at );
261 }
262
263 static void
at_clean(AttributeType * a)264 at_clean( AttributeType *a )
265 {
266 if ( a->sat_equality ) {
267 MatchingRule *mr;
268
269 mr = mr_find( a->sat_equality->smr_oid );
270 assert( mr != NULL );
271 if ( mr != a->sat_equality ) {
272 ch_free( a->sat_equality );
273 a->sat_equality = NULL;
274 }
275 }
276
277 assert( a->sat_syntax != NULL );
278 if ( a->sat_syntax != NULL ) {
279 Syntax *syn;
280
281 syn = syn_find( a->sat_syntax->ssyn_oid );
282 assert( syn != NULL );
283 if ( syn != a->sat_syntax ) {
284 ch_free( a->sat_syntax );
285 a->sat_syntax = NULL;
286 }
287 }
288
289 if ( a->sat_oidmacro ) {
290 ldap_memfree( a->sat_oidmacro );
291 a->sat_oidmacro = NULL;
292 }
293 if ( a->sat_soidmacro ) {
294 ldap_memfree( a->sat_soidmacro );
295 a->sat_soidmacro = NULL;
296 }
297 if ( a->sat_subtypes ) {
298 ldap_memfree( a->sat_subtypes );
299 a->sat_subtypes = NULL;
300 }
301 }
302
303 static void
at_destroy_one(void * v)304 at_destroy_one( void *v )
305 {
306 struct aindexrec *air = v;
307 AttributeType *a = air->air_at;
308
309 at_clean( a );
310 ad_destroy(a->sat_ad);
311 ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex);
312 ldap_attributetype_free((LDAPAttributeType *)a);
313 ldap_memfree(air);
314 }
315
316 void
at_destroy(void)317 at_destroy( void )
318 {
319 AttributeType *a;
320
321 while( !LDAP_STAILQ_EMPTY(&attr_list) ) {
322 a = LDAP_STAILQ_FIRST(&attr_list);
323 LDAP_STAILQ_REMOVE_HEAD(&attr_list, sat_next);
324
325 at_delete_names( a );
326 }
327
328 ldap_avl_free(attr_index, at_destroy_one);
329
330 if ( slap_schema.si_at_undefined ) {
331 ad_destroy(slap_schema.si_at_undefined->sat_ad);
332 }
333
334 if ( slap_schema.si_at_proxied ) {
335 ad_destroy(slap_schema.si_at_proxied->sat_ad);
336 }
337 }
338
339 int
at_start(AttributeType ** at)340 at_start( AttributeType **at )
341 {
342 assert( at != NULL );
343
344 *at = LDAP_STAILQ_FIRST(&attr_list);
345
346 return (*at != NULL);
347 }
348
349 int
at_next(AttributeType ** at)350 at_next( AttributeType **at )
351 {
352 assert( at != NULL );
353
354 #if 0 /* pedantic check: don't use this */
355 {
356 AttributeType *tmp = NULL;
357
358 LDAP_STAILQ_FOREACH(tmp,&attr_list,sat_next) {
359 if ( tmp == *at ) {
360 break;
361 }
362 }
363
364 assert( tmp != NULL );
365 }
366 #endif
367
368 if ( *at == NULL ) {
369 return 0;
370 }
371
372 *at = LDAP_STAILQ_NEXT(*at,sat_next);
373
374 return (*at != NULL);
375 }
376
377 /*
378 * check whether the two attributeTypes actually __are__ identical,
379 * or rather inconsistent
380 */
381 static int
at_check_dup(AttributeType * sat,AttributeType * new_sat)382 at_check_dup(
383 AttributeType *sat,
384 AttributeType *new_sat )
385 {
386 if ( new_sat->sat_oid != NULL ) {
387 if ( sat->sat_oid == NULL ) {
388 return SLAP_SCHERR_ATTR_INCONSISTENT;
389 }
390
391 if ( strcmp( sat->sat_oid, new_sat->sat_oid ) != 0 ) {
392 return SLAP_SCHERR_ATTR_INCONSISTENT;
393 }
394
395 } else {
396 if ( sat->sat_oid != NULL ) {
397 return SLAP_SCHERR_ATTR_INCONSISTENT;
398 }
399 }
400
401 if ( new_sat->sat_names ) {
402 int i;
403
404 if ( sat->sat_names == NULL ) {
405 return SLAP_SCHERR_ATTR_INCONSISTENT;
406 }
407
408 for ( i = 0; new_sat->sat_names[ i ]; i++ ) {
409 if ( sat->sat_names[ i ] == NULL ) {
410 return SLAP_SCHERR_ATTR_INCONSISTENT;
411 }
412
413 if ( strcasecmp( sat->sat_names[ i ],
414 new_sat->sat_names[ i ] ) != 0 )
415 {
416 return SLAP_SCHERR_ATTR_INCONSISTENT;
417 }
418 }
419 } else {
420 if ( sat->sat_names != NULL ) {
421 return SLAP_SCHERR_ATTR_INCONSISTENT;
422 }
423 }
424
425 return SLAP_SCHERR_ATTR_DUP;
426 }
427
428 static struct aindexrec *air_old;
429
430 static int
at_dup_error(void * left,void * right)431 at_dup_error( void *left, void *right )
432 {
433 air_old = left;
434 return -1;
435 }
436
437 static int
at_insert(AttributeType ** rat,AttributeType * prev,const char ** err)438 at_insert(
439 AttributeType **rat,
440 AttributeType *prev,
441 const char **err )
442 {
443 struct aindexrec *air;
444 char **names = NULL;
445 AttributeType *sat = *rat;
446
447 if ( sat->sat_oid ) {
448 air = (struct aindexrec *)
449 ch_calloc( 1, sizeof(struct aindexrec) );
450 ber_str2bv( sat->sat_oid, 0, 0, &air->air_name );
451 air->air_at = sat;
452 air_old = NULL;
453
454 if ( ldap_avl_insert( &attr_index, (caddr_t) air,
455 attr_index_cmp, at_dup_error ) )
456 {
457 AttributeType *old_sat;
458 int rc;
459
460 *err = sat->sat_oid;
461
462 assert( air_old != NULL );
463 old_sat = air_old->air_at;
464
465 /* replacing a deleted definition? */
466 if ( old_sat->sat_flags & SLAP_AT_DELETED ) {
467 AttributeType tmp;
468 AttributeDescription *ad;
469
470 /* Keep old oid, free new oid;
471 * Keep old ads, free new ads;
472 * Keep old ad_mutex, free new ad_mutex;
473 * Keep new everything else, free old
474 */
475 tmp = *old_sat;
476 *old_sat = *sat;
477 old_sat->sat_oid = tmp.sat_oid;
478 tmp.sat_oid = sat->sat_oid;
479 old_sat->sat_ad = tmp.sat_ad;
480 tmp.sat_ad = sat->sat_ad;
481 old_sat->sat_ad_mutex = tmp.sat_ad_mutex;
482 tmp.sat_ad_mutex = sat->sat_ad_mutex;
483 *sat = tmp;
484
485 /* Check for basic ad pointing at old cname */
486 for ( ad = old_sat->sat_ad; ad; ad=ad->ad_next ) {
487 if ( ad->ad_cname.bv_val == sat->sat_cname.bv_val ) {
488 ad->ad_cname = old_sat->sat_cname;
489 break;
490 }
491 }
492
493 at_clean( sat );
494 at_destroy_one( air );
495
496 air = air_old;
497 sat = old_sat;
498 *rat = sat;
499 } else {
500 ldap_memfree( air );
501
502 rc = at_check_dup( old_sat, sat );
503
504 return rc;
505 }
506 }
507 /* FIX: temporal consistency check */
508 at_bvfind( &air->air_name );
509 }
510
511 names = sat->sat_names;
512 if ( names ) {
513 while ( *names ) {
514 air = (struct aindexrec *)
515 ch_calloc( 1, sizeof(struct aindexrec) );
516 ber_str2bv( *names, 0, 0, &air->air_name );
517 air->air_at = sat;
518 if ( ldap_avl_insert( &attr_index, (caddr_t) air,
519 attr_index_cmp, ldap_avl_dup_error ) )
520 {
521 AttributeType *old_sat;
522 int rc;
523
524 *err = *names;
525
526 old_sat = at_bvfind( &air->air_name );
527 assert( old_sat != NULL );
528 rc = at_check_dup( old_sat, sat );
529
530 ldap_memfree(air);
531
532 while ( names > sat->sat_names ) {
533 struct aindexrec tmpair;
534
535 names--;
536 ber_str2bv( *names, 0, 0, &tmpair.air_name );
537 tmpair.air_at = sat;
538 air = (struct aindexrec *)ldap_avl_delete( &attr_index,
539 (caddr_t)&tmpair, attr_index_cmp );
540 assert( air != NULL );
541 ldap_memfree( air );
542 }
543
544 if ( sat->sat_oid ) {
545 struct aindexrec tmpair;
546
547 ber_str2bv( sat->sat_oid, 0, 0, &tmpair.air_name );
548 tmpair.air_at = sat;
549 air = (struct aindexrec *)ldap_avl_delete( &attr_index,
550 (caddr_t)&tmpair, attr_index_cmp );
551 assert( air != NULL );
552 ldap_memfree( air );
553 }
554
555 return rc;
556 }
557 /* FIX: temporal consistency check */
558 at_bvfind(&air->air_name);
559 names++;
560 }
561 }
562
563 if ( sat->sat_oid ) {
564 slap_ad_undef_promote( sat->sat_oid, sat );
565 }
566
567 names = sat->sat_names;
568 if ( names ) {
569 while ( *names ) {
570 slap_ad_undef_promote( *names, sat );
571 names++;
572 }
573 }
574
575 if ( sat->sat_flags & SLAP_AT_HARDCODE ) {
576 prev = at_sys_tail;
577 at_sys_tail = sat;
578 }
579 if ( prev ) {
580 LDAP_STAILQ_INSERT_AFTER( &attr_list, prev, sat, sat_next );
581 } else {
582 LDAP_STAILQ_INSERT_TAIL( &attr_list, sat, sat_next );
583 }
584
585 return 0;
586 }
587
588 int
at_add(LDAPAttributeType * at,int user,AttributeType ** rsat,AttributeType * prev,const char ** err)589 at_add(
590 LDAPAttributeType *at,
591 int user,
592 AttributeType **rsat,
593 AttributeType *prev,
594 const char **err )
595 {
596 AttributeType *sat = NULL;
597 MatchingRule *mr = NULL;
598 Syntax *syn = NULL;
599 int i;
600 int code = LDAP_SUCCESS;
601 char *cname = NULL;
602 char *oidm = NULL;
603 char *soidm = NULL;
604
605 if ( !at->at_oid ) {
606 *err = "";
607 return SLAP_SCHERR_ATTR_INCOMPLETE;
608 }
609
610 if ( !OID_LEADCHAR( at->at_oid[0] )) {
611 char *oid;
612
613 /* Expand OID macros */
614 oid = oidm_find( at->at_oid );
615 if ( !oid ) {
616 *err = at->at_oid;
617 return SLAP_SCHERR_OIDM;
618 }
619 if ( oid != at->at_oid ) {
620 oidm = at->at_oid;
621 at->at_oid = oid;
622 }
623 }
624
625 if ( at->at_syntax_oid && !OID_LEADCHAR( at->at_syntax_oid[0] )) {
626 char *oid;
627
628 /* Expand OID macros */
629 oid = oidm_find( at->at_syntax_oid );
630 if ( !oid ) {
631 *err = at->at_syntax_oid;
632 code = SLAP_SCHERR_OIDM;
633 goto error_return;
634 }
635 if ( oid != at->at_syntax_oid ) {
636 soidm = at->at_syntax_oid;
637 at->at_syntax_oid = oid;
638 }
639 }
640
641 if ( at->at_names && at->at_names[0] ) {
642 int i;
643
644 for( i=0; at->at_names[i]; i++ ) {
645 if( !slap_valid_descr( at->at_names[i] ) ) {
646 *err = at->at_names[i];
647 code = SLAP_SCHERR_BAD_DESCR;
648 goto error_return;
649 }
650 }
651
652 cname = at->at_names[0];
653
654 } else {
655 cname = at->at_oid;
656
657 }
658
659 *err = cname;
660
661 if ( !at->at_usage && at->at_no_user_mod ) {
662 /* user attribute must be modifiable */
663 code = SLAP_SCHERR_ATTR_BAD_USAGE;
664 goto error_return;
665 }
666
667 if ( at->at_collective ) {
668 if( at->at_usage ) {
669 /* collective attributes cannot be operational */
670 code = SLAP_SCHERR_ATTR_BAD_USAGE;
671 goto error_return;
672 }
673
674 if( at->at_single_value ) {
675 /* collective attributes cannot be single-valued */
676 code = SLAP_SCHERR_ATTR_BAD_USAGE;
677 goto error_return;
678 }
679 }
680
681 sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
682 AC_MEMCPY( &sat->sat_atype, at, sizeof(LDAPAttributeType));
683
684 sat->sat_cname.bv_val = cname;
685 sat->sat_cname.bv_len = strlen( cname );
686 sat->sat_oidmacro = oidm;
687 sat->sat_soidmacro = soidm;
688 ldap_pvt_thread_mutex_init(&sat->sat_ad_mutex);
689
690 if ( at->at_sup_oid ) {
691 AttributeType *supsat = at_find(at->at_sup_oid);
692
693 if ( supsat == NULL ) {
694 *err = at->at_sup_oid;
695 code = SLAP_SCHERR_ATTR_NOT_FOUND;
696 goto error_return;
697 }
698
699 sat->sat_sup = supsat;
700
701 if ( at_append_to_list(sat, &supsat->sat_subtypes) ) {
702 code = SLAP_SCHERR_OUTOFMEM;
703 goto error_return;
704 }
705
706 if ( sat->sat_usage != supsat->sat_usage ) {
707 /* subtypes must have same usage as their SUP */
708 code = SLAP_SCHERR_ATTR_BAD_USAGE;
709 goto error_return;
710 }
711
712 if ( supsat->sat_obsolete && !sat->sat_obsolete ) {
713 /* subtypes must be obsolete if super is */
714 code = SLAP_SCHERR_ATTR_BAD_SUP;
715 goto error_return;
716 }
717
718 if ( sat->sat_flags & SLAP_AT_FINAL ) {
719 /* cannot subtype a "final" attribute type */
720 code = SLAP_SCHERR_ATTR_BAD_SUP;
721 goto error_return;
722 }
723 }
724
725 /*
726 * Inherit definitions from superiors. We only check the
727 * direct superior since that one has already inherited from
728 * its own superiors
729 */
730 if ( sat->sat_sup ) {
731 Syntax *syn = syn_find(sat->sat_sup->sat_syntax->ssyn_oid);
732 if ( syn != sat->sat_sup->sat_syntax ) {
733 sat->sat_syntax = ch_malloc( sizeof( Syntax ));
734 *sat->sat_syntax = *sat->sat_sup->sat_syntax;
735 } else {
736 sat->sat_syntax = sat->sat_sup->sat_syntax;
737 }
738 if ( sat->sat_sup->sat_equality ) {
739 MatchingRule *mr = mr_find( sat->sat_sup->sat_equality->smr_oid );
740 if ( mr != sat->sat_sup->sat_equality ) {
741 sat->sat_equality = ch_malloc( sizeof( MatchingRule ));
742 *sat->sat_equality = *sat->sat_sup->sat_equality;
743 } else {
744 sat->sat_equality = sat->sat_sup->sat_equality;
745 }
746 }
747 sat->sat_approx = sat->sat_sup->sat_approx;
748 sat->sat_ordering = sat->sat_sup->sat_ordering;
749 sat->sat_substr = sat->sat_sup->sat_substr;
750 }
751
752 /*
753 * check for X-ORDERED attributes
754 */
755 if ( sat->sat_extensions ) {
756 for (i=0; sat->sat_extensions[i]; i++) {
757 if (!strcasecmp( sat->sat_extensions[i]->lsei_name,
758 "X-ORDERED" ) && sat->sat_extensions[i]->lsei_values ) {
759 if ( !strcasecmp( sat->sat_extensions[i]->lsei_values[0],
760 "VALUES" )) {
761 sat->sat_flags |= SLAP_AT_ORDERED_VAL;
762 break;
763 } else if ( !strcasecmp( sat->sat_extensions[i]->lsei_values[0],
764 "SIBLINGS" )) {
765 sat->sat_flags |= SLAP_AT_ORDERED_SIB;
766 break;
767 }
768 }
769 }
770 }
771
772 if ( !user )
773 sat->sat_flags |= SLAP_AT_HARDCODE;
774
775 if ( at->at_syntax_oid ) {
776 syn = syn_find(sat->sat_syntax_oid);
777 if ( syn == NULL ) {
778 *err = sat->sat_syntax_oid;
779 code = SLAP_SCHERR_SYN_NOT_FOUND;
780 goto error_return;
781 }
782
783 if ( sat->sat_syntax != NULL && sat->sat_syntax != syn ) {
784 /* BEWARE: no loop detection! */
785 if ( syn_is_sup( sat->sat_syntax, syn ) ) {
786 code = SLAP_SCHERR_ATTR_BAD_SUP;
787 goto error_return;
788 }
789 }
790
791 sat->sat_syntax = syn;
792
793 } else if ( sat->sat_syntax == NULL ) {
794 code = SLAP_SCHERR_ATTR_INCOMPLETE;
795 goto error_return;
796 }
797
798 if ( sat->sat_equality_oid ) {
799 mr = mr_find(sat->sat_equality_oid);
800
801 if( mr == NULL ) {
802 *err = sat->sat_equality_oid;
803 code = SLAP_SCHERR_MR_NOT_FOUND;
804 goto error_return;
805 }
806
807 if(( mr->smr_usage & SLAP_MR_EQUALITY ) != SLAP_MR_EQUALITY ) {
808 *err = sat->sat_equality_oid;
809 code = SLAP_SCHERR_ATTR_BAD_MR;
810 goto error_return;
811 }
812
813 if( sat->sat_syntax != mr->smr_syntax ) {
814 if( mr->smr_compat_syntaxes == NULL ) {
815 *err = sat->sat_equality_oid;
816 code = SLAP_SCHERR_ATTR_BAD_MR;
817 goto error_return;
818 }
819
820 for(i=0; mr->smr_compat_syntaxes[i]; i++) {
821 if( sat->sat_syntax == mr->smr_compat_syntaxes[i] ) {
822 i = -1;
823 break;
824 }
825 }
826
827 if( i >= 0 ) {
828 *err = sat->sat_equality_oid;
829 code = SLAP_SCHERR_ATTR_BAD_MR;
830 goto error_return;
831 }
832 }
833
834 sat->sat_equality = mr;
835 sat->sat_approx = mr->smr_associated;
836 }
837
838 if ( sat->sat_ordering_oid ) {
839 if( !sat->sat_equality ) {
840 *err = sat->sat_ordering_oid;
841 code = SLAP_SCHERR_ATTR_BAD_MR;
842 goto error_return;
843 }
844
845 mr = mr_find(sat->sat_ordering_oid);
846
847 if( mr == NULL ) {
848 *err = sat->sat_ordering_oid;
849 code = SLAP_SCHERR_MR_NOT_FOUND;
850 goto error_return;
851 }
852
853 if(( mr->smr_usage & SLAP_MR_ORDERING ) != SLAP_MR_ORDERING ) {
854 *err = sat->sat_ordering_oid;
855 code = SLAP_SCHERR_ATTR_BAD_MR;
856 goto error_return;
857 }
858
859 if( sat->sat_syntax != mr->smr_syntax ) {
860 if( mr->smr_compat_syntaxes == NULL ) {
861 *err = sat->sat_ordering_oid;
862 code = SLAP_SCHERR_ATTR_BAD_MR;
863 goto error_return;
864 }
865
866 for(i=0; mr->smr_compat_syntaxes[i]; i++) {
867 if( sat->sat_syntax == mr->smr_compat_syntaxes[i] ) {
868 i = -1;
869 break;
870 }
871 }
872
873 if( i >= 0 ) {
874 *err = sat->sat_ordering_oid;
875 code = SLAP_SCHERR_ATTR_BAD_MR;
876 goto error_return;
877 }
878 }
879
880 sat->sat_ordering = mr;
881 }
882
883 if ( sat->sat_substr_oid ) {
884 if( !sat->sat_equality ) {
885 *err = sat->sat_substr_oid;
886 code = SLAP_SCHERR_ATTR_BAD_MR;
887 goto error_return;
888 }
889
890 mr = mr_find(sat->sat_substr_oid);
891
892 if( mr == NULL ) {
893 *err = sat->sat_substr_oid;
894 code = SLAP_SCHERR_MR_NOT_FOUND;
895 goto error_return;
896 }
897
898 if(( mr->smr_usage & SLAP_MR_SUBSTR ) != SLAP_MR_SUBSTR ) {
899 *err = sat->sat_substr_oid;
900 code = SLAP_SCHERR_ATTR_BAD_MR;
901 goto error_return;
902 }
903
904 /* due to funky LDAP builtin substring rules,
905 * we check against the equality rule assertion
906 * syntax and compat syntaxes instead of those
907 * associated with the substrings rule.
908 */
909 if( sat->sat_syntax != sat->sat_equality->smr_syntax ) {
910 if( sat->sat_equality->smr_compat_syntaxes == NULL ) {
911 *err = sat->sat_substr_oid;
912 code = SLAP_SCHERR_ATTR_BAD_MR;
913 goto error_return;
914 }
915
916 for(i=0; sat->sat_equality->smr_compat_syntaxes[i]; i++) {
917 if( sat->sat_syntax ==
918 sat->sat_equality->smr_compat_syntaxes[i] )
919 {
920 i = -1;
921 break;
922 }
923 }
924
925 if( i >= 0 ) {
926 *err = sat->sat_substr_oid;
927 code = SLAP_SCHERR_ATTR_BAD_MR;
928 goto error_return;
929 }
930 }
931
932 sat->sat_substr = mr;
933 }
934
935 code = at_insert( &sat, prev, err );
936 if ( code != 0 ) {
937 error_return:;
938 if ( sat ) {
939 ldap_pvt_thread_mutex_destroy( &sat->sat_ad_mutex );
940 ch_free( sat );
941 }
942
943 if ( oidm ) {
944 SLAP_FREE( at->at_oid );
945 at->at_oid = oidm;
946 }
947
948 if ( soidm ) {
949 SLAP_FREE( at->at_syntax_oid );
950 at->at_syntax_oid = soidm;
951 }
952
953 } else if ( rsat ) {
954 *rsat = sat;
955 }
956
957 return code;
958 }
959
960 #ifdef LDAP_DEBUG
961 #ifdef SLAPD_UNUSED
962 static int
at_index_printnode(void * v_air,void * ignore)963 at_index_printnode( void *v_air, void *ignore )
964 {
965 struct aindexrec *air = v_air;
966 printf("%s = %s\n",
967 air->air_name.bv_val,
968 ldap_attributetype2str(&air->air_at->sat_atype) );
969 return( 0 );
970 }
971
972 static void
at_index_print(void)973 at_index_print( void )
974 {
975 printf("Printing attribute type index:\n");
976 (void) ldap_avl_apply( attr_index, at_index_printnode, 0, -1, AVL_INORDER );
977 }
978 #endif
979 #endif
980
981 void
at_unparse(BerVarray * res,AttributeType * start,AttributeType * end,int sys)982 at_unparse( BerVarray *res, AttributeType *start, AttributeType *end, int sys )
983 {
984 AttributeType *at;
985 int i, num;
986 struct berval bv, *bva = NULL, idx;
987 char ibuf[32];
988
989 if ( !start )
990 start = LDAP_STAILQ_FIRST( &attr_list );
991
992 /* count the result size */
993 i = 0;
994 for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) {
995 if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break;
996 i++;
997 if ( at == end ) break;
998 }
999 if (!i) return;
1000
1001 num = i;
1002 bva = ch_malloc( (num+1) * sizeof(struct berval) );
1003 BER_BVZERO( bva );
1004 idx.bv_val = ibuf;
1005 if ( sys ) {
1006 idx.bv_len = 0;
1007 ibuf[0] = '\0';
1008 }
1009 i = 0;
1010 for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) {
1011 LDAPAttributeType lat, *latp;
1012 if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break;
1013 if ( at->sat_oidmacro || at->sat_soidmacro ) {
1014 lat = at->sat_atype;
1015 if ( at->sat_oidmacro )
1016 lat.at_oid = at->sat_oidmacro;
1017 if ( at->sat_soidmacro )
1018 lat.at_syntax_oid = at->sat_soidmacro;
1019 latp = ⪫
1020 } else {
1021 latp = &at->sat_atype;
1022 }
1023 if ( ldap_attributetype2bv( latp, &bv ) == NULL ) {
1024 ber_bvarray_free( bva );
1025 }
1026 if ( !sys ) {
1027 idx.bv_len = sprintf(idx.bv_val, "{%d}", i);
1028 }
1029 bva[i].bv_len = idx.bv_len + bv.bv_len;
1030 bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
1031 strcpy( bva[i].bv_val, ibuf );
1032 strcpy( bva[i].bv_val + idx.bv_len, bv.bv_val );
1033 i++;
1034 bva[i].bv_val = NULL;
1035 ldap_memfree( bv.bv_val );
1036 if ( at == end ) break;
1037 }
1038 *res = bva;
1039 }
1040
1041 int
at_schema_info(Entry * e)1042 at_schema_info( Entry *e )
1043 {
1044 AttributeDescription *ad_attributeTypes = slap_schema.si_ad_attributeTypes;
1045 AttributeType *at;
1046 struct berval val;
1047 struct berval nval;
1048
1049 LDAP_STAILQ_FOREACH(at,&attr_list,sat_next) {
1050 if( at->sat_flags & SLAP_AT_HIDE ) continue;
1051
1052 if ( ldap_attributetype2bv( &at->sat_atype, &val ) == NULL ) {
1053 return -1;
1054 }
1055
1056 ber_str2bv( at->sat_oid, 0, 0, &nval );
1057
1058 if( attr_merge_one( e, ad_attributeTypes, &val, &nval ) )
1059 {
1060 return -1;
1061 }
1062 ldap_memfree( val.bv_val );
1063 }
1064 return 0;
1065 }
1066
1067 int
register_at(const char * def,AttributeDescription ** rad,int dupok)1068 register_at( const char *def, AttributeDescription **rad, int dupok )
1069 {
1070 LDAPAttributeType *at;
1071 int code, freeit = 0;
1072 const char *err;
1073 AttributeDescription *ad = NULL;
1074
1075 at = ldap_str2attributetype( def, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
1076 if ( !at ) {
1077 Debug( LDAP_DEBUG_ANY,
1078 "register_at: AttributeType \"%s\": %s, %s\n",
1079 def, ldap_scherr2str(code), err );
1080 return code;
1081 }
1082
1083 code = at_add( at, 0, NULL, NULL, &err );
1084 if ( code ) {
1085 if ( code == SLAP_SCHERR_ATTR_DUP && dupok ) {
1086 freeit = 1;
1087
1088 } else {
1089 Debug( LDAP_DEBUG_ANY,
1090 "register_at: AttributeType \"%s\": %s, %s\n",
1091 def, scherr2str(code), err );
1092 ldap_attributetype_free( at );
1093 return code;
1094 }
1095 }
1096 code = slap_str2ad( at->at_names[0], &ad, &err );
1097 if ( freeit || code ) {
1098 ldap_attributetype_free( at );
1099 } else {
1100 ldap_memfree( at );
1101 }
1102 if ( code ) {
1103 Debug( LDAP_DEBUG_ANY, "register_at: AttributeType \"%s\": %s\n",
1104 def, err );
1105 }
1106 if ( rad ) *rad = ad;
1107 return code;
1108 }
1109