X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fad.c;h=9740fb0fdf0468d093a9e9a54b19a8bfc922acf8;hb=d9e7a7190b5f9e84dc0dba80f5bf1af993190218;hp=3d1335b435d86c45d0073b9794e92502be90c6a8;hpb=80f67ef11e0e1e80ab934764687c6e50a221ef02;p=openldap diff --git a/servers/slapd/ad.c b/servers/slapd/ad.c index 3d1335b435..9740fb0fdf 100644 --- a/servers/slapd/ad.c +++ b/servers/slapd/ad.c @@ -364,15 +364,18 @@ done:; } static int is_ad_sublang( - const char *sublang, - const char *suplang ) + struct berval *sublangbv, + struct berval *suplangbv ) { - const char *supp, *supdelimp; - const char *subp, *subdelimp; + const char *suplang, *supp, *supdelimp; + const char *sublang, *subp, *subdelimp; int suplen, sublen; - if( suplang == NULL ) return 1; - if( sublang == NULL ) return 0; + if( suplangbv->bv_len == 0 ) return 1; + if( sublangbv->bv_len == 0 ) return 0; + + sublang =sublangbv->bv_val; + suplang =suplangbv->bv_val; for( supp=suplang ; supp; supp=supdelimp ) { supdelimp = strchrlen( supp, ';', &suplen ); @@ -413,7 +416,7 @@ int is_ad_subtype( } /* check for language tags */ - if ( !is_ad_sublang( sub->ad_lang.bv_val, super->ad_lang.bv_val )) { + if ( !is_ad_sublang( &sub->ad_lang, &super->ad_lang )) { return 0; } @@ -431,18 +434,39 @@ int ad_inlist( int rc; if ( attrs->an_desc ) { - if ( is_ad_subtype( desc, attrs->an_desc )) + if ( desc == attrs->an_desc ) { + return 1; + } + + /* + * EXTENSION: if requested description is preceeded by an + * a '-' character, do not match on subtypes. + */ + if ( attrs->an_name.bv_val[0] != '-' && + is_ad_subtype( desc, attrs->an_desc )) + { return 1; + } + continue; } /* - * EXTENSION: see if requested description is an object class + * EXTENSION: see if requested description is +objectClass * if so, return attributes which the class requires/allows */ oc = attrs->an_oc; - if( oc == NULL ) { - oc = oc_bvfind( &attrs->an_name ); + if( oc == NULL && attrs->an_name.bv_val ) { + switch( attrs->an_name.bv_val[0] ) { + case '+': { /* new way */ + struct berval ocname; + ocname.bv_len = attrs->an_name.bv_len - 1; + ocname.bv_val = &attrs->an_name.bv_val[1]; + oc = oc_bvfind( &ocname ); + } break; + default: /* old (deprecated) way */ + oc = oc_bvfind( &attrs->an_name ); + } attrs->an_oc = oc; } if( oc != NULL ) { @@ -577,8 +601,16 @@ an_find( return( 0 ); } -/* Convert a delimited string into a list of AttributeNames; Add on - * to an existing list if it was given. +/* + * Convert a delimited string into a list of AttributeNames; + * add on to an existing list if it was given. If the string + * is not a valid attribute name, if a '-' is prepended it is + * skipped and the remaining name is tried again; if a '+' is + * prepended, an objectclass name is searched instead. + * + * NOTE: currently, if a valid attribute name is not found, + * the same string is also checked as valid objectclass name; + * however, this behavior is deprecated. */ AttributeName * str2anlist( AttributeName *an, char *in, const char *brkstr ) @@ -615,18 +647,54 @@ str2anlist( AttributeName *an, char *in, const char *brkstr ) ber_str2bv(s, 0, 1, &anew->an_name); slap_bv2ad(&anew->an_name, &anew->an_desc, &text); if ( !anew->an_desc ) { - anew->an_oc = oc_bvfind( &anew->an_name ); - if ( !anew->an_oc ) { - free( an ); - /* overwrites input string on error! */ - strcpy( in, s ); - return NULL; + switch( anew->an_name.bv_val[0] ) { + case '-': { + struct berval adname; + adname.bv_len = anew->an_name.bv_len - 1; + adname.bv_val = &anew->an_name.bv_val[1]; + slap_bv2ad(&adname, &anew->an_desc, &text); + if ( !anew->an_desc ) { + free( an ); + /* + * overwrites input string + * on error! + */ + strcpy( in, s ); + return NULL; + } + } break; + + case '+': { + struct berval ocname; + ocname.bv_len = anew->an_name.bv_len - 1; + ocname.bv_val = &anew->an_name.bv_val[1]; + anew->an_oc = oc_bvfind( &ocname ); + if ( !anew->an_oc ) { + free( an ); + /* + * overwrites input string + * on error! + */ + strcpy( in, s ); + return NULL; + } + } break; + + default: + /* old (deprecated) way */ + anew->an_oc = oc_bvfind( &anew->an_name ); + if ( !anew->an_oc ) { + free( an ); + /* overwrites input string on error! */ + strcpy( in, s ); + return NULL; + } } } anew++; } - anew->an_name.bv_val = NULL; + anew->an_name.bv_val = NULL; free( str ); return( an ); }