X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Facl.c;h=48f93c81966e13ef2a29442da677e0b231b100d3;hb=3bf9998d7885ef6bbc4690d4229e5cb5068a35de;hp=6a2621da43b4434390e0748ff2c3549aab3db9ae;hpb=e27a2c7252f97936f99f9c46513108b194306583;p=openldap diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 6a2621da43..48f93c8196 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2006 The OpenLDAP Foundation. + * Copyright 1998-2008 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,6 +40,9 @@ #define ACL_BUF_SIZE 1024 /* use most appropriate size */ static const struct berval acl_bv_ip_eq = BER_BVC( "IP=" ); +#ifdef LDAP_PF_INET6 +static const struct berval acl_bv_ipv6_eq = BER_BVC( "IP=[" ); +#endif /* LDAP_PF_INET6 */ #ifdef LDAP_PF_LOCAL static const struct berval acl_bv_path_eq = BER_BVC("PATH="); #endif /* LDAP_PF_LOCAL */ @@ -134,7 +137,6 @@ slap_access_allowed( slap_access_t access_level; const char *attr; regmatch_t matches[MAXREMATCHES]; - int st_same_attr = 0; assert( op != NULL ); assert( e != NULL ); @@ -198,24 +200,17 @@ slap_access_allowed( ret = 0; control = ACL_BREAK; - if ( st_same_attr ) { - assert( state->as_vd_acl != NULL ); - + if ( state && state->as_vd_ad == desc ) { a = state->as_vd_acl; count = state->as_vd_acl_count; - if ( !ACL_IS_INVALID( state->as_vd_acl_mask ) ) { - mask = state->as_vd_acl_mask; - AC_MEMCPY( matches, state->as_vd_acl_matches, sizeof(matches) ); - goto vd_access; - } } else { if ( state ) state->as_vi_acl = NULL; a = NULL; - ACL_PRIV_ASSIGN( mask, *maskp ); count = 0; - memset( matches, '\0', sizeof( matches ) ); } + ACL_PRIV_ASSIGN( mask, *maskp ); + memset( matches, '\0', sizeof( matches ) ); while ( ( a = slap_acl_get( a, &count, op, e, desc, val, MAXREMATCHES, matches, state ) ) != NULL ) @@ -239,18 +234,17 @@ slap_access_allowed( ( state->as_recorded & ACL_STATE_RECORDED_NV ) ) { Debug( LDAP_DEBUG_ACL, - "=> slap_access_allowed: result from state (%s)\n", + "=> slap_access_allowed: result was in cache (%s)\n", attr, 0, 0 ); ret = state->as_result; goto done; } else { Debug( LDAP_DEBUG_ACL, - "=> slap_access_allowed: no res from state (%s)\n", + "=> slap_access_allowed: result not in cache (%s)\n", attr, 0, 0 ); } } -vd_access: control = slap_acl_mask( a, &mask, op, e, desc, val, MAXREMATCHES, matches, count, state ); @@ -310,7 +304,7 @@ fe_access_allowed( be_orig = op->o_bd; if ( op->o_bd == NULL ) { - op->o_bd = select_backend( &op->o_req_ndn, 0, 0 ); + op->o_bd = select_backend( &op->o_req_ndn, 0 ); if ( op->o_bd == NULL ) op->o_bd = frontendDB; } @@ -340,7 +334,6 @@ access_allowed_mask( slap_mask_t mask; slap_access_t access_level; const char *attr; - int st_same_attr = 0; static AccessControlState state_init = ACL_STATE_INIT; assert( e != NULL ); @@ -358,12 +351,15 @@ access_allowed_mask( assert( attr != NULL ); if ( op ) { - if ( op->o_is_auth_check && + if ( op->o_acl_priv != ACL_NONE ) { + access = op->o_acl_priv; + + } else if ( op->o_is_auth_check && ( access_level == ACL_SEARCH || access_level == ACL_READ ) ) { access = ACL_AUTH; - } else if ( get_manageDIT( op ) && access_level == ACL_WRITE && + } else if ( get_relax( op ) && access_level == ACL_WRITE && desc == slap_schema.si_ad_entry ) { access = ACL_MANAGE; @@ -377,17 +373,10 @@ access_allowed_mask( { return state->as_result; - } else if ( ( state->as_recorded & ACL_STATE_RECORDED_VD ) && - val != NULL && state->as_vd_acl == NULL ) - { - return state->as_result; } - st_same_attr = 1; } else { *state = state_init; } - - state->as_vd_ad = desc; } Debug( LDAP_DEBUG_ACL, @@ -403,14 +392,12 @@ access_allowed_mask( op->o_bd = LDAP_STAILQ_FIRST( &backendDB ); be_null = 1; -#ifdef LDAP_DEVEL - /* - * FIXME: experimental; use first backend rules - * iff there is no global_acl (ITS#3100) */ + /* FIXME: experimental; use first backend rules + * iff there is no global_acl (ITS#3100) + */ if ( frontendDB->be_acl != NULL ) { op->o_bd = frontendDB; } -#endif /* LDAP_DEVEL */ } assert( op->o_bd != NULL ); @@ -455,6 +442,7 @@ done: state->as_result = ret; } state->as_recorded |= ACL_STATE_RECORDED; + state->as_vd_ad = desc; } if ( be_null ) op->o_bd = NULL; if ( maskp ) ACL_PRIV_ASSIGN( *maskp, mask ); @@ -509,7 +497,7 @@ slap_acl_get( dnlen = e->e_nname.bv_len; - for ( ; a != NULL; a = a->acl_next ) { + for ( ; a != NULL; prev = a, a = a->acl_next ) { (*count) ++; if ( a->acl_dn_pat.bv_len || ( a->acl_dn_style != ACL_STYLE_REGEX )) { @@ -580,11 +568,8 @@ slap_acl_get( if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) { state->as_recorded |= ACL_STATE_RECORDED_VD; - state->as_vd_acl = a; - state->as_vd_acl_count = *count; - state->as_vd_access = a->acl_access; - state->as_vd_access_count = 1; - ACL_INVALIDATE( state->as_vd_acl_mask ); + state->as_vd_acl = prev; + state->as_vd_acl_count = *count - 1; } if ( a->acl_attrval_style == ACL_STYLE_REGEX ) { @@ -667,6 +652,17 @@ slap_acl_get( return( NULL ); } +/* + * Record value-dependent access control state + */ +#define ACL_RECORD_VALUE_STATE do { \ + if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) { \ + state->as_recorded |= ACL_STATE_RECORDED_VD; \ + state->as_vd_acl = a; \ + state->as_vd_acl_count = count; \ + } \ + } while( 0 ) + static int acl_mask_dn( Operation *op, @@ -676,7 +672,7 @@ acl_mask_dn( AccessControl *a, int nmatch, regmatch_t *matches, - slap_dn_access *b, + slap_dn_access *bdn, struct berval *opndn ) { /* @@ -688,40 +684,20 @@ acl_mask_dn( * NOTE: styles "anonymous", "users" and "self" * have been moved to enum slap_style_t, whose * value is set in a_dn_style; however, the string - * is maintaned in a_dn_pat. + * is maintained in a_dn_pat. */ - if ( b->a_style == ACL_STYLE_ANONYMOUS ) { + + if ( bdn->a_style == ACL_STYLE_ANONYMOUS ) { if ( !BER_BVISEMPTY( opndn ) ) { return 1; } - } else if ( b->a_style == ACL_STYLE_USERS ) { + } else if ( bdn->a_style == ACL_STYLE_USERS ) { if ( BER_BVISEMPTY( opndn ) ) { return 1; } - if ( b->a_self ) { - const char *dummy; - int rc, match = 0; - - /* must have DN syntax */ - if ( desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) return 1; - - /* check if the target is an attribute. */ - if ( val == NULL ) return 1; - - /* target is attribute, check if the attribute value - * is the op dn. - */ - rc = value_match( &match, desc, - desc->ad_type->sat_equality, 0, - val, opndn, &dummy ); - /* on match error or no match, fail the ACL clause */ - if ( rc != LDAP_SUCCESS || match != 0 ) - return 1; - } - - } else if ( b->a_style == ACL_STYLE_SELF ) { + } else if ( bdn->a_style == ACL_STYLE_SELF ) { struct berval ndn, selfndn; int level; @@ -729,7 +705,7 @@ acl_mask_dn( return 1; } - level = b->a_self_level; + level = bdn->a_self_level; if ( level < 0 ) { selfndn = *opndn; ndn = e->e_nname; @@ -752,8 +728,8 @@ acl_mask_dn( return 1; } - } else if ( b->a_style == ACL_STYLE_REGEX ) { - if ( !ber_bvccmp( &b->a_pat, '*' ) ) { + } else if ( bdn->a_style == ACL_STYLE_REGEX ) { + if ( !ber_bvccmp( &bdn->a_pat, '*' ) ) { int tmp_nmatch; regmatch_t tmp_matches[2], *tmp_matchesp = tmp_matches; @@ -795,7 +771,7 @@ acl_mask_dn( return 1; } - if ( !regex_matches( &b->a_pat, opndn->bv_val, + if ( !regex_matches( &bdn->a_pat, opndn->bv_val, e->e_ndn, tmp_nmatch, tmp_matchesp ) ) { return 1; @@ -810,7 +786,7 @@ acl_mask_dn( if ( e->e_dn == NULL ) return 1; - if ( b->a_expand ) { + if ( bdn->a_expand ) { struct berval bv; char buf[ACL_BUF_SIZE]; @@ -858,7 +834,7 @@ acl_mask_dn( return 1; } - if ( acl_string_expand( &bv, &b->a_pat, + if ( acl_string_expand( &bv, &bdn->a_pat, e->e_nname.bv_val, tmp_nmatch, tmp_matchesp ) ) { @@ -874,7 +850,7 @@ acl_mask_dn( } } else { - pat = b->a_pat; + pat = bdn->a_pat; } patlen = pat.bv_len; @@ -884,13 +860,13 @@ acl_mask_dn( } - if ( b->a_style == ACL_STYLE_BASE ) { + if ( bdn->a_style == ACL_STYLE_BASE ) { /* base dn -- entire object DN must match */ if ( odnlen != patlen ) { goto dn_match_cleanup; } - } else if ( b->a_style == ACL_STYLE_ONE ) { + } else if ( bdn->a_style == ACL_STYLE_ONE ) { ber_len_t rdnlen = 0; if ( odnlen <= patlen ) { @@ -906,12 +882,12 @@ acl_mask_dn( goto dn_match_cleanup; } - } else if ( b->a_style == ACL_STYLE_SUBTREE ) { + } else if ( bdn->a_style == ACL_STYLE_SUBTREE ) { if ( odnlen > patlen && !DN_SEPARATOR( opndn->bv_val[odnlen - patlen - 1] ) ) { goto dn_match_cleanup; } - } else if ( b->a_style == ACL_STYLE_CHILDREN ) { + } else if ( bdn->a_style == ACL_STYLE_CHILDREN ) { if ( odnlen <= patlen ) { goto dn_match_cleanup; } @@ -920,8 +896,8 @@ acl_mask_dn( goto dn_match_cleanup; } - } else if ( b->a_style == ACL_STYLE_LEVEL ) { - int level = b->a_level; + } else if ( bdn->a_style == ACL_STYLE_LEVEL ) { + int level = bdn->a_level; struct berval ndn; if ( odnlen <= patlen ) { @@ -952,7 +928,7 @@ acl_mask_dn( got_match = !strcmp( pat.bv_val, &opndn->bv_val[ odnlen - patlen ] ); dn_match_cleanup:; - if ( pat.bv_val != b->a_pat.bv_val ) { + if ( pat.bv_val != bdn->a_pat.bv_val ) { slap_sl_free( pat.bv_val, op->o_tmpmemctx ); } @@ -964,21 +940,6 @@ dn_match_cleanup:; return 0; } -/* - * Record value-dependent access control state - */ -#define ACL_RECORD_VALUE_STATE do { \ - if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) { \ - state->as_recorded |= ACL_STATE_RECORDED_VD; \ - state->as_vd_acl = a; \ - AC_MEMCPY( state->as_vd_acl_matches, matches, \ - sizeof( state->as_vd_acl_matches )) ; \ - state->as_vd_acl_count = count; \ - state->as_vd_access = b; \ - state->as_vd_access_count = i; \ - } \ - } while( 0 ) - static int acl_mask_dnattr( Operation *op, @@ -1013,11 +974,10 @@ acl_mask_dnattr( at != NULL; at = attrs_find( at->a_next, bdn->a_at ) ) { - if ( value_find_ex( bdn->a_at, + if ( attr_valfind( at, SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, - at->a_nvals, - &bv, op->o_tmpmemctx ) == 0 ) + &bv, NULL, op->o_tmpmemctx ) == 0 ) { /* found it */ match = 1; @@ -1050,7 +1010,7 @@ acl_mask_dnattr( return 1; ACL_RECORD_VALUE_STATE; - + /* this is a self clause, check if the target is an * attribute. */ @@ -1122,16 +1082,8 @@ slap_acl_mask( accessmask2str( *mask, accessmaskbuf, 1 ) ); - if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD ) - && state->as_vd_acl == a ) - { - b = state->as_vd_access; - i = state->as_vd_access_count; - - } else { - b = a->acl_access; - i = 1; - } + b = a->acl_access; + i = 1; for ( ; b != NULL; b = b->a_next, i++ ) { slap_mask_t oldmask, modmask; @@ -1151,7 +1103,7 @@ slap_acl_mask( * NOTE: styles "anonymous", "users" and "self" * have been moved to enum slap_style_t, whose * value is set in a_dn_style; however, the string - * is maintaned in a_dn_pat. + * is maintained in a_dn_pat. */ if ( acl_mask_dn( op, e, desc, val, a, nmatch, matches, @@ -1175,7 +1127,7 @@ slap_acl_mask( * NOTE: styles "anonymous", "users" and "self" * have been moved to enum slap_style_t, whose * value is set in a_dn_style; however, the string - * is maintaned in a_dn_pat. + * is maintained in a_dn_pat. */ if ( op->o_conn && !BER_BVISNULL( &op->o_conn->c_ndn ) ) @@ -1328,7 +1280,7 @@ slap_acl_mask( /* extract IP and try exact match */ } else if ( b->a_peername_style == ACL_STYLE_IP ) { char *port; - char buf[] = "255.255.255.255"; + char buf[STRLENOF("255.255.255.255") + 1]; struct berval ip; unsigned long addr; int port_number = -1; @@ -1369,6 +1321,50 @@ slap_acl_mask( if ( (addr & b->a_peername_mask) != b->a_peername_addr ) continue; +#ifdef LDAP_PF_INET6 + /* extract IPv6 and try exact match */ + } else if ( b->a_peername_style == ACL_STYLE_IPV6 ) { + char *port; + char buf[STRLENOF("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF") + 1]; + struct berval ip; + struct in6_addr addr; + int port_number = -1; + + if ( strncasecmp( op->o_conn->c_peer_name.bv_val, + acl_bv_ipv6_eq.bv_val, + acl_bv_ipv6_eq.bv_len ) != 0 ) + continue; + + ip.bv_val = op->o_conn->c_peer_name.bv_val + acl_bv_ipv6_eq.bv_len; + ip.bv_len = op->o_conn->c_peer_name.bv_len - acl_bv_ipv6_eq.bv_len; + + port = strrchr( ip.bv_val, ']' ); + if ( port ) { + ip.bv_len = port - ip.bv_val; + ++port; + if ( port[0] == ':' && lutil_atoi( &port_number, ++port ) != 0 ) + continue; + } + + /* the port check can be anticipated here */ + if ( b->a_peername_port != -1 && port_number != b->a_peername_port ) + continue; + + /* address longer than expected? */ + if ( ip.bv_len >= sizeof(buf) ) + continue; + + AC_MEMCPY( buf, ip.bv_val, ip.bv_len ); + buf[ ip.bv_len ] = '\0'; + + if ( inet_pton( AF_INET6, buf, &addr ) != 1 ) + continue; + + /* check mask */ + if ( !slap_addr6_mask( &addr, &b->a_peername_mask6, &b->a_peername_addr6 ) ) + continue; +#endif /* LDAP_PF_INET6 */ + #ifdef LDAP_PF_LOCAL /* extract path and try exact match */ } else if ( b->a_peername_style == ACL_STYLE_PATH ) { @@ -1661,6 +1657,36 @@ slap_acl_mask( } } + /* check for the "self" modifier in the field */ + if ( b->a_dn.a_self ) { + const char *dummy; + int rc, match = 0; + + ACL_RECORD_VALUE_STATE; + + /* must have DN syntax */ + if ( desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName && + !is_at_syntax( desc->ad_type, SLAPD_NAMEUID_SYNTAX )) continue; + + /* check if the target is an attribute. */ + if ( val == NULL ) continue; + + /* a DN must be present */ + if ( BER_BVISEMPTY( &op->o_ndn ) ) { + continue; + } + + /* target is attribute, check if the attribute value + * is the op dn. + */ + rc = value_match( &match, desc, + desc->ad_type->sat_equality, 0, + val, &op->o_ndn, &dummy ); + /* on match error or no match, fail the ACL clause */ + if ( rc != LDAP_SUCCESS || match != 0 ) + continue; + } + #ifdef SLAP_DYNACL if ( b->a_dynacl ) { slap_dynacl_t *da; @@ -1681,20 +1707,21 @@ slap_acl_mask( } /* start out with nothing granted, nothing denied */ - ACL_INIT(tgrant); - ACL_INIT(tdeny); + ACL_INVALIDATE(tgrant); + ACL_INVALIDATE(tdeny); for ( da = b->a_dynacl; da; da = da->da_next ) { slap_access_t grant, deny; - ACL_INIT(grant); - ACL_INIT(deny); + ACL_INVALIDATE(grant); + ACL_INVALIDATE(deny); Debug( LDAP_DEBUG_ACL, " <= check a_dynacl: %s\n", da->da_name, 0, 0 ); - (void)( *da->da_mask )( da->da_private, op, e, desc, val, nmatch, matches, &grant, &deny ); + (void)da->da_mask( da->da_private, op, e, desc, + val, nmatch, matches, &grant, &deny ); tgrant |= grant; tdeny |= deny; @@ -2004,6 +2031,10 @@ acl_set_cb_gather( Operation *op, SlapReply *rs ) for ( j = 0; !BER_BVISNULL( &rs->sr_attrs[ j ].an_name ); j++ ) { AttributeDescription *desc = rs->sr_attrs[ j ].an_desc; + + if ( desc == NULL ) { + continue; + } if ( desc == slap_schema.si_ad_entryDN ) { bvalsp = bvals; @@ -2015,17 +2046,12 @@ acl_set_cb_gather( Operation *op, SlapReply *rs ) a = attr_find( rs->sr_entry->e_attrs, desc ); if ( a != NULL ) { - int i; - - for ( i = 0; !BER_BVISNULL( &a->a_nvals[ i ] ); i++ ) - ; - bvalsp = a->a_nvals; } } } - if ( bvals ) { + if ( bvalsp ) { p->bvals = slap_set_join( p->cookie, p->bvals, ( '|' | SLAP_SET_RREF ), bvalsp ); } @@ -2049,8 +2075,6 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de int nattrs = 0; slap_callback cb = { NULL, acl_set_cb_gather, NULL, NULL }; acl_set_gather_t p = { 0 }; - const char *text = NULL; - static struct berval defaultFilter_bv = BER_BVC( "(objectClass=*)" ); /* this routine needs to return the bervals instead of * plain strings, since syntax is not known. It should @@ -2062,6 +2086,10 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de rc = ldap_url_parse( name->bv_val, &ludp ); if ( rc != LDAP_URL_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, + "%s acl_set_gather: unable to parse URL=\"%s\"\n", + cp->asc_op->o_log_prefix, name->bv_val, 0 ); + rc = LDAP_PROTOCOL_ERROR; goto url_done; } @@ -2070,6 +2098,10 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de { /* host part must be empty */ /* extensions parts must be empty */ + Debug( LDAP_DEBUG_TRACE, + "%s acl_set_gather: host/exts must be absent in URL=\"%s\"\n", + cp->asc_op->o_log_prefix, name->bv_val, 0 ); + rc = LDAP_PROTOCOL_ERROR; goto url_done; } @@ -2080,11 +2112,19 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de &op2.o_req_ndn, cp->asc_op->o_tmpmemctx ); BER_BVZERO( &op2.o_req_dn ); if ( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, + "%s acl_set_gather: DN=\"%s\" normalize failed\n", + cp->asc_op->o_log_prefix, op2.o_req_dn.bv_val, 0 ); + goto url_done; } - op2.o_bd = select_backend( &op2.o_req_ndn, 0, 1 ); + op2.o_bd = select_backend( &op2.o_req_ndn, 1 ); if ( ( op2.o_bd == NULL ) || ( op2.o_bd->be_search == NULL ) ) { + Debug( LDAP_DEBUG_TRACE, + "%s acl_set_gather: no database could be selected for DN=\"%s\"\n", + cp->asc_op->o_log_prefix, op2.o_req_ndn.bv_val, 0 ); + rc = LDAP_NO_SUCH_OBJECT; goto url_done; } @@ -2093,35 +2133,46 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de if ( ludp->lud_filter ) { ber_str2bv_x( ludp->lud_filter, 0, 0, &op2.ors_filterstr, cp->asc_op->o_tmpmemctx ); + op2.ors_filter = str2filter_x( cp->asc_op, op2.ors_filterstr.bv_val ); + if ( op2.ors_filter == NULL ) { + Debug( LDAP_DEBUG_TRACE, + "%s acl_set_gather: unable to parse filter=\"%s\"\n", + cp->asc_op->o_log_prefix, op2.ors_filterstr.bv_val, 0 ); + + rc = LDAP_PROTOCOL_ERROR; + goto url_done; + } } else { - op2.ors_filterstr = defaultFilter_bv; + op2.ors_filterstr = *slap_filterstr_objectClass_pres; + op2.ors_filter = (Filter *)slap_filter_objectClass_pres; } - op2.ors_filter = str2filter_x( cp->asc_op, op2.ors_filterstr.bv_val ); - if ( op2.ors_filter == NULL ) { - rc = LDAP_PROTOCOL_ERROR; - goto url_done; - } /* Grab the scope */ op2.ors_scope = ludp->lud_scope; /* Grap the attributes */ if ( ludp->lud_attrs ) { + int i; + for ( ; ludp->lud_attrs[ nattrs ]; nattrs++ ) ; - anlistp = slap_sl_malloc( sizeof( AttributeName ) * ( nattrs + 2 ), + anlistp = slap_sl_calloc( sizeof( AttributeName ), nattrs + 2, cp->asc_op->o_tmpmemctx ); - for ( ; ludp->lud_attrs[ nattrs ]; nattrs++ ) { - ber_str2bv( ludp->lud_attrs[ nattrs ], 0, 0, &anlistp[ nattrs ].an_name ); - anlistp[ nattrs ].an_desc = NULL; - rc = slap_bv2ad( &anlistp[ nattrs ].an_name, - &anlistp[ nattrs ].an_desc, &text ); - if ( rc != LDAP_SUCCESS ) { - goto url_done; + for ( i = 0, nattrs = 0; ludp->lud_attrs[ i ]; i++ ) { + struct berval name; + AttributeDescription *desc = NULL; + const char *text = NULL; + + ber_str2bv( ludp->lud_attrs[ i ], 0, 0, &name ); + rc = slap_bv2ad( &name, &desc, &text ); + if ( rc == LDAP_SUCCESS ) { + anlistp[ nattrs ].an_name = name; + anlistp[ nattrs ].an_desc = desc; + nattrs++; } } @@ -2158,7 +2209,7 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de } url_done:; - if ( op2.ors_filter ) { + if ( op2.ors_filter && op2.ors_filter != slap_filter_objectClass_pres ) { filter_free_x( cp->asc_op, op2.ors_filter ); } if ( !BER_BVISNULL( &op2.o_req_ndn ) ) { @@ -2228,7 +2279,7 @@ acl_match_set ( } else { struct berval subjdn, ndn = BER_BVNULL; struct berval setat; - BerVarray bvals; + BerVarray bvals = NULL; const char *text; AttributeDescription *desc = NULL;