X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Facl.c;h=48f93c81966e13ef2a29442da677e0b231b100d3;hb=3bf9998d7885ef6bbc4690d4229e5cb5068a35de;hp=3a3568f0112706893406408dcec88a48b46ab9a4;hpb=2c3a06321a02dd231ced6e18dfcdf77f1d5690a2;p=openldap
diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c
index 3a3568f011..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;
@@ -1694,7 +1720,8 @@ slap_acl_mask(
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 ) ) {