Operation *op, Entry *e,
AttributeDescription *desc,
struct berval *val,
- int nmatch, regmatch_t *matches,
+ AclRegexMatches *matches,
AccessControlState *state );
static slap_control_t slap_acl_mask(
Operation *op, Entry *e,
AttributeDescription *desc,
struct berval *val,
- int nmatch,
- regmatch_t *matches,
+ AclRegexMatches *matches,
int count,
AccessControlState *state,
slap_access_t access );
static int regex_matches(
struct berval *pat, char *str, char *buf,
- int nmatch, regmatch_t *matches);
+ AclRegexMatches *matches);
typedef struct AclSetCookie {
SetCookie asc_cookie;
Entry *asc_e;
} AclSetCookie;
+
SLAP_SET_GATHER acl_set_gather;
SLAP_SET_GATHER acl_set_gather2;
return 1;
}
+#define MATCHES_DNMAXCOUNT(m) \
+ ( sizeof ( (m)->dn_data ) / sizeof( *(m)->dn_data ) )
+#define MATCHES_VALMAXCOUNT(m) \
+ ( sizeof ( (m)->val_data ) / sizeof( *(m)->val_data ) )
+#define MATCHES_MEMSET(m) { \
+ memset( (m)->dn_data, '\0', sizeof( (m)->dn_data ) ); \
+ memset( (m)->val_data, '\0', sizeof( (m)->val_data ) ); \
+ (m)->dn_count = MATCHES_DNMAXCOUNT( (m) ); \
+ (m)->val_count = MATCHES_VALMAXCOUNT( (m) ); \
+} while ( 0 /* CONSTCOND */ )
+
int
slap_access_allowed(
Operation *op,
slap_control_t control;
slap_access_t access_level;
const char *attr;
- regmatch_t matches[MAXREMATCHES];
- AccessControlState acl_state = ACL_STATE_INIT;
+ AclRegexMatches matches;
+ AccessControlState acl_state = ACL_STATE_INIT;
assert( op != NULL );
assert( e != NULL );
state->as_fe_done = 0;
ACL_PRIV_ASSIGN( mask, *maskp );
- memset( matches, '\0', sizeof( matches ) );
+ MATCHES_MEMSET( &matches );
while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
- MAXREMATCHES, matches, state ) ) != NULL )
+ &matches, state ) ) != NULL )
{
- int i;
+ int i;
+ int dnmaxcount = MATCHES_DNMAXCOUNT( &matches );
+ int valmaxcount = MATCHES_VALMAXCOUNT( &matches );
+ regmatch_t *dn_data = matches.dn_data;
+ regmatch_t *val_data = matches.val_data;
+
+ /* DN matches */
+ for ( i = 0; i < dnmaxcount && dn_data[i].rm_eo > 0; i++ ) {
+ char *debugmsg = "=> match[dn%d]: %d %d ";
+ char *data = e->e_ndn;
+
+ Debug( LDAP_DEBUG_ACL, debugmsg, i,
+ (int)dn_data[i].rm_so,
+ (int)dn_data[i].rm_eo );
+ if ( dn_data[i].rm_so <= dn_data[0].rm_eo ) {
+ int n;
+ for ( n = dn_data[i].rm_so;
+ n < dn_data[i].rm_eo; n++ ) {
+ Debug( LDAP_DEBUG_ACL, "%c",
+ data[n], 0, 0 );
+ }
+ }
+ Debug( LDAP_DEBUG_ACL, "\n", 0, 0, 0 );
+ }
- for ( i = 0; i < MAXREMATCHES && matches[i].rm_so > 0; i++ ) {
- Debug( LDAP_DEBUG_ACL, "=> match[%d]: %d %d ", i,
- (int)matches[i].rm_so, (int)matches[i].rm_eo );
- if ( matches[i].rm_so <= matches[0].rm_eo ) {
+ /* val matches */
+ for ( i = 0; i < valmaxcount && val_data[i].rm_eo > 0; i++ ) {
+ char *debugmsg = "=> match[val%d]: %d %d ";
+ char *data = val->bv_val;
+
+ Debug( LDAP_DEBUG_ACL, debugmsg, i,
+ (int)val_data[i].rm_so,
+ (int)val_data[i].rm_eo );
+ if ( val_data[i].rm_so <= val_data[0].rm_eo ) {
int n;
- for ( n = matches[i].rm_so; n < matches[i].rm_eo; n++ ) {
- Debug( LDAP_DEBUG_ACL, "%c", e->e_ndn[n], 0, 0 );
+ for ( n = val_data[i].rm_so;
+ n < val_data[i].rm_eo; n++ ) {
+ Debug( LDAP_DEBUG_ACL, "%c",
+ data[n], 0, 0 );
}
}
- Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );
+ Debug( LDAP_DEBUG_ACL, "\n", 0, 0, 0 );
}
if ( state ) {
}
control = slap_acl_mask( a, &mask, op,
- e, desc, val, MAXREMATCHES, matches, count, state, access );
+ e, desc, val, &matches, count, state, access );
if ( control != ACL_BREAK ) {
break;
}
- memset( matches, '\0', sizeof( matches ) );
+ MATCHES_MEMSET( &matches );
}
if ( ACL_IS_INVALID( mask ) ) {
Entry *e,
AttributeDescription *desc,
struct berval *val,
- int nmatch,
- regmatch_t *matches,
+ AclRegexMatches *matches,
AccessControlState *state )
{
const char *attr;
if ( a->acl_dn_style == ACL_STYLE_REGEX ) {
Debug( LDAP_DEBUG_ACL, "=> dnpat: [%d] %s nsub: %d\n",
*count, a->acl_dn_pat.bv_val, (int) a->acl_dn_re.re_nsub );
- if (regexec(&a->acl_dn_re, e->e_ndn, nmatch, matches, 0))
+ if ( regexec ( &a->acl_dn_re,
+ e->e_ndn,
+ matches->dn_count,
+ matches->dn_data, 0 ) )
continue;
} else {
}
if ( a->acl_attrs && !ad_inlist( desc, a->acl_attrs ) ) {
- matches[0].rm_so = matches[0].rm_eo = -1;
+ matches->dn_data[0].rm_so = -1;
+ matches->dn_data[0].rm_eo = -1;
+ matches->val_data[0].rm_so = -1;
+ matches->val_data[0].rm_eo = -1;
continue;
}
}
if ( a->acl_attrval_style == ACL_STYLE_REGEX ) {
+ int rc;
+
Debug( LDAP_DEBUG_ACL,
"acl_get: valpat %s\n",
a->acl_attrval.bv_val, 0, 0 );
- if ( regexec( &a->acl_attrval_re, val->bv_val, 0, NULL, 0 ) )
+ if ( rc = regexec ( &a->acl_attrval_re,
+ val->bv_val,
+ matches->val_count,
+ matches->val_data, 0 ) )
{
continue;
}
AttributeDescription *desc,
struct berval *val,
AccessControl *a,
- int nmatch,
- regmatch_t *matches,
+ AclRegexMatches *matches,
slap_dn_access *bdn,
struct berval *opndn )
{
} else if ( bdn->a_style == ACL_STYLE_REGEX ) {
if ( !ber_bvccmp( &bdn->a_pat, '*' ) ) {
- int tmp_nmatch;
- regmatch_t tmp_matches[2],
- *tmp_matchesp = tmp_matches;
-
+ AclRegexMatches tmp_matches,
+ *tmp_matchesp = &tmp_matches;
int rc = 0;
+ int dnoffset;
+ regmatch_t *tmp_data;
+
+ MATCHES_MEMSET( &tmp_matches );
+ tmp_data = &tmp_matches.dn_data[0];
- switch ( a->acl_dn_style ) {
+ if ( a->acl_attrval_style == ACL_STYLE_REGEX )
+ tmp_matchesp = matches;
+ else switch ( a->acl_dn_style ) {
case ACL_STYLE_REGEX:
if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
- tmp_matchesp = matches;
- tmp_nmatch = nmatch;
+ tmp_matchesp = matches;
break;
}
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
case ACL_STYLE_BASE:
- tmp_matches[0].rm_so = 0;
- tmp_matches[0].rm_eo = e->e_nname.bv_len;
- tmp_nmatch = 1;
+ tmp_data[0].rm_so = 0;
+ tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_matches.dn_count = 1;
break;
case ACL_STYLE_ONE:
case ACL_STYLE_SUBTREE:
case ACL_STYLE_CHILDREN:
- tmp_matches[0].rm_so = 0;
- tmp_matches[0].rm_eo = e->e_nname.bv_len;
- tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
- tmp_matches[1].rm_eo = e->e_nname.bv_len;
- tmp_nmatch = 2;
+ tmp_data[0].rm_so = 0;
+ tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+ tmp_data[1].rm_eo = e->e_nname.bv_len;
+ tmp_matches.dn_count = 2;
break;
default:
}
if ( !regex_matches( &bdn->a_pat, opndn->bv_val,
- e->e_ndn, tmp_nmatch, tmp_matchesp ) )
+ e->e_ndn, tmp_matchesp ) )
{
return 1;
}
struct berval bv;
char buf[ACL_BUF_SIZE];
- int tmp_nmatch;
- regmatch_t tmp_matches[2],
- *tmp_matchesp = tmp_matches;
-
+ AclRegexMatches tmp_matches,
+ *tmp_matchesp = &tmp_matches;
int rc = 0;
+ regmatch_t *tmp_data;
+
+ MATCHES_MEMSET( &tmp_matches );
+ tmp_data = &tmp_matches.dn_data[0];
bv.bv_len = sizeof( buf ) - 1;
bv.bv_val = buf;
- switch ( a->acl_dn_style ) {
+ /* Expand value regex */
+ if ( a->acl_attrval_style == ACL_STYLE_REGEX )
+ tmp_matchesp = matches;
+ else switch ( a->acl_dn_style ) {
case ACL_STYLE_REGEX:
if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
tmp_matchesp = matches;
- tmp_nmatch = nmatch;
break;
}
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
case ACL_STYLE_BASE:
- tmp_matches[0].rm_so = 0;
- tmp_matches[0].rm_eo = e->e_nname.bv_len;
- tmp_nmatch = 1;
+ tmp_data[0].rm_so = 0;
+ tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_matches.dn_count = 1;
break;
case ACL_STYLE_ONE:
case ACL_STYLE_SUBTREE:
case ACL_STYLE_CHILDREN:
- tmp_matches[0].rm_so = 0;
- tmp_matches[0].rm_eo = e->e_nname.bv_len;
- tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
- tmp_matches[1].rm_eo = e->e_nname.bv_len;
- tmp_nmatch = 2;
+ tmp_data[0].rm_so = 0;
+ tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+ tmp_data[1].rm_eo = e->e_nname.bv_len;
+ tmp_matches.dn_count = 2;
break;
default:
}
if ( acl_string_expand( &bv, &bdn->a_pat,
- e->e_nname.bv_val,
- tmp_nmatch, tmp_matchesp ) )
+ e->e_nname.bv_val,
+ val->bv_val, tmp_matchesp ) )
{
return 1;
}
AccessControl *a,
Access *b,
int i,
- regmatch_t *matches,
+ AclRegexMatches *matches,
int count,
AccessControlState *state,
slap_dn_access *bdn,
Entry *e,
AttributeDescription *desc,
struct berval *val,
- int nmatch,
- regmatch_t *matches,
+ AclRegexMatches *matches,
int count,
AccessControlState *state,
slap_access_t access )
* is maintained in a_dn_pat.
*/
- if ( acl_mask_dn( op, e, desc, val, a, nmatch, matches,
+ if ( acl_mask_dn( op, e, desc, val, a, matches,
&b->a_dn, &op->o_ndn ) )
{
continue;
ndn = op->o_ndn;
}
- if ( acl_mask_dn( op, e, desc, val, a, nmatch, matches,
+ if ( acl_mask_dn( op, e, desc, val, a, matches,
&b->a_realdn, &ndn ) )
{
continue;
if ( !ber_bvccmp( &b->a_sockurl_pat, '*' ) ) {
if ( b->a_sockurl_style == ACL_STYLE_REGEX) {
if (!regex_matches( &b->a_sockurl_pat, op->o_conn->c_listener_url.bv_val,
- e->e_ndn, nmatch, matches ) )
+ e->e_ndn, matches ) )
{
continue;
}
bv.bv_len = sizeof( buf ) - 1;
bv.bv_val = buf;
- if ( acl_string_expand( &bv, &b->a_sockurl_pat,
- e->e_ndn, nmatch, matches ) )
+ if ( acl_string_expand( &bv, &b->a_sockurl_pat, e->e_ndn, val->bv_val, matches ) )
{
continue;
}
if ( !ber_bvccmp( &b->a_domain_pat, '*' ) ) {
if ( b->a_domain_style == ACL_STYLE_REGEX) {
if (!regex_matches( &b->a_domain_pat, op->o_conn->c_peer_domain.bv_val,
- e->e_ndn, nmatch, matches ) )
+ e->e_ndn, matches ) )
{
continue;
}
bv.bv_len = sizeof(buf) - 1;
bv.bv_val = buf;
- if ( acl_string_expand(&bv, &b->a_domain_pat,
- e->e_ndn, nmatch, matches) )
+ if ( acl_string_expand(&bv, &b->a_domain_pat, e->e_ndn, val->bv_val, matches) )
{
continue;
}
if ( !ber_bvccmp( &b->a_peername_pat, '*' ) ) {
if ( b->a_peername_style == ACL_STYLE_REGEX ) {
if (!regex_matches( &b->a_peername_pat, op->o_conn->c_peer_name.bv_val,
- e->e_ndn, nmatch, matches ) )
+ e->e_ndn, matches ) )
{
continue;
}
bv.bv_len = sizeof( buf ) - 1;
bv.bv_val = buf;
- if ( acl_string_expand( &bv, &b->a_peername_pat,
- e->e_ndn, nmatch, matches ) )
+ if ( acl_string_expand( &bv, &b->a_peername_pat, e->e_ndn, val->bv_val, matches ) )
{
continue;
}
if ( !ber_bvccmp( &b->a_sockname_pat, '*' ) ) {
if ( b->a_sockname_style == ACL_STYLE_REGEX) {
if (!regex_matches( &b->a_sockname_pat, op->o_conn->c_sock_name.bv_val,
- e->e_ndn, nmatch, matches ) )
+ e->e_ndn, matches ) )
{
continue;
}
bv.bv_len = sizeof( buf ) - 1;
bv.bv_val = buf;
- if ( acl_string_expand( &bv, &b->a_sockname_pat,
- e->e_ndn, nmatch, matches ) )
+ if ( acl_string_expand( &bv, &b->a_sockname_pat, e->e_ndn, val->bv_val, matches ) )
{
continue;
}
/* see if asker is listed in dnattr */
if ( b->a_group_style == ACL_STYLE_EXPAND ) {
char buf[ACL_BUF_SIZE];
- int tmp_nmatch;
- regmatch_t tmp_matches[2],
- *tmp_matchesp = tmp_matches;
+ AclRegexMatches tmp_matches,
+ *tmp_matchesp = &tmp_matches;
+ regmatch_t *tmp_data;
+
+ MATCHES_MEMSET( &tmp_matches );
+ tmp_data = &tmp_matches.dn_data[0];
bv.bv_len = sizeof(buf) - 1;
bv.bv_val = buf;
rc = 0;
- switch ( a->acl_dn_style ) {
+ if ( a->acl_attrval_style == ACL_STYLE_REGEX )
+ tmp_matchesp = matches;
+ else switch ( a->acl_dn_style ) {
case ACL_STYLE_REGEX:
if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
tmp_matchesp = matches;
- tmp_nmatch = nmatch;
break;
}
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
case ACL_STYLE_BASE:
- tmp_matches[0].rm_so = 0;
- tmp_matches[0].rm_eo = e->e_nname.bv_len;
- tmp_nmatch = 1;
+ tmp_data[0].rm_so = 0;
+ tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_matches.dn_count = 1;
break;
case ACL_STYLE_ONE:
case ACL_STYLE_SUBTREE:
case ACL_STYLE_CHILDREN:
- tmp_matches[0].rm_so = 0;
- tmp_matches[0].rm_eo = e->e_nname.bv_len;
- tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
- tmp_matches[1].rm_eo = e->e_nname.bv_len;
- tmp_nmatch = 2;
+ tmp_data[0].rm_so = 0;
+ tmp_data[0].rm_eo = e->e_nname.bv_len;
+
+ tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+ tmp_data[1].rm_eo = e->e_nname.bv_len;
+ tmp_matches.dn_count = 2;
break;
default:
}
if ( acl_string_expand( &bv, &b->a_group_pat,
- e->e_nname.bv_val,
- tmp_nmatch, tmp_matchesp ) )
+ e->e_nname.bv_val, val->bv_val,
+ tmp_matchesp ) )
{
continue;
}
b->a_set_pat.bv_val, 0, 0 );
if ( b->a_set_style == ACL_STYLE_EXPAND ) {
- int tmp_nmatch;
- regmatch_t tmp_matches[2],
- *tmp_matchesp = tmp_matches;
+ AclRegexMatches tmp_matches,
+ *tmp_matchesp = &tmp_matches;
int rc = 0;
+ regmatch_t *tmp_data;
+
+ MATCHES_MEMSET( &tmp_matches );
+ tmp_data = &tmp_matches.dn_data[0];
bv.bv_len = sizeof( buf ) - 1;
bv.bv_val = buf;
rc = 0;
- switch ( a->acl_dn_style ) {
+ if ( a->acl_attrval_style == ACL_STYLE_REGEX )
+ tmp_matchesp = matches;
+ else switch ( a->acl_dn_style ) {
case ACL_STYLE_REGEX:
if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
tmp_matchesp = matches;
- tmp_nmatch = nmatch;
break;
}
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
case ACL_STYLE_BASE:
- tmp_matches[0].rm_so = 0;
- tmp_matches[0].rm_eo = e->e_nname.bv_len;
- tmp_nmatch = 1;
+ tmp_data[0].rm_so = 0;
+ tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_matches.dn_count = 1;
break;
case ACL_STYLE_ONE:
case ACL_STYLE_SUBTREE:
case ACL_STYLE_CHILDREN:
- tmp_matches[0].rm_so = 0;
- tmp_matches[0].rm_eo = e->e_nname.bv_len;
- tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
- tmp_matches[1].rm_eo = e->e_nname.bv_len;
- tmp_nmatch = 2;
+ tmp_data[0].rm_so = 0;
+ tmp_data[0].rm_eo = e->e_nname.bv_len;
+ tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
+ tmp_data[1].rm_eo = e->e_nname.bv_len; tmp_matches.dn_count = 2;
break;
default:
}
if ( acl_string_expand( &bv, &b->a_set_pat,
- e->e_nname.bv_val,
- tmp_nmatch, tmp_matchesp ) )
+ e->e_nname.bv_val, val->bv_val,
+ tmp_matchesp ) )
{
continue;
}
Debug( LDAP_DEBUG_ACL, " <= check a_dynacl: %s\n",
da->da_name, 0, 0 );
+ /*
+ * XXXmanu Only DN matches are supplied
+ * sending attribute values matches require
+ * an API update
+ */
(void)da->da_mask( da->da_private, op, e, desc,
- val, nmatch, matches, &grant, &deny );
+ val, matches.dn_count, matches.dn_data,
+ &grant, &deny );
tgrant |= grant;
tdeny |= deny;
acl_string_expand(
struct berval *bv,
struct berval *pat,
- char *match,
- int nmatch,
- regmatch_t *matches)
+ char *dn_match,
+ char *val_match,
+ AclRegexMatches *matches)
{
ber_len_t size;
char *sp;
char *dp;
int flag;
+ enum { DN_FLAG, VAL_FLAG } tflag;
size = 0;
bv->bv_val[0] = '\0';
bv->bv_len--; /* leave space for lone $ */
flag = 0;
+ tflag = DN_FLAG;
for ( dp = bv->bv_val, sp = pat->bv_val; size < bv->bv_len &&
sp < pat->bv_val + pat->bv_len ; sp++ )
{
*dp++ = '$';
size++;
flag = 0;
+ tflag = DN_FLAG;
+
+ } else if ( flag == 2 && *sp == 'v' /*'}'*/) {
+ tflag = VAL_FLAG;
+
+ } else if ( flag == 2 && *sp == 'd' /*'}'*/) {
+ tflag = DN_FLAG;
} else if ( flag == 1 && *sp == '{' /*'}'*/) {
flag = 2;
} else if ( *sp >= '0' && *sp <= '9' ) {
+ int nm;
+ regmatch_t *m;
+ char *data;
int n;
int i;
int l;
}
}
- if ( n >= nmatch ) {
+ switch (tflag) {
+ case DN_FLAG:
+ nm = matches->dn_count;
+ m = matches->dn_data;
+ data = dn_match;
+ break;
+ case VAL_FLAG:
+ nm = matches->val_count;
+ m = matches->val_data;
+ data = val_match;
+ break;
+ }
+ if ( n >= nm ) {
+ /* FIXME: error */
+ return 1;
+ }
+ if ( data == NULL ) {
/* FIXME: error */
return 1;
}
*dp = '\0';
- i = matches[n].rm_so;
- l = matches[n].rm_eo;
+ i = m[n].rm_so;
+ l = m[n].rm_eo;
+
for ( ; size < bv->bv_len && i < l; size++, i++ ) {
- *dp++ = match[i];
+ *dp++ = data[i];
}
*dp = '\0';
flag = 0;
+ tflag = DN_FLAG;
}
} else {
if (*sp == '$') {
*dp = '\0';
bv->bv_len = size;
- Debug( LDAP_DEBUG_TRACE, "=> acl_string_expand: pattern: %.*s\n", (int)pat->bv_len, pat->bv_val, 0 );
- Debug( LDAP_DEBUG_TRACE, "=> acl_string_expand: expanded: %s\n", bv->bv_val, 0, 0 );
+ Debug( LDAP_DEBUG_ACL, "=> acl_string_expand: pattern: %.*s\n", (int)pat->bv_len, pat->bv_val, 0 );
+ Debug( LDAP_DEBUG_ACL, "=> acl_string_expand: expanded: %s\n", bv->bv_val, 0, 0 );
return 0;
}
struct berval *pat, /* pattern to expand and match against */
char *str, /* string to match against pattern */
char *buf, /* buffer with $N expansion variables */
- int nmatch, /* size of the matches array */
- regmatch_t *matches /* offsets in buffer for $N expansion variables */
+ AclRegexMatches *matches /* offsets in buffer for $N expansion variables */
)
{
regex_t re;
str = "";
};
- acl_string_expand( &bv, pat, buf, nmatch, matches );
+ acl_string_expand( &bv, pat, buf, NULL, matches );
rc = regcomp( &re, newbuf, REG_EXTENDED|REG_ICASE );
if ( rc ) {
char error[ACL_BUF_SIZE];