ITS#2497, implement value-level ACLs:

access to attr=foo val.regex=bar.*
This commit is contained in:
Howard Chu 2003-09-20 03:23:10 +00:00
parent 8f3d3cf3c9
commit 1240c70ff4
3 changed files with 90 additions and 5 deletions

View File

@ -50,6 +50,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(
@ -286,7 +287,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 +380,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 +403,7 @@ acl_get(
Operation *op,
Entry *e,
AttributeDescription *desc,
struct berval *val,
int nmatch,
regmatch_t *matches )
{
@ -515,7 +518,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 +615,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 )
{

View File

@ -233,6 +233,36 @@ parse_acl(
acl_usage();
}
} else if ( strncasecmp( left, "val", 3 ) == 0 ) {
if ( a->acl_attrval.bv_len ) {
fprintf( stderr,
"%s: line %d: attr val already specified in to clause.\n",
fname, lineno );
acl_usage();
}
if ( a->acl_attrs == NULL || a->acl_attrs[1].an_name.bv_val ) {
fprintf( stderr,
"%s: line %d: attr val requires a single attribute.\n",
fname, lineno );
acl_usage();
}
ber_str2bv( right, 0, 1, &a->acl_attrval );
if ( style && strcasecmp( style, "regex" ) == 0 ) {
int e = regcomp( &a->acl_attrval_re, a->acl_attrval.bv_val,
REG_EXTENDED | REG_ICASE | REG_NOSUB );
if ( e ) {
char buf[512];
regerror( e, &a->acl_attrval_re, buf, sizeof(buf) );
fprintf( stderr, "%s: line %d: "
"regular expression \"%s\" bad because of %s\n",
fname, lineno, right, buf );
acl_usage();
}
a->acl_attrval_style = ACL_STYLE_REGEX;
} else {
a->acl_attrval_style = ACL_STYLE_BASE;
}
} else {
fprintf( stderr,
"%s: line %d: expecting <what> got \"%s\"\n",
@ -1298,7 +1328,7 @@ acl_usage( void )
"<access clause> ::= access to <what> "
"[ by <who> <access> [ <control> ] ]+ \n"
"<what> ::= * | [dn[.<dnstyle>]=<DN>] [filter=<filter>] [attrs=<attrlist>]\n"
"<attrlist> ::= <attr> | <attr> , <attrlist>\n"
"<attrlist> ::= <attr> [val[.<style>]=<value>] | <attr> , <attrlist>\n"
"<attr> ::= <attrname> | entry | children\n"
"<who> ::= [ * | anonymous | users | self | dn[.<dnstyle>]=<DN> ]\n"
"\t[dnattr=<attrname>]\n"
@ -1654,6 +1684,13 @@ print_acl( Backend *be, AccessControl *a )
fprintf( stderr, "\n" );
}
if ( a->acl_attrval.bv_len != 0 ) {
to++;
fprintf( stderr, " val.%s=%s\n",
style_strings[a->acl_attrval_style], a->acl_attrval.bv_val );
}
if( !to ) {
fprintf( stderr, " *\n" );
}

View File

@ -1173,6 +1173,9 @@ typedef struct slap_acl {
regex_t acl_dn_re;
struct berval acl_dn_pat;
AttributeName *acl_attrs;
slap_style_t acl_attrval_style;
regex_t acl_attrval_re;
struct berval acl_attrval;
/* "by" part: list of who has what access to the entries */
Access *acl_access;