]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/ad.c
fix a_nvals according to back-ldap implementation (ITS#2716; at least part of it)
[openldap] / servers / slapd / ad.c
index a6083bd379c079978a9f1da1f30cc9ffcec171fc..c65934f1541835460556a0eb25cebf432d35b8a3 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#include "lutil.h"
 
 typedef struct Attr_option {
        struct berval name;     /* option name or prefix */
@@ -191,8 +192,7 @@ int slap_bv2ad(
                        desc.ad_flags |= SLAP_DESC_BINARY;
                        continue;
 
-               } else if ( ad_find_option_definition( opt, optlen ) )
-               {
+               } else if ( ad_find_option_definition( opt, optlen ) ) {
                        int i;
 
                        if( opt[optlen-1] == '-' ) {
@@ -222,10 +222,10 @@ int slap_bv2ad(
                                } else if ( rc > 0 ||
                                        ( rc == 0 && (unsigned)optlen > tags[i].bv_len ))
                                {
-                                       AC_MEMCPY( &tags[i+1], &tags[i],
-                                               (ntags-i)*sizeof(struct berval) );
-                                       tags[i].bv_val = opt;
-                                       tags[i].bv_len = optlen;
+                                       AC_MEMCPY( &tags[i+2], &tags[i+1],
+                                               (ntags-i-1)*sizeof(struct berval) );
+                                       tags[i+1].bv_val = opt;
+                                       tags[i+1].bv_len = optlen;
                                        goto done;
                                }
                        }
@@ -325,6 +325,7 @@ done:;
                }
 
                d2 = ch_malloc(sizeof(AttributeDescription) + dlen);
+               d2->ad_next = NULL;
                d2->ad_type = desc.ad_type;
                d2->ad_flags = desc.ad_flags;
                d2->ad_cname.bv_len = desc.ad_type->sat_cname.bv_len;
@@ -352,16 +353,13 @@ done:;
                                                j = (lp
                                                     ? lp - desc.ad_tags.bv_val - 1
                                                     : strlen( desc.ad_tags.bv_val ));
-                                               strncpy(cp, desc.ad_tags.bv_val, j);
-                                               cp += j;
+                                               cp = lutil_strncopy(cp, desc.ad_tags.bv_val, j);
                                        }
                                }
-                               strcpy(cp, ";binary");
-                               cp += sizeof(";binary")-1;
+                               cp = lutil_strcopy(cp, ";binary");
                                if( lp != NULL ) {
                                        *cp++ = ';';
-                                       strcpy(cp, lp);
-                                       cp += strlen( cp );
+                                       cp = lutil_strcopy(cp, lp);
                                }
                                d2->ad_cname.bv_len = cp - d2->ad_cname.bv_val;
                                if( desc.ad_tags.bv_len )
@@ -412,9 +410,6 @@ static int is_ad_subtags(
        const char *subtags, *subp, *subdelimp;
        int  suplen, sublen;
 
-       if( suptagsbv->bv_len == 0 ) return 1;
-       if( subtagsbv->bv_len == 0 ) return 0;
-
        subtags =subtagsbv->bv_val;
        suptags =suptagsbv->bv_val;
 
@@ -447,9 +442,13 @@ int is_ad_subtype(
        AttributeDescription *super
 )
 {
+       AttributeType *a;
        int lr;
 
-       if( !is_at_subtype( sub->ad_type, super->ad_type ) ) {
+       for ( a = sub->ad_type; a; a=a->sat_sup ) {
+               if ( a == super->ad_type ) break;
+       }
+       if( !a ) {
                return 0;
        }
 
@@ -460,11 +459,12 @@ int is_ad_subtype(
        }
 
        /* check for tagging options */
-       if ( !is_ad_subtags( &sub->ad_tags, &super->ad_tags )) {
+       if ( super->ad_tags.bv_len == 0 )
+               return 1;
+       if ( sub->ad_tags.bv_len == 0 )
                return 0;
-       }
 
-       return 1;
+       return is_ad_subtags( &sub->ad_tags, &super->ad_tags );
 }
 
 int ad_inlist(
@@ -474,24 +474,50 @@ int ad_inlist(
        if (! attrs ) return 0;
 
        for( ; attrs->an_name.bv_val; attrs++ ) {
+               AttributeType *a;
                ObjectClass *oc;
                int rc;
                
                if ( attrs->an_desc ) {
+                       int lr;
+
                        if ( desc == attrs->an_desc ) {
                                return 1;
                        }
 
                        /*
-                        * EXTENSION: if requested description is preceeded by an
+                        * EXTENSION: if requested description is preceeded by
                         * a '-' character, do not match on subtypes.
                         */
-                       if ( attrs->an_name.bv_val[0] != '-' &&
-                               is_ad_subtype( desc, attrs->an_desc ))
-                       {
+                       if ( attrs->an_name.bv_val[0] == '-' ) {
+                               continue;
+                       }
+                       
+                       /* Is this a subtype of the requested attr? */
+                       for (a = desc->ad_type; a; a=a->sat_sup) {
+                               if ( a == attrs->an_desc->ad_type )
+                                       break;
+                       }
+                       if ( !a ) {
+                               continue;
+                       }
+                       /* Does desc support all the requested flags? */
+                       lr = desc->ad_tags.bv_len ? SLAP_DESC_TAG_RANGE : 0;
+                       if(( attrs->an_desc->ad_flags & (desc->ad_flags | lr))
+                               != attrs->an_desc->ad_flags ) {
+                               continue;
+                       }
+                       /* Do the descs have compatible tags? */
+                       if ( attrs->an_desc->ad_tags.bv_len == 0 ) {
+                               return 1;
+                       }
+                       if ( desc->ad_tags.bv_len == 0) {
+                               continue;
+                       }
+                       if ( is_ad_subtags( &desc->ad_tags,
+                               &attrs->an_desc->ad_tags ) ) {
                                return 1;
                        }
-
                        continue;
                }
 
@@ -523,9 +549,11 @@ int ad_inlist(
                                /* allow return of required attributes */
                                int i;
                                for ( i = 0; oc->soc_required[i] != NULL; i++ ) {
-                                       rc = is_at_subtype( desc->ad_type,
-                                               oc->soc_required[i] );
-                                       if( rc ) return 1;
+                                       for (a = desc->ad_type; a; a=a->sat_sup) {
+                                               if ( a == oc->soc_required[i] ) {
+                                                       return 1;
+                                               }
+                                       }
                                }
                        }
 
@@ -533,9 +561,11 @@ int ad_inlist(
                                /* allow return of allowed attributes */
                                int i;
                                for ( i = 0; oc->soc_allowed[i] != NULL; i++ ) {
-                                       rc = is_at_subtype( desc->ad_type,
-                                               oc->soc_allowed[i] );
-                                       if( rc ) return 1;
+                                       for (a = desc->ad_type; a; a=a->sat_sup) {
+                                               if ( a == oc->soc_allowed[i] ) {
+                                                       return 1;
+                                               }
+                                       }
                                }
                        }
 
@@ -748,7 +778,8 @@ str2anlist( AttributeName *an, char *in, const char *brkstr )
 int
 ad_define_option( const char *name, const char *fname, int lineno )
 {
-       int i, j, len, optlen;
+       int i;
+       unsigned int optlen;
 
        if ( options == &lang_option ) {
                options = NULL;
@@ -774,7 +805,7 @@ ad_define_option( const char *name, const char *fname, int lineno )
        } while ( name[++optlen] );
 
        options = ch_realloc( options,
-                             (option_count+1) * sizeof(Attr_option) );
+               (option_count+1) * sizeof(Attr_option) );
 
        if ( strcasecmp( name, "binary" ) == 0
             || ad_find_option_definition( name, optlen ) ) {
@@ -844,3 +875,25 @@ ad_find_option_definition( const char *opt, int optlen )
        }
        return NULL;
 }
+
+MatchingRule *ad_mr(
+       AttributeDescription *ad,
+       unsigned usage )
+{
+       switch( usage & SLAP_MR_TYPE_MASK ) {
+       case SLAP_MR_NONE:
+       case SLAP_MR_EQUALITY:
+               return ad->ad_type->sat_equality;
+               break;
+       case SLAP_MR_ORDERING:
+               return ad->ad_type->sat_ordering;
+               break;
+       case SLAP_MR_SUBSTR:
+               return ad->ad_type->sat_substr;
+               break;
+       case SLAP_MR_EXT:
+       default:
+               assert( 0 /* ad_mr: bad usage */);
+       }
+       return NULL;
+}