From cac30b1855c8217abd16670e389d9dd3d8cec9e2 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 10 Mar 2004 02:59:03 +0000 Subject: [PATCH] ITS#3008 fix value-based ACLs --- servers/slapd/acl.c | 202 ++++++++++++++++++----------------------- servers/slapd/result.c | 69 +++++++++----- 2 files changed, 131 insertions(+), 140 deletions(-) diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index dccaeded05..c4f4d2bdcc 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -535,6 +535,89 @@ acl_get( #endif } + if ( a->acl_attrs && !ad_inlist( desc, a->acl_attrs ) ) { + matches[0].rm_so = matches[0].rm_eo = -1; + continue; + } + + /* Is this ACL only for a specific value? */ + if ( a->acl_attrval.bv_len ) { + if ( val == NULL ) { + continue; + } + 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)) + continue; + } 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 ( a->acl_attrs[0].an_desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) { + if (value_match( &match, desc, + desc->ad_type->sat_equality, 0, + val, &a->acl_attrval, &text ) != LDAP_SUCCESS || + match ) + continue; + + } else { + int patlen, vdnlen; + + patlen = a->acl_attrval.bv_len; + vdnlen = val->bv_len; + + if ( vdnlen < patlen ) + continue; + + if ( a->acl_dn_style == ACL_STYLE_BASE ) { + if ( vdnlen > patlen ) + continue; + + } else if ( a->acl_dn_style == ACL_STYLE_ONE ) { + int rdnlen = -1; + + if ( !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) ) + continue; + + rdnlen = dn_rdnlen( NULL, val ); + if ( rdnlen != vdnlen - patlen - 1 ) + continue; + + } else if ( a->acl_dn_style == ACL_STYLE_SUBTREE ) { + if ( vdnlen > patlen && !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) ) + continue; + + } else if ( a->acl_dn_style == ACL_STYLE_CHILDREN ) { + if ( vdnlen <= patlen ) + continue; + + if ( !DN_SEPARATOR( val->bv_val[vdnlen - patlen - 1] ) ) + continue; + } + + if ( strcmp( a->acl_attrval.bv_val, val->bv_val + vdnlen - patlen )) + continue; + } + } + } + if ( a->acl_filter != NULL ) { ber_int_t rc = test_filter( NULL, e, a->acl_filter ); if ( rc != LDAP_COMPARE_TRUE ) { @@ -544,25 +627,12 @@ acl_get( #ifdef NEW_LOGGING LDAP_LOG( ACL, DETAIL1, - "acl_get: [%d] check attr %s\n", *count, attr ,0 ); + "acl_get: [%d] attr %s\n", *count, attr ,0 ); #else - Debug( LDAP_DEBUG_ACL, "=> acl_get: [%d] check attr %s\n", + Debug( LDAP_DEBUG_ACL, "=> acl_get: [%d] attr %s\n", *count, attr, 0); #endif - if ( a->acl_attrs == NULL || - ad_inlist( desc, a->acl_attrs ) ) - { -#ifdef NEW_LOGGING - LDAP_LOG( ACL, DETAIL1, - "acl_get: [%d] acl %s attr: %s\n", *count, e->e_dn, attr ); -#else - Debug( LDAP_DEBUG_ACL, - "<= acl_get: [%d] acl %s attr: %s\n", - *count, e->e_dn, attr ); -#endif - return a; - } - matches[0].rm_so = matches[0].rm_eo = -1; + return a; } #ifdef NEW_LOGGING @@ -646,106 +716,6 @@ 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 ( a->acl_attrs[0].an_desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) { - if (value_match( &match, desc, - desc->ad_type->sat_equality, 0, - val, &a->acl_attrval, &text ) != LDAP_SUCCESS || - match ) - return ACL_BREAK; - - } else { - int patlen, vdnlen, rc, got_match = 0; - struct berval vdn = { 0, NULL }; - - /* it is a DN */ - assert( a->acl_attrs[0].an_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ); - - rc = dnNormalize( 0, NULL, NULL, val, &vdn, - op->o_tmpmemctx ); - if ( rc != LDAP_SUCCESS ) { - /* error */ - return ACL_BREAK; - } - - patlen = a->acl_attrval.bv_len; - vdnlen = vdn.bv_len; - - if ( vdnlen < patlen ) - goto attrval_cleanup; - - if ( a->acl_dn_style == ACL_STYLE_BASE ) { - if ( vdnlen > patlen ) - goto attrval_cleanup; - - } else if ( a->acl_dn_style == ACL_STYLE_ONE ) { - int rdnlen = -1; - - if ( !DN_SEPARATOR( vdn.bv_val[vdnlen - patlen - 1] ) ) - goto attrval_cleanup; - - rdnlen = dn_rdnlen( NULL, &vdn ); - if ( rdnlen != vdnlen - patlen - 1 ) - goto attrval_cleanup; - - } else if ( a->acl_dn_style == ACL_STYLE_SUBTREE ) { - if ( vdnlen > patlen && !DN_SEPARATOR( vdn.bv_val[vdnlen - patlen - 1] ) ) - goto attrval_cleanup; - - } else if ( a->acl_dn_style == ACL_STYLE_CHILDREN ) { - if ( vdnlen <= patlen ) - goto attrval_cleanup; - - if ( !DN_SEPARATOR( vdn.bv_val[vdnlen - patlen - 1] ) ) - goto attrval_cleanup; - } - - got_match = strcmp( a->acl_attrval.bv_val, vdn.bv_val + vdnlen - patlen ); - -attrval_cleanup:; - if ( vdn.bv_val ) - free( vdn.bv_val ); - - if ( !got_match ) - return ACL_BREAK; - - } - } - } if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD ) && state->as_vd_acl == a ) diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 6340845013..2f97e13ab4 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -888,6 +888,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) for ( a = rs->sr_entry->e_attrs, j = 0; a != NULL; a = a->a_next, j++ ) { AttributeDescription *desc = a->a_desc; + int finish = 0; if ( rs->sr_attrs == NULL ) { /* all attrs request, skip operational attributes */ @@ -909,39 +910,42 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) } } - if ( ! access_allowed( op, rs->sr_entry, desc, NULL, - ACL_READ, &acl_state ) ) - { + if ( op->ors_attrsonly ) { + if ( ! access_allowed( op, rs->sr_entry, desc, NULL, + ACL_READ, &acl_state ) ) + { #ifdef NEW_LOGGING - LDAP_LOG( ACL, INFO, - "send_search_entry: conn %lu access to attribute %s not " - "allowed\n", op->o_connid, desc->ad_cname.bv_val, 0 ); + LDAP_LOG( ACL, INFO, + "send_search_entry: conn %lu access to attribute %s not " + "allowed\n", op->o_connid, desc->ad_cname.bv_val, 0 ); #else - Debug( LDAP_DEBUG_ACL, "acl: " - "access to attribute %s not allowed\n", - desc->ad_cname.bv_val, 0, 0 ); + Debug( LDAP_DEBUG_ACL, "acl: " + "access to attribute %s not allowed\n", + desc->ad_cname.bv_val, 0, 0 ); #endif - continue; - } + continue; + } - if (( rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname )) == -1 ) { + if (( rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname )) == -1 ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "send_search_entry: conn %lu ber_printf failed\n", - op->o_connid, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "send_search_entry: conn %lu ber_printf failed\n", + op->o_connid, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); + Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); #endif - if ( op->o_res_ber == NULL ) ber_free_buf( ber ); - send_ldap_error( op, rs, LDAP_OTHER, "encoding description error"); - goto error_return; - } + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); + send_ldap_error( op, rs, LDAP_OTHER, "encoding description error"); + goto error_return; + } + finish = 1; - if ( ! op->ors_attrsonly ) { - for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) { + } else { + int first = 1; + for ( i = 0; a->a_nvals[i].bv_val != NULL; i++ ) { if ( ! access_allowed( op, rs->sr_entry, - desc, &a->a_vals[i], ACL_READ, &acl_state ) ) + desc, &a->a_nvals[i], ACL_READ, &acl_state ) ) { #ifdef NEW_LOGGING LDAP_LOG( ACL, INFO, @@ -962,6 +966,23 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) continue; } + if ( first ) { + first = 0; + finish = 1; + if (( rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname )) == -1 ) { +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, ERR, + "send_search_entry: conn %lu ber_printf failed\n", + op->o_connid, 0, 0 ); +#else + Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); +#endif + + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); + send_ldap_error( op, rs, LDAP_OTHER, "encoding description error"); + goto error_return; + } + } if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, @@ -980,7 +1001,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) } } - if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) { + if ( finish && ( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "send_search_entry: conn %lu ber_printf failed\n", -- 2.39.5