X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fad.c;h=9740fb0fdf0468d093a9e9a54b19a8bfc922acf8;hb=d9e7a7190b5f9e84dc0dba80f5bf1af993190218;hp=3cb1806d35b167c2bdc5353b3704b63f84779568;hpb=8057b1a0a84eb3f75f3da5878cedd7cd6e045e52;p=openldap diff --git a/servers/slapd/ad.c b/servers/slapd/ad.c index 3cb1806d35..9740fb0fdf 100644 --- a/servers/slapd/ad.c +++ b/servers/slapd/ad.c @@ -102,7 +102,6 @@ int slap_bv2ad( AttributeDescription desc, *d2; char *name, *options; char *opt, *next; - char *s, *ptr; int nlang; int langlen; @@ -172,7 +171,7 @@ int slap_bv2ad( if( !slap_syntax_is_binary( desc.ad_type->sat_syntax )) { /* not stored in binary, disallow option */ - *text = "option \"binary\" with type not supported"; + *text = "option \"binary\" not supported with type"; return rtn; } @@ -201,14 +200,15 @@ int slap_bv2ad( int rc; rc = strncasecmp( opt, langs[i].bv_val, - optlen < langs[i].bv_len ? optlen : langs[i].bv_len ); + (unsigned) optlen < langs[i].bv_len + ? optlen : langs[i].bv_len ); - if( rc == 0 && optlen == langs[i].bv_len ) { + if( rc == 0 && (unsigned)optlen == langs[i].bv_len ) { /* duplicate (ignore) */ goto done; } else if ( rc > 0 || - ( rc == 0 && optlen > langs[i].bv_len )) + ( rc == 0 && (unsigned)optlen > langs[i].bv_len )) { AC_MEMCPY( &langs[i+1], &langs[i], (nlang-i)*sizeof(struct berval) ); @@ -278,7 +278,7 @@ done:; /* Not found, add new one */ while (d2 == NULL) { - int dlen = 0; + size_t dlen = 0; ldap_pvt_thread_mutex_lock( &desc.ad_type->sat_ad_mutex ); /* check again now that we've locked */ for (d2 = desc.ad_type->sat_ad; d2; d2=d2->ad_next) { @@ -303,20 +303,21 @@ done:; * options length. */ if (desc.ad_lang.bv_len || desc.ad_flags != SLAP_DESC_NONE) { + dlen = desc.ad_type->sat_cname.bv_len; if (desc.ad_lang.bv_len) { - dlen = desc.ad_lang.bv_len+1; + dlen += 1+desc.ad_lang.bv_len; } - dlen += desc.ad_type->sat_cname.bv_len+1; if( slap_ad_is_binary( &desc ) ) { - dlen += sizeof("binary"); + dlen += sizeof(";binary")-1; } } - d2 = ch_malloc(sizeof(AttributeDescription) + dlen); + d2 = ch_malloc(sizeof(AttributeDescription) + dlen + 1); d2->ad_type = desc.ad_type; d2->ad_flags = desc.ad_flags; - d2->ad_cname.bv_len = desc.ad_cname.bv_len; + d2->ad_cname.bv_len = desc.ad_type->sat_cname.bv_len; d2->ad_lang.bv_len = desc.ad_lang.bv_len; + if (dlen == 0) { d2->ad_cname.bv_val = d2->ad_type->sat_cname.bv_val; d2->ad_lang.bv_val = NULL; @@ -326,7 +327,7 @@ done:; if( slap_ad_is_binary( &desc ) ) { strcpy(d2->ad_cname.bv_val+d2->ad_cname.bv_len, ";binary"); - d2->ad_cname.bv_len += sizeof("binary"); + d2->ad_cname.bv_len += sizeof(";binary")-1; } if( d2->ad_lang.bv_len ) { d2->ad_cname.bv_val[d2->ad_cname.bv_len++]=';'; @@ -350,7 +351,6 @@ done:; d2->ad_next = desc.ad_type->sat_ad->ad_next; desc.ad_type->sat_ad->ad_next = d2; } - free(desc.ad_lang.bv_val); ldap_pvt_thread_mutex_unlock( &desc.ad_type->sat_ad_mutex ); } @@ -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 ) { @@ -456,7 +480,7 @@ int ad_inlist( int i; for ( i = 0; oc->soc_required[i] != NULL; i++ ) { rc = is_at_subtype( desc->ad_type, - oc->soc_allowed[i] ); + oc->soc_required[i] ); if( rc ) return 1; } } @@ -531,8 +555,8 @@ int slap_bv2undef_ad( } if( !desc ) { - desc = ch_malloc(sizeof(AttributeDescription) + - bv->bv_len + 1); + desc = ch_malloc(sizeof(AttributeDescription) + 1 + + bv->bv_len); desc->ad_flags = SLAP_DESC_NONE; desc->ad_lang.bv_val = 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 ); }