3 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6 /* attr.c - routines for dealing with attributes */
18 #include <ac/socket.h>
19 #include <ac/string.h>
28 static void at_index_print( void );
32 attr_free( Attribute *a )
35 ber_bvecfree( a->a_vals );
40 attrs_free( Attribute *a )
44 for( ; a != NULL ; a = next ) {
50 Attribute *attr_dup( Attribute *a )
54 if( a == NULL) return NULL;
56 tmp = ch_malloc( sizeof(Attribute) );
58 if( a->a_vals != NULL ) {
61 for( i=0; a->a_vals[i] != NULL; i++ ) {
65 tmp->a_vals = ch_malloc((i+1) * sizeof(struct berval*));
67 for( i=0; a->a_vals[i] != NULL; i++ ) {
68 tmp->a_vals[i] = ber_bvdup( a->a_vals[i] );
70 if( tmp->a_vals[i] == NULL ) break;
73 tmp->a_vals[i] = NULL;
79 tmp->a_type = ch_strdup( a->a_type );
80 tmp->a_syntax = a->a_syntax;
86 Attribute *attrs_dup( Attribute *a )
88 Attribute *tmp, **next;
90 if( a == NULL ) return NULL;
95 for( ; a != NULL ; a = a->a_next ) {
96 *next = attr_dup( a );
97 next = &((*next)->a_next);
105 * attr_normalize - normalize an attribute name (make it all lowercase)
109 attr_normalize( char *s )
113 return( ldap_pvt_str2lower( s ) );
117 * attr_merge_fast - merge the given type and value with the list of
118 * attributes in attrs. called from str2entry(), where we can make some
119 * assumptions to make things faster.
120 * returns 0 everything went ok
128 struct berval **vals,
136 for ( *a = &e->e_attrs; **a != NULL; *a = &(**a)->a_next ) {
137 if ( strcasecmp( (**a)->a_type, type ) == 0 ) {
144 **a = (Attribute *) ch_malloc( sizeof(Attribute) );
145 (**a)->a_type = attr_normalize( ch_strdup( type ) );
146 (**a)->a_vals = NULL;
147 (**a)->a_syntax = attr_syntax( type );
148 (**a)->a_next = NULL;
151 return( value_add_fast( &(**a)->a_vals, vals, nvals, naddvals,
156 * attr_merge - merge the given type and value with the list of
157 * attributes in attrs.
158 * returns 0 everything went ok
171 for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
172 if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
178 *a = (Attribute *) ch_malloc( sizeof(Attribute) );
179 (*a)->a_type = attr_normalize( ch_strdup( type ) );
181 (*a)->a_syntax = attr_syntax( type );
185 return( value_add( &(*a)->a_vals, vals ) );
189 * attr_find - find and return attribute type in list a
198 for ( ; a != NULL; a = a->a_next ) {
199 if ( strcasecmp( a->a_type, type ) == 0 ) {
208 * attr_delete - delete the attribute type in list pointed to by attrs
209 * return 0 deleted ok
210 * 1 not found in list a
211 * -1 something bad happened
223 for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
224 if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
240 #define DEFAULT_SYNTAX SYNTAX_CIS
243 * attr_syntax - return the syntax of attribute type
247 attr_syntax( char *type )
253 return( sat->sat_syntax_compat );
256 return( DEFAULT_SYNTAX );
260 * attr_syntax_config - process an attribute syntax config line
272 LDAP_ATTRIBUTE_TYPE *at;
278 Debug( LDAP_DEBUG_ANY,
279 "%s: line %d: missing name in \"attribute <name>+ <syntax>\" (ignored)\n",
284 at = (LDAP_ATTRIBUTE_TYPE *)
285 ch_calloc( 1, sizeof(LDAP_ATTRIBUTE_TYPE) );
288 if ( strcasecmp( argv[lasti], "caseignorestring" ) == 0 ||
289 strcasecmp( argv[lasti], "cis" ) == 0 ) {
290 at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
291 at->at_equality_oid = "2.5.13.2";
292 at->at_ordering_oid = "2.5.13.3";
293 at->at_substr_oid = "2.5.13.4";
294 } else if ( strcasecmp( argv[lasti], "telephone" ) == 0 ||
295 strcasecmp( argv[lasti], "tel" ) == 0 ) {
296 at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.50";
297 at->at_equality_oid = "2.5.13.20";
298 at->at_substr_oid = "2.5.13.21";
299 } else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) {
300 at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.12";
301 at->at_equality_oid = "2.5.13.1";
302 } else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 ||
303 strcasecmp( argv[lasti], "ces" ) == 0 ) {
304 at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
305 at->at_equality_oid = "2.5.13.5";
306 at->at_ordering_oid = "2.5.13.6";
307 at->at_substr_oid = "2.5.13.7";
308 } else if ( strcasecmp( argv[lasti], "binary" ) == 0 ||
309 strcasecmp( argv[lasti], "bin" ) == 0 ) {
310 at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.5";
311 /* There is no match for binary syntax. Really */
313 Debug( LDAP_DEBUG_ANY,
314 "%s: line %d: unknown syntax \"%s\" in attribute line (ignored)\n",
315 fname, lineno, argv[lasti] );
316 Debug( LDAP_DEBUG_ANY,
317 "possible syntaxes are \"cis\", \"ces\", \"tel\", \"dn\", or \"bin\"\n",
319 free( (AttributeType *) at );
325 at->at_names = charray_dup( argv );
328 code = at_add( at, &err );
330 fprintf( stderr, "%s: line %d: %s %s\n",
331 fname, lineno, scherr2str(code), err);
332 exit( EXIT_FAILURE );
344 if ( at_find( name ) ) {
350 attr_syntax_config( "implicit", 0, 2, argv );
357 AttributeType *air_at;
360 static Avlnode *attr_index = NULL;
361 static AttributeType *attr_list = NULL;
365 struct aindexrec *air1,
366 struct aindexrec *air2
369 return (strcasecmp( air1->air_name, air2->air_name ));
375 struct aindexrec *air
378 return (strcasecmp( type, air->air_name ));
386 struct aindexrec *air = NULL;
387 char *p, *tmpname = NULL;
390 * The name may actually be an AttributeDescription, i.e. it may
391 * contain options. Let's deal with it.
393 p = strchr( name, ';' );
395 tmpname = ch_malloc( p-name+1 );
396 strncpy( tmpname, name, p-name );
397 tmpname[p-name] = '\0';
399 tmpname = (char *)name;
400 if ( (air = (struct aindexrec *) avl_find( attr_index, tmpname,
401 (AVL_CMP) attr_index_name_cmp )) != NULL ) {
402 if ( tmpname != name )
403 ldap_memfree( tmpname );
404 return( air->air_at );
406 if ( tmpname != name )
407 ldap_memfree( tmpname );
414 AttributeType ***listp
417 AttributeType **list;
418 AttributeType **list1;
424 list = calloc(size, sizeof(AttributeType *));
436 list1 = realloc(list, size*sizeof(AttributeType *));
451 AttributeType ***listp
454 AttributeType **list;
455 AttributeType **list1;
463 for ( i=0; list[i]; i++ )
468 for ( i=pos, j=pos+1; list[j]; i++, j++ ) {
472 /* Tell the runtime this can be shrinked */
473 list1 = realloc(list, (i+1)*sizeof(AttributeType **));
492 for ( i=0; list[i]; i++ ) {
493 if ( sat == list[i] ) {
507 struct aindexrec *air;
511 while ( *atp != NULL ) {
512 atp = &(*atp)->sat_next;
516 if ( sat->sat_oid ) {
517 air = (struct aindexrec *)
518 ch_calloc( 1, sizeof(struct aindexrec) );
519 air->air_name = sat->sat_oid;
521 if ( avl_insert( &attr_index, (caddr_t) air,
522 (AVL_CMP) attr_index_cmp,
523 (AVL_DUP) avl_dup_error ) ) {
526 return SLAP_SCHERR_DUP_ATTR;
528 /* FIX: temporal consistency check */
529 at_find(air->air_name);
531 if ( (names = sat->sat_names) ) {
533 air = (struct aindexrec *)
534 ch_calloc( 1, sizeof(struct aindexrec) );
535 air->air_name = ch_strdup(*names);
537 if ( avl_insert( &attr_index, (caddr_t) air,
538 (AVL_CMP) attr_index_cmp,
539 (AVL_DUP) avl_dup_error ) ) {
541 ldap_memfree(air->air_name);
543 return SLAP_SCHERR_DUP_ATTR;
545 /* FIX: temporal consistency check */
546 at_find(air->air_name);
556 LDAP_ATTRIBUTE_TYPE *at,
567 if ( at->at_names && at->at_names[0] ) {
568 errattr = at->at_names[0];
569 } else if ( at->at_oid ) {
570 errattr = at->at_oid;
573 return SLAP_SCHERR_ATTR_INCOMPLETE;
575 sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
576 memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE));
577 if ( at->at_sup_oid ) {
578 if ( (sat1 = at_find(at->at_sup_oid)) ) {
580 if ( at_append_to_list(sat, &sat1->sat_subtypes) ) {
582 return SLAP_SCHERR_OUTOFMEM;
585 *err = at->at_sup_oid;
586 return SLAP_SCHERR_ATTR_NOT_FOUND;
590 if ( at->at_syntax_oid ) {
591 if ( (syn = syn_find(sat->sat_syntax_oid)) ) {
592 sat->sat_syntax = syn;
594 *err = sat->sat_syntax_oid;
595 return SLAP_SCHERR_SYN_NOT_FOUND;
597 if ( !strcmp(at->at_syntax_oid,
598 "1.3.6.1.4.1.1466.115.121.1.15") ) {
599 if ( at->at_equality_oid &&
600 !strcmp(at->at_equality_oid, "2.5.13.5") ) {
601 sat->sat_syntax_compat = SYNTAX_CES;
603 sat->sat_syntax_compat = SYNTAX_CIS;
605 } else if ( !strcmp(at->at_syntax_oid,
606 "1.3.6.1.4.1.1466.115.121.1.50") ) {
607 sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
608 } else if ( !strcmp(at->at_syntax_oid,
609 "1.3.6.1.4.1.1466.115.121.1.12") ) {
610 sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN;
611 } else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.5") ) {
612 sat->sat_syntax_compat = SYNTAX_BIN;
614 sat->sat_syntax_compat = DEFAULT_SYNTAX;
617 sat->sat_syntax_compat = DEFAULT_SYNTAX;
620 if ( sat->sat_equality_oid ) {
621 if ( (mr = mr_find(sat->sat_equality_oid)) ) {
622 sat->sat_equality = mr;
624 *err = sat->sat_equality_oid;
625 return SLAP_SCHERR_MR_NOT_FOUND;
628 if ( sat->sat_ordering_oid ) {
629 if ( (mr = mr_find(sat->sat_ordering_oid)) ) {
630 sat->sat_ordering = mr;
632 *err = sat->sat_ordering_oid;
633 return SLAP_SCHERR_MR_NOT_FOUND;
636 if ( sat->sat_substr_oid ) {
637 if ( (mr = mr_find(sat->sat_substr_oid)) ) {
638 sat->sat_substr = mr;
640 *err = sat->sat_substr_oid;
641 return SLAP_SCHERR_MR_NOT_FOUND;
646 * Now inherit definitions from superiors. We only check the
647 * direct superior since that one has already inherited from
650 if ( sat->sat_sup ) {
651 if ( !sat->sat_syntax ) {
652 sat->sat_syntax = sat->sat_sup->sat_syntax;
653 sat->sat_syntax_len = sat->sat_sup->sat_syntax_len;
655 if ( !sat->sat_equality ) {
656 sat->sat_equality = sat->sat_sup->sat_equality;
658 if ( !sat->sat_ordering ) {
659 sat->sat_ordering = sat->sat_sup->sat_ordering;
661 if ( !sat->sat_substr ) {
662 sat->sat_substr = sat->sat_sup->sat_substr;
665 code = at_insert(sat,err);
671 at_canonical_name( char * a_type )
675 if ( (atp=at_find(a_type)) == NULL ) {
679 } else if ( atp->sat_names
681 && (*(atp->sat_names[0]) != '\0') ) {
683 return atp->sat_names[0];
685 } else if (atp->sat_oid && (*atp->sat_oid != '\0')) {
695 }/* char * at_canonica_name() */
698 #if defined( SLAPD_SCHEMA_DN )
701 at_schema_info( Entry *e )
704 struct berval *vals[2];
710 for ( at = attr_list; at; at = at->sat_next ) {
711 val.bv_val = ldap_attributetype2str( &at->sat_atype );
713 val.bv_len = strlen( val.bv_val );
714 Debug( LDAP_DEBUG_TRACE, "Merging at [%ld] %s\n",
715 (long) val.bv_len, val.bv_val, 0 );
716 attr_merge( e, "attributeTypes", vals );
717 ldap_memfree( val.bv_val );
729 at_index_printnode( struct aindexrec *air )
732 printf( "%s = %s\n", air->air_name, ldap_attributetype2str(&air->air_at->sat_atype) );
737 at_index_print( void )
739 printf("Printing attribute type index:\n");
740 (void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
741 0, -1, AVL_INORDER );