]> git.sur5r.net Git - openldap/commitdiff
ITS#5903 restructure callbacks
authorHoward Chu <hyc@openldap.org>
Wed, 28 Jan 2009 00:29:34 +0000 (00:29 +0000)
committerHoward Chu <hyc@openldap.org>
Wed, 28 Jan 2009 00:29:34 +0000 (00:29 +0000)
servers/slapd/overlays/memberof.c

index 72b29ed8dfeb5e43a1d7761b764dbd04dc12937e..ecb8e06ffd59f2c785df68129816eb7649a9d19b 100644 (file)
@@ -178,13 +178,6 @@ typedef enum memberof_is_t {
        MEMBEROF_IS_BOTH = (MEMBEROF_IS_GROUP|MEMBEROF_IS_MEMBER)
 } memberof_is_t;
 
-/*
- * failover storage for member attribute values of groups being deleted
- * handles [no]thread cases.
- */
-static BerVarray       saved_member_vals;
-static BerVarray       saved_memberof_vals;
-
 static void
 memberof_saved_member_free( void *key, void *data )
 {
@@ -242,10 +235,16 @@ memberof_saved_member_set( Operation *op, void *keyp, BerVarray vals )
 
 typedef struct memberof_cookie_t {
        AttributeDescription    *ad;
-       void                    *key;
+       BerVarray               vals;
        int                     foundit;
 } memberof_cookie_t;
 
+typedef struct memberof_cbinfo_t {
+       slap_overinst *on;
+       BerVarray member;
+       BerVarray memberof;
+} memberof_cbinfo_t;
+       
 static int
 memberof_isGroupOrMember_cb( Operation *op, SlapReply *rs )
 {
@@ -269,7 +268,6 @@ memberof_saveMember_cb( Operation *op, SlapReply *rs )
        if ( rs->sr_type == REP_SEARCH ) {
                memberof_cookie_t       *mc;
                Attribute               *a;
-               BerVarray               vals = NULL;
 
                mc = (memberof_cookie_t *)op->o_callback->sc_private;
                mc->foundit = 1;
@@ -279,11 +277,9 @@ memberof_saveMember_cb( Operation *op, SlapReply *rs )
 
                a = attr_find( rs->sr_entry->e_attrs, mc->ad );
                if ( a != NULL ) {
-                       vals = a->a_nvals;
+                       ber_bvarray_dup_x( &mc->vals, a->a_nvals, op->o_tmpmemctx );
                }
 
-               memberof_saved_member_set( op, mc->key, vals );
-
                if ( a && attr_find( a->a_next, mc->ad ) != NULL ) {
                        Debug( LDAP_DEBUG_ANY,
                                "%s: memberof_saveMember_cb(\"%s\"): "
@@ -303,18 +299,19 @@ memberof_saveMember_cb( Operation *op, SlapReply *rs )
  * attribute values of groups being deleted.
  */
 static int
-memberof_isGroupOrMember( Operation *op, memberof_is_t *iswhatp )
+memberof_isGroupOrMember( Operation *op, memberof_is_t *iswhatp, memberof_cbinfo_t *mci )
 {
-       slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;
+       slap_overinst           *on = mci->on;
        memberof_t              *mo = (memberof_t *)on->on_bi.bi_private;
 
        Operation               op2 = *op;
        SlapReply               rs2 = { REP_RESULT };
        slap_callback           cb = { 0 };
-       memberof_cookie_t       mc;
+       BackendInfo     *bi = op->o_bd->bd_info;
        AttributeName           an[ 2 ];
 
        memberof_is_t           iswhat = MEMBEROF_IS_NONE;
+       memberof_cookie_t       mc;
 
        assert( iswhatp != NULL );
        assert( *iswhatp != MEMBEROF_IS_NONE );
@@ -343,8 +340,8 @@ memberof_isGroupOrMember( Operation *op, memberof_is_t *iswhatp )
 
        if ( *iswhatp & MEMBEROF_IS_GROUP ) {
                mc.ad = mo->mo_ad_member;
-               mc.key = &saved_member_vals;
                mc.foundit = 0;
+               mc.vals = NULL;
                an[ 0 ].an_desc = mo->mo_ad_member;
                an[ 0 ].an_name = an[ 0 ].an_desc->ad_cname;
                op2.ors_filterstr = mo->mo_groupFilterstr;
@@ -352,20 +349,19 @@ memberof_isGroupOrMember( Operation *op, memberof_is_t *iswhatp )
 
                op2.o_bd->bd_info = (BackendInfo *)on->on_info;
                (void)op->o_bd->be_search( &op2, &rs2 );
-               op2.o_bd->bd_info = (BackendInfo *)on;
+               op2.o_bd->bd_info = bi;
 
                if ( mc.foundit ) {
                        iswhat |= MEMBEROF_IS_GROUP;
+                       mci->member = mc.vals;
 
-               } else {
-                       memberof_saved_member_set( op, mc.key, NULL );
                }
        }
 
        if ( *iswhatp & MEMBEROF_IS_MEMBER ) {
                mc.ad = mo->mo_ad_memberof;
-               mc.key = &saved_memberof_vals;
                mc.foundit = 0;
+               mc.vals = NULL;
                an[ 0 ].an_desc = mo->mo_ad_memberof;
                an[ 0 ].an_name = an[ 0 ].an_desc->ad_cname;
                op2.ors_filterstr = mo->mo_memberFilterstr;
@@ -373,13 +369,12 @@ memberof_isGroupOrMember( Operation *op, memberof_is_t *iswhatp )
 
                op2.o_bd->bd_info = (BackendInfo *)on->on_info;
                (void)op->o_bd->be_search( &op2, &rs2 );
-               op2.o_bd->bd_info = (BackendInfo *)on;
+               op2.o_bd->bd_info = bi;
 
                if ( mc.foundit ) {
                        iswhat |= MEMBEROF_IS_MEMBER;
+                       mci->memberof = mc.vals;
 
-               } else {
-                       memberof_saved_member_set( op, mc.key, NULL );
                }
        }
 
@@ -402,7 +397,8 @@ memberof_value_modify(
        struct berval           *new_dn,
        struct berval           *new_ndn )
 {
-       slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
+       memberof_cbinfo_t *mci = op->o_callback->sc_private;
+       slap_overinst   *on = mci->on;
        memberof_t      *mo = (memberof_t *)on->on_bi.bi_private;
 
        Operation       op2 = *op;
@@ -417,8 +413,6 @@ memberof_value_modify(
        op2.o_req_dn = *ndn;
        op2.o_req_ndn = *ndn;
 
-       op2.o_bd->bd_info = (BackendInfo *)on->on_info;
-
        op2.o_callback = &cb;
        op2.o_dn = op->o_bd->be_rootdn;
        op2.o_ndn = op->o_bd->be_rootndn;
@@ -527,11 +521,29 @@ memberof_value_modify(
         * not optimal in terms of performance.  At least it would
         * move towards self-repairing capabilities. */
 
-       op2.o_bd->bd_info = (BackendInfo *)on;
-
        return rs2.sr_err;
 }
 
+static int
+memberof_cleanup( Operation *op, SlapReply *rs )
+{
+       slap_callback *sc = op->o_callback;
+       memberof_cbinfo_t *mci = sc->sc_private;
+
+       op->o_callback = sc->sc_next;
+       if ( mci->memberof )
+               ber_bvarray_free_x( mci->memberof, op->o_tmpmemctx );
+       if ( mci->member )
+               ber_bvarray_free_x( mci->member, op->o_tmpmemctx );
+       op->o_tmpfree( sc, op->o_tmpmemctx );
+       return 0;
+}
+
+static int memberof_res_add( Operation *op, SlapReply *rs );
+static int memberof_res_delete( Operation *op, SlapReply *rs );
+static int memberof_res_modify( Operation *op, SlapReply *rs );
+static int memberof_res_modrdn( Operation *op, SlapReply *rs );
+
 static int
 memberof_op_add( Operation *op, SlapReply *rs )
 {
@@ -542,6 +554,8 @@ memberof_op_add( Operation *op, SlapReply *rs )
        int             rc = SLAP_CB_CONTINUE;
        int             i;
        struct berval   save_dn, save_ndn;
+       slap_callback *sc;
+       memberof_cbinfo_t *mci;
 
        if ( op->ora_e->e_attrs == NULL ) {
                /* FIXME: global overlay; need to deal with */
@@ -733,7 +747,18 @@ memberof_op_add( Operation *op, SlapReply *rs )
        }
 
        rc = SLAP_CB_CONTINUE;
-       
+
+       sc = op->o_tmpalloc( sizeof(slap_callback)+sizeof(*mci), op->o_tmpmemctx );
+       sc->sc_private = sc+1;
+       sc->sc_response = memberof_res_add;
+       sc->sc_cleanup = memberof_cleanup;
+       mci = sc->sc_private;
+       mci->on = on;
+       mci->member = NULL;
+       mci->memberof = NULL;
+       sc->sc_next = op->o_callback;
+       op->o_callback = sc;
+
 done:;
        op->o_dn = save_dn;
        op->o_ndn = save_ndn;
@@ -749,12 +774,26 @@ memberof_op_delete( Operation *op, SlapReply *rs )
        memberof_t      *mo = (memberof_t *)on->on_bi.bi_private;
 
        memberof_is_t   iswhat = MEMBEROF_IS_GROUP;
+       slap_callback *sc;
+       memberof_cbinfo_t *mci;
 
        if ( MEMBEROF_REFINT( mo ) ) {
                iswhat = MEMBEROF_IS_BOTH;
        }
 
-       memberof_isGroupOrMember( op, &iswhat );
+       sc = op->o_tmpalloc( sizeof(slap_callback)+sizeof(*mci), op->o_tmpmemctx );
+       sc->sc_private = sc+1;
+       sc->sc_response = memberof_res_delete;
+       sc->sc_cleanup = memberof_cleanup;
+       mci = sc->sc_private;
+       mci->on = on;
+       mci->member = NULL;
+       mci->memberof = NULL;
+
+       memberof_isGroupOrMember( op, &iswhat, mci );
+
+       sc->sc_next = op->o_callback;
+       op->o_callback = sc;
 
        return SLAP_CB_CONTINUE;
 }
@@ -766,9 +805,11 @@ memberof_op_modify( Operation *op, SlapReply *rs )
        memberof_t      *mo = (memberof_t *)on->on_bi.bi_private;
 
        Modifications   **mlp, **mmlp = NULL;
-       int             rc = SLAP_CB_CONTINUE;
+       int             rc = SLAP_CB_CONTINUE, save_member = 0;
        struct berval   save_dn, save_ndn;
        memberof_is_t   iswhat = MEMBEROF_IS_GROUP;
+       slap_callback *sc;
+       memberof_cbinfo_t *mci, mcis;
 
        if ( MEMBEROF_REVERSE( mo ) ) {
                for ( mlp = &op->orm_modlist; *mlp; mlp = &(*mlp)->sml_next ) {
@@ -783,12 +824,12 @@ memberof_op_modify( Operation *op, SlapReply *rs )
 
        save_dn = op->o_dn;
        save_ndn = op->o_ndn;
+       mcis.on = on;
 
-       if ( memberof_isGroupOrMember( op, &iswhat ) == LDAP_SUCCESS
+       if ( memberof_isGroupOrMember( op, &iswhat, &mcis ) == LDAP_SUCCESS
                && ( iswhat & MEMBEROF_IS_GROUP ) )
        {
                Modifications *ml;
-               int save_member = 0;
 
                for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
                        if ( ml->sml_desc == mo->mo_ad_member ) {
@@ -801,20 +842,6 @@ memberof_op_modify( Operation *op, SlapReply *rs )
                        }
                }
 
-               if ( save_member ) {
-                       BerVarray       vals = NULL;
-
-                       op->o_dn = op->o_bd->be_rootdn;
-                       op->o_ndn = op->o_bd->be_rootndn;
-                       op->o_bd->bd_info = (BackendInfo *)on->on_info;
-                       rc = backend_attribute( op, NULL, &op->o_req_ndn,
-                                       mo->mo_ad_member, &vals, ACL_READ );
-                       op->o_bd->bd_info = (BackendInfo *)on;
-                       if ( rc == LDAP_SUCCESS && vals != NULL ) {
-                               memberof_saved_member_set( op, &saved_member_vals, vals );
-                               ber_bvarray_free_x( vals, op->o_tmpmemctx );
-                       }
-               }
 
                if ( MEMBEROF_DANGLING_CHECK( mo )
                                && !get_relax( op ) )
@@ -1147,6 +1174,27 @@ done2:;
                op->o_bd->bd_info = (BackendInfo *)on;
        }
 
+       sc = op->o_tmpalloc( sizeof(slap_callback)+sizeof(*mci), op->o_tmpmemctx );
+       sc->sc_private = sc+1;
+       sc->sc_response = memberof_res_modify;
+       sc->sc_cleanup = memberof_cleanup;
+       mci = sc->sc_private;
+       mci->on = on;
+       mci->member = NULL;
+       mci->memberof = NULL;
+
+       if ( save_member ) {
+               op->o_dn = op->o_bd->be_rootdn;
+               op->o_ndn = op->o_bd->be_rootndn;
+               op->o_bd->bd_info = (BackendInfo *)on->on_info;
+               rc = backend_attribute( op, NULL, &op->o_req_ndn,
+                               mo->mo_ad_member, &mci->member, ACL_READ );
+               op->o_bd->bd_info = (BackendInfo *)on;
+       }
+
+       sc->sc_next = op->o_callback;
+       op->o_callback = sc;
+
        rc = SLAP_CB_CONTINUE;
 
 done:;
@@ -1157,34 +1205,60 @@ done:;
        return rc;
 }
 
+static int
+memberof_op_modrdn( Operation *op, SlapReply *rs )
+{
+       slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
+       slap_callback *sc;
+       memberof_cbinfo_t *mci;
+
+       sc = op->o_tmpalloc( sizeof(slap_callback)+sizeof(*mci), op->o_tmpmemctx );
+       sc->sc_private = sc+1;
+       sc->sc_response = memberof_res_modrdn;
+       sc->sc_cleanup = memberof_cleanup;
+       mci = sc->sc_private;
+       mci->on = on;
+       mci->member = NULL;
+       mci->memberof = NULL;
+
+       sc->sc_next = op->o_callback;
+       op->o_callback = sc;
+
+       return SLAP_CB_CONTINUE;
+}
+
 /*
  * response callback that adds memberof values when a group is added.
  */
 static int
 memberof_res_add( Operation *op, SlapReply *rs )
 {
-       slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
+       memberof_cbinfo_t *mci = op->o_callback->sc_private;
+       slap_overinst   *on = mci->on;
        memberof_t      *mo = (memberof_t *)on->on_bi.bi_private;
 
        int             i;
 
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               return SLAP_CB_CONTINUE;
+       }
+
        if ( MEMBEROF_REVERSE( mo ) ) {
                Attribute       *ma;
 
                ma = attr_find( op->ora_e->e_attrs, mo->mo_ad_memberof );
                if ( ma != NULL ) {
-                       Operation       op2 = *op;
-                       SlapReply       rs2 = { 0 };
+                       char relax = op->o_relax;
 
                        /* relax is required to allow to add
                         * a non-existing member */
-                       op2.o_relax = SLAP_CONTROL_CRITICAL;
+                       op->o_relax = SLAP_CONTROL_CRITICAL;
 
                        for ( i = 0; !BER_BVISNULL( &ma->a_nvals[ i ] ); i++ ) {
                
                                /* the modification is attempted
                                 * with the original identity */
-                               (void)memberof_value_modify( &op2, &rs2,
+                               (void)memberof_value_modify( op, rs,
                                        &ma->a_nvals[ i ], mo->mo_ad_member,
                                        NULL, NULL, &op->o_req_dn, &op->o_req_ndn );
                        }
@@ -1218,13 +1292,18 @@ memberof_res_add( Operation *op, SlapReply *rs )
 static int
 memberof_res_delete( Operation *op, SlapReply *rs )
 {
-       slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
+       memberof_cbinfo_t *mci = op->o_callback->sc_private;
+       slap_overinst   *on = mci->on;
        memberof_t      *mo = (memberof_t *)on->on_bi.bi_private;
 
        BerVarray       vals;
        int             i;
 
-       vals = memberof_saved_member_get( op, &saved_member_vals );
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               return SLAP_CB_CONTINUE;
+       }
+
+       vals = mci->member;
        if ( vals != NULL ) {
                for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) {
                        (void)memberof_value_modify( op, rs,
@@ -1232,13 +1311,10 @@ memberof_res_delete( Operation *op, SlapReply *rs )
                                        &op->o_req_dn, &op->o_req_ndn,
                                        NULL, NULL );
                }
-
-               memberof_saved_member_set( op, &saved_memberof_vals, NULL );
-               ber_bvarray_free( vals );
        }
 
        if ( MEMBEROF_REFINT( mo ) ) {
-               vals = memberof_saved_member_get( op, &saved_memberof_vals );
+               vals = mci->memberof;
                if ( vals != NULL ) {
                        for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) {
                                (void)memberof_value_modify( op, rs,
@@ -1246,9 +1322,6 @@ memberof_res_delete( Operation *op, SlapReply *rs )
                                                &op->o_req_dn, &op->o_req_ndn,
                                                NULL, NULL );
                        }
-
-                       memberof_saved_member_set( op, &saved_member_vals, NULL );
-                       ber_bvarray_free( vals );
                }
        }
 
@@ -1262,7 +1335,8 @@ memberof_res_delete( Operation *op, SlapReply *rs )
 static int
 memberof_res_modify( Operation *op, SlapReply *rs )
 {
-       slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
+       memberof_cbinfo_t *mci = op->o_callback->sc_private;
+       slap_overinst   *on = mci->on;
        memberof_t      *mo = (memberof_t *)on->on_bi.bi_private;
 
        int             i, rc;
@@ -1270,6 +1344,10 @@ memberof_res_modify( Operation *op, SlapReply *rs )
        BerVarray       vals;
        memberof_is_t   iswhat = MEMBEROF_IS_GROUP;
 
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               return SLAP_CB_CONTINUE;
+       }
+
        if ( MEMBEROF_REVERSE( mo ) ) {
                for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
                        if ( ml->sml_desc == mo->mo_ad_memberof ) {
@@ -1332,7 +1410,7 @@ memberof_res_modify( Operation *op, SlapReply *rs )
                }
        }
 
-       if ( memberof_isGroupOrMember( op, &iswhat ) == LDAP_SUCCESS
+       if ( memberof_isGroupOrMember( op, &iswhat, mci ) == LDAP_SUCCESS
                        && ( iswhat & MEMBEROF_IS_GROUP ) )
        {
                for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
@@ -1355,7 +1433,7 @@ memberof_res_modify( Operation *op, SlapReply *rs )
                                /* fall thru */
        
                        case LDAP_MOD_REPLACE:
-                               vals = memberof_saved_member_get( op, &saved_member_vals );
+                               vals = mci->member;
 
                                /* delete all ... */
                                if ( vals != NULL ) {
@@ -1365,7 +1443,6 @@ memberof_res_modify( Operation *op, SlapReply *rs )
                                                                &op->o_req_dn, &op->o_req_ndn,
                                                                NULL, NULL );
                                        }
-                                       ber_bvarray_free_x( vals, op->o_tmpmemctx );
                                }
        
                                if ( ml->sml_op == LDAP_MOD_DELETE || !ml->sml_values ) {
@@ -1395,12 +1472,13 @@ memberof_res_modify( Operation *op, SlapReply *rs )
 
 /*
  * response callback that adds/deletes member values when a group member
- * is modified.
+ * is renamed.
  */
 static int
-memberof_res_rename( Operation *op, SlapReply *rs )
+memberof_res_modrdn( Operation *op, SlapReply *rs )
 {
-       slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
+       memberof_cbinfo_t *mci = op->o_callback->sc_private;
+       slap_overinst   *on = mci->on;
        memberof_t      *mo = (memberof_t *)on->on_bi.bi_private;
 
        struct berval   newPDN, newDN = BER_BVNULL, newPNDN, newNDN;
@@ -1410,6 +1488,10 @@ memberof_res_rename( Operation *op, SlapReply *rs )
        struct berval   save_dn, save_ndn;
        memberof_is_t   iswhat = MEMBEROF_IS_GROUP;
 
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               return SLAP_CB_CONTINUE;
+       }
+
        if ( MEMBEROF_REFINT( mo ) ) {
                iswhat |= MEMBEROF_IS_MEMBER;
        }
@@ -1428,7 +1510,7 @@ memberof_res_rename( Operation *op, SlapReply *rs )
 
        op->o_req_dn = newNDN;
        op->o_req_ndn = newNDN;
-       rc = memberof_isGroupOrMember( op, &iswhat );
+       rc = memberof_isGroupOrMember( op, &iswhat, mci );
        op->o_req_dn = save_dn;
        op->o_req_ndn = save_ndn;
 
@@ -1488,30 +1570,6 @@ done:;
        return SLAP_CB_CONTINUE;
 }
 
-static int
-memberof_response( Operation *op, SlapReply *rs )
-{
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               return SLAP_CB_CONTINUE;
-       }
-
-       switch ( op->o_tag ) {
-       case LDAP_REQ_ADD:
-               return memberof_res_add( op, rs );
-
-       case LDAP_REQ_DELETE:
-               return memberof_res_delete( op, rs );
-
-       case LDAP_REQ_MODIFY:
-               return memberof_res_modify( op, rs );
-
-       case LDAP_REQ_MODDN:
-               return memberof_res_rename( op, rs );
-
-       default:
-               return SLAP_CB_CONTINUE;
-       }
-}
 
 static int
 memberof_db_init(
@@ -2057,8 +2115,7 @@ memberof_initialize( void )
        memberof.on_bi.bi_op_add = memberof_op_add;
        memberof.on_bi.bi_op_delete = memberof_op_delete;
        memberof.on_bi.bi_op_modify = memberof_op_modify;
-
-       memberof.on_response = memberof_response;
+       memberof.on_bi.bi_op_modrdn = memberof_op_modrdn;
 
        memberof.on_bi.bi_cf_ocs = mo_ocs;