X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fat.c;h=911c46f8702d5a993233951d8e443d1abbd2d1c8;hb=4d36fd5a3ed407b0a53004d1431f1669222138b4;hp=5c3cad15c5667774beca4a5a53645227f2d5bb0a;hpb=ef7b93242d070dc2eee857c8e8c90f4d3b7a5580;p=openldap diff --git a/servers/slapd/at.c b/servers/slapd/at.c index 5c3cad15c5..911c46f870 100644 --- a/servers/slapd/at.c +++ b/servers/slapd/at.c @@ -1,6 +1,6 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* at.c - routines for dealing with attribute types */ @@ -44,7 +44,7 @@ int is_at_subtype( } struct aindexrec { - char *air_name; + struct berval air_name; AttributeType *air_at; }; @@ -57,22 +57,42 @@ attr_index_cmp( struct aindexrec *air2 ) { - return (strcasecmp( air1->air_name, air2->air_name )); + int i = air1->air_name.bv_len - air2->air_name.bv_len; + if (i) + return i; + return (strcasecmp( air1->air_name.bv_val, air2->air_name.bv_val )); } static int attr_index_name_cmp( - const char *type, + struct berval *type, struct aindexrec *air ) { - return (strcasecmp( type, air->air_name )); + int i = type->bv_len - air->air_name.bv_len; + if (i) + return i; + return (strncasecmp( type->bv_val, air->air_name.bv_val, + type->bv_len )); } AttributeType * at_find( const char *name ) +{ + struct berval bv; + + bv.bv_val = (char *)name; + bv.bv_len = strlen( name ); + + return at_bvfind( &bv ); +} + +AttributeType * +at_bvfind( + struct berval *name +) { struct aindexrec *air; @@ -171,6 +191,23 @@ at_find_in_list( return -1; } +void +at_destroy( void ) +{ + AttributeType *a, *n; + avl_free(attr_index, ldap_memfree); + + for (a=attr_list; a; a=n) { + n = a->sat_next; + if (a->sat_subtypes) ldap_memfree(a->sat_subtypes); + ad_destroy(a->sat_ad); + ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex); + ldap_attributetype_free((LDAPAttributeType *)a); + } + if ( slap_schema.si_at_undefined ) + ad_destroy(slap_schema.si_at_undefined->sat_ad); +} + static int at_insert( AttributeType *sat, @@ -190,35 +227,36 @@ at_insert( if ( sat->sat_oid ) { air = (struct aindexrec *) ch_calloc( 1, sizeof(struct aindexrec) ); - air->air_name = sat->sat_oid; + air->air_name.bv_val = sat->sat_oid; + air->air_name.bv_len = strlen(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; + return SLAP_SCHERR_ATTR_DUP; } /* FIX: temporal consistency check */ - at_find(air->air_name); + at_bvfind(&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_name.bv_val = *names; + air->air_name.bv_len = strlen(*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->air_name); ldap_memfree(air); - return SLAP_SCHERR_DUP_ATTR; + return SLAP_SCHERR_ATTR_DUP; } /* FIX: temporal consistency check */ - at_find(air->air_name); + at_bvfind(&air->air_name); names++; } } @@ -236,13 +274,42 @@ at_add( MatchingRule *mr; Syntax *syn; int code; - char *cname; + char *cname; + char *oid; + + if ( !OID_LEADCHAR( at->at_oid[0] )) { + /* Expand OID macros */ + oid = oidm_find( at->at_oid ); + if ( !oid ) { + *err = at->at_oid; + return SLAP_SCHERR_OIDM; + } + if ( oid != at->at_oid ) { + ldap_memfree( at->at_oid ); + at->at_oid = oid; + } + } + + if ( at->at_syntax_oid && !OID_LEADCHAR( at->at_syntax_oid[0] )) { + /* Expand OID macros */ + oid = oidm_find( at->at_syntax_oid ); + if ( !oid ) { + *err = at->at_syntax_oid; + return SLAP_SCHERR_OIDM; + } + if ( oid != at->at_syntax_oid ) { + ldap_memfree( at->at_syntax_oid ); + at->at_syntax_oid = oid; + } + + } if ( at->at_names && at->at_names[0] ) { int i; for( i=0; at->at_names[i]; i++ ) { if( !slap_valid_descr( at->at_names[i] ) ) { + *err = at->at_names[i]; return SLAP_SCHERR_BAD_DESCR; } } @@ -251,18 +318,37 @@ at_add( } else if ( at->at_oid ) { cname = at->at_oid; + } else { + *err = ""; return SLAP_SCHERR_ATTR_INCOMPLETE; } + *err = cname; + + if ( !at->at_usage && at->at_no_user_mod ) { + /* user attribute must be modifable */ + return SLAP_SCHERR_ATTR_BAD_USAGE; + } + if ( at->at_collective ) { - return SLAP_SCHERR_NOT_SUPPORTED; + if( at->at_usage ) { + /* collective attributes cannot be operational */ + return SLAP_SCHERR_ATTR_BAD_USAGE; + } + + if( at->at_single_value ) { + /* collective attributes cannot be single-valued */ + return SLAP_SCHERR_ATTR_BAD_USAGE; + } } sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) ); AC_MEMCPY( &sat->sat_atype, at, sizeof(LDAPAttributeType)); - sat->sat_cname = cname; + sat->sat_cname.bv_val = cname; + sat->sat_cname.bv_len = strlen( cname ); + ldap_pvt_thread_mutex_init(&sat->sat_ad_mutex); if ( at->at_sup_oid ) { AttributeType *supsat = at_find(at->at_sup_oid); @@ -275,9 +361,18 @@ at_add( sat->sat_sup = supsat; if ( at_append_to_list(sat, &supsat->sat_subtypes) ) { - *err = cname; return SLAP_SCHERR_OUTOFMEM; } + + if ( sat->sat_usage != supsat->sat_usage ) { + /* subtypes must have same usage as their SUP */ + return SLAP_SCHERR_ATTR_BAD_USAGE; + } + + if ( sat->sat_flags & SLAP_AT_FINAL ) { + /* cannot subtype a "final" attribute type */ + return SLAP_SCHERR_ATTR_BAD_SUP; + } } /* @@ -345,7 +440,7 @@ at_index_printnode( struct aindexrec *air ) { printf("%s = %s\n", - air->air_name, + air->air_name.bv_val, ldap_attributetype2str(&air->air_at->sat_atype) ); return( 0 ); } @@ -363,27 +458,26 @@ at_index_print( void ) int at_schema_info( Entry *e ) { - struct berval val; - struct berval *vals[2]; + struct berval vals[2]; AttributeType *at; AttributeDescription *ad_attributeTypes = slap_schema.si_ad_attributeTypes; - vals[0] = &val; - vals[1] = NULL; + vals[1].bv_val = NULL; for ( at = attr_list; at; at = at->sat_next ) { - val.bv_val = ldap_attributetype2str( &at->sat_atype ); - if ( val.bv_val == NULL ) { + if ( ldap_attributetype2bv( &at->sat_atype, vals ) == NULL ) { return -1; } - val.bv_len = strlen( val.bv_val ); + + if( at->sat_flags & SLAP_AT_HIDE ) continue; + #if 0 Debug( LDAP_DEBUG_TRACE, "Merging at [%ld] %s\n", - (long) val.bv_len, val.bv_val, 0 ); + (long) vals[0].bv_len, vals[0].bv_val, 0 ); #endif attr_merge( e, ad_attributeTypes, vals ); - ldap_memfree( val.bv_val ); + ldap_memfree( vals[0].bv_val ); } return 0; }