/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2007 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_CHILDREN,
+ 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("[children]"),
+ 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(
ACL_INIT(mask);
for ( i = 1; acl_get_part( list, i + 1, ';', &bv ) >= 0; i += 2 ) {
if ( aci_list_has_attr( &bv, attr, val ) == 0 ) {
+ Debug( LDAP_DEBUG_ACL,
+ " <= aci_list_get_attr_rights "
+ "test %s for %s -> failed\n",
+ bv.bv_val, attr->bv_val, 0 );
continue;
}
+ Debug( LDAP_DEBUG_ACL,
+ " <= aci_list_get_attr_rights "
+ "test %s for %s -> ok\n",
+ bv.bv_val, attr->bv_val, 0 );
+
if ( acl_get_part( list, i, ';', &bv ) < 0 ) {
+ Debug( LDAP_DEBUG_ACL,
+ " <= aci_list_get_attr_rights "
+ "test no rights\n",
+ 0, 0, 0 );
continue;
}
mask |= aci_list_map_rights( &bv );
+ Debug( LDAP_DEBUG_ACL,
+ " <= aci_list_get_attr_rights "
+ "rights %s to mask 0x%x\n",
+ bv.bv_val, mask, 0 );
}
return mask;
static int
aci_list_get_rights(
- struct berval *list,
- const struct berval *attr,
- struct berval *val,
- slap_access_t *grant,
- slap_access_t *deny )
+ struct berval *list,
+ struct berval *attr,
+ struct berval *val,
+ slap_access_t *grant,
+ slap_access_t *deny )
{
- struct berval perm, actn;
+ struct berval perm, actn, baseattr;
slap_access_t *mask;
int i, found;
- if ( attr == NULL || BER_BVISEMPTY( attr )
- || ber_bvstrcasecmp( attr, &aci_bv[ ACI_BV_ENTRY ] ) == 0 )
- {
- attr = &aci_bv[ ACI_BV_BR_ENTRY ];
- }
+ if ( attr == NULL || BER_BVISEMPTY( attr ) ) {
+ attr = (struct berval *)&aci_bv[ ACI_BV_ENTRY ];
+ } else if ( acl_get_part( attr, 0, ';', &baseattr ) > 0 ) {
+ attr = &baseattr;
+ }
found = 0;
ACL_INIT(*grant);
ACL_INIT(*deny);
return rc;
}
-int
+static int
aci_mask(
Operation *op,
Entry *e,
This routine now supports scope={ENTRY,CHILDREN}
with the semantics:
- ENTRY applies to "entry" and "subtree";
- - CHILDREN aplies to "children" and "subtree"
+ - CHILDREN applies to "children" and "subtree"
*/
/* check that the aci has all 5 components */
}
} 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,
+ NULL,
OpenLDAPaciValidate,
OpenLDAPaciPretty
};
&slap_ad_aci
};
- LDAPAttributeType *at;
- AttributeType *sat;
int rc;
- const char *text;
/* ACI syntax */
rc = register_syntax( &aci_syntax_def );
}
/* ACI attribute */
- at = ldap_str2attributetype( aci_at.desc,
- &rc, &text, LDAP_SCHEMA_ALLOW_ALL );
- if ( !at ) {
- Debug( LDAP_DEBUG_ANY,
- "%s AttributeType load 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 );
- return rc;
- }
- ldap_memfree( at );
-
- rc = slap_str2ad( aci_at.name,
- aci_at.ad, &text );
+ rc = register_at( aci_at.desc, aci_at.ad, 0 );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
- "unable to find AttributeDescription "
- "\"%s\": %d (%s)\n",
- aci_at.name, rc, text );
- return 1;
+ "aci_init: at_register failed\n", 0, 0, 0 );
+ return rc;
}
/* install flags */
- sat->sat_flags |= aci_at.flags;
+ (*aci_at.ad)->ad_type->sat_flags |= aci_at.flags;
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 */
* aci is accepted in following form:
* oid#scope#rights#type#subject
* Where:
- * oid := numeric OID
- * scope := entry|children
+ * oid := numeric OID (currently ignored)
+ * scope := entry|children|subtree
* rights := right[[$right]...]
* right := (grant|deny);action
- * action := perms;attr[[;perms;attr]...]
+ * action := perms;attrs[[;perms;attrs]...]
* perms := perm[[,perm]...]
* perm := c|s|r|w|x
- * attr := attributeType|[all]
- * type := public|users|self|dnattr|group|role|set|set-ref|
- * access_id|subtree|onelevel|children
+ * attrs := attribute[[,attribute]..]|"[all]"
+ * attribute := attributeType|attributeType=attributeValue|attributeType=attributeValuePrefix*
+ * type := public|users|self|dnattr|group|role|set|set-ref|
+ * access_id|subtree|onelevel|children
*/
static int
OpenLDAPaciValidatePerms(
break;
default:
+ Debug( LDAP_DEBUG_ACL, "aciValidatePerms: perms needs to be one of x,d,c,s,r,w in '%s'\n", perms->bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
assert( i != perms->bv_len );
if ( perms->bv_val[ i ] != ',' ) {
+ Debug( LDAP_DEBUG_ACL, "aciValidatePerms: missing comma in '%s'\n", perms->bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
if ( acl_get_part( action, 0, ';', &bv ) < 0 ||
bv_getcaseidx( &bv, ACIgrantdeny ) == -1 )
{
+ Debug( LDAP_DEBUG_ACL, "aciValidateRight: '%s' must be either 'grant' or 'deny'\n", bv.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
} else {
/* attr */
- AttributeDescription *ad = NULL;
- const char *text = NULL;
+ AttributeDescription *ad;
+ const char *text;
+ struct berval attr, left, right;
+ int j;
/* could be "[all]" or an attribute description */
if ( ber_bvstrcasecmp( &bv, &aci_bv[ ACI_BV_BR_ALL ] ) == 0 ) {
continue;
}
- if ( slap_bv2ad( &bv, &ad, &text ) != LDAP_SUCCESS ) {
- return LDAP_INVALID_SYNTAX;
+
+ for ( j = 0; acl_get_part( &bv, j, ',', &attr ) >= 0; j++ )
+ {
+ ad = NULL;
+ text = NULL;
+ if ( acl_get_part( &attr, 0, '=', &left ) < 0
+ || acl_get_part( &attr, 1, '=', &right ) < 0 )
+ {
+ if ( slap_bv2ad( &attr, &ad, &text ) != LDAP_SUCCESS )
+ {
+ Debug( LDAP_DEBUG_ACL, "aciValidateRight: unknown attribute: '%s'\n", attr.bv_val, 0, 0 );
+ return LDAP_INVALID_SYNTAX;
+ }
+ } else {
+ if ( slap_bv2ad( &left, &ad, &text ) != LDAP_SUCCESS )
+ {
+ Debug( LDAP_DEBUG_ACL, "aciValidateRight: unknown attribute: '%s'\n", left.bv_val, 0, 0 );
+ return LDAP_INVALID_SYNTAX;
+ }
+ }
}
}
}
return LDAP_SUCCESS;
} else {
+ Debug( LDAP_DEBUG_ACL, "aciValidateRight: perms:attr need to be pairs in '%s'\n", action->bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
/* grant|deny */
if ( acl_get_part( action, 0, ';', &grantdeny ) < 0 ) {
+ Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: missing ';' in '%s'\n", action->bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
idx = bv_getcaseidx( &grantdeny, ACIgrantdeny );
if ( idx == -1 ) {
+ Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: '%s' must be grant or deny\n", grantdeny.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
ber_dupbv_x( naction, (struct berval *)ACIgrantdeny[ idx ], ctx );
for ( i = 1; acl_get_part( action, i, ';', &bv ) >= 0; i++ ) {
+ struct berval nattrs = BER_BVNULL;
+ int freenattrs = 1;
if ( i & 1 ) {
/* perms */
if ( OpenLDAPaciValidatePerms( &bv ) != LDAP_SUCCESS )
/* could be "[all]" or an attribute description */
if ( ber_bvstrcasecmp( &bv, &aci_bv[ ACI_BV_BR_ALL ] ) == 0 ) {
- bv = aci_bv[ ACI_BV_BR_ALL ];
+ nattrs = aci_bv[ ACI_BV_BR_ALL ];
+ freenattrs = 0;
} else {
AttributeDescription *ad = NULL;
+ AttributeDescription adstatic= { 0 };
const char *text = NULL;
- int rc;
+ struct berval attr, left, right;
+ int j;
+ int len;
- rc = slap_bv2ad( &bv, &ad, &text );
- if ( rc != LDAP_SUCCESS ) {
- return LDAP_INVALID_SYNTAX;
+ for ( j = 0; acl_get_part( &bv, j, ',', &attr ) >= 0; j++ )
+ {
+ ad = NULL;
+ text = NULL;
+ /* openldap 2.1 aci compabitibility [entry] -> entry */
+ if ( ber_bvstrcasecmp( &attr, &aci_bv[ ACI_BV_BR_ENTRY ] ) == 0 ) {
+ ad = &adstatic;
+ adstatic.ad_cname = aci_bv[ ACI_BV_ENTRY ];
+
+ /* openldap 2.1 aci compabitibility [children] -> children */
+ } else if ( ber_bvstrcasecmp( &attr, &aci_bv[ ACI_BV_BR_CHILDREN ] ) == 0 ) {
+ ad = &adstatic;
+ adstatic.ad_cname = aci_bv[ ACI_BV_CHILDREN ];
+
+ /* openldap 2.1 aci compabitibility [all] -> only [all] */
+ } else if ( ber_bvstrcasecmp( &attr, &aci_bv[ ACI_BV_BR_ALL ] ) == 0 ) {
+ ber_memfree_x( nattrs.bv_val, ctx );
+ nattrs = aci_bv[ ACI_BV_BR_ALL ];
+ freenattrs = 0;
+ break;
+
+ } else if ( acl_get_part( &attr, 0, '=', &left ) < 0
+ || acl_get_part( &attr, 1, '=', &right ) < 0 )
+ {
+ if ( slap_bv2ad( &attr, &ad, &text ) != LDAP_SUCCESS )
+ {
+ ber_memfree_x( nattrs.bv_val, ctx );
+ Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: unknown attribute: '%s'\n", attr.bv_val, 0, 0 );
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ } else {
+ if ( slap_bv2ad( &left, &ad, &text ) != LDAP_SUCCESS )
+ {
+ ber_memfree_x( nattrs.bv_val, ctx );
+ Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: unknown attribute: '%s'\n", left.bv_val, 0, 0 );
+ return LDAP_INVALID_SYNTAX;
+ }
+ }
+
+
+ len = nattrs.bv_len + ( !BER_BVISEMPTY( &nattrs ) ? STRLENOF( "," ) : 0 )
+ + ad->ad_cname.bv_len;
+ nattrs.bv_val = ber_memrealloc_x( nattrs.bv_val, len + 1, ctx );
+ ptr = &nattrs.bv_val[ nattrs.bv_len ];
+ if ( !BER_BVISEMPTY( &nattrs ) ) {
+ *ptr++ = ',';
+ }
+ ptr = lutil_strncopy( ptr, ad->ad_cname.bv_val, ad->ad_cname.bv_len );
+ ptr[ 0 ] = '\0';
+ nattrs.bv_len = len;
}
- bv = ad->ad_cname;
}
naction->bv_val = ber_memrealloc_x( naction->bv_val,
naction->bv_len + STRLENOF( ";" )
+ perms.bv_len + STRLENOF( ";" )
- + bv.bv_len + 1,
+ + nattrs.bv_len + 1,
ctx );
ptr = &naction->bv_val[ naction->bv_len ];
ptr = lutil_strncopy( ptr, perms.bv_val, perms.bv_len );
ptr[ 0 ] = ';';
ptr++;
- ptr = lutil_strncopy( ptr, bv.bv_val, bv.bv_len );
+ ptr = lutil_strncopy( ptr, nattrs.bv_val, nattrs.bv_len );
ptr[ 0 ] = '\0';
naction->bv_len += STRLENOF( ";" ) + perms.bv_len
- + STRLENOF( ";" ) + bv.bv_len;
+ + STRLENOF( ";" ) + nattrs.bv_len;
+ if ( freenattrs ) {
+ ber_memfree_x( nattrs.bv_val, ctx );
+ }
}
}
return LDAP_SUCCESS;
} else {
+ Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: perms:attr need to be pairs in '%s'\n", action->bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
}
type = BER_BVNULL,
subject = BER_BVNULL;
int idx;
-
+ int rc;
+
if ( BER_BVISEMPTY( val ) ) {
+ Debug( LDAP_DEBUG_ACL, "aciValidatet: value is empty\n", 0, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
* I'd replace it with X-ORDERED VALUES so that
* it's guaranteed values are maintained and used
* in the desired order */
+ Debug( LDAP_DEBUG_ACL, "aciValidate: invalid oid '%s'\n", oid.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
if ( acl_get_part( val, 1, '#', &scope ) < 0 ||
bv_getcaseidx( &scope, OpenLDAPaciscopes ) == -1 )
{
+ Debug( LDAP_DEBUG_ACL, "aciValidate: invalid scope '%s'\n", scope.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
/* type */
if ( acl_get_part( val, 3, '#', &type ) < 0 ) {
+ Debug( LDAP_DEBUG_ACL, "aciValidate: missing type in '%s'\n", val->bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
idx = bv_getcaseidx( &type, OpenLDAPacitypes );
struct berval isgr;
if ( acl_get_part( &type, 0, '/', &isgr ) < 0 ) {
+ Debug( LDAP_DEBUG_ACL, "aciValidate: invalid type '%s'\n", type.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
idx = bv_getcaseidx( &isgr, OpenLDAPacitypes );
if ( idx == -1 || idx >= LAST_OPTIONAL ) {
+ Debug( LDAP_DEBUG_ACL, "aciValidate: invalid type '%s'\n", isgr.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
}
/* subject */
bv_get_tail( val, &type, &subject );
if ( subject.bv_val[ 0 ] != '#' ) {
+ Debug( LDAP_DEBUG_ACL, "aciValidate: missing subject in '%s'\n", val->bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
if ( OpenLDAPacitypes[ idx ] == &aci_bv[ ACI_BV_DNATTR ] ) {
AttributeDescription *ad = NULL;
const char *text = NULL;
- int rc;
rc = slap_bv2ad( &subject, &ad, &text );
if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_ACL, "aciValidate: unknown dn attribute '%s'\n", subject.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
if ( ad->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) {
/* FIXME: allow nameAndOptionalUID? */
+ Debug( LDAP_DEBUG_ACL, "aciValidate: wrong syntax for dn attribute '%s'\n", subject.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
}
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;
rc = slap_bv2ad( &atbv, &ad, &text );
if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_ACL, "aciValidate: unknown group attribute '%s'\n", atbv.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
-
- } else {
- ocbv.bv_len = type.bv_len
- - ( ocbv.bv_val - type.bv_val );
}
if ( oc_bvfind( &ocbv ) == NULL ) {
+ Debug( LDAP_DEBUG_ACL, "aciValidate: unknown group '%s'\n", ocbv.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
}
if ( BER_BVISEMPTY( &subject ) ) {
/* empty DN invalid */
+ Debug( LDAP_DEBUG_ACL, "aciValidate: missing dn in '%s'\n", val->bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
subject.bv_len--;
/* FIXME: pass DN syntax? */
- return dnValidate( NULL, &subject );
+ rc = dnValidate( NULL, &subject );
+ if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_ACL, "aciValidate: invalid dn '%s'\n", subject.bv_val, 0, 0 );
+ }
+ return rc;
}
static int
freetype = 0;
char *ptr;
+ BER_BVZERO( out );
+
if ( BER_BVISEMPTY( val ) ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: value is empty\n", 0, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
if ( acl_get_part( val, 0, '#', &oid ) < 0 ||
numericoidValidate( NULL, &oid ) != LDAP_SUCCESS )
{
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid oid '%s'\n", oid.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
/* scope: normalize by replacing with OpenLDAPaciscopes */
if ( acl_get_part( val, 1, '#', &scope ) < 0 ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing scope in '%s'\n", val->bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
idx = bv_getcaseidx( &scope, OpenLDAPaciscopes );
if ( idx == -1 ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid scope '%s'\n", scope.bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
scope = *OpenLDAPaciscopes[ idx ];
/* rights */
if ( acl_get_part( val, 2, '#', &rights ) < 0 ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing rights in '%s'\n", val->bv_val, 0, 0 );
return LDAP_INVALID_SYNTAX;
}
if ( OpenLDAPaciNormalizeRights( &rights, &nrights, ctx )
/* type */
if ( acl_get_part( val, 3, '#', &type ) < 0 ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing type in '%s'\n", val->bv_val, 0, 0 );
rc = LDAP_INVALID_SYNTAX;
goto cleanup;
}
struct berval isgr;
if ( acl_get_part( &type, 0, '/', &isgr ) < 0 ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid type '%s'\n", type.bv_val, 0, 0 );
rc = LDAP_INVALID_SYNTAX;
goto cleanup;
}
idx = bv_getcaseidx( &isgr, OpenLDAPacitypes );
if ( idx == -1 || idx >= LAST_OPTIONAL ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid type '%s'\n", isgr.bv_val, 0, 0 );
rc = LDAP_INVALID_SYNTAX;
goto cleanup;
}
bv_get_tail( val, &type, &subject );
if ( BER_BVISEMPTY( &subject ) || subject.bv_val[ 0 ] != '#' ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing subject in '%s'\n", val->bv_val, 0, 0 );
rc = LDAP_INVALID_SYNTAX;
goto cleanup;
}
freesubject = 1;
} else {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid subject dn '%s'\n", subject.bv_val, 0, 0 );
goto cleanup;
}
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 );
rc = slap_bv2ad( &atbv, &ad, &text );
if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: unknown group attribute '%s'\n", atbv.bv_val, 0, 0 );
rc = LDAP_INVALID_SYNTAX;
goto cleanup;
}
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 );
if ( oc == NULL ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid group '%s'\n", ocbv.bv_val, 0, 0 );
rc = LDAP_INVALID_SYNTAX;
goto cleanup;
}
rc = slap_bv2ad( &subject, &ad, &text );
if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: unknown dn attribute '%s'\n", subject.bv_val, 0, 0 );
rc = LDAP_INVALID_SYNTAX;
goto cleanup;
}
if ( ad->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) {
/* FIXME: allow nameAndOptionalUID? */
+ Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: wrong syntax for dn attribute '%s'\n", subject.bv_val, 0, 0 );
rc = LDAP_INVALID_SYNTAX;
goto cleanup;
}
out->bv_len =
oid.bv_len + STRLENOF( "#" )
+ scope.bv_len + STRLENOF( "#" )
- + rights.bv_len + STRLENOF( "#" )
+ + nrights.bv_len + STRLENOF( "#" )
+ ntype.bv_len + STRLENOF( "#" )
+ nsubject.bv_len;
int
init_module( int argc, char *argv[] )
{
- return slap_dynacl_register();
+ return dynacl_aci_init();
}
#endif /* SLAPD_ACI_ENABLED == SLAPD_MOD_DYNAMIC */