X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Fad.c;h=8543c9b2a4fb2041b32254e133a06ba48fa4f368;hb=e2483d8a9bc7fa72bac53d8af3ed215d3a1d80d0;hp=407b091cadf503595b36517f36e21ed1e615c749;hpb=dd66e6e9292c1a250a89865d691f836003d08517;p=openldap diff --git a/servers/slapd/ad.c b/servers/slapd/ad.c index 407b091cad..8543c9b2a4 100644 --- a/servers/slapd/ad.c +++ b/servers/slapd/ad.c @@ -1,9 +1,18 @@ +/* ad.c - routines for dealing with attribute descriptions */ /* $OpenLDAP$ */ -/* - * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2003 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ -/* ad.c - routines for dealing with attribute descriptions */ #include "portable.h" @@ -17,6 +26,7 @@ #include "ldap_pvt.h" #include "slap.h" +#include "lutil.h" typedef struct Attr_option { struct berval name; /* option name or prefix */ @@ -221,10 +231,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; } } @@ -352,16 +362,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 +419,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 +451,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 +468,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 +483,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; } @@ -502,18 +537,60 @@ int ad_inlist( oc = attrs->an_oc; if( oc == NULL && attrs->an_name.bv_val ) { switch( attrs->an_name.bv_val[0] ) { - case '+': { /* new way */ + case '+': /* new way */ + case '!': { /* exclude */ 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 ); + attrs->an_oc_exclude = 0; + if ( oc && attrs->an_name.bv_val[0] == '!' ) { + attrs->an_oc_exclude = 1; + } } break; + default: /* old (deprecated) way */ oc = oc_bvfind( &attrs->an_name ); } attrs->an_oc = oc; } if( oc != NULL ) { + if ( attrs->an_oc_exclude ) { + int gotit = 0; + + if ( oc == slap_schema.si_oc_extensibleObject ) { + /* extensibleObject allows the return of anything */ + return 0; + } + + if( oc->soc_required ) { + /* allow return of required attributes */ + int i; + + for ( i = 0; oc->soc_required[i] != NULL; i++ ) { + for (a = desc->ad_type; a; a=a->sat_sup) { + if ( a == oc->soc_required[i] ) { + return 0; + } + } + } + } + + if( oc->soc_allowed ) { + /* allow return of allowed attributes */ + int i; + for ( i = 0; oc->soc_allowed[i] != NULL; i++ ) { + for (a = desc->ad_type; a; a=a->sat_sup) { + if ( a == oc->soc_allowed[i] ) { + return 0; + } + } + } + } + + return 1; + } + if ( oc == slap_schema.si_oc_extensibleObject ) { /* extensibleObject allows the return of anything */ return 1; @@ -522,10 +599,13 @@ int ad_inlist( if( oc->soc_required ) { /* 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 +613,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; + } + } } } @@ -650,7 +732,8 @@ an_find( * 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. + * prepended, an objectclass name is searched instead; if a + * '!' is prepended, the objectclass name is negated. * * NOTE: currently, if a valid attribute name is not found, * the same string is also checked as valid objectclass name; @@ -688,6 +771,7 @@ str2anlist( AttributeName *an, char *in, const char *brkstr ) { anew->an_desc = NULL; anew->an_oc = NULL; + anew->an_oc_exclude = 0; ber_str2bv(s, 0, 1, &anew->an_name); slap_bv2ad(&anew->an_name, &anew->an_desc, &text); if ( !anew->an_desc ) { @@ -708,7 +792,8 @@ str2anlist( AttributeName *an, char *in, const char *brkstr ) } } break; - case '+': { + case '+': + case '!': { struct berval ocname; ocname.bv_len = anew->an_name.bv_len - 1; ocname.bv_val = &anew->an_name.bv_val[1]; @@ -722,6 +807,10 @@ str2anlist( AttributeName *an, char *in, const char *brkstr ) strcpy( in, s ); return NULL; } + + if ( anew->an_name.bv_val[0] == '!' ) { + anew->an_oc_exclude = 1; + } } break; default: @@ -845,3 +934,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; +}