From 09f88136d0dbd81cb676b9c39b89cb697947837f Mon Sep 17 00:00:00 2001 From: Quanah Gibson-Mount Date: Thu, 15 Apr 2010 22:35:22 +0000 Subject: [PATCH] add support for allowedChildClasses, allowedChildClassesEffective: the former basically consists of all structural objectClasses, the latter is identical if the user can write 'children', absent otherwise --- contrib/slapd-modules/allowed/README | 14 +-- contrib/slapd-modules/allowed/allowed.c | 112 +++++++++++++++++++++--- 2 files changed, 105 insertions(+), 21 deletions(-) diff --git a/contrib/slapd-modules/allowed/README b/contrib/slapd-modules/allowed/README index 197f7a2afc..16a7897765 100644 --- a/contrib/slapd-modules/allowed/README +++ b/contrib/slapd-modules/allowed/README @@ -10,22 +10,14 @@ It adds to entries returned by search operations the value of attributes "allowedAttributesEffective" -No other use is made of those attributes: they cannot be compared, -they cannot be used in search filters, they cannot be used in ACLs, ... - - --- o --- o --- o --- - -Other attributes like - "allowedChildClasses" + "allowedChildClassesEffective" -make little sense within OpenLDAP's slapd right now, since any AUXILIARY -objectClass can be added to an entry, while no STRUCTURAL objectClass can. -This may change when DIT structure rules are implemented, while ACLs may -restrict what AUXILIARY objectClasses can be added to an entry. +No other use is made of those attributes: they cannot be compared, +they cannot be used in search filters, they cannot be used in ACLs, ... --- o --- o --- o --- diff --git a/contrib/slapd-modules/allowed/allowed.c b/contrib/slapd-modules/allowed/allowed.c index f562d987ae..ad22caa4bf 100644 --- a/contrib/slapd-modules/allowed/allowed.c +++ b/contrib/slapd-modules/allowed/allowed.c @@ -176,9 +176,6 @@ aa_operational( Operation *op, SlapReply *rs ) struct berval *v; AttributeType **atp = NULL; ObjectClass **ocp = NULL; - BerVarray bv_allowed = NULL, - bv_effective = NULL; - int i, ja = 0, je = 0; #define GOT_NONE (0x0U) #define GOT_C (0x1U) @@ -217,10 +214,13 @@ aa_operational( Operation *op, SlapReply *rs ) /* shouldn't be called without an entry; please check */ assert( rs->sr_entry != NULL ); + for ( ap = &rs->sr_operational_attrs; *ap != NULL; ap = &(*ap)->a_next ) + /* go to last */ ; + /* see caveats; this is not guaranteed for all backends */ a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_objectClass ); if ( a == NULL ) { - return SLAP_CB_CONTINUE; + goto do_oc; } /* if client has no access to objectClass attribute; don't compute */ @@ -246,13 +246,21 @@ aa_operational( Operation *op, SlapReply *rs ) aa_add_oc( oc, &ocp, &atp ); if ( oc->soc_sups ) { + int i; + for ( i = 0; oc->soc_sups[ i ] != NULL; i++ ) { aa_add_oc( oc->soc_sups[ i ], &ocp, &atp ); } } } + ch_free( ocp ); + if ( atp != NULL ) { + BerVarray bv_allowed = NULL, + bv_effective = NULL; + int i, ja = 0, je = 0; + for ( i = 0; atp[ i ] != NULL; i++ ) /* just count */ ; @@ -287,8 +295,7 @@ aa_operational( Operation *op, SlapReply *rs ) } } - for ( ap = &rs->sr_operational_attrs; *ap != NULL; ap = &(*ap)->a_next ) - /* go to last */ ; + ch_free( atp ); if ( ( got & GOT_A ) && ja > 0 ) { BER_BVZERO( &bv_allowed[ ja ] ); @@ -298,7 +305,7 @@ aa_operational( Operation *op, SlapReply *rs ) (*ap)->a_numvals = ja; ap = &(*ap)->a_next; } - + if ( ( got & GOT_AE ) && je > 0 ) { BER_BVZERO( &bv_effective[ je ] ); *ap = attr_alloc( ad_allowedAttributesEffective ); @@ -307,12 +314,97 @@ aa_operational( Operation *op, SlapReply *rs ) (*ap)->a_numvals = je; ap = &(*ap)->a_next; } - + *ap = NULL; } - ch_free( atp ); - ch_free( ocp ); +do_oc:; + if ( ( got & GOT_C ) || ( got & GOT_CE ) ) { + BerVarray bv_allowed = NULL, + bv_effective = NULL; + int i, ja = 0, je = 0; + + ObjectClass *oc; + + for ( oc_start( &oc ); oc != NULL; oc_next( &oc ) ) { + /* we can only add AUXILIARY objectClasses */ + if ( oc->soc_kind != LDAP_SCHEMA_AUXILIARY ) { + continue; + } + + i++; + } + + if ( got & GOT_C ) { + bv_allowed = ber_memalloc( sizeof( struct berval ) * ( i + 1 ) ); + } + if ( got & GOT_CE ) { + bv_effective = ber_memalloc( sizeof( struct berval ) * ( i + 1 ) ); + } + + for ( oc_start( &oc ); oc != NULL; oc_next( &oc ) ) { + /* we can only add AUXILIARY objectClasses */ + if ( oc->soc_kind != LDAP_SCHEMA_AUXILIARY ) { + continue; + } + + if ( got & GOT_C ) { + ber_dupbv( &bv_allowed[ ja ], &oc->soc_cname ); + ja++; + } + + if ( got & GOT_CE ) { + if ( !access_allowed( op, rs->sr_entry, + slap_schema.si_ad_objectClass, + &oc->soc_cname, ACL_WRITE, NULL ) ) + { + goto done_ce; + } + + if ( oc->soc_required ) { + for ( i = 0; oc->soc_required[ i ] != NULL; i++ ) { + AttributeDescription *ad = NULL; + const char *text = NULL; + + if ( slap_bv2ad( &oc->soc_required[ i ]->sat_cname, &ad, &text ) ) { + /* log? */ + continue; + } + + if ( !access_allowed( op, rs->sr_entry, + ad, NULL, ACL_WRITE, NULL ) ) + { + goto done_ce; + } + } + } + + ber_dupbv( &bv_effective[ je ], &oc->soc_cname ); + je++; + } +done_ce:; + } + + if ( ( got & GOT_C ) && ja > 0 ) { + BER_BVZERO( &bv_allowed[ ja ] ); + *ap = attr_alloc( ad_allowedChildClasses ); + (*ap)->a_vals = bv_allowed; + (*ap)->a_nvals = bv_allowed; + (*ap)->a_numvals = ja; + ap = &(*ap)->a_next; + } + + if ( ( got & GOT_CE ) && je > 0 ) { + BER_BVZERO( &bv_effective[ je ] ); + *ap = attr_alloc( ad_allowedChildClassesEffective ); + (*ap)->a_vals = bv_effective; + (*ap)->a_nvals = bv_effective; + (*ap)->a_numvals = je; + ap = &(*ap)->a_next; + } + + *ap = NULL; + } return SLAP_CB_CONTINUE; } -- 2.39.5