]> git.sur5r.net Git - openldap/commitdiff
add support for allowedChildClasses, allowedChildClassesEffective: the former basical...
authorQuanah Gibson-Mount <quanah@openldap.org>
Thu, 15 Apr 2010 22:35:22 +0000 (22:35 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Thu, 15 Apr 2010 22:35:22 +0000 (22:35 +0000)
contrib/slapd-modules/allowed/README
contrib/slapd-modules/allowed/allowed.c

index 197f7a2afc493222608a971f5b740ac8871efbc9..16a7897765fd4f4fa28b8665859ae460d9a664a0 100644 (file)
@@ -10,22 +10,14 @@ It adds to entries returned by search operations the value of attributes
 "allowedAttributesEffective"
        <http://msdn.microsoft.com/en-us/library/ms675218(VS.85).aspx>
 
-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"
        <http://msdn.microsoft.com/en-us/library/ms675219(VS.85).aspx>
+
 "allowedChildClassesEffective"
        <http://msdn.microsoft.com/en-us/library/ms675220(VS.85).aspx>
 
-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 ---
 
index f562d987aeaf9faf2a97f4c43234981c491ea2bf..ad22caa4bf874d665b4513be4985f46b94305bef 100644 (file)
@@ -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;
 }