X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Facl.c;h=c648d4ef6fb6dcabf90ac232bfe29f5b718c7231;hb=bd1543ce44c8478d8785cabbe449516167d72141;hp=5b1f0434b84f1e19589728a7ec6502811c334519;hpb=94e88c3700b677b07da52f7b9555c487b387267d;p=openldap diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 5b1f0434b8..c648d4ef6f 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -1,8 +1,27 @@ /* acl.c - routines to parse and check acl's */ /* $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 + * . + */ +/* Portions Copyright (c) 1995 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. */ #include "portable.h" @@ -50,6 +69,7 @@ static AccessControl * acl_get( AccessControl *ac, int *count, Operation *op, Entry *e, AttributeDescription *desc, + struct berval *val, int nmatches, regmatch_t *matches ); static slap_control_t acl_mask( @@ -177,8 +197,8 @@ access_allowed( } #ifdef LDAP_SLAPI - ret = slapi_x_access_allowed( op, e, desc, val, access, state ); - if ( ret == 0 ) { + if ( op->o_pb && + !slapi_x_access_allowed( op, e, desc, val, access, state )) { /* ACL plugin denied access */ goto done; } @@ -286,7 +306,7 @@ access_allowed( memset(matches, '\0', sizeof(matches)); } - while((a = acl_get( a, &count, op, e, desc, + while((a = acl_get( a, &count, op, e, desc, val, MAXREMATCHES, matches )) != NULL) { int i; @@ -379,10 +399,11 @@ 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) ) + if ( !(state->as_recorded & ACL_STATE_RECORDED_VD) ) { state->as_vi_acl = a; + state->as_result = ret; + } state->as_recorded |= ACL_STATE_RECORDED; - state->as_result = ret; } if (be_null) op->o_bd = NULL; return ret; @@ -401,6 +422,7 @@ acl_get( Operation *op, Entry *e, AttributeDescription *desc, + struct berval *val, int nmatch, regmatch_t *matches ) { @@ -515,7 +537,7 @@ acl_get( Debug( LDAP_DEBUG_ACL, "=> acl_get: [%d] check attr %s\n", *count, attr, 0); #endif - if ( attr == NULL || a->acl_attrs == NULL || + if ( a->acl_attrs == NULL || ad_inlist( desc, a->acl_attrs ) ) { #ifdef NEW_LOGGING @@ -612,6 +634,48 @@ acl_mask( accessmask2str( *mask, accessmaskbuf ) ); #endif + /* Is this ACL only for a specific value? */ + if ( a->acl_attrval.bv_len ) { + if ( state && !state->as_vd_acl ) { + state->as_vd_acl = a; + state->as_vd_access = a->acl_access; + state->as_vd_access_count = 1; + } + if ( val == NULL ) { + return ACL_BREAK; + } + if ( a->acl_attrval_style == ACL_STYLE_REGEX ) { +#ifdef NEW_LOGGING + LDAP_LOG( ACL, DETAIL1, + "acl_get: valpat %s\n", + a->acl_attrval.bv_val, 0, 0 ); +#else + Debug( LDAP_DEBUG_ACL, + "acl_get: valpat %s\n", + a->acl_attrval.bv_val, 0, 0 ); +#endif + if (regexec(&a->acl_attrval_re, val->bv_val, 0, NULL, 0)) + return ACL_BREAK; + } else { + int match = 0; + const char *text; +#ifdef NEW_LOGGING + LDAP_LOG( ACL, DETAIL1, + "acl_get: val %s\n", + a->acl_attrval.bv_val, 0, 0 ); +#else + Debug( LDAP_DEBUG_ACL, + "acl_get: val %s\n", + a->acl_attrval.bv_val, 0, 0 ); +#endif + if (value_match( &match, desc, + desc->ad_type->sat_equality, 0, + val, &a->acl_attrval, &text ) != LDAP_SUCCESS || + match ) + return ACL_BREAK; + } + } + if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD ) && state->as_vd_acl == a ) {