X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fattr.c;h=014fe649de39798a882c67bb4d6b0cbbb5fbcb2d;hb=e2b5b211558ee778f07954d3843b914f19f6c6b5;hp=c1178c94e919005772ca5bb535f616829a8ba29d;hpb=5ef648a109669cd4a8a776f2233a51436cebcdb8;p=openldap diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c index c1178c94e9..014fe649de 100644 --- a/servers/slapd/attr.c +++ b/servers/slapd/attr.c @@ -18,10 +18,13 @@ #include #endif -#include - +#include "ldap_defaults.h" #include "slap.h" +#ifdef LDAP_DEBUG +static void at_index_print( void ); +#endif + void attr_free( Attribute *a ) { @@ -39,6 +42,8 @@ attr_normalize( char *s ) { char *save; + assert( s != NULL ); + for ( save = s; *s; s++ ) { *s = TOLOWER( (unsigned char) *s ); } @@ -172,60 +177,6 @@ attr_delete( #define DEFAULT_SYNTAX SYNTAX_CIS -struct asyntaxinfo { - char **asi_names; - int asi_syntax; -}; - -static Avlnode *attr_syntaxes = NULL; - -static int -attr_syntax_cmp( - struct asyntaxinfo *a1, - struct asyntaxinfo *a2 -) -{ - return( strcasecmp( a1->asi_names[0], a2->asi_names[0] ) ); -} - -static int -attr_syntax_name_cmp( - char *type, - struct asyntaxinfo *a -) -{ - return( strcasecmp( type, a->asi_names[0] ) ); -} - -static int -attr_syntax_names_cmp( - char *type, - struct asyntaxinfo *a -) -{ - int i; - - for ( i = 0; a->asi_names[i] != NULL; i++ ) { - if ( strcasecmp( type, a->asi_names[i] ) == 0 ) { - return( 0 ); - } - } - return( 1 ); -} - -static int -attr_syntax_dup( - struct asyntaxinfo *a1, - struct asyntaxinfo *a2 -) -{ - if ( a1->asi_syntax != a2->asi_syntax ) { - return( -1 ); - } - - return( 1 ); -} - /* * attr_syntax - return the syntax of attribute type */ @@ -233,14 +184,11 @@ attr_syntax_dup( int attr_syntax( char *type ) { - struct asyntaxinfo *asi = NULL; + AttributeType *sat; - if ( (asi = (struct asyntaxinfo *) avl_find( attr_syntaxes, type, - (AVL_CMP) attr_syntax_name_cmp )) != NULL || - (asi = (struct asyntaxinfo *) avl_find_lin( attr_syntaxes, type, - (AVL_CMP) attr_syntax_names_cmp )) != NULL ) - { - return( asi->asi_syntax ); + sat = at_find(type); + if ( sat ) { + return( sat->sat_syntax_compat ); } return( DEFAULT_SYNTAX ); @@ -259,8 +207,10 @@ attr_syntax_config( ) { char *save; - struct asyntaxinfo *a; + LDAP_ATTRIBUTE_TYPE *at; int lasti; + int code; + const char *err; if ( argc < 2 ) { Debug( LDAP_DEBUG_ANY, @@ -269,23 +219,34 @@ attr_syntax_config( return; } - a = (struct asyntaxinfo *) ch_calloc( 1, sizeof(struct asyntaxinfo) ); + at = (LDAP_ATTRIBUTE_TYPE *) + ch_calloc( 1, sizeof(LDAP_ATTRIBUTE_TYPE) ); lasti = argc - 1; if ( strcasecmp( argv[lasti], "caseignorestring" ) == 0 || strcasecmp( argv[lasti], "cis" ) == 0 ) { - a->asi_syntax = SYNTAX_CIS; + at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15"; + at->at_equality_oid = "2.5.13.2"; + at->at_ordering_oid = "2.5.13.3"; + at->at_substr_oid = "2.5.13.4"; } else if ( strcasecmp( argv[lasti], "telephone" ) == 0 || strcasecmp( argv[lasti], "tel" ) == 0 ) { - a->asi_syntax = (SYNTAX_CIS | SYNTAX_TEL); + at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.50"; + at->at_equality_oid = "2.5.13.20"; + at->at_substr_oid = "2.5.13.21"; } else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) { - a->asi_syntax = (SYNTAX_CIS | SYNTAX_DN); + at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.12"; + at->at_equality_oid = "2.5.13.1"; } else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 || strcasecmp( argv[lasti], "ces" ) == 0 ) { - a->asi_syntax = SYNTAX_CES; + at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15"; + at->at_equality_oid = "2.5.13.5"; + at->at_ordering_oid = "2.5.13.6"; + at->at_substr_oid = "2.5.13.7"; } else if ( strcasecmp( argv[lasti], "binary" ) == 0 || strcasecmp( argv[lasti], "bin" ) == 0 ) { - a->asi_syntax = SYNTAX_BIN; + at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.5"; + /* There is no match for binary syntax. Really */ } else { Debug( LDAP_DEBUG_ANY, "%s: line %d: unknown syntax \"%s\" in attribute line (ignored)\n", @@ -293,50 +254,411 @@ attr_syntax_config( Debug( LDAP_DEBUG_ANY, "possible syntaxes are \"cis\", \"ces\", \"tel\", \"dn\", or \"bin\"\n", 0, 0, 0 ); - free( (char *) a ); + free( (AttributeType *) at ); return; } + save = argv[lasti]; argv[lasti] = NULL; - a->asi_names = charray_dup( argv ); + at->at_names = charray_dup( argv ); argv[lasti] = save; - switch ( avl_insert( &attr_syntaxes, (caddr_t) a, - (AVL_CMP) attr_syntax_cmp, - (AVL_DUP) attr_syntax_dup ) ) { - case -1: /* duplicate - different syntaxes */ - Debug( LDAP_DEBUG_ARGS, "%s: line %d: duplicate attribute\n", - fname, lineno, 0 ); - /* FALL */ + code = at_add( at, &err ); + if ( code ) { + fprintf( stderr, "%s: line %d: %s %s\n", + fname, lineno, scherr2str(code), err); + exit( 1 ); + } + ldap_memfree(at); +} - case 1: /* duplicate - same syntaxes */ - charray_free( a->asi_names ); - free( (char *) a ); - break; +int +at_fake_if_needed( + char *name +) +{ + char *argv[3]; - default: /* inserted */ - break; + if ( at_find( name ) ) { + return 0; + } else { + argv[0] = name; + argv[1] = "cis"; + argv[2] = NULL; + attr_syntax_config( "implicit", 0, 2, argv ); + return 0; } } -#ifdef LDAP_DEBUG +struct aindexrec { + char *air_name; + AttributeType *air_at; +}; + +static Avlnode *attr_index = NULL; +static AttributeType *attr_list = NULL; + +static int +attr_index_cmp( + struct aindexrec *air1, + struct aindexrec *air2 +) +{ + return (strcasecmp( air1->air_name, air2->air_name )); +} static int -attr_syntax_printnode( struct asyntaxinfo *a ) +attr_index_name_cmp( + char *type, + struct aindexrec *air +) +{ + return (strcasecmp( type, air->air_name )); +} + +AttributeType * +at_find( + const char *name +) +{ + struct aindexrec *air = NULL; + + if ( (air = (struct aindexrec *) avl_find( attr_index, name, + (AVL_CMP) attr_index_name_cmp )) != NULL ) { + return( air->air_at ); + } + return( NULL ); +} + +int +at_append_to_list( + AttributeType *sat, + AttributeType ***listp +) +{ + AttributeType **list; + AttributeType **list1; + int size; + + list = *listp; + if ( !list ) { + size = 2; + list = calloc(size, sizeof(AttributeType *)); + if ( !list ) { + return -1; + } + } else { + size = 0; + list1 = *listp; + while ( *list1 ) { + size++; + list1++; + } + size += 2; + list1 = realloc(list, size*sizeof(AttributeType *)); + if ( !list1 ) { + return -1; + } + list = list1; + } + list[size-2] = sat; + list[size-1] = NULL; + *listp = list; + return 0; +} + +int +at_delete_from_list( + int pos, + AttributeType ***listp +) +{ + AttributeType **list; + AttributeType **list1; + int i; + int j; + + if ( pos < 0 ) { + return -2; + } + list = *listp; + for ( i=0; list[i]; i++ ) + ; + if ( pos >= i ) { + return -2; + } + for ( i=pos, j=pos+1; list[j]; i++, j++ ) { + list[i] = list[j]; + } + list[i] = NULL; + /* Tell the runtime this can be shrinked */ + list1 = realloc(list, (i+1)*sizeof(AttributeType **)); + if ( !list1 ) { + return -1; + } + *listp = list1; + return 0; +} + +int +at_find_in_list( + AttributeType *sat, + AttributeType **list +) { int i; - printf( "syntax: 0x%x\n", a->asi_syntax ); - for ( i = 0; a->asi_names[i] != NULL; i++ ) { - printf( " name: %s\n", a->asi_names[i] ); + if ( !list ) { + return -1; + } + for ( i=0; list[i]; i++ ) { + if ( sat == list[i] ) { + return i; + } + } + return -1; +} + +static int +at_insert( + AttributeType *sat, + const char **err +) +{ + AttributeType **atp; + struct aindexrec *air; + char **names; + + atp = &attr_list; + while ( *atp != NULL ) { + atp = &(*atp)->sat_next; + } + *atp = sat; + + if ( sat->sat_oid ) { + air = (struct aindexrec *) + ch_calloc( 1, sizeof(struct aindexrec) ); + air->air_name = sat->sat_oid; + air->air_at = sat; + if ( avl_insert( &attr_index, (caddr_t) air, + (AVL_CMP) attr_index_cmp, + (AVL_DUP) avl_dup_error ) ) { + *err = sat->sat_oid; + ldap_memfree(air); + return SLAP_SCHERR_DUP_ATTR; + } + /* FIX: temporal consistency check */ + at_find(air->air_name); + } + if ( (names = sat->sat_names) ) { + while ( *names ) { + air = (struct aindexrec *) + ch_calloc( 1, sizeof(struct aindexrec) ); + air->air_name = ch_strdup(*names); + air->air_at = sat; + if ( avl_insert( &attr_index, (caddr_t) air, + (AVL_CMP) attr_index_cmp, + (AVL_DUP) avl_dup_error ) ) { + *err = *names; + ldap_memfree(air); + return SLAP_SCHERR_DUP_ATTR; + } + /* FIX: temporal consistency check */ + at_find(air->air_name); + names++; + } + } + + return 0; +} + +int +at_add( + LDAP_ATTRIBUTE_TYPE *at, + const char **err +) +{ + AttributeType *sat; + AttributeType *sat1; + MatchingRule *mr; + Syntax *syn; + int code; + char *errattr; + + if ( at->at_names && at->at_names[0] ) { + errattr = at->at_names[0]; + } else if ( at->at_oid ) { + errattr = at->at_oid; + } else { + errattr = ""; + return SLAP_SCHERR_ATTR_INCOMPLETE; + } + sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) ); + memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE)); + if ( at->at_sup_oid ) { + if ( (sat1 = at_find(at->at_sup_oid)) ) { + sat->sat_sup = sat1; + if ( at_append_to_list(sat, &sat1->sat_subtypes) ) { + *err = errattr; + return SLAP_SCHERR_OUTOFMEM; + } + } else { + *err = at->at_sup_oid; + return SLAP_SCHERR_ATTR_NOT_FOUND; + } + } + + if ( at->at_syntax_oid ) { + if ( (syn = syn_find(sat->sat_syntax_oid)) ) { + sat->sat_syntax = syn; + } else { + *err = sat->sat_syntax_oid; + return SLAP_SCHERR_SYN_NOT_FOUND; + } + if ( !strcmp(at->at_syntax_oid, + "1.3.6.1.4.1.1466.115.121.1.15") ) { + if ( at->at_equality_oid && + !strcmp(at->at_equality_oid, "2.5.13.5") ) { + sat->sat_syntax_compat = SYNTAX_CES; + } else { + sat->sat_syntax_compat = SYNTAX_CIS; + } + } else if ( !strcmp(at->at_syntax_oid, + "1.3.6.1.4.1.1466.115.121.1.50") ) { + sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL; + } else if ( !strcmp(at->at_syntax_oid, + "1.3.6.1.4.1.1466.115.121.1.12") ) { + sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN; + } else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.5") ) { + sat->sat_syntax_compat = SYNTAX_BIN; + } else { + sat->sat_syntax_compat = DEFAULT_SYNTAX; + } + } else { + sat->sat_syntax_compat = DEFAULT_SYNTAX; + } + + if ( sat->sat_equality_oid ) { + if ( (mr = mr_find(sat->sat_equality_oid)) ) { + sat->sat_equality = mr; + } else { + *err = sat->sat_equality_oid; + return SLAP_SCHERR_MR_NOT_FOUND; + } } + if ( sat->sat_ordering_oid ) { + if ( (mr = mr_find(sat->sat_ordering_oid)) ) { + sat->sat_ordering = mr; + } else { + *err = sat->sat_ordering_oid; + return SLAP_SCHERR_MR_NOT_FOUND; + } + } + if ( sat->sat_substr_oid ) { + if ( (mr = mr_find(sat->sat_substr_oid)) ) { + sat->sat_substr = mr; + } else { + *err = sat->sat_substr_oid; + return SLAP_SCHERR_MR_NOT_FOUND; + } + } + + /* + * Now inherit definitions from superiors. We only check the + * direct superior since that one has already inherited from + * its own superiorss + */ + if ( sat->sat_sup ) { + if ( !sat->sat_syntax ) { + sat->sat_syntax = sat->sat_sup->sat_syntax; + sat->sat_syntax_len = sat->sat_sup->sat_syntax_len; + } + if ( !sat->sat_equality ) { + sat->sat_equality = sat->sat_sup->sat_equality; + } + if ( !sat->sat_ordering ) { + sat->sat_ordering = sat->sat_sup->sat_ordering; + } + if ( !sat->sat_substr ) { + sat->sat_substr = sat->sat_sup->sat_substr; + } + } + code = at_insert(sat,err); + return code; +} + + +char * +at_canonical_name( char * a_type ) +{ + AttributeType *atp; + + if ( (atp=at_find(a_type)) == NULL ) { + + return a_type; + + } else if ( atp->sat_names + && atp->sat_names[0] + && (*(atp->sat_names[0]) != '\0') ) { + + return atp->sat_names[0]; + + } else if (atp->sat_oid && (*atp->sat_oid != '\0')) { + + return atp->sat_oid; + + } else { + + return a_type; + + } + +}/* char * at_canonica_name() */ + + +#if defined( SLAPD_SCHEMA_DN ) + +int +at_schema_info( Entry *e ) +{ + struct berval val; + struct berval *vals[2]; + AttributeType *at; + + vals[0] = &val; + vals[1] = NULL; + + for ( at = attr_list; at; at = at->sat_next ) { + val.bv_val = ldap_attributetype2str( &at->sat_atype ); + if ( val.bv_val ) { + val.bv_len = strlen( val.bv_val ); + Debug( LDAP_DEBUG_TRACE, "Merging at [%d] %s\n", + val.bv_len, val.bv_val, 0 ); + attr_merge( e, "attributeTypes", vals ); + ldap_memfree( val.bv_val ); + } else { + return -1; + } + } + return 0; +} +#endif + +#ifdef LDAP_DEBUG + +static int +at_index_printnode( struct aindexrec *air ) +{ + + printf( "%s = %s\n", air->air_name, ldap_attributetype2str(&air->air_at->sat_atype) ); return( 0 ); } static void -attr_syntax_print( void ) +at_index_print( void ) { - (void) avl_apply( attr_syntaxes, (AVL_APPLY) attr_syntax_printnode, + printf("Printing attribute type index:\n"); + (void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode, 0, -1, AVL_INORDER ); }