X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Facl.c;h=50511134b12f55537979035c1bc034cc1eae0c75;hb=17f95a3fd30247a0735a3526d85b46178304748d;hp=1295b9950791cbbf6dcfc2bb2f42461601767be9;hpb=f8c0481dd47a78d24a57e9872e8b775a7152b4d2;p=openldap diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 1295b99507..50511134b1 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -1,7 +1,7 @@ /* acl.c - routines to parse and check acl's */ /* $OpenLDAP$ */ /* - * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -121,7 +121,7 @@ access_allowed( { int ret = 1; int count; - AccessControl *a; + AccessControl *a = NULL; #ifdef LDAP_DEBUG char accessmaskbuf[ACCESSMASK_MAXLEN]; @@ -130,6 +130,9 @@ access_allowed( slap_control_t control; const char *attr; regmatch_t matches[MAXREMATCHES]; + int st_same_attr = 0; + int st_initialized = 0; + static AccessControlState state_init = ACL_STATE_INIT; assert( e != NULL ); assert( desc != NULL ); @@ -139,7 +142,7 @@ access_allowed( assert( attr != NULL ); - if( state && state->as_recorded ) { + if( state && state->as_recorded && state->as_vd_ad==desc) { if( state->as_recorded & ACL_STATE_RECORDED_NV && val == NULL ) { @@ -150,6 +153,9 @@ access_allowed( { return state->as_result; } + st_same_attr = 1; + } if (state) { + state->as_vd_ad=desc; } #ifdef NEW_LOGGING @@ -246,7 +252,7 @@ access_allowed( ret = 0; control = ACL_BREAK; - if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD )) { + if( st_same_attr ) { assert( state->as_vd_acl != NULL ); a = state->as_vd_acl; @@ -290,6 +296,18 @@ access_allowed( #endif } + if (state) { + if (state->as_vi_acl == a && (state->as_recorded & ACL_STATE_RECORDED_NV)) { + Debug( LDAP_DEBUG_ACL, "access_allowed: result from state (%s)\n", attr, 0, 0 ); + return state->as_result; + } else if (!st_initialized) { + Debug( LDAP_DEBUG_ACL, "access_allowed: no res from state (%s)\n", attr, 0, 0); + *state = state_init; + state->as_vd_ad=desc; + st_initialized=1; + } + } + vd_access: control = acl_mask( a, &mask, be, conn, op, e, desc, val, matches, count, state ); @@ -342,6 +360,9 @@ vd_access: done: if( state != NULL ) { + /* If not value-dependent, save ACL in case of more attrs */ + if ( !(state->as_recorded & ACL_STATE_RECORDED_VD) ) + state->as_vi_acl = a; state->as_recorded |= ACL_STATE_RECORDED; state->as_result = ret; } @@ -605,17 +626,17 @@ acl_mask( * user is bound as somebody in the same namespace as * the entry, OR the given dn matches the dn pattern */ - if ( ber_bvcmp( &b->a_dn_pat, &aci_bv_anonymous ) == 0 ) { + if ( bvmatch( &b->a_dn_pat, &aci_bv_anonymous ) ) { if ( op->o_ndn.bv_len != 0 ) { continue; } - } else if ( ber_bvcmp( &b->a_dn_pat, &aci_bv_users ) == 0 ) { + } else if ( bvmatch( &b->a_dn_pat, &aci_bv_users ) ) { if ( op->o_ndn.bv_len == 0 ) { continue; } - } else if ( ber_bvcmp( &b->a_dn_pat, &aci_bv_self ) == 0 ) { + } else if ( bvmatch( &b->a_dn_pat, &aci_bv_self ) ) { if ( op->o_ndn.bv_len == 0 ) { continue; } @@ -764,7 +785,7 @@ dn_match_cleanup:; if ( b->a_domain_expand ) { struct berval bv; - bv.bv_len = sizeof(buf); + bv.bv_len = sizeof(buf) - 1; bv.bv_val = buf; string_expand(&bv, &b->a_domain_pat, e->e_ndn, matches); @@ -867,7 +888,8 @@ dn_match_cleanup:; at != NULL; at = attrs_find( at->a_next, b->a_dn_at ) ) { - if( value_find( b->a_dn_at, at->a_vals, &bv ) == 0 ) { + if( value_find_ex( b->a_dn_at, + SLAP_MR_VALUE_NORMALIZED_MATCH, at->a_vals, &bv ) == 0 ) { /* found it */ match = 1; break; @@ -919,7 +941,6 @@ dn_match_cleanup:; } if ( b->a_group_pat.bv_len ) { - char buf[ACL_BUF_SIZE]; struct berval bv; struct berval ndn = { 0, NULL }; int rc; @@ -928,29 +949,33 @@ dn_match_cleanup:; continue; } - bv.bv_len = sizeof(buf) - 1; - bv.bv_val = buf; - /* b->a_group is an unexpanded entry name, expanded it should be an * entry with objectclass group* and we test to see if odn is one of * the values in the attribute group */ /* see if asker is listed in dnattr */ if ( b->a_group_style == ACL_STYLE_REGEX ) { - string_expand(&bv, &b->a_group_pat, e->e_ndn, matches); - if ( dnNormalize2(NULL, &bv, &ndn) != LDAP_SUCCESS ) { + char buf[ACL_BUF_SIZE]; + bv.bv_len = sizeof(buf) - 1; + bv.bv_val = buf; + + string_expand( &bv, &b->a_group_pat, e->e_ndn, matches ); + if ( dnNormalize2( NULL, &bv, &ndn ) != LDAP_SUCCESS ) { /* did not expand to a valid dn */ continue; } + bv = ndn; + } else { bv = b->a_group_pat; } - rc = backend_group(be, conn, op, e, &bv, &op->o_ndn, - b->a_group_oc, b->a_group_at); - if ( ndn.bv_val ) - free( ndn.bv_val ); + rc = backend_group( be, conn, op, e, &bv, &op->o_ndn, + b->a_group_oc, b->a_group_at ); + + if ( ndn.bv_val ) free( ndn.bv_val ); + if ( rc != 0 ) { continue; } @@ -1197,6 +1222,7 @@ acl_check_modlist( ) { struct berval *bv; + AccessControlState state = ACL_STATE_INIT; assert( be != NULL ); @@ -1251,9 +1277,6 @@ acl_check_modlist( } for ( ; mlist != NULL; mlist = mlist->sml_next ) { - static AccessControlState state_init = ACL_STATE_INIT; - AccessControlState state; - /* * no-user-modification operational attributes are ignored * by ACL_WRITE checking as any found here are not provided @@ -1272,8 +1295,6 @@ acl_check_modlist( continue; } - state = state_init; - switch ( mlist->sml_op ) { case LDAP_MOD_REPLACE: /* @@ -1389,7 +1410,7 @@ aci_set_gather (void *cookie, struct berval *name, struct berval *attr) const char *text; AttributeDescription *desc = NULL; if (slap_bv2ad(attr, &desc, &text) == LDAP_SUCCESS) { - backend_attribute(cp->be, NULL, NULL, + backend_attribute(cp->be, NULL, cp->op, cp->e, &ndn, desc, &bvals); } free(ndn.bv_val); @@ -1438,7 +1459,7 @@ aci_match_set ( if ( dnNormalize2(NULL, &subjdn, &ndn) == LDAP_SUCCESS && slap_bv2ad(&setat, &desc, &text) == LDAP_SUCCESS ) { - backend_attribute(be, NULL, NULL, e, + backend_attribute(be, NULL, op, e, &ndn, desc, &bvals); if ( bvals != NULL ) { if ( bvals[0].bv_val != NULL ) { @@ -1670,11 +1691,12 @@ aci_group_member ( if (grp_oc != NULL && grp_ad != NULL ) { char buf[ACL_BUF_SIZE]; struct berval bv, ndn; - bv.bv_len = sizeof( buf ); + bv.bv_len = sizeof( buf ) - 1; bv.bv_val = (char *)&buf; string_expand(&bv, &subjdn, e->e_ndn, matches); if ( dnNormalize2(NULL, &bv, &ndn) == LDAP_SUCCESS ) { - rc = (backend_group(be, conn, op, e, &ndn, &op->o_ndn, grp_oc, grp_ad) == 0); + rc = (backend_group(be, conn, op, e, &ndn, &op->o_ndn, + grp_oc, grp_ad) == 0); free( ndn.bv_val ); } } @@ -1746,10 +1768,10 @@ aci_mask( if (ber_bvstrcasecmp( &aci_bv_access_id, &bv ) == 0) { struct berval ndn; - rc = 1; + rc = 0; if ( dnNormalize2(NULL, &sdn, &ndn) == LDAP_SUCCESS ) { - if (!dn_match( &op->o_ndn, &ndn)) - rc = 0; + if (dn_match( &op->o_ndn, &ndn)) + rc = 1; free(ndn.bv_val); } return (rc); @@ -1780,7 +1802,7 @@ aci_mask( at != NULL; at = attrs_find( at->a_next, ad ) ) { - if (value_find( ad, at->a_vals, &bv) == 0 ) { + if (value_find_ex( ad, SLAP_MR_VALUE_NORMALIZED_MATCH, at->a_vals, &bv) == 0 ) { rc = 1; break; } @@ -1917,7 +1939,7 @@ regex_matches( struct berval bv; int rc; - bv.bv_len = sizeof(newbuf); + bv.bv_len = sizeof(newbuf) - 1; bv.bv_val = newbuf; if(str == NULL) str = "";