AccessControl *ac, int *count,
Operation *op, Entry *e,
AttributeDescription *desc,
+ struct berval *val,
int nmatches, regmatch_t *matches );
static slap_control_t acl_mask(
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;
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;
Operation *op,
Entry *e,
AttributeDescription *desc,
+ struct berval *val,
int nmatch,
regmatch_t *matches )
{
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
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 )
{
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",
"<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"
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" );
}