X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Faci.c;h=28b99388ea2381f791e423411a116c095f774b8f;hb=72d2ee4d19ee76e7d81d402c4056ce665f797045;hp=a77a9fb3ceefedb1667701975ef8556f5f6ac143;hpb=3ee954de818f9558ef0175104ec6c96deaca0b63;p=openldap diff --git a/servers/slapd/aci.c b/servers/slapd/aci.c index a77a9fb3ce..28b99388ea 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,91 @@ #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( @@ -321,7 +400,7 @@ done: return rc; } -int +static int aci_mask( Operation *op, Entry *e, @@ -554,12 +633,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 +650,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, @@ -627,7 +706,7 @@ aci_init( void ) &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; } @@ -635,9 +714,9 @@ aci_init( void ) 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 ); @@ -646,7 +725,7 @@ aci_init( void ) 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; @@ -658,12 +737,6 @@ aci_init( void ) 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 +817,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 +845,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 +857,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 +979,6 @@ dynacl_aci_init( void ) return rc; } -#endif /* SLAP_DYNACL */ /* ACI syntax validation */ @@ -1319,16 +1402,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; @@ -1342,10 +1423,6 @@ OpenLDAPaciValidate( 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 ) { @@ -1474,10 +1551,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 +1562,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 ); @@ -1504,10 +1578,6 @@ OpenLDAPaciPrettyNormal( } 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 ); @@ -1632,7 +1702,7 @@ OpenLDAPaciNormalize( int init_module( int argc, char *argv[] ) { - return slap_dynacl_register(); + return dynacl_aci_init(); } #endif /* SLAPD_ACI_ENABLED == SLAPD_MOD_DYNAMIC */