#ifdef SLAPD_ACI_ENABLED
static int aci_mask(
Backend *be,
+ Connection *conn,
Operation *op,
Entry *e,
AttributeDescription *desc,
regmatch_t *matches )
{
const char *attr;
+ int dnlen, patlen;
+
assert( e != NULL );
assert( count != NULL );
a = a->acl_next;
}
+ dnlen = strlen(e->e_ndn);
+
for ( ; a != NULL; a = a->acl_next ) {
(*count) ++;
if (a->acl_dn_pat != NULL) {
- Debug( LDAP_DEBUG_ACL, "=> dnpat: [%d] %s nsub: %d\n",
- *count, a->acl_dn_pat, (int) a->acl_dn_re.re_nsub );
+ if ( a->acl_dn_style == ACL_STYLE_REGEX ) {
+ Debug( LDAP_DEBUG_ACL, "=> dnpat: [%d] %s nsub: %d\n",
+ *count, a->acl_dn_pat, (int) a->acl_dn_re.re_nsub );
- if (regexec(&a->acl_dn_re, e->e_ndn, nmatch, matches, 0)) {
- continue;
+ if (regexec(&a->acl_dn_re, e->e_ndn, nmatch, matches, 0))
+ continue;
} else {
- Debug( LDAP_DEBUG_ACL, "=> acl_get: [%d] matched\n",
- *count, 0, 0);
+ Debug( LDAP_DEBUG_ACL, "=> dn: [%d] %s\n",
+ *count, a->acl_dn_pat, 0 );
+
+ patlen = strlen( a->acl_dn_pat );
+ if ( dnlen < patlen )
+ continue;
+
+ if ( a->acl_dn_style == ACL_STYLE_BASE ) {
+ /* base dn -- entire object DN must match */
+ if ( dnlen != patlen )
+ continue;
+
+ } else if ( a->acl_dn_style == ACL_STYLE_ONE ) {
+ char *rdn;
+ int rdnlen = -1;
+
+ if ( dnlen <= patlen )
+ continue;
+
+ if ( e->e_ndn[dnlen - patlen - 1] != ',' )
+ continue;
+
+ rdn = dn_rdn( NULL, e->e_ndn );
+ if ( rdn != NULL ) {
+ rdnlen = strlen( rdn );
+ ch_free( rdn );
+ }
+ if ( rdnlen != dnlen - patlen - 1 )
+ continue;
+
+ } else if ( a->acl_dn_style == ACL_STYLE_SUBTREE ) {
+ if ( dnlen > patlen && e->e_ndn[dnlen - patlen - 1] != ',' )
+ continue;
+
+ } else if ( a->acl_dn_style == ACL_STYLE_CHILDREN ) {
+ if ( dnlen <= patlen )
+ continue;
+ if ( e->e_ndn[dnlen - patlen - 1] != ',' )
+ continue;
+ }
+
+ if ( strcmp( a->acl_dn_pat, e->e_ndn + dnlen - patlen ) != 0 )
+ continue;
}
+
+ Debug( LDAP_DEBUG_ACL, "=> acl_get: [%d] matched\n",
+ *count, 0, 0 );
}
if ( a->acl_filter != NULL ) {
regmatch_t *matches
)
{
- int i;
+ int i, odnlen, patlen;
Access *b;
#ifdef LDAP_DEBUG
char accessmaskbuf[ACCESSMASK_MAXLEN];
continue;
}
- } else if ( strcmp( b->a_dn_pat, "*" ) != 0 ) {
- int ret = regex_matches( b->a_dn_pat,
- op->o_ndn, e->e_ndn, matches );
+ } else if ( b->a_dn_style == ACL_STYLE_REGEX ) {
+ if ( strcmp( b->a_dn_pat, "*" ) != 0 ) {
+ int ret = regex_matches( b->a_dn_pat,
+ op->o_ndn, e->e_ndn, matches );
+
+ if( ret == 0 ) {
+ continue;
+ }
+ }
+
+ } else {
+ if ( e->e_dn == NULL )
+ continue;
- if( ret == 0 ) {
+ patlen = strlen( b->a_dn_pat );
+ odnlen = strlen( op->o_ndn );
+ if ( odnlen < patlen )
continue;
+
+ if ( b->a_dn_style == ACL_STYLE_BASE ) {
+ /* base dn -- entire object DN must match */
+ if ( odnlen != patlen )
+ continue;
+
+ } else if ( b->a_dn_style == ACL_STYLE_ONE ) {
+ char *rdn;
+ int rdnlen = -1;
+
+ if ( odnlen <= patlen )
+ continue;
+
+ if ( op->o_ndn[odnlen - patlen - 1] != ',' )
+ continue;
+
+ rdn = dn_rdn( NULL, op->o_ndn );
+ if ( rdn != NULL ) {
+ rdnlen = strlen( rdn );
+ ch_free( rdn );
+ }
+ if ( rdnlen != odnlen - patlen - 1 )
+ continue;
+
+ } else if ( b->a_dn_style == ACL_STYLE_SUBTREE ) {
+ if ( odnlen > patlen && op->o_ndn[odnlen - patlen - 1] != ',' )
+ continue;
+
+ } else if ( b->a_dn_style == ACL_STYLE_CHILDREN ) {
+ if ( odnlen <= patlen )
+ continue;
+ if ( op->o_ndn[odnlen - patlen - 1] != ',' )
+ continue;
}
+
+ if ( strcmp( b->a_dn_pat, op->o_ndn + odnlen - patlen ) != 0 )
+ continue;
+
}
}
Debug( LDAP_DEBUG_ACL, "<= check a_sockurl_pat: %s\n",
b->a_sockurl_pat, 0, 0 );
- if ( strcmp( b->a_sockurl_pat, "*" ) != 0 &&
- !regex_matches( b->a_sockurl_pat, conn->c_listener_url,
- e->e_ndn, matches ) )
- {
- continue;
+ if ( strcmp( b->a_sockurl_pat, "*" ) != 0) {
+ if ( b->a_sockurl_style == ACL_STYLE_REGEX) {
+ if (!regex_matches( b->a_sockurl_pat, conn->c_listener_url,
+ e->e_ndn, matches ) )
+ {
+ continue;
+ }
+ } else {
+ if ( strcasecmp( b->a_sockurl_pat, conn->c_listener_url ) == 0 )
+ continue;
+ }
}
}
Debug( LDAP_DEBUG_ACL, "<= check a_domain_pat: %s\n",
b->a_domain_pat, 0, 0 );
- if ( strcmp( b->a_domain_pat, "*" ) != 0 &&
- !regex_matches( b->a_domain_pat, conn->c_peer_domain,
- e->e_ndn, matches ) )
- {
- continue;
+ if ( strcmp( b->a_domain_pat, "*" ) != 0) {
+ if ( b->a_domain_style == ACL_STYLE_REGEX) {
+ if (!regex_matches( b->a_domain_pat, conn->c_peer_domain,
+ e->e_ndn, matches ) )
+ {
+ continue;
+ }
+ } else {
+ if ( strcasecmp( b->a_domain_pat, conn->c_peer_domain ) == 0 )
+ continue;
+ }
}
}
Debug( LDAP_DEBUG_ACL, "<= check a_peername_path: %s\n",
b->a_peername_pat, 0, 0 );
- if ( strcmp( b->a_peername_pat, "*" ) != 0 &&
- !regex_matches( b->a_peername_pat, conn->c_peer_name,
- e->e_ndn, matches ) )
- {
- continue;
+ if ( strcmp( b->a_peername_pat, "*" ) != 0) {
+ if ( b->a_peername_style == ACL_STYLE_REGEX) {
+ if (!regex_matches( b->a_peername_pat, conn->c_peer_name,
+ e->e_ndn, matches ) )
+ {
+ continue;
+ }
+ } else {
+ if ( strcasecmp( b->a_peername_pat, conn->c_peer_name ) == 0 )
+ continue;
+ }
}
}
Debug( LDAP_DEBUG_ACL, "<= check a_sockname_path: %s\n",
b->a_sockname_pat, 0, 0 );
- if ( strcmp( b->a_sockname_pat, "*" ) != 0 &&
- !regex_matches( b->a_sockname_pat, conn->c_sock_name,
- e->e_ndn, matches ) )
- {
- continue;
+ if ( strcmp( b->a_sockname_pat, "*" ) != 0) {
+ if ( b->a_sockname_style == ACL_STYLE_REGEX) {
+ if (!regex_matches( b->a_sockname_pat, conn->c_sock_name,
+ e->e_ndn, matches ) )
+ {
+ continue;
+ }
+ } else {
+ if ( strcasecmp( b->a_sockname_pat, conn->c_sock_name ) == 0 )
+ continue;
+ }
}
}
* the values in the attribute group
*/
/* see if asker is listed in dnattr */
- string_expand(buf, sizeof(buf), b->a_group_pat, e->e_ndn, matches);
- if ( dn_normalize(buf) == NULL ) {
- /* did not expand to a valid dn */
- continue;
+ if ( b->a_group_style != ACL_STYLE_REGEX ) {
+ string_expand(buf, sizeof(buf), b->a_group_pat, e->e_ndn, matches);
+ if ( dn_normalize(buf) == NULL ) {
+ /* did not expand to a valid dn */
+ continue;
+ }
+ } else {
+ strncpy( buf, b->a_group_pat, sizeof(buf) - 1 );
+ buf[sizeof(buf) - 1] = 0;
}
if (backend_group(be, e, buf, op->o_ndn,
* rights given by the acis.
*/
for ( i = 0; at->a_vals[i] != NULL; i++ ) {
- if (aci_mask( be, op,
+ if (aci_mask( be, conn, op,
e, desc, val, at->a_vals[i],
matches, &grant, &deny ) != 0)
{
static int
aci_mask(
Backend *be,
+ Connection *conn,
Operation *op,
Entry *e,
AttributeDescription *desc,
{
struct berval bv, perms, sdn;
char *subjdn;
- int rc, i;
- char *attr;
+ int rc;
+ char *attr = desc->ad_cname->bv_val;
/* parse an aci of the form:
oid#scope#action;rights;attr;rights;attr$action;rights;attr;rights;attr#dnType#subjectDN
)
{
int i;
- char *left, *right;
+ char *left, *right, *style;
AccessControl *a;
Access *b;
int rc;
}
split( argv[i], '=', &left, &right );
+ split( left, '.', &left, &style );
+
+ if ( right == NULL || *right == '\0' ) {
+ fprintf( stderr,
+ "%s: line %d: missing \"=\" in (or value after) \"%s\" in to clause\n",
+ fname, lineno, left );
+ acl_usage();
+ }
if ( strcasecmp( left, "dn" ) == 0 ) {
if( a->acl_dn_pat != NULL ) {
acl_usage();
}
- if ( right == NULL ) {
- fprintf( stderr,
- "%s: line %d: missing \"=\" in \"%s\" in to clause\n",
- fname, lineno, left );
- acl_usage();
- }
+ if ( style == NULL || *style == '\0'
+ || strcasecmp( style, "regex" ) == 0 )
+ {
+ a->acl_dn_style = ACL_STYLE_REGEX;
+ if ( strcmp(right, "*") == 0
+ || strcmp(right, ".*") == 0
+ || strcmp(right, ".*$") == 0
+ || strcmp(right, "^.*") == 0
+ || strcmp(right, "^.*$$") == 0
+ || strcmp(right, ".*$$") == 0
+ || strcmp(right, "^.*$$") == 0 )
+ {
+ a->acl_dn_pat = ch_strdup( "*" );
- if( *right == '\0' ) {
- a->acl_dn_pat = ch_strdup("anonymous");
+ } else {
+ a->acl_dn_pat = ch_strdup( right );
+ }
+ } else if ( strcasecmp( style, "base" ) == 0 ) {
+ a->acl_dn_style = ACL_STYLE_BASE;
+ a->acl_dn_pat = ch_strdup( right );
- } else if ( strcmp(right, "*") == 0
- || strcmp(right, ".*") == 0
- || strcmp(right, ".*$") == 0
- || strcmp(right, "^.*") == 0
- || strcmp(right, "^.*$$") == 0
- || strcmp(right, ".*$$") == 0
- || strcmp(right, "^.*$$") == 0 )
- {
- a->acl_dn_pat = ch_strdup( "*" );
+ } else if ( strcasecmp( style, "one" ) == 0 ) {
+ a->acl_dn_style = ACL_STYLE_ONE;
+ a->acl_dn_pat = ch_strdup( right );
- } else {
+ } else if ( strcasecmp( style, "subtree" ) == 0 ) {
+ a->acl_dn_style = ACL_STYLE_SUBTREE;
a->acl_dn_pat = ch_strdup( right );
+
+ } else if ( strcasecmp( style, "children" ) == 0 ) {
+ a->acl_dn_style = ACL_STYLE_CHILDREN;
+ a->acl_dn_pat = ch_strdup( right );
+
+ } else {
+ fprintf( stderr,
+ "%s: line %d: unknown dn style \"%s\" in to clause\n",
+ fname, lineno, style );
+ acl_usage();
}
continue;
}
- if ( right == NULL || *right == '\0' ) {
- fprintf( stderr,
- "%s: line %d: missing \"=\" in (or value after) \"%s\" in to clause\n",
- fname, lineno, left );
- acl_usage();
- }
-
if ( strcasecmp( left, "filter" ) == 0 ) {
if ( (a->acl_filter = str2filter(
right )) == NULL ) {
}
if( a->acl_dn_pat != NULL ) {
- int e = regcomp( &a->acl_dn_re, a->acl_dn_pat,
- REG_EXTENDED | REG_ICASE );
- if ( e ) {
- char buf[512];
- regerror( e, &a->acl_dn_re, buf, sizeof(buf) );
- fprintf( stderr,
- "%s: line %d: regular expression \"%s\" bad because of %s\n",
- fname, lineno, right, buf );
- acl_usage();
+ if ( a->acl_dn_style != ACL_STYLE_REGEX )
+ {
+ dn_normalize(a->acl_dn_pat);
+
+ } else {
+ int e = regcomp( &a->acl_dn_re, a->acl_dn_pat,
+ REG_EXTENDED | REG_ICASE );
+ if ( e ) {
+ char buf[512];
+ regerror( e, &a->acl_dn_re, buf, sizeof(buf) );
+ fprintf( stderr,
+ "%s: line %d: regular expression \"%s\" bad because of %s\n",
+ fname, lineno, right, buf );
+ acl_usage();
+ }
}
}
/* get <who> */
for ( ; i < argc; i++ ) {
char *pat;
+ slap_style_t sty = ACL_STYLE_REGEX;
+
split( argv[i], '=', &left, &right );
+ split( left, '.', &left, &style );
+ if ( style == NULL || *style == '\0'
+ || strcasecmp( style, "regex" ) == 0 )
+ {
+ sty = ACL_STYLE_REGEX;
+ } else if ( strcasecmp( style, "exact" ) == 0 ) {
+ sty = ACL_STYLE_BASE;
+ } else if ( strcasecmp( style, "base" ) == 0 ) {
+ sty = ACL_STYLE_BASE;
+ } else if ( strcasecmp( style, "one" ) == 0 ) {
+ sty = ACL_STYLE_ONE;
+ } else if ( strcasecmp( style, "subtree" ) == 0 ) {
+ sty = ACL_STYLE_SUBTREE;
+ } else if ( strcasecmp( style, "children" ) == 0 ) {
+ sty = ACL_STYLE_CHILDREN;
+ } else {
+ fprintf( stderr,
+ "%s: line %d: unknown style \"%s\" in by clause\n",
+ fname, lineno, style );
+ acl_usage();
+ }
if ( strcasecmp( argv[i], "*" ) == 0 ) {
pat = ch_strdup( "*" );
pat = ch_strdup( "users" );
} else if ( strcasecmp( left, "dn" ) == 0 ) {
- if( right == NULL ) {
- /* no '=' */
- pat = ch_strdup( "users" );
-
- } else if (*right == '\0' ) {
- /* dn="" */
- pat = ch_strdup( "anonymous" );
-
- } else if ( strcmp( right, "*" ) == 0 ) {
- /* dn=* */
- /* any or users? users for now */
- pat = ch_strdup( "users" );
-
- } else if ( strcmp( right, ".+" ) == 0
- || strcmp( right, "^.+" ) == 0
- || strcmp( right, ".+$" ) == 0
- || strcmp( right, "^.+$" ) == 0
- || strcmp( right, ".+$$" ) == 0
- || strcmp( right, "^.+$$" ) == 0 )
- {
- pat = ch_strdup( "users" );
-
- } else if ( strcmp( right, ".*" ) == 0
- || strcmp( right, "^.*" ) == 0
- || strcmp( right, ".*$" ) == 0
- || strcmp( right, "^.*$" ) == 0
- || strcmp( right, ".*$$" ) == 0
- || strcmp( right, "^.*$$" ) == 0 )
- {
- pat = ch_strdup( "*" );
+ if ( sty == ACL_STYLE_REGEX ) {
+ b->a_dn_style = ACL_STYLE_REGEX;
+ if( right == NULL ) {
+ /* no '=' */
+ pat = ch_strdup( "users" );
+
+ } else if (*right == '\0' ) {
+ /* dn="" */
+ pat = ch_strdup( "anonymous" );
+
+ } else if ( strcmp( right, "*" ) == 0 ) {
+ /* dn=* */
+ /* any or users? users for now */
+ pat = ch_strdup( "users" );
+
+ } else if ( strcmp( right, ".+" ) == 0
+ || strcmp( right, "^.+" ) == 0
+ || strcmp( right, ".+$" ) == 0
+ || strcmp( right, "^.+$" ) == 0
+ || strcmp( right, ".+$$" ) == 0
+ || strcmp( right, "^.+$$" ) == 0 )
+ {
+ pat = ch_strdup( "users" );
+
+ } else if ( strcmp( right, ".*" ) == 0
+ || strcmp( right, "^.*" ) == 0
+ || strcmp( right, ".*$" ) == 0
+ || strcmp( right, "^.*$" ) == 0
+ || strcmp( right, ".*$$" ) == 0
+ || strcmp( right, "^.*$$" ) == 0 )
+ {
+ pat = ch_strdup( "*" );
+
+ } else {
+ regtest(fname, lineno, right);
+ pat = ch_strdup( right );
+ }
+ } else if ( right == NULL || *right == '\0' ) {
+ fprintf( stderr,
+ "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n",
+ fname, lineno, left );
+ acl_usage();
} else {
- regtest(fname, lineno, right);
pat = ch_strdup( right );
}
}
b->a_dn_pat = pat;
+ b->a_dn_style = sty;
+ if ( sty != ACL_STYLE_REGEX )
+ dn_normalize(pat);
continue;
}
continue;
}
+ if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) {
+ fprintf( stderr,
+ "%s: line %d: inappropriate style \"%s\" in by clause\n",
+ fname, lineno, style );
+ acl_usage();
+ }
+
if ( strncasecmp( left, "group", sizeof("group")-1 ) == 0 ) {
char *name = NULL;
char *value = NULL;
}
}
- regtest(fname, lineno, right);
- b->a_group_pat = ch_strdup( right );
+ b->a_group_style = sty;
+ if (sty == ACL_STYLE_REGEX) {
+ regtest(fname, lineno, right);
+ b->a_group_pat = ch_strdup( right );
+ } else {
+ b->a_group_pat = ch_strdup( right );
+ dn_normalize(b->a_group_pat);
+ }
if (value && *value) {
b->a_group_oc = oc_find( value );
acl_usage();
}
- regtest(fname, lineno, right);
+ b->a_peername_style = sty;
+ if (sty == ACL_STYLE_REGEX) {
+ regtest(fname, lineno, right);
+ }
b->a_peername_pat = ch_strdup( right );
continue;
}
acl_usage();
}
- regtest(fname, lineno, right);
+ b->a_sockname_style = sty;
+ if (sty == ACL_STYLE_REGEX) {
+ regtest(fname, lineno, right);
+ }
b->a_sockname_pat = ch_strdup( right );
continue;
}
acl_usage();
}
- regtest(fname, lineno, right);
+ b->a_domain_style = sty;
+ if (sty == ACL_STYLE_REGEX) {
+ regtest(fname, lineno, right);
+ }
b->a_domain_pat = ch_strdup( right );
continue;
}
acl_usage();
}
- regtest(fname, lineno, right);
+ b->a_sockurl_style = sty;
+ if (sty == ACL_STYLE_REGEX) {
+ regtest(fname, lineno, right);
+ }
b->a_sockurl_pat = ch_strdup( right );
continue;
}
#ifdef LDAP_DEBUG
+static char *style_strings[5] = {
+ "regex",
+ "base",
+ "one",
+ "subtree",
+ "children"
+ };
+
+
static void
print_access( Access *b )
{
fprintf( stderr, " %s", b->a_dn_pat );
} else {
- fprintf( stderr, " dn=%s", b->a_dn_pat );
+ fprintf( stderr, " dn.%s=%s", style_strings[b->a_dn_style], b->a_dn_pat );
}
}
}
if ( b->a_group_pat != NULL ) {
- fprintf( stderr, " group: %s", b->a_group_pat );
+ fprintf( stderr, " group=%s", b->a_group_pat );
if ( b->a_group_oc ) {
fprintf( stderr, " objectClass: %s",
if ( a->acl_dn_pat != NULL ) {
to++;
- fprintf( stderr, " dn=%s\n",
- a->acl_dn_pat );
+ fprintf( stderr, " dn.%s=%s\n",
+ style_strings[a->acl_dn_style], a->acl_dn_pat );
}
if ( a->acl_filter != NULL ) {