X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fat.c;h=5a1fdd954b226421468718dec751e49b871204bb;hb=8623c98726058d801aea6ee505ea307618334bc2;hp=4538f5b5d4c4d8f1619bf818b4b392a8916515eb;hpb=2bdc0819b4b99f7fb7c054b8ceae0d964ff8be31;p=openldap diff --git a/servers/slapd/at.c b/servers/slapd/at.c index 4538f5b5d4..5a1fdd954b 100644 --- a/servers/slapd/at.c +++ b/servers/slapd/at.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2007 The OpenLDAP Foundation. + * Copyright 1998-2011 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -74,7 +74,7 @@ struct aindexrec { static Avlnode *attr_index = NULL; static Avlnode *attr_cache = NULL; -static LDAP_STAILQ_HEAD(ATList, slap_attribute_type) attr_list +static LDAP_STAILQ_HEAD(ATList, AttributeType) attr_list = LDAP_STAILQ_HEAD_INITIALIZER(attr_list); /* Last hardcoded attribute registered */ @@ -253,7 +253,7 @@ at_delete( AttributeType *at ) { at->sat_flags |= SLAP_AT_DELETED; - LDAP_STAILQ_REMOVE(&attr_list,at,slap_attribute_type,sat_next); + LDAP_STAILQ_REMOVE(&attr_list, at, AttributeType, sat_next); at_delete_names( at ); } @@ -288,6 +288,10 @@ at_clean( AttributeType *a ) ldap_memfree( a->sat_oidmacro ); a->sat_oidmacro = NULL; } + if ( a->sat_soidmacro ) { + ldap_memfree( a->sat_soidmacro ); + a->sat_soidmacro = NULL; + } if ( a->sat_subtypes ) { ldap_memfree( a->sat_subtypes ); a->sat_subtypes = NULL; @@ -459,6 +463,7 @@ at_insert( /* Keep old oid, free new oid; * Keep old ads, free new ads; + * Keep old ad_mutex, free new ad_mutex; * Keep new everything else, free old */ tmp = *old_sat; @@ -467,6 +472,8 @@ at_insert( tmp.sat_oid = sat->sat_oid; old_sat->sat_ad = tmp.sat_ad; tmp.sat_ad = sat->sat_ad; + old_sat->sat_ad_mutex = tmp.sat_ad_mutex; + tmp.sat_ad_mutex = sat->sat_ad_mutex; *sat = tmp; /* Check for basic ad pointing at old cname */ @@ -587,6 +594,7 @@ at_add( int code = LDAP_SUCCESS; char *cname = NULL; char *oidm = NULL; + char *soidm = NULL; if ( !at->at_oid ) { *err = ""; @@ -619,7 +627,7 @@ at_add( goto error_return; } if ( oid != at->at_syntax_oid ) { - ldap_memfree( at->at_syntax_oid ); + soidm = at->at_syntax_oid; at->at_syntax_oid = oid; } } @@ -670,6 +678,7 @@ at_add( sat->sat_cname.bv_val = cname; sat->sat_cname.bv_len = strlen( cname ); sat->sat_oidmacro = oidm; + sat->sat_soidmacro = soidm; ldap_pvt_thread_mutex_init(&sat->sat_ad_mutex); if ( at->at_sup_oid ) { @@ -713,8 +722,22 @@ at_add( * its own superiorss */ if ( sat->sat_sup ) { - sat->sat_syntax = sat->sat_sup->sat_syntax; - sat->sat_equality = sat->sat_sup->sat_equality; + Syntax *syn = syn_find(sat->sat_sup->sat_syntax->ssyn_oid); + if ( syn != sat->sat_sup->sat_syntax ) { + sat->sat_syntax = ch_malloc( sizeof( Syntax )); + *sat->sat_syntax = *sat->sat_sup->sat_syntax; + } else { + sat->sat_syntax = sat->sat_sup->sat_syntax; + } + if ( sat->sat_sup->sat_equality ) { + MatchingRule *mr = mr_find( sat->sat_sup->sat_equality->smr_oid ); + if ( mr != sat->sat_sup->sat_equality ) { + sat->sat_equality = ch_malloc( sizeof( MatchingRule )); + *sat->sat_equality = *sat->sat_sup->sat_equality; + } else { + sat->sat_equality = sat->sat_sup->sat_equality; + } + } sat->sat_approx = sat->sat_sup->sat_approx; sat->sat_ordering = sat->sat_sup->sat_ordering; sat->sat_substr = sat->sat_sup->sat_substr; @@ -751,9 +774,12 @@ at_add( goto error_return; } - if( sat->sat_syntax != NULL && sat->sat_syntax != syn ) { - code = SLAP_SCHERR_ATTR_BAD_SUP; - goto error_return; + if ( sat->sat_syntax != NULL && sat->sat_syntax != syn ) { + /* BEWARE: no loop detection! */ + if ( syn_is_sup( sat->sat_syntax, syn ) ) { + code = SLAP_SCHERR_ATTR_BAD_SUP; + goto error_return; + } } sat->sat_syntax = syn; @@ -913,6 +939,11 @@ error_return:; at->at_oid = oidm; } + if ( soidm ) { + SLAP_FREE( at->at_syntax_oid ); + at->at_syntax_oid = soidm; + } + } else if ( rsat ) { *rsat = sat; } @@ -973,9 +1004,12 @@ at_unparse( BerVarray *res, AttributeType *start, AttributeType *end, int sys ) for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) { LDAPAttributeType lat, *latp; if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break; - if ( at->sat_oidmacro ) { + if ( at->sat_oidmacro || at->sat_soidmacro ) { lat = at->sat_atype; - lat.at_oid = at->sat_oidmacro; + if ( at->sat_oidmacro ) + lat.at_oid = at->sat_oidmacro; + if ( at->sat_soidmacro ) + lat.at_syntax_oid = at->sat_soidmacro; latp = ⪫ } else { latp = &at->sat_atype; @@ -1025,7 +1059,7 @@ at_schema_info( Entry *e ) } int -register_at( char *def, AttributeDescription **rad, int dupok ) +register_at( const char *def, AttributeDescription **rad, int dupok ) { LDAPAttributeType *at; int code, freeit = 0; @@ -1046,10 +1080,10 @@ register_at( char *def, AttributeDescription **rad, int dupok ) freeit = 1; } else { - ldap_attributetype_free( at ); Debug( LDAP_DEBUG_ANY, "register_at: AttributeType \"%s\": %s, %s\n", def, scherr2str(code), err ); + ldap_attributetype_free( at ); return code; } }