X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Faclparse.c;h=fddae6b13a5eec2f6a9fbe8fdb2e6db8a78150b0;hb=b94a77687075b0eb2d54d087b8b956d197c1023c;hp=c039c6e25a5a8eec7691268f5b91e775bba0e66a;hpb=cd9a9c628dd08435dff10b25eb9c6de5f7f4a604;p=openldap
diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c
index c039c6e25a..fddae6b13a 100644
--- a/servers/slapd/aclparse.c
+++ b/servers/slapd/aclparse.c
@@ -2,7 +2,7 @@
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software .
*
- * Copyright 1998-2004 The OpenLDAP Foundation.
+ * Copyright 1998-2005 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,11 @@ static char *style_strings[] = {
"one",
"subtree",
"children",
+ "level",
"attrof",
+ "anonymous",
+ "users",
+ "self",
"ip",
"path",
NULL
@@ -62,10 +66,46 @@ static void print_acl(Backend *be, AccessControl *a);
static void print_access(Access *b);
#endif
-#ifdef LDAP_DEVEL
+static int check_scope( BackendDB *be, AccessControl *a );
+
+#ifdef SLAP_DYNACL
static int
-check_scope( BackendDB *be, AccessControl *a );
-#endif /* LDAP_DEVEL */
+slap_dynacl_config( const char *fname, int lineno, Access *b, const char *name, slap_style_t sty, const char *right )
+{
+ slap_dynacl_t *da, *tmp;
+ int rc = 0;
+
+ for ( da = b->a_dynacl; da; da = da->da_next ) {
+ if ( strcasecmp( da->da_name, name ) == 0 ) {
+ fprintf( stderr,
+ "%s: line %d: dynacl \"%s\" already specified.\n",
+ fname, lineno, name );
+ acl_usage();
+ }
+ }
+
+ da = slap_dynacl_get( name );
+ if ( da == NULL ) {
+ return -1;
+ }
+
+ tmp = ch_malloc( sizeof( slap_dynacl_t ) );
+ *tmp = *da;
+
+ if ( tmp->da_parse ) {
+ rc = ( *tmp->da_parse )( fname, lineno, sty, right, &tmp->da_private );
+ if ( rc ) {
+ ch_free( tmp );
+ return rc;
+ }
+ }
+
+ tmp->da_next = b->a_dynacl;
+ b->a_dynacl = tmp;
+
+ return 0;
+}
+#endif /* SLAP_DYNACL */
static void
regtest(const char *fname, int lineno, char *pat) {
@@ -103,7 +143,7 @@ regtest(const char *fname, int lineno, char *pat) {
}
*dp = '\0';
- if ( size >= (sizeof(buf)-1) ) {
+ if ( size >= (sizeof(buf) - 1) ) {
fprintf( stderr,
"%s: line %d: regular expression \"%s\" too large\n",
fname, lineno, pat );
@@ -121,7 +161,6 @@ regtest(const char *fname, int lineno, char *pat) {
regfree(&re);
}
-#ifdef LDAP_DEVEL
/*
* Experimental
*
@@ -142,16 +181,24 @@ check_scope( BackendDB *be, AccessControl *a )
dn = be->be_nsuffix[0];
- if ( a->acl_dn_pat.bv_len || a->acl_dn_style != ACL_STYLE_REGEX ) {
+ if ( BER_BVISEMPTY( &dn ) ) {
+ return ACL_SCOPE_OK;
+ }
+
+ if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||
+ a->acl_dn_style != ACL_STYLE_REGEX )
+ {
slap_style_t style = a->acl_dn_style;
if ( style == ACL_STYLE_REGEX ) {
- char dnbuf[SLAP_LDAPDN_MAXLEN + 2];
- char rebuf[SLAP_LDAPDN_MAXLEN + 1];
- regex_t re;
- int rc;
+ char dnbuf[SLAP_LDAPDN_MAXLEN + 2];
+ char rebuf[SLAP_LDAPDN_MAXLEN + 1];
+ ber_len_t rebuflen;
+ regex_t re;
+ int rc;
- /* add trailing '$' */
+ /* add trailing '$' to database suffix to form
+ * a simple trial regex pattern "$" */
AC_MEMCPY( dnbuf, be->be_nsuffix[0].bv_val,
be->be_nsuffix[0].bv_len );
dnbuf[be->be_nsuffix[0].bv_len] = '$';
@@ -161,17 +208,26 @@ check_scope( BackendDB *be, AccessControl *a )
return ACL_SCOPE_WARN;
}
- /* remove trailing '$' */
- AC_MEMCPY( rebuf, a->acl_dn_pat.bv_val,
- a->acl_dn_pat.bv_len + 1 );
- if ( a->acl_dn_pat.bv_val[a->acl_dn_pat.bv_len - 1] == '$' ) {
- rebuf[a->acl_dn_pat.bv_len - 1] = '\0';
+ /* remove trailing ')$', if any, from original
+ * regex pattern */
+ rebuflen = a->acl_dn_pat.bv_len;
+ AC_MEMCPY( rebuf, a->acl_dn_pat.bv_val, rebuflen + 1 );
+ if ( rebuf[rebuflen - 1] == '$' ) {
+ rebuf[--rebuflen] = '\0';
+ }
+ while ( rebuflen > be->be_nsuffix[0].bv_len && rebuf[rebuflen - 1] == ')' ) {
+ rebuf[--rebuflen] = '\0';
+ }
+ if ( rebuflen == be->be_nsuffix[0].bv_len ) {
+ rc = ACL_SCOPE_WARN;
+ goto regex_done;
}
/* not a clear indication of scoping error, though */
rc = regexec( &re, rebuf, 0, NULL, 0 )
? ACL_SCOPE_WARN : ACL_SCOPE_OK;
+regex_done:;
regfree( &re );
return rc;
}
@@ -185,8 +241,8 @@ check_scope( BackendDB *be, AccessControl *a )
/* base is blatantly wrong */
if ( style == ACL_STYLE_BASE ) return ACL_SCOPE_ERR;
- /* one can be wrong if there is more
- * than one level between the suffix
+ /* a style of one can be wrong if there is
+ * more than one level between the suffix
* and the pattern */
if ( style == ACL_STYLE_ONE ) {
int rdnlen = -1, sep = 0;
@@ -227,7 +283,8 @@ check_scope( BackendDB *be, AccessControl *a )
}
if ( dn.bv_len < patlen &&
- !DN_SEPARATOR( a->acl_dn_pat.bv_val[patlen -dn.bv_len - 1] )) {
+ !DN_SEPARATOR( a->acl_dn_pat.bv_val[patlen - dn.bv_len - 1] ))
+ {
return ACL_SCOPE_ERR;
}
@@ -242,7 +299,6 @@ check_scope( BackendDB *be, AccessControl *a )
return ACL_SCOPE_UNKNOWN;
}
-#endif /* LDAP_DEVEL */
void
parse_acl(
@@ -250,8 +306,7 @@ parse_acl(
const char *fname,
int lineno,
int argc,
- char **argv
-)
+ char **argv )
{
int i;
char *left, *right, *style, *next;
@@ -279,8 +334,8 @@ parse_acl(
}
if ( strcasecmp( argv[i], "*" ) == 0 ) {
- if( a->acl_dn_pat.bv_len ||
- ( a->acl_dn_style != ACL_STYLE_REGEX ) )
+ if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||
+ a->acl_dn_style != ACL_STYLE_REGEX )
{
fprintf( stderr,
"%s: line %d: dn pattern"
@@ -289,8 +344,7 @@ parse_acl(
acl_usage();
}
- a->acl_dn_pat.bv_val = ch_strdup( "*" );
- a->acl_dn_pat.bv_len = 1;
+ ber_str2bv( "*", STRLENOF( "*" ), 1, &a->acl_dn_pat );
continue;
}
@@ -305,8 +359,8 @@ parse_acl(
}
if ( strcasecmp( left, "dn" ) == 0 ) {
- if( a->acl_dn_pat.bv_len != 0 ||
- ( a->acl_dn_style != ACL_STYLE_REGEX ) )
+ if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||
+ a->acl_dn_style != ACL_STYLE_REGEX )
{
fprintf( stderr,
"%s: line %d: dn pattern"
@@ -333,8 +387,7 @@ parse_acl(
strcasecmp( style, "sub" ) == 0 )
{
if( *right == '\0' ) {
- a->acl_dn_pat.bv_val = ch_strdup( "*" );
- a->acl_dn_pat.bv_len = 1;
+ ber_str2bv( "*", STRLENOF( "*" ), 1, &a->acl_dn_pat );
} else {
a->acl_dn_style = ACL_STYLE_SUBTREE;
@@ -361,8 +414,7 @@ parse_acl(
|| strcmp(right, ".*$$") == 0
|| strcmp(right, "^.*$$") == 0 )
{
- a->acl_dn_pat.bv_val = ch_strdup( "*" );
- a->acl_dn_pat.bv_len = sizeof("*")-1;
+ ber_str2bv( "*", STRLENOF("*"), 1, &a->acl_dn_pat );
} else {
acl_regex_normalized_dn( right, &a->acl_dn_pat );
@@ -398,13 +450,14 @@ parse_acl(
}
} else if ( strncasecmp( left, "val", 3 ) == 0 ) {
- if ( a->acl_attrval.bv_len ) {
+ if ( !BER_BVISEMPTY( &a->acl_attrval ) ) {
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 ) {
+ if ( a->acl_attrs == NULL || !BER_BVISEMPTY( &a->acl_attrs[1].an_name ) )
+ {
fprintf( stderr,
"%s: line %d: attr val requires a single attribute.\n",
fname, lineno );
@@ -455,7 +508,7 @@ parse_acl(
a->acl_attrs[0].an_desc->ad_cname.bv_val );
a->acl_attrval_style = ACL_STYLE_BASE;
}
-
+
} else {
fprintf( stderr,
"%s: line %d: unknown val.