3 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6 /* at.c - routines for dealing with attribute types */
14 #include <ac/socket.h>
15 #include <ac/string.h>
26 for( ; at != NULL; at = at->sat_sup ) {
27 if( at->sat_syntax_oid ) {
28 return ( strcmp( at->sat_syntax_oid, oid ) == 0 );
39 for( ; sub != NULL; sub = sub->sat_sup ) {
40 if( sub == sup ) return 1;
47 struct berval air_name;
48 AttributeType *air_at;
51 static Avlnode *attr_index = NULL;
52 static LDAP_SLIST_HEAD(ATList, slap_attribute_type) attr_list
53 = LDAP_SLIST_HEAD_INITIALIZER(&attr_list);
61 const struct aindexrec *air1 = v_air1;
62 const struct aindexrec *air2 = v_air2;
63 int i = air1->air_name.bv_len - air2->air_name.bv_len;
66 return (strcasecmp( air1->air_name.bv_val, air2->air_name.bv_val ));
75 const struct berval *type = v_type;
76 const struct aindexrec *air = v_air;
77 int i = type->bv_len - air->air_name.bv_len;
80 return (strncasecmp( type->bv_val, air->air_name.bv_val,
91 bv.bv_val = (char *)name;
92 bv.bv_len = strlen( name );
94 return at_bvfind( &bv );
102 struct aindexrec *air;
104 air = avl_find( attr_index, name, attr_index_name_cmp );
106 return air != NULL ? air->air_at : NULL;
112 AttributeType ***listp
115 AttributeType **list;
116 AttributeType **list1;
122 list = ch_calloc(size, sizeof(AttributeType *));
134 list1 = ch_realloc(list, size*sizeof(AttributeType *));
149 AttributeType ***listp
152 AttributeType **list;
153 AttributeType **list1;
161 for ( i=0; list[i]; i++ )
166 for ( i=pos, j=pos+1; list[j]; i++, j++ ) {
170 /* Tell the runtime this can be shrinked */
171 list1 = ch_realloc(list, (i+1)*sizeof(AttributeType **));
190 for ( i=0; list[i]; i++ ) {
191 if ( sat == list[i] ) {
202 avl_free(attr_index, ldap_memfree);
204 while( !LDAP_SLIST_EMPTY(&attr_list) ) {
205 a = LDAP_SLIST_FIRST(&attr_list);
206 LDAP_SLIST_REMOVE_HEAD(&attr_list, sat_next);
208 if (a->sat_subtypes) ldap_memfree(a->sat_subtypes);
209 ad_destroy(a->sat_ad);
210 ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex);
211 ldap_attributetype_free((LDAPAttributeType *)a);
214 if ( slap_schema.si_at_undefined ) {
215 ad_destroy(slap_schema.si_at_undefined->sat_ad);
220 at_start( AttributeType **at )
224 *at = LDAP_SLIST_FIRST(&attr_list);
226 return (*at != NULL);
230 at_next( AttributeType **at )
234 #if 1 /* pedantic check */
236 AttributeType *tmp = NULL;
238 LDAP_SLIST_FOREACH(tmp,&attr_list,sat_next) {
248 *at = LDAP_SLIST_NEXT(*at,sat_next);
250 return (*at != NULL);
261 struct aindexrec *air;
264 LDAP_SLIST_NEXT( sat, sat_next ) = NULL;
265 LDAP_SLIST_INSERT_HEAD( &attr_list, sat, sat_next );
267 if ( sat->sat_oid ) {
268 air = (struct aindexrec *)
269 ch_calloc( 1, sizeof(struct aindexrec) );
270 air->air_name.bv_val = sat->sat_oid;
271 air->air_name.bv_len = strlen(sat->sat_oid);
273 if ( avl_insert( &attr_index, (caddr_t) air,
274 attr_index_cmp, avl_dup_error ) ) {
277 return SLAP_SCHERR_ATTR_DUP;
279 /* FIX: temporal consistency check */
280 at_bvfind(&air->air_name);
283 if ( (names = sat->sat_names) ) {
285 air = (struct aindexrec *)
286 ch_calloc( 1, sizeof(struct aindexrec) );
287 air->air_name.bv_val = *names;
288 air->air_name.bv_len = strlen(*names);
290 if ( avl_insert( &attr_index, (caddr_t) air,
291 attr_index_cmp, avl_dup_error ) ) {
294 return SLAP_SCHERR_ATTR_DUP;
296 /* FIX: temporal consistency check */
297 at_bvfind(&air->air_name);
307 LDAPAttributeType *at,
319 if ( !OID_LEADCHAR( at->at_oid[0] )) {
320 /* Expand OID macros */
321 oid = oidm_find( at->at_oid );
324 return SLAP_SCHERR_OIDM;
326 if ( oid != at->at_oid ) {
327 ldap_memfree( at->at_oid );
332 if ( at->at_syntax_oid && !OID_LEADCHAR( at->at_syntax_oid[0] )) {
333 /* Expand OID macros */
334 oid = oidm_find( at->at_syntax_oid );
336 *err = at->at_syntax_oid;
337 return SLAP_SCHERR_OIDM;
339 if ( oid != at->at_syntax_oid ) {
340 ldap_memfree( at->at_syntax_oid );
341 at->at_syntax_oid = oid;
345 if ( at->at_names && at->at_names[0] ) {
348 for( i=0; at->at_names[i]; i++ ) {
349 if( !slap_valid_descr( at->at_names[i] ) ) {
350 *err = at->at_names[i];
351 return SLAP_SCHERR_BAD_DESCR;
355 cname = at->at_names[0];
357 } else if ( at->at_oid ) {
362 return SLAP_SCHERR_ATTR_INCOMPLETE;
367 if ( !at->at_usage && at->at_no_user_mod ) {
368 /* user attribute must be modifable */
369 return SLAP_SCHERR_ATTR_BAD_USAGE;
372 if ( at->at_collective ) {
374 /* collective attributes cannot be operational */
375 return SLAP_SCHERR_ATTR_BAD_USAGE;
378 if( at->at_single_value ) {
379 /* collective attributes cannot be single-valued */
380 return SLAP_SCHERR_ATTR_BAD_USAGE;
384 sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
385 AC_MEMCPY( &sat->sat_atype, at, sizeof(LDAPAttributeType));
387 sat->sat_cname.bv_val = cname;
388 sat->sat_cname.bv_len = strlen( cname );
389 ldap_pvt_thread_mutex_init(&sat->sat_ad_mutex);
391 if ( at->at_sup_oid ) {
392 AttributeType *supsat = at_find(at->at_sup_oid);
394 if ( supsat == NULL ) {
395 *err = at->at_sup_oid;
396 return SLAP_SCHERR_ATTR_NOT_FOUND;
399 sat->sat_sup = supsat;
401 if ( at_append_to_list(sat, &supsat->sat_subtypes) ) {
402 return SLAP_SCHERR_OUTOFMEM;
405 if ( sat->sat_usage != supsat->sat_usage ) {
406 /* subtypes must have same usage as their SUP */
407 return SLAP_SCHERR_ATTR_BAD_USAGE;
410 if ( supsat->sat_obsolete && !sat->sat_obsolete ) {
411 /* subtypes must be obsolete if super is */
412 return SLAP_SCHERR_ATTR_BAD_SUP;
415 if ( sat->sat_flags & SLAP_AT_FINAL ) {
416 /* cannot subtype a "final" attribute type */
417 return SLAP_SCHERR_ATTR_BAD_SUP;
422 * Inherit definitions from superiors. We only check the
423 * direct superior since that one has already inherited from
426 if ( sat->sat_sup ) {
427 sat->sat_syntax = sat->sat_sup->sat_syntax;
428 sat->sat_equality = sat->sat_sup->sat_equality;
429 sat->sat_approx = sat->sat_sup->sat_approx;
430 sat->sat_ordering = sat->sat_sup->sat_ordering;
431 sat->sat_substr = sat->sat_sup->sat_substr;
434 if ( at->at_syntax_oid ) {
435 syn = syn_find(sat->sat_syntax_oid);
437 *err = sat->sat_syntax_oid;
438 return SLAP_SCHERR_SYN_NOT_FOUND;
441 if( sat->sat_syntax != NULL && sat->sat_syntax != syn ) {
442 return SLAP_SCHERR_ATTR_BAD_SUP;
445 sat->sat_syntax = syn;
447 } else if ( sat->sat_syntax == NULL ) {
448 return SLAP_SCHERR_ATTR_INCOMPLETE;
451 if ( sat->sat_equality_oid ) {
452 mr = mr_find(sat->sat_equality_oid);
455 *err = sat->sat_equality_oid;
456 return SLAP_SCHERR_MR_NOT_FOUND;
459 if(( mr->smr_usage & SLAP_MR_EQUALITY ) != SLAP_MR_EQUALITY ) {
460 *err = sat->sat_equality_oid;
461 return SLAP_SCHERR_ATTR_BAD_MR;
464 if( sat->sat_syntax != mr->smr_syntax ) {
465 if( mr->smr_compat_syntaxes == NULL ) {
466 *err = sat->sat_equality_oid;
467 return SLAP_SCHERR_ATTR_BAD_MR;
470 for(i=0; mr->smr_compat_syntaxes[i]; i++) {
471 if( sat->sat_syntax == mr->smr_compat_syntaxes[i] ) {
478 *err = sat->sat_equality_oid;
479 return SLAP_SCHERR_ATTR_BAD_MR;
483 sat->sat_equality = mr;
484 sat->sat_approx = mr->smr_associated;
487 if ( sat->sat_ordering_oid ) {
488 if( !sat->sat_equality ) {
489 *err = sat->sat_ordering_oid;
490 return SLAP_SCHERR_ATTR_BAD_MR;
493 mr = mr_find(sat->sat_ordering_oid);
496 *err = sat->sat_ordering_oid;
497 return SLAP_SCHERR_MR_NOT_FOUND;
500 if(( mr->smr_usage & SLAP_MR_ORDERING ) != SLAP_MR_ORDERING ) {
501 *err = sat->sat_ordering_oid;
502 return SLAP_SCHERR_ATTR_BAD_MR;
505 if( sat->sat_syntax != mr->smr_syntax ) {
506 if( mr->smr_compat_syntaxes == NULL ) {
507 *err = sat->sat_ordering_oid;
508 return SLAP_SCHERR_ATTR_BAD_MR;
511 for(i=0; mr->smr_compat_syntaxes[i]; i++) {
512 if( sat->sat_syntax == mr->smr_compat_syntaxes[i] ) {
519 *err = sat->sat_ordering_oid;
520 return SLAP_SCHERR_ATTR_BAD_MR;
524 sat->sat_ordering = mr;
527 if ( sat->sat_substr_oid ) {
528 if( !sat->sat_equality ) {
529 *err = sat->sat_substr_oid;
530 return SLAP_SCHERR_ATTR_BAD_MR;
533 mr = mr_find(sat->sat_substr_oid);
536 *err = sat->sat_substr_oid;
537 return SLAP_SCHERR_MR_NOT_FOUND;
540 if(( mr->smr_usage & SLAP_MR_SUBSTR ) != SLAP_MR_SUBSTR ) {
541 *err = sat->sat_substr_oid;
542 return SLAP_SCHERR_ATTR_BAD_MR;
545 /* due to funky LDAP builtin substring rules, we
546 * we check against the equality rule assertion
547 * syntax and compat syntaxes instead of those
548 * associated with the substrings rule.
550 if( sat->sat_syntax != sat->sat_equality->smr_syntax ) {
551 if( sat->sat_equality->smr_compat_syntaxes == NULL ) {
552 *err = sat->sat_substr_oid;
553 return SLAP_SCHERR_ATTR_BAD_MR;
556 for(i=0; sat->sat_equality->smr_compat_syntaxes[i]; i++) {
557 if( sat->sat_syntax ==
558 sat->sat_equality->smr_compat_syntaxes[i] )
566 *err = sat->sat_substr_oid;
567 return SLAP_SCHERR_ATTR_BAD_MR;
571 sat->sat_substr = mr;
574 code = at_insert(sat,err);
580 at_index_printnode( void *v_air, void *ignore )
582 struct aindexrec *air = v_air;
584 air->air_name.bv_val,
585 ldap_attributetype2str(&air->air_at->sat_atype) );
590 at_index_print( void )
592 printf("Printing attribute type index:\n");
593 (void) avl_apply( attr_index, at_index_printnode, 0, -1, AVL_INORDER );
598 at_schema_info( Entry *e )
600 AttributeDescription *ad_attributeTypes = slap_schema.si_ad_attributeTypes;
607 LDAP_SLIST_FOREACH(at,&attr_list,sat_next) {
608 if( at->sat_flags & SLAP_AT_HIDE ) continue;
610 if ( ldap_attributetype2bv( &at->sat_atype, &val ) == NULL ) {
615 nval.bv_val = at->sat_oid;
616 nval.bv_len = strlen(at->sat_oid);
618 if( attr_merge_one( e, ad_attributeTypes, &val, &nval ) )
620 if( attr_merge_one( e, ad_attributeTypes, &val ) )
625 ldap_memfree( val.bv_val );