ITS#3008 fix value-based ACLs

This commit is contained in:
Howard Chu 2004-03-10 02:59:03 +00:00
parent 75725a7ad8
commit cac30b1855
2 changed files with 131 additions and 140 deletions

View File

@ -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 )

View File

@ -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",