/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2006 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include "lber_pvt.h"
#include "lutil.h"
-#define ACI_BUF_SIZE 1024 /* use most appropriate size */
+/* use most appropriate size */
+#define ACI_BUF_SIZE 1024
-#ifdef SLAP_DYNACL
-static
-#endif /* SLAP_DYNACL */
-AttributeDescription *slap_ad_aci;
+/* move to "stable" when no longer experimental */
+#define SLAPD_ACI_SYNTAX "1.3.6.1.4.1.4203.666.2.1"
+
+/* change this to "OpenLDAPset" */
+#define SLAPD_ACI_SET_ATTR "template"
+
+typedef enum slap_aci_scope_t {
+ SLAP_ACI_SCOPE_ENTRY = 0x1,
+ SLAP_ACI_SCOPE_CHILDREN = 0x2,
+ SLAP_ACI_SCOPE_SUBTREE = ( SLAP_ACI_SCOPE_ENTRY | SLAP_ACI_SCOPE_CHILDREN )
+} slap_aci_scope_t;
+
+enum {
+ ACI_BV_ENTRY,
+ ACI_BV_CHILDREN,
+ ACI_BV_ONELEVEL,
+ ACI_BV_SUBTREE,
+
+ ACI_BV_BR_ENTRY,
+ ACI_BV_BR_ALL,
+
+ ACI_BV_ACCESS_ID,
+ ACI_BV_PUBLIC,
+ ACI_BV_USERS,
+ ACI_BV_SELF,
+ ACI_BV_DNATTR,
+ ACI_BV_GROUP,
+ ACI_BV_ROLE,
+ ACI_BV_SET,
+ ACI_BV_SET_REF,
+
+ ACI_BV_GRANT,
+ ACI_BV_DENY,
+
+ ACI_BV_GROUP_CLASS,
+ ACI_BV_GROUP_ATTR,
+ ACI_BV_ROLE_CLASS,
+ ACI_BV_ROLE_ATTR,
+
+ ACI_BV_SET_ATTR,
+
+ ACI_BV_LAST
+};
+
+static const struct berval aci_bv[] = {
+ /* scope */
+ BER_BVC("entry"),
+ BER_BVC("children"),
+ BER_BVC("onelevel"),
+ BER_BVC("subtree"),
+
+ /* */
+ BER_BVC("[entry]"),
+ BER_BVC("[all]"),
+
+ /* type */
+ BER_BVC("access-id"),
+ BER_BVC("public"),
+ BER_BVC("users"),
+ BER_BVC("self"),
+ BER_BVC("dnattr"),
+ BER_BVC("group"),
+ BER_BVC("role"),
+ BER_BVC("set"),
+ BER_BVC("set-ref"),
+
+ /* actions */
+ BER_BVC("grant"),
+ BER_BVC("deny"),
+
+ /* schema */
+ BER_BVC(SLAPD_GROUP_CLASS),
+ BER_BVC(SLAPD_GROUP_ATTR),
+ BER_BVC(SLAPD_ROLE_CLASS),
+ BER_BVC(SLAPD_ROLE_ATTR),
+
+ BER_BVC(SLAPD_ACI_SET_ATTR),
+
+ BER_BVNULL
+};
+
+static AttributeDescription *slap_ad_aci;
static int
OpenLDAPaciValidate(
return rc;
}
-int
+static int
aci_mask(
Operation *op,
Entry *e,
}
} else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET ], &type ) == 0 ) {
- if ( acl_match_set( &sdn, op, e, 0 ) ) {
+ if ( acl_match_set( &sdn, op, e, NULL ) ) {
return 1;
}
} else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET_REF ], &type ) == 0 ) {
- if ( acl_match_set( &sdn, op, e, 1 ) ) {
+ if ( acl_match_set( &sdn, op, e, (struct berval *)&aci_bv[ ACI_BV_SET_ATTR ] ) ) {
return 1;
}
return 0;
}
-int
+static int
aci_init( void )
{
- /* OpenLDAP Experimental Syntax */
+ /* OpenLDAP eXperimental Syntax */
static slap_syntax_defs_rec aci_syntax_def = {
"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
SLAP_SYNTAX_HIDE,
&rc, &text, LDAP_SCHEMA_ALLOW_ALL );
if ( !at ) {
Debug( LDAP_DEBUG_ANY,
- "%s AttributeType load failed: %s %s\n",
+ "aci_init: AttributeType \"%s\" parse failed: %s %s\n",
aci_at.name, ldap_scherr2str( rc ), text );
return rc;
}
rc = at_add( at, 0, &sat, &text );
if ( rc != LDAP_SUCCESS ) {
ldap_attributetype_free( at );
- fprintf( stderr, "iMUX_monitor_schema_init: "
- "AttributeType load failed: %s %s\n",
- scherr2str( rc ), text );
+ Debug( LDAP_DEBUG_ANY,
+ "aci_init: AttributeType \"%s\" load failed: %s %s\n",
+ aci_at.name, scherr2str( rc ), text );
return rc;
}
ldap_memfree( at );
aci_at.ad, &text );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
- "unable to find AttributeDescription "
+ "aci_init: unable to find AttributeDescription "
"\"%s\": %d (%s)\n",
aci_at.name, rc, text );
return 1;
return rc;
}
-#ifdef SLAP_DYNACL
-/*
- * FIXME: there is a silly dependence that makes it difficult
- * to move ACIs in a run-time loadable module under the "dynacl"
- * umbrella, because sets share some helpers with ACIs.
- */
static int
dynacl_aci_parse(
const char *fname,
char accessmaskbuf1[ACCESSMASK_MAXLEN];
#endif /* LDAP_DEBUG */
+ if ( BER_BVISEMPTY( &e->e_nname ) ) {
+ /* no ACIs in the root DSE */
+ return -1;
+ }
+
/* start out with nothing granted, nothing denied */
ACL_INIT(tgrant);
ACL_INIT(tdeny);
}
}
- Debug( LDAP_DEBUG_ACL, "<= aci_mask grant %s deny %s\n",
+ Debug( LDAP_DEBUG_ACL, " <= aci_mask grant %s deny %s\n",
accessmask2str( tgrant, accessmaskbuf, 1 ),
accessmask2str( tdeny, accessmaskbuf1, 1 ), 0 );
}
if ( tgrant == ACL_PRIV_NONE && tdeny == ACL_PRIV_NONE ) {
struct berval parent_ndn;
-#if 1
- /* to solve the chicken'n'egg problem of accessing
- * the OpenLDAPaci attribute, the direct access
- * to the entry's attribute is unchecked; however,
- * further accesses to OpenLDAPaci values in the
- * ancestors occur through backend_attribute(), i.e.
- * with the identity of the operation, requiring
- * further access checking. For uniformity, this
- * makes further requests occur as the rootdn, if
- * any, i.e. searching for the OpenLDAPaci attribute
- * is considered an internal search. If this is not
- * acceptable, then the same check needs be performed
- * when accessing the entry's attribute. */
- Operation op2 = *op;
-
- if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) {
- op2.o_dn = op->o_bd->be_rootdn;
- op2.o_ndn = op->o_bd->be_rootndn;
- }
-#endif
-
dnParent( &e->e_nname, &parent_ndn );
while ( !BER_BVISEMPTY( &parent_ndn ) ){
int i;
BerVarray bvals = NULL;
int ret, stop;
- Debug( LDAP_DEBUG_ACL, "checking ACI of \"%s\"\n", parent_ndn.bv_val, 0, 0 );
- ret = backend_attribute( &op2, NULL, &parent_ndn, ad, &bvals, ACL_AUTH );
+ /* to solve the chicken'n'egg problem of accessing
+ * the OpenLDAPaci attribute, the direct access
+ * to the entry's attribute is unchecked; however,
+ * further accesses to OpenLDAPaci values in the
+ * ancestors occur through backend_attribute(), i.e.
+ * with the identity of the operation, requiring
+ * further access checking. For uniformity, this
+ * makes further requests occur as the rootdn, if
+ * any, i.e. searching for the OpenLDAPaci attribute
+ * is considered an internal search. If this is not
+ * acceptable, then the same check needs be performed
+ * when accessing the entry's attribute. */
+ struct berval save_o_dn, save_o_ndn;
+
+ if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) {
+ save_o_dn = op->o_dn;
+ save_o_ndn = op->o_ndn;
+
+ op->o_dn = op->o_bd->be_rootdn;
+ op->o_ndn = op->o_bd->be_rootndn;
+ }
+
+ Debug( LDAP_DEBUG_ACL, " checking ACI of \"%s\"\n", parent_ndn.bv_val, 0, 0 );
+ ret = backend_attribute( op, NULL, &parent_ndn, ad, &bvals, ACL_AUTH );
+
+ if ( !BER_BVISNULL( &op->o_bd->be_rootndn ) ) {
+ op->o_dn = save_o_dn;
+ op->o_ndn = save_o_ndn;
+ }
switch ( ret ) {
case LDAP_SUCCESS :
return rc;
}
-#endif /* SLAP_DYNACL */
/* ACI syntax validation */
struct berval ocbv = BER_BVNULL,
atbv = BER_BVNULL;
- ocbv.bv_val = strchr( type.bv_val, '/' );
- if ( ocbv.bv_val != NULL
- && ( ocbv.bv_val - type.bv_val ) < type.bv_len )
- {
+ ocbv.bv_val = ber_bvchr( &type, '/' );
+ if ( ocbv.bv_val != NULL ) {
ocbv.bv_val++;
+ ocbv.bv_len = type.bv_len
+ - ( ocbv.bv_val - type.bv_val );
- atbv.bv_val = strchr( ocbv.bv_val, '/' );
- if ( atbv.bv_val != NULL
- && ( atbv.bv_val - ocbv.bv_val ) < ocbv.bv_len )
- {
+ atbv.bv_val = ber_bvchr( &ocbv, '/' );
+ if ( atbv.bv_val != NULL ) {
AttributeDescription *ad = NULL;
const char *text = NULL;
int rc;
if ( rc != LDAP_SUCCESS ) {
return LDAP_INVALID_SYNTAX;
}
-
- } else {
- ocbv.bv_len = type.bv_len
- - ( ocbv.bv_val - type.bv_val );
}
if ( oc_bvfind( &ocbv ) == NULL ) {
struct berval ocbv = BER_BVNULL,
atbv = BER_BVNULL;
- ocbv.bv_val = strchr( type.bv_val, '/' );
- if ( ocbv.bv_val != NULL
- && ( ocbv.bv_val - type.bv_val ) < type.bv_len )
- {
+ ocbv.bv_val = ber_bvchr( &type, '/' );
+ if ( ocbv.bv_val != NULL ) {
ObjectClass *oc = NULL;
AttributeDescription *ad = NULL;
const char *text = NULL;
bv.bv_len = ntype.bv_len;
ocbv.bv_val++;
+ ocbv.bv_len = type.bv_len - ( ocbv.bv_val - type.bv_val );
- atbv.bv_val = strchr( ocbv.bv_val, '/' );
- if ( atbv.bv_val != NULL
- && ( atbv.bv_val - ocbv.bv_val ) < ocbv.bv_len )
- {
+ atbv.bv_val = ber_bvchr( &ocbv, '/' );
+ if ( atbv.bv_val != NULL ) {
atbv.bv_val++;
atbv.bv_len = type.bv_len
- ( atbv.bv_val - type.bv_val );
}
bv.bv_len += STRLENOF( "/" ) + ad->ad_cname.bv_len;
-
- } else {
- ocbv.bv_len = type.bv_len
- - ( ocbv.bv_val - type.bv_val );
}
oc = oc_bvfind( &ocbv );
int
init_module( int argc, char *argv[] )
{
- return slap_dynacl_register();
+ return dynacl_aci_init();
}
#endif /* SLAPD_ACI_ENABLED == SLAPD_MOD_DYNAMIC */