2 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5 /* attr.c - routines for dealing with attributes */
17 #include <ac/socket.h>
18 #include <ac/string.h>
21 #ifdef HAVE_SYS_PARAM_H
22 #include <sys/param.h>
25 #include "ldap_defaults.h"
29 static void at_index_print( void );
33 attr_free( Attribute *a )
36 ber_bvecfree( a->a_vals );
41 attrs_free( Attribute *a )
45 for( ; a != NULL ; a = next ) {
51 Attribute *attr_dup( Attribute *a )
55 if( a == NULL) return NULL;
57 tmp = ch_malloc( sizeof(Attribute) );
59 if( a->a_vals != NULL ) {
62 for( i=0; a->a_vals[i] != NULL; i++ ) {
66 tmp->a_vals = ch_malloc((i+1) * sizeof(struct berval*));
68 for( i=0; a->a_vals[i] != NULL; i++ ) {
69 tmp->a_vals[i] = ber_bvdup( a->a_vals[i] );
72 tmp->a_vals[i] = NULL;
78 tmp->a_type = ch_strdup( a->a_type );
79 tmp->a_syntax = a->a_syntax;
85 Attribute *attrs_dup( Attribute *a )
87 Attribute *tmp, **next;
89 if( a == NULL ) return NULL;
94 for( ; a != NULL ; a = a->a_next ) {
95 *next = attr_dup( a );
96 next = &((*next)->a_next);
104 * attr_normalize - normalize an attribute name (make it all lowercase)
108 attr_normalize( char *s )
112 return( str2lower( s ) );
116 * attr_merge_fast - merge the given type and value with the list of
117 * attributes in attrs. called from str2entry(), where we can make some
118 * assumptions to make things faster.
119 * returns 0 everything went ok
127 struct berval **vals,
135 for ( *a = &e->e_attrs; **a != NULL; *a = &(**a)->a_next ) {
136 if ( strcasecmp( (**a)->a_type, type ) == 0 ) {
143 **a = (Attribute *) ch_malloc( sizeof(Attribute) );
144 (**a)->a_type = attr_normalize( ch_strdup( type ) );
145 (**a)->a_vals = NULL;
146 (**a)->a_syntax = attr_syntax( type );
147 (**a)->a_next = NULL;
150 return( value_add_fast( &(**a)->a_vals, vals, nvals, naddvals,
155 * attr_merge - merge the given type and value with the list of
156 * attributes in attrs.
157 * returns 0 everything went ok
170 for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
171 if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
177 *a = (Attribute *) ch_malloc( sizeof(Attribute) );
178 (*a)->a_type = attr_normalize( ch_strdup( type ) );
180 (*a)->a_syntax = attr_syntax( type );
184 return( value_add( &(*a)->a_vals, vals ) );
188 * attr_find - find and return attribute type in list a
197 for ( ; a != NULL; a = a->a_next ) {
198 if ( strcasecmp( a->a_type, type ) == 0 ) {
207 * attr_delete - delete the attribute type in list pointed to by attrs
208 * return 0 deleted ok
209 * 1 not found in list a
210 * -1 something bad happened
222 for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
223 if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
239 #define DEFAULT_SYNTAX SYNTAX_CIS
242 * attr_syntax - return the syntax of attribute type
246 attr_syntax( char *type )
252 return( sat->sat_syntax_compat );
255 return( DEFAULT_SYNTAX );
259 * attr_syntax_config - process an attribute syntax config line
271 LDAP_ATTRIBUTE_TYPE *at;
277 Debug( LDAP_DEBUG_ANY,
278 "%s: line %d: missing name in \"attribute <name>+ <syntax>\" (ignored)\n",
283 at = (LDAP_ATTRIBUTE_TYPE *)
284 ch_calloc( 1, sizeof(LDAP_ATTRIBUTE_TYPE) );
287 if ( strcasecmp( argv[lasti], "caseignorestring" ) == 0 ||
288 strcasecmp( argv[lasti], "cis" ) == 0 ) {
289 at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
290 at->at_equality_oid = "2.5.13.2";
291 at->at_ordering_oid = "2.5.13.3";
292 at->at_substr_oid = "2.5.13.4";
293 } else if ( strcasecmp( argv[lasti], "telephone" ) == 0 ||
294 strcasecmp( argv[lasti], "tel" ) == 0 ) {
295 at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.50";
296 at->at_equality_oid = "2.5.13.20";
297 at->at_substr_oid = "2.5.13.21";
298 } else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) {
299 at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.12";
300 at->at_equality_oid = "2.5.13.1";
301 } else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 ||
302 strcasecmp( argv[lasti], "ces" ) == 0 ) {
303 at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
304 at->at_equality_oid = "2.5.13.5";
305 at->at_ordering_oid = "2.5.13.6";
306 at->at_substr_oid = "2.5.13.7";
307 } else if ( strcasecmp( argv[lasti], "binary" ) == 0 ||
308 strcasecmp( argv[lasti], "bin" ) == 0 ) {
309 at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.5";
310 /* There is no match for binary syntax. Really */
312 Debug( LDAP_DEBUG_ANY,
313 "%s: line %d: unknown syntax \"%s\" in attribute line (ignored)\n",
314 fname, lineno, argv[lasti] );
315 Debug( LDAP_DEBUG_ANY,
316 "possible syntaxes are \"cis\", \"ces\", \"tel\", \"dn\", or \"bin\"\n",
318 free( (AttributeType *) at );
324 at->at_names = charray_dup( argv );
327 code = at_add( at, &err );
329 fprintf( stderr, "%s: line %d: %s %s\n",
330 fname, lineno, scherr2str(code), err);
331 exit( EXIT_FAILURE );
343 if ( at_find( name ) ) {
349 attr_syntax_config( "implicit", 0, 2, argv );
356 AttributeType *air_at;
359 static Avlnode *attr_index = NULL;
360 static AttributeType *attr_list = NULL;
364 struct aindexrec *air1,
365 struct aindexrec *air2
368 return (strcasecmp( air1->air_name, air2->air_name ));
374 struct aindexrec *air
377 return (strcasecmp( type, air->air_name ));
385 struct aindexrec *air = NULL;
387 if ( (air = (struct aindexrec *) avl_find( attr_index, name,
388 (AVL_CMP) attr_index_name_cmp )) != NULL ) {
389 return( air->air_at );
397 AttributeType ***listp
400 AttributeType **list;
401 AttributeType **list1;
407 list = calloc(size, sizeof(AttributeType *));
419 list1 = realloc(list, size*sizeof(AttributeType *));
434 AttributeType ***listp
437 AttributeType **list;
438 AttributeType **list1;
446 for ( i=0; list[i]; i++ )
451 for ( i=pos, j=pos+1; list[j]; i++, j++ ) {
455 /* Tell the runtime this can be shrinked */
456 list1 = realloc(list, (i+1)*sizeof(AttributeType **));
475 for ( i=0; list[i]; i++ ) {
476 if ( sat == list[i] ) {
490 struct aindexrec *air;
494 while ( *atp != NULL ) {
495 atp = &(*atp)->sat_next;
499 if ( sat->sat_oid ) {
500 air = (struct aindexrec *)
501 ch_calloc( 1, sizeof(struct aindexrec) );
502 air->air_name = sat->sat_oid;
504 if ( avl_insert( &attr_index, (caddr_t) air,
505 (AVL_CMP) attr_index_cmp,
506 (AVL_DUP) avl_dup_error ) ) {
509 return SLAP_SCHERR_DUP_ATTR;
511 /* FIX: temporal consistency check */
512 at_find(air->air_name);
514 if ( (names = sat->sat_names) ) {
516 air = (struct aindexrec *)
517 ch_calloc( 1, sizeof(struct aindexrec) );
518 air->air_name = ch_strdup(*names);
520 if ( avl_insert( &attr_index, (caddr_t) air,
521 (AVL_CMP) attr_index_cmp,
522 (AVL_DUP) avl_dup_error ) ) {
525 return SLAP_SCHERR_DUP_ATTR;
527 /* FIX: temporal consistency check */
528 at_find(air->air_name);
538 LDAP_ATTRIBUTE_TYPE *at,
549 if ( at->at_names && at->at_names[0] ) {
550 errattr = at->at_names[0];
551 } else if ( at->at_oid ) {
552 errattr = at->at_oid;
555 return SLAP_SCHERR_ATTR_INCOMPLETE;
557 sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
558 memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE));
559 if ( at->at_sup_oid ) {
560 if ( (sat1 = at_find(at->at_sup_oid)) ) {
562 if ( at_append_to_list(sat, &sat1->sat_subtypes) ) {
564 return SLAP_SCHERR_OUTOFMEM;
567 *err = at->at_sup_oid;
568 return SLAP_SCHERR_ATTR_NOT_FOUND;
572 if ( at->at_syntax_oid ) {
573 if ( (syn = syn_find(sat->sat_syntax_oid)) ) {
574 sat->sat_syntax = syn;
576 *err = sat->sat_syntax_oid;
577 return SLAP_SCHERR_SYN_NOT_FOUND;
579 if ( !strcmp(at->at_syntax_oid,
580 "1.3.6.1.4.1.1466.115.121.1.15") ) {
581 if ( at->at_equality_oid &&
582 !strcmp(at->at_equality_oid, "2.5.13.5") ) {
583 sat->sat_syntax_compat = SYNTAX_CES;
585 sat->sat_syntax_compat = SYNTAX_CIS;
587 } else if ( !strcmp(at->at_syntax_oid,
588 "1.3.6.1.4.1.1466.115.121.1.50") ) {
589 sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
590 } else if ( !strcmp(at->at_syntax_oid,
591 "1.3.6.1.4.1.1466.115.121.1.12") ) {
592 sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN;
593 } else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.5") ) {
594 sat->sat_syntax_compat = SYNTAX_BIN;
596 sat->sat_syntax_compat = DEFAULT_SYNTAX;
599 sat->sat_syntax_compat = DEFAULT_SYNTAX;
602 if ( sat->sat_equality_oid ) {
603 if ( (mr = mr_find(sat->sat_equality_oid)) ) {
604 sat->sat_equality = mr;
606 *err = sat->sat_equality_oid;
607 return SLAP_SCHERR_MR_NOT_FOUND;
610 if ( sat->sat_ordering_oid ) {
611 if ( (mr = mr_find(sat->sat_ordering_oid)) ) {
612 sat->sat_ordering = mr;
614 *err = sat->sat_ordering_oid;
615 return SLAP_SCHERR_MR_NOT_FOUND;
618 if ( sat->sat_substr_oid ) {
619 if ( (mr = mr_find(sat->sat_substr_oid)) ) {
620 sat->sat_substr = mr;
622 *err = sat->sat_substr_oid;
623 return SLAP_SCHERR_MR_NOT_FOUND;
628 * Now inherit definitions from superiors. We only check the
629 * direct superior since that one has already inherited from
632 if ( sat->sat_sup ) {
633 if ( !sat->sat_syntax ) {
634 sat->sat_syntax = sat->sat_sup->sat_syntax;
635 sat->sat_syntax_len = sat->sat_sup->sat_syntax_len;
637 if ( !sat->sat_equality ) {
638 sat->sat_equality = sat->sat_sup->sat_equality;
640 if ( !sat->sat_ordering ) {
641 sat->sat_ordering = sat->sat_sup->sat_ordering;
643 if ( !sat->sat_substr ) {
644 sat->sat_substr = sat->sat_sup->sat_substr;
647 code = at_insert(sat,err);
653 at_canonical_name( char * a_type )
657 if ( (atp=at_find(a_type)) == NULL ) {
661 } else if ( atp->sat_names
663 && (*(atp->sat_names[0]) != '\0') ) {
665 return atp->sat_names[0];
667 } else if (atp->sat_oid && (*atp->sat_oid != '\0')) {
677 }/* char * at_canonica_name() */
680 #if defined( SLAPD_SCHEMA_DN )
683 at_schema_info( Entry *e )
686 struct berval *vals[2];
692 for ( at = attr_list; at; at = at->sat_next ) {
693 val.bv_val = ldap_attributetype2str( &at->sat_atype );
695 val.bv_len = strlen( val.bv_val );
696 Debug( LDAP_DEBUG_TRACE, "Merging at [%d] %s\n",
697 val.bv_len, val.bv_val, 0 );
698 attr_merge( e, "attributeTypes", vals );
699 ldap_memfree( val.bv_val );
711 at_index_printnode( struct aindexrec *air )
714 printf( "%s = %s\n", air->air_name, ldap_attributetype2str(&air->air_at->sat_atype) );
719 at_index_print( void )
721 printf("Printing attribute type index:\n");
722 (void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
723 0, -1, AVL_INORDER );