From 1e849ec14d3178a49ec5d30fae76711915f4d1a1 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 17 Dec 2006 22:57:45 +0000 Subject: [PATCH] ITS#4638 restore original parameters on op completion (this is preliminary, more work remains) --- servers/slapd/overlays/rwm.c | 248 +++++++++++++++++++++++++---------- servers/slapd/slap.h | 26 ++-- 2 files changed, 190 insertions(+), 84 deletions(-) diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c index 6f3bfddcf2..c515339f98 100644 --- a/servers/slapd/overlays/rwm.c +++ b/servers/slapd/overlays/rwm.c @@ -26,11 +26,110 @@ #include "slap.h" #include "rwm.h" +typedef struct rwm_op_state { + struct berval ro_dn; + struct berval ro_ndn; + struct berval r_dn; + struct berval r_ndn; + OpRequest o_request; +} rwm_op_state; + static int rwm_db_destroy( BackendDB *be ); +typedef struct rwm_op_cb { + slap_callback cb; + rwm_op_state ros; +} rwm_op_cb; + +static rwm_op_cb rwm_cb; + +static void +rwm_keyfree( + void *key, + void *data ) +{ + ber_memfree_x( data, NULL ); +} + +static int +rwm_op_cleanup( Operation *op, SlapReply *rs ) +{ + slap_callback *cb = op->o_callback; + rwm_op_state *ros = cb->sc_private; + + if ( rs->sr_type == REP_RESULT || op->o_abandon || + rs->sr_err == SLAPD_ABANDON ) { + + op->o_req_dn = ros->ro_dn; + op->o_req_ndn = ros->ro_ndn; + + if ( !BER_BVISEMPTY( &ros->r_dn )) ch_free( ros->r_dn.bv_val ); + if ( !BER_BVISEMPTY( &ros->r_ndn )) ch_free( ros->r_ndn.bv_val ); + + switch( op->o_tag ) { + case LDAP_REQ_COMPARE: + break; + case LDAP_REQ_MODIFY: + break; + case LDAP_REQ_MODRDN: + if ( op->orr_newSup != ros->orr_newSup ) { + ch_free( op->orr_newSup->bv_val ); + ch_free( op->orr_nnewSup->bv_val ); + op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx ); + op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx ); + op->orr_newSup = ros->orr_newSup; + op->orr_nnewSup = ros->orr_nnewSup; + } + break; + case LDAP_REQ_SEARCH: + ch_free( op->ors_attrs ); + filter_free_x( op, op->ors_filter ); + ch_free( op->ors_filterstr.bv_val ); + op->ors_attrs = ros->ors_attrs; + op->ors_filter = ros->ors_filter; + op->ors_filterstr = ros->ors_filterstr; + break; + default: break; + } + } + + return SLAP_CB_CONTINUE; +} + +static rwm_op_cb * +rwm_callback_get( Operation *op, SlapReply *rs ) +{ + rwm_op_cb *roc = NULL; + + if ( op->o_threadctx == NULL ) { + roc = &rwm_cb; + } else { + ldap_pvt_thread_pool_getkey( op->o_threadctx, + rwm_keyfree, (void *)&roc, NULL ); + if ( roc == NULL ) { + roc = ch_malloc( sizeof( struct rwm_op_cb )); + ldap_pvt_thread_pool_setkey( op->o_threadctx, + rwm_keyfree, roc, rwm_keyfree ); + } + } + roc->cb.sc_cleanup = rwm_op_cleanup; + roc->cb.sc_response = NULL; + roc->cb.sc_next = op->o_callback; + roc->cb.sc_private = &roc->ros; + roc->ros.ro_dn = op->o_req_dn; + roc->ros.ro_ndn = op->o_req_ndn; + roc->ros.o_request = op->o_request; + BER_BVZERO( &roc->ros.r_dn ); + BER_BVZERO( &roc->ros.r_ndn ); + + return roc; +} + + static int -rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie ) +rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie, + rwm_op_state *ros ) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; struct ldaprwmap *rwmap = @@ -77,12 +176,12 @@ rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie ) } if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) { - op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); op->o_req_dn = dn; + ros->r_dn = dn; } else { op->o_req_dn = ndn; } - op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); + ros->r_ndn = ndn; op->o_req_ndn = ndn; return LDAP_SUCCESS; @@ -101,11 +200,13 @@ rwm_op_add( Operation *op, SlapReply *rs ) char *olddn = op->o_req_dn.bv_val; int isupdate; + rwm_op_cb *roc = rwm_callback_get( op, rs ); + #ifdef ENABLE_REWRITE - rc = rwm_op_dn_massage( op, rs, "addDN" ); + rc = rwm_op_dn_massage( op, rs, "addDN", &roc->ros ); #else /* ! ENABLE_REWRITE */ rc = 1; - rc = rwm_op_dn_massage( op, rs, &rc ); + rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros ); #endif /* ! ENABLE_REWRITE */ if ( rc != LDAP_SUCCESS ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; @@ -225,7 +326,8 @@ cleanup_attr:; attr_free( a ); } - /* TODO: map attribute types, values of DN-valued attributes ... */ + op->o_callback = &roc->cb; + return SLAP_CB_CONTINUE; } @@ -261,11 +363,13 @@ rwm_op_bind( Operation *op, SlapReply *rs ) slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; int rc; + rwm_op_cb *roc = rwm_callback_get( op, rs ); + #ifdef ENABLE_REWRITE - rc = rwm_op_dn_massage( op, rs, "bindDN" ); + rc = rwm_op_dn_massage( op, rs, "bindDN", &roc->ros ); #else /* ! ENABLE_REWRITE */ rc = 1; - rc = rwm_op_dn_massage( op, rs, &rc ); + rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros ); #endif /* ! ENABLE_REWRITE */ if ( rc != LDAP_SUCCESS ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; @@ -273,6 +377,8 @@ rwm_op_bind( Operation *op, SlapReply *rs ) return -1; } + op->o_callback = &roc->cb; + return SLAP_CB_CONTINUE; } @@ -301,11 +407,13 @@ rwm_op_compare( Operation *op, SlapReply *rs ) struct berval mapped_at = BER_BVNULL, mapped_vals[2] = { BER_BVNULL, BER_BVNULL }; + rwm_op_cb *roc = rwm_callback_get( op, rs ); + #ifdef ENABLE_REWRITE - rc = rwm_op_dn_massage( op, rs, "compareDN" ); + rc = rwm_op_dn_massage( op, rs, "compareDN", &roc->ros ); #else /* ! ENABLE_REWRITE */ rc = 1; - rc = rwm_op_dn_massage( op, rs, &rc ); + rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros ); #endif /* ! ENABLE_REWRITE */ if ( rc != LDAP_SUCCESS ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; @@ -383,6 +491,8 @@ rwm_op_compare( Operation *op, SlapReply *rs ) op->orc_ava->aa_desc = ad; } + op->o_callback = &roc->cb; + return SLAP_CB_CONTINUE; } @@ -392,11 +502,13 @@ rwm_op_delete( Operation *op, SlapReply *rs ) slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; int rc; + rwm_op_cb *roc = rwm_callback_get( op, rs ); + #ifdef ENABLE_REWRITE - rc = rwm_op_dn_massage( op, rs, "deleteDN" ); + rc = rwm_op_dn_massage( op, rs, "deleteDN", &roc->ros ); #else /* ! ENABLE_REWRITE */ rc = 1; - rc = rwm_op_dn_massage( op, rs, &rc ); + rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros ); #endif /* ! ENABLE_REWRITE */ if ( rc != LDAP_SUCCESS ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; @@ -404,6 +516,8 @@ rwm_op_delete( Operation *op, SlapReply *rs ) return -1; } + op->o_callback = &roc->cb; + return SLAP_CB_CONTINUE; } @@ -418,11 +532,13 @@ rwm_op_modify( Operation *op, SlapReply *rs ) Modifications **mlp; int rc; + rwm_op_cb *roc = rwm_callback_get( op, rs ); + #ifdef ENABLE_REWRITE - rc = rwm_op_dn_massage( op, rs, "modifyDN" ); + rc = rwm_op_dn_massage( op, rs, "modifyDN", &roc->ros ); #else /* ! ENABLE_REWRITE */ rc = 1; - rc = rwm_op_dn_massage( op, rs, &rc ); + rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros ); #endif /* ! ENABLE_REWRITE */ if ( rc != LDAP_SUCCESS ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; @@ -546,6 +662,8 @@ cleanup_mod:; free( ml ); } + op->o_callback = &roc->cb; + return SLAP_CB_CONTINUE; } @@ -558,6 +676,8 @@ rwm_op_modrdn( Operation *op, SlapReply *rs ) int rc; + rwm_op_cb *roc = rwm_callback_get( op, rs ); + if ( op->orr_newSup ) { dncookie dc; struct berval nnewSup = BER_BVNULL; @@ -585,8 +705,10 @@ rwm_op_modrdn( Operation *op, SlapReply *rs ) } if ( op->orr_newSup->bv_val != newSup.bv_val ) { - op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx ); - op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx ); + op->orr_newSup = op->o_tmpalloc( sizeof( struct berval ), + op->o_tmpmemctx ); + op->orr_nnewSup = op->o_tmpalloc( sizeof( struct berval ), + op->o_tmpmemctx ); *op->orr_newSup = newSup; *op->orr_nnewSup = nnewSup; } @@ -596,61 +718,43 @@ rwm_op_modrdn( Operation *op, SlapReply *rs ) * Rewrite the dn, if needed */ #ifdef ENABLE_REWRITE - rc = rwm_op_dn_massage( op, rs, "renameDN" ); + rc = rwm_op_dn_massage( op, rs, "renameDN", &roc->ros ); #else /* ! ENABLE_REWRITE */ rc = 1; - rc = rwm_op_dn_massage( op, rs, &rc ); + rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros ); #endif /* ! ENABLE_REWRITE */ if ( rc != LDAP_SUCCESS ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; send_ldap_error( op, rs, rc, "renameDN massage error" ); + if ( op->orr_newSup != roc->ros.orr_newSup ) { + ch_free( op->orr_newSup->bv_val ); + ch_free( op->orr_nnewSup->bv_val ); + op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx ); + op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx ); + op->orr_newSup = roc->ros.orr_newSup; + op->orr_nnewSup = roc->ros.orr_nnewSup; + } return -1; } /* TODO: rewrite newRDN, attribute types, * values of DN-valued attributes ... */ - return SLAP_CB_CONTINUE; -} -static slap_callback rwm_cb; + op->o_callback = &roc->cb; -static void -rwm_keyfree( - void *key, - void *data ) -{ - ber_memfree_x( data, NULL ); + return SLAP_CB_CONTINUE; } -static slap_callback * -rwm_callback_get( Operation *op ) -{ - void *data = NULL; - - if ( op->o_threadctx == NULL ) { - return &rwm_cb; - } - - ldap_pvt_thread_pool_getkey( op->o_threadctx, - rwm_keyfree, &data, NULL ); - if ( data == NULL ) { - data = ch_calloc( sizeof( slap_callback ), 1 ); - ldap_pvt_thread_pool_setkey( op->o_threadctx, - rwm_keyfree, data, rwm_keyfree ); - } - - return (slap_callback *)data; -} static int rwm_swap_attrs( Operation *op, SlapReply *rs ) { slap_callback *cb = op->o_callback; - AttributeName *an = (AttributeName *)cb->sc_private; + rwm_op_state *ros = cb->sc_private; - rs->sr_attrs = an; + rs->sr_attrs = ros->ors_attrs; - return SLAP_CB_CONTINUE; + return SLAP_CB_CONTINUE; } static int @@ -666,19 +770,20 @@ rwm_op_search( Operation *op, SlapReply *rs ) struct berval fstr = BER_BVNULL; Filter *f = NULL; - slap_callback *cb = NULL; AttributeName *an = NULL; char *text = NULL; + rwm_op_cb *roc = rwm_callback_get( op, rs ); + #ifdef ENABLE_REWRITE rc = rewrite_session_var_set( rwmap->rwm_rw, op->o_conn, "searchFilter", op->ors_filterstr.bv_val ); if ( rc == LDAP_SUCCESS ) - rc = rwm_op_dn_massage( op, rs, "searchDN" ); + rc = rwm_op_dn_massage( op, rs, "searchDN", &roc->ros ); #else /* ! ENABLE_REWRITE */ rc = 1; - rc = rwm_op_dn_massage( op, rs, &rc ); + rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros ); #endif /* ! ENABLE_REWRITE */ if ( rc != LDAP_SUCCESS ) { text = "searchDN massage error"; @@ -711,14 +816,6 @@ rwm_op_search( Operation *op, SlapReply *rs ) goto error_return; } - if ( !BER_BVISNULL( &op->ors_filterstr ) ) { - ch_free( op->ors_filterstr.bv_val ); - } - - if( op->ors_filter ) { - filter_free_x( op, op->ors_filter ); - } - op->ors_filter = f; op->ors_filterstr = fstr; @@ -729,15 +826,10 @@ rwm_op_search( Operation *op, SlapReply *rs ) goto error_return; } - cb = rwm_callback_get( op ); - - cb->sc_response = rwm_swap_attrs; - cb->sc_cleanup = NULL; - cb->sc_private = (void *)op->ors_attrs; - cb->sc_next = op->o_callback; - - op->o_callback = cb; op->ors_attrs = an; + roc->cb.sc_response = rwm_swap_attrs; + + op->o_callback = &roc->cb; return SLAP_CB_CONTINUE; @@ -754,6 +846,8 @@ error_return:; ch_free( fstr.bv_val ); } + op->oq_search = roc->ros.oq_search; + op->o_bd->bd_info = (BackendInfo *)on->on_info; send_ldap_error( op, rs, rc, text ); @@ -766,6 +860,7 @@ rwm_exop_passwd( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; int rc; + rwm_op_cb *roc; struct berval id = BER_BVNULL, pwold = BER_BVNULL, @@ -799,11 +894,13 @@ rwm_exop_passwd( Operation *op, SlapReply *rs ) ber_dupbv_x( &op->o_req_ndn, &op->o_ndn, op->o_tmpmemctx ); } + roc = rwm_callback_get( op, rs ); + #ifdef ENABLE_REWRITE - rc = rwm_op_dn_massage( op, rs, "extendedDN" ); + rc = rwm_op_dn_massage( op, rs, "extendedDN", &roc->ros ); #else /* ! ENABLE_REWRITE */ rc = 1; - rc = rwm_op_dn_massage( op, rs, &rc ); + rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros ); #endif /* ! ENABLE_REWRITE */ if ( rc != LDAP_SUCCESS ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; @@ -813,6 +910,8 @@ rwm_exop_passwd( Operation *op, SlapReply *rs ) /* TODO: re-encode the request with the massaged DN */ + op->o_callback = &roc->cb; + return SLAP_CB_CONTINUE; } @@ -829,6 +928,7 @@ rwm_extended( Operation *op, SlapReply *rs ) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; int rc; + rwm_op_cb *roc; int i; @@ -852,11 +952,13 @@ rwm_extended( Operation *op, SlapReply *rs ) } } + roc = rwm_callback_get( op, rs ); + #ifdef ENABLE_REWRITE - rc = rwm_op_dn_massage( op, rs, "extendedDN" ); + rc = rwm_op_dn_massage( op, rs, "extendedDN", &roc->ros ); #else /* ! ENABLE_REWRITE */ rc = 1; - rc = rwm_op_dn_massage( op, rs, &rc ); + rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros ); #endif /* ! ENABLE_REWRITE */ if ( rc != LDAP_SUCCESS ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; @@ -865,6 +967,8 @@ rwm_extended( Operation *op, SlapReply *rs ) } /* TODO: rewrite/map extended data ? ... */ + op->o_callback = &roc->cb; + return SLAP_CB_CONTINUE; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 3eb7aa1e18..e7d3b5a88a 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -2381,6 +2381,19 @@ typedef struct slap_op_header { #endif } Opheader; +typedef union slap_op_request { + req_add_s oq_add; + req_bind_s oq_bind; + req_compare_s oq_compare; + req_modify_s oq_modify; + req_modrdn_s oq_modrdn; + req_search_s oq_search; + req_abandon_s oq_abandon; + req_abandon_s oq_cancel; + req_extended_s oq_extended; + req_pwdexop_s oq_pwdexop; +} OpRequest; + typedef struct slap_op { Opheader *o_hdr; @@ -2409,18 +2422,7 @@ typedef struct slap_op { struct berval o_req_dn; /* DN of target of request */ struct berval o_req_ndn; - union o_req_u { - req_add_s oq_add; - req_bind_s oq_bind; - req_compare_s oq_compare; - req_modify_s oq_modify; - req_modrdn_s oq_modrdn; - req_search_s oq_search; - req_abandon_s oq_abandon; - req_abandon_s oq_cancel; - req_extended_s oq_extended; - req_pwdexop_s oq_pwdexop; - } o_request; + OpRequest o_request; /* short hands for union members */ #define oq_add o_request.oq_add -- 2.39.5