]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/ad.c
Converted ch_calloc and ch_malloc calls to SLAP_CALLOC and SLAP_MALLOC.
[openldap] / servers / slapd / ad.c
index 3cb1806d35b167c2bdc5353b3704b63f84779568..9740fb0fdf0468d093a9e9a54b19a8bfc922acf8 100644 (file)
@@ -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 );
 }