check_scope( BackendDB *be, AccessControl *a );
#endif /* LDAP_DEVEL */
+#ifdef SLAP_DYNACL
+static int
+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) {
int e;
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 "<suffix>$" */
AC_MEMCPY( dnbuf, be->be_nsuffix[0].bv_val,
be->be_nsuffix[0].bv_len );
dnbuf[be->be_nsuffix[0].bv_len] = '$';
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;
}
/* 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;
ber_str2bv("self", STRLENOF( "self" ), 1, &bv);
sty = ACL_STYLE_SELF;
- } else if ( strcasecmp( argv[i], "creator" ) == 0 ) {
- ber_str2bv("creator", STRLENOF( "creator" ), 1, &bv);
- sty = ACL_STYLE_CREATOR;
-
} else if ( strcasecmp( left, "dn" ) == 0 ) {
if ( sty == ACL_STYLE_REGEX ) {
b->a_dn_style = ACL_STYLE_REGEX;
sty != ACL_STYLE_ANONYMOUS &&
sty != ACL_STYLE_USERS &&
sty != ACL_STYLE_SELF &&
- sty != ACL_STYLE_CREATOR &&
expand == 0 )
{
rc = dnNormalize(0, NULL, NULL,
acl_usage();
}
- if ( BER_BVISEMPTY( &b->a_peername_pat ) ) {
+ if ( !BER_BVISEMPTY( &b->a_peername_pat ) ) {
fprintf( stderr, "%s: line %d: "
"peername pattern already specified.\n",
fname, lineno );
continue;
}
+#ifdef SLAP_DYNACL
+ {
+ char *name = NULL;
+
+ if ( strcasecmp( left, "aci" ) == 0 ) {
+ name = "aci";
+
+ } else if ( strncasecmp( left, "dynacl/", STRLENOF( "dynacl/" ) ) == 0 ) {
+ name = &left[ STRLENOF( "dynacl/" ) ];
+ }
+
+ if ( name ) {
+ if ( slap_dynacl_config( fname, lineno, b, name, sty, right ) ) {
+ fprintf( stderr, "%s: line %d: "
+ "unable to configure dynacl \"%s\"\n",
+ fname, lineno, name );
+ acl_usage();
+ }
+
+ continue;
+ }
+ }
+#else /* ! SLAP_DYNACL */
+
#ifdef SLAPD_ACI_ENABLED
if ( strcasecmp( left, "aci" ) == 0 ) {
if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) {
continue;
}
#endif /* SLAPD_ACI_ENABLED */
+#endif /* ! SLAP_DYNACL */
if ( strcasecmp( left, "ssf" ) == 0 ) {
if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
if ( be != NULL ) {
#ifdef LDAP_DEVEL
+ if ( !BER_BVISNULL( &be->be_nsuffix[ 1 ] ) ) {
+ fprintf( stderr, "%s: line %d: warning: "
+ "scope checking only applies to single-valued "
+ "suffix databases\n",
+ fname, lineno );
+ /* go ahead, since checking is not authoritative */
+ }
+
switch ( check_scope( be, a ) ) {
case ACL_SCOPE_UNKNOWN:
fprintf( stderr, "%s: line %d: warning: "
"<what> ::= * | [dn[.<dnstyle>]=<DN>] [filter=<filter>] [attrs=<attrlist>]\n"
"<attrlist> ::= <attr> [val[.<style>]=<value>] | <attr> , <attrlist>\n"
"<attr> ::= <attrname> | entry | children\n",
- "<who> ::= [ * | anonymous | users | self | creator | dn[.<dnstyle>]=<DN> ]\n"
+ "<who> ::= [ * | anonymous | users | self | dn[.<dnstyle>]=<DN> ]\n"
"\t[dnattr=<attrname>]\n"
"\t[group[/<objectclass>[/<attrname>]][.<style>]=<group>]\n"
"\t[peername[.<peernamestyle>]=<peer>] [sockname[.<style>]=<name>]\n"
if ( ber_bvccmp( &b->a_dn_pat, '*' ) ||
b->a_dn_style == ACL_STYLE_ANONYMOUS /* strcmp( b->a_dn_pat.bv_val, "anonymous" ) == 0 */ ||
b->a_dn_style == ACL_STYLE_USERS /* strcmp( b->a_dn_pat.bv_val, "users" ) == 0 */ ||
- b->a_dn_style == ACL_STYLE_SELF /* strcmp( b->a_dn_pat.bv_val, "self" ) == 0 */ ||
- b->a_dn_style == ACL_STYLE_CREATOR /* strcmp( b->a_dn_pat.bv_val, "creator" ) == 0 */ )
+ b->a_dn_style == ACL_STYLE_SELF /* strcmp( b->a_dn_pat.bv_val, "self" ) == 0 */ )
{
fprintf( stderr, " %s", b->a_dn_pat.bv_val );
fprintf( stderr, " set=\"%s\"", b->a_set_pat.bv_val );
}
+#ifdef SLAP_DYNACL
+ if ( b->a_dynacl ) {
+ slap_dynacl_t *da;
+
+ for ( da = b->a_dynacl; da; da = da->da_next ) {
+ if ( da->da_print ) {
+ (void)( *da->da_print )( da->da_private );
+ }
+ }
+ }
+#else /* ! SLAP_DYNACL */
#ifdef SLAPD_ACI_ENABLED
if ( b->a_aci_at != NULL ) {
fprintf( stderr, " aci=%s", b->a_aci_at->ad_cname.bv_val );
}
#endif
+#endif /* SLAP_DYNACL */
/* Security Strength Factors */
if ( b->a_authz.sai_ssf ) {
if ( ! first ) fprintf( stderr, "," );
if (an->an_oc) {
fputc( an->an_oc_exclude ? '!' : '@', stderr);
+ fputs( an->an_oc->soc_cname.bv_val, stderr );
+
+ } else {
+ fputs( an->an_name.bv_val, stderr );
}
- fputs( an->an_name.bv_val, stderr );
first = 0;
}
fprintf( stderr, "\n" );