X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Faci.c;h=97276cfc0b625b26c83aa1e33c093b1ada4a2482;hb=58886b6a9c7c6b8e9e829fe24fe057e5a77b6117;hp=a77a9fb3ceefedb1667701975ef8556f5f6ac143;hpb=3ee954de818f9558ef0175104ec6c96deaca0b63;p=openldap diff --git a/servers/slapd/aci.c b/servers/slapd/aci.c index a77a9fb3ce..97276cfc0b 100644 --- a/servers/slapd/aci.c +++ b/servers/slapd/aci.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * 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 @@ -40,12 +40,93 @@ #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( @@ -197,14 +278,18 @@ aci_list_get_attr_rights( 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 rightsk\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; @@ -212,22 +297,22 @@ aci_list_get_attr_rights( 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); @@ -321,7 +406,7 @@ done: return rc; } -int +static int aci_mask( Operation *op, Entry *e, @@ -554,12 +639,12 @@ aci_mask( } } 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; } @@ -571,10 +656,10 @@ aci_mask( 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, @@ -605,10 +690,7 @@ aci_init( void ) &slap_ad_aci }; - LDAPAttributeType *at; - AttributeType *sat; int rc; - const char *text; /* ACI syntax */ rc = register_syntax( &aci_syntax_def ); @@ -623,47 +705,19 @@ aci_init( void ) } /* 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, @@ -744,6 +798,11 @@ dynacl_aci_mask( 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); @@ -767,7 +826,7 @@ dynacl_aci_mask( } } - 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 ); } @@ -779,35 +838,41 @@ dynacl_aci_mask( 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 : @@ -895,7 +960,6 @@ dynacl_aci_init( void ) return rc; } -#endif /* SLAP_DYNACL */ /* ACI syntax validation */ @@ -945,16 +1009,17 @@ bv_get_tail( * 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( @@ -973,6 +1038,7 @@ 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; } @@ -986,6 +1052,7 @@ OpenLDAPaciValidatePerms( 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; } @@ -1014,6 +1081,7 @@ OpenLDAPaciValidateRight( 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; } @@ -1027,16 +1095,36 @@ OpenLDAPaciValidateRight( } 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; + } + } } } } @@ -1046,6 +1134,7 @@ OpenLDAPaciValidateRight( 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; } @@ -1066,16 +1155,20 @@ OpenLDAPaciNormalizeRight( /* 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 ) @@ -1090,25 +1183,76 @@ OpenLDAPaciNormalizeRight( /* 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 ]; @@ -1117,10 +1261,13 @@ OpenLDAPaciNormalizeRight( 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 ); + } } } @@ -1129,6 +1276,7 @@ OpenLDAPaciNormalizeRight( 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; } } @@ -1238,8 +1386,10 @@ OpenLDAPaciValidate( 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; } @@ -1251,6 +1401,7 @@ OpenLDAPaciValidate( * 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; } @@ -1258,6 +1409,7 @@ OpenLDAPaciValidate( 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; } @@ -1270,6 +1422,7 @@ OpenLDAPaciValidate( /* 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 ); @@ -1277,11 +1430,13 @@ OpenLDAPaciValidate( 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; } } @@ -1289,6 +1444,7 @@ OpenLDAPaciValidate( /* 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; } @@ -1296,15 +1452,16 @@ OpenLDAPaciValidate( 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; } } @@ -1319,16 +1476,14 @@ OpenLDAPaciValidate( 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; @@ -1340,15 +1495,13 @@ OpenLDAPaciValidate( 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; } } @@ -1356,6 +1509,7 @@ OpenLDAPaciValidate( 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; } @@ -1363,7 +1517,11 @@ OpenLDAPaciValidate( 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 @@ -1388,6 +1546,7 @@ OpenLDAPaciPrettyNormal( char *ptr; if ( BER_BVISEMPTY( val ) ) { + Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: value is empty\n", 0, 0, 0 ); return LDAP_INVALID_SYNTAX; } @@ -1395,21 +1554,25 @@ OpenLDAPaciPrettyNormal( 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 ) @@ -1420,6 +1583,7 @@ OpenLDAPaciPrettyNormal( /* 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; } @@ -1428,12 +1592,14 @@ OpenLDAPaciPrettyNormal( 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; } @@ -1444,6 +1610,7 @@ OpenLDAPaciPrettyNormal( 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; } @@ -1464,6 +1631,7 @@ OpenLDAPaciPrettyNormal( freesubject = 1; } else { + Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid subject dn '%s'\n", subject.bv_val, 0, 0 ); goto cleanup; } @@ -1474,10 +1642,8 @@ OpenLDAPaciPrettyNormal( 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; @@ -1487,11 +1653,10 @@ OpenLDAPaciPrettyNormal( 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 ); @@ -1499,19 +1664,17 @@ OpenLDAPaciPrettyNormal( 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; } @@ -1547,12 +1710,14 @@ OpenLDAPaciPrettyNormal( 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; } @@ -1564,7 +1729,7 @@ OpenLDAPaciPrettyNormal( 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; @@ -1632,7 +1797,7 @@ OpenLDAPaciNormalize( int init_module( int argc, char *argv[] ) { - return slap_dynacl_register(); + return dynacl_aci_init(); } #endif /* SLAPD_ACI_ENABLED == SLAPD_MOD_DYNAMIC */