AttributeDescription desc, *d2;
char *name, *options;
char *opt, *next;
- char *s, *ptr;
int nlang;
int langlen;
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;
}
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) );
/* 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) {
* 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;
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++]=';';
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 );
}
}
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 );
}
/* 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;
}
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 ) {
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;
}
}
}
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;
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 )
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 );
}