mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-01 14:15:49 +08:00
ITS#3008 fix value-based ACLs
This commit is contained in:
parent
75725a7ad8
commit
cac30b1855
@ -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 )
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user