From 37ef5350bdb9f303fa886f7bf9ec0b3912523059 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Tue, 6 Apr 2004 00:47:21 +0000 Subject: [PATCH] Rework return of update referrals --- servers/slapd/add.c | 34 +++++++++++++--------------------- servers/slapd/delete.c | 31 ++++++++++++------------------- servers/slapd/modify.c | 42 +++++++++++++++++------------------------- servers/slapd/modrdn.c | 28 +++++++++------------------- servers/slapd/passwd.c | 30 ++++++++++++++++-------------- servers/slapd/result.c | 22 +++++++++++++++++----- servers/slapd/slap.h | 7 ++++--- 7 files changed, 88 insertions(+), 106 deletions(-) diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 4557d083da..ca3cb67264 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -212,8 +212,8 @@ do_add( Operation *op, SlapReply *rs ) if ( op->o_bd == NULL ) { rs->sr_ref = referral_rewrite( default_referral, NULL, &e->e_name, LDAP_SCOPE_DEFAULT ); - if (!rs->sr_ref) rs->sr_ref = default_referral; - if ( rs->sr_ref != NULL ) { + if ( !rs->sr_ref ) rs->sr_ref = default_referral; + if ( rs->sr_ref ) { rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); @@ -222,7 +222,7 @@ do_add( Operation *op, SlapReply *rs ) } } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, - "referral missing" ); + "no global superior knowledge" ); } goto done; } @@ -252,8 +252,7 @@ do_add( Operation *op, SlapReply *rs ) /* do the update here */ int repl_user = be_isupdate(op->o_bd, &op->o_ndn ); #ifndef SLAPD_MULTIMASTER - if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ) && - ( !op->o_bd->be_update_ndn.bv_len || repl_user )) + if ( !SLAP_SHADOW(op->o_bd) || repl_user ) #else if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) #endif @@ -264,7 +263,7 @@ do_add( Operation *op, SlapReply *rs ) slap_callback cb = { NULL, slap_replog_cb, NULL, NULL }; rs->sr_err = slap_mods_check( modlist, update, &rs->sr_text, - textbuf, textlen, NULL ); + textbuf, textlen, NULL ); if( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); @@ -288,7 +287,7 @@ do_add( Operation *op, SlapReply *rs ) } rs->sr_err = slap_mods2entry( modlist, &e, repl_user, 0, - &rs->sr_text, textbuf, textlen ); + &rs->sr_text, textbuf, textlen ); if( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto done; @@ -338,17 +337,8 @@ do_add( Operation *op, SlapReply *rs ) } #endif /* LDAP_SLAPI */ - if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { - syncinfo_t *si; - LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) { - struct berval tmpbv; - ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] ); - ber_bvarray_add( &defref, &tmpbv ); - } - } else { - defref = op->o_bd->be_update_refs - ? op->o_bd->be_update_refs : default_referral; - } + defref = op->o_bd->be_update_refs + ? op->o_bd->be_update_refs : default_referral; if ( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, @@ -358,11 +348,13 @@ do_add( Operation *op, SlapReply *rs ) if (!rs->sr_ref) rs->sr_ref = default_referral; send_ldap_result( op, rs ); - if ( rs->sr_ref != default_referral ) ber_bvarray_free( rs->sr_ref ); + if ( rs->sr_ref != default_referral ) { + ber_bvarray_free( rs->sr_ref ); + } } else { send_ldap_error( op, rs, - LDAP_UNWILLING_TO_PERFORM, - "referral missing" ); + LDAP_UNWILLING_TO_PERFORM, + "shadow context; no update referral" ); } #endif /* SLAPD_MULTIMASTER */ } diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index 1749c0975c..b3bb25f2ab 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -138,7 +138,8 @@ do_delete( * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ - if ( (op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 )) == NULL ) { + op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 ); + if ( op->o_bd == NULL ) { rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); @@ -151,7 +152,7 @@ do_delete( if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref ); } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, - "referral missing" ); + "no global superior knowledge" ); } goto cleanup; } @@ -206,8 +207,7 @@ do_delete( /* do the update here */ int repl_user = be_isupdate( op->o_bd, &op->o_ndn ); #ifndef SLAPD_MULTIMASTER - if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ) && - ( !op->o_bd->be_update_ndn.bv_len || repl_user )) + if ( !SLAP_SHADOW(op->o_bd) || repl_user ) #else if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) #endif @@ -240,7 +240,8 @@ do_delete( op->o_managedsait = 1; while ( rs->sr_err == LDAP_SUCCESS && - op->o_delete_glue_parent ) { + op->o_delete_glue_parent ) + { op->o_delete_glue_parent = 0; if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) { slap_callback cb = { NULL }; @@ -264,18 +265,9 @@ do_delete( #ifndef SLAPD_MULTIMASTER } else { - BerVarray defref = NULL; - if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { - syncinfo_t *si; - LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) { - struct berval tmpbv; - ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] ); - ber_bvarray_add( &defref, &tmpbv ); - } - } else { - defref = op->o_bd->be_update_refs - ? op->o_bd->be_update_refs : default_referral; - } + BerVarray defref = op->o_bd->be_update_refs + ? op->o_bd->be_update_refs : default_referral; + if ( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); @@ -284,10 +276,11 @@ do_delete( send_ldap_result( op, rs ); if (rs->sr_ref != defref) ber_bvarray_free( rs->sr_ref ); + } else { send_ldap_error( op, rs, - LDAP_UNWILLING_TO_PERFORM, - "referral missing" ); + LDAP_UNWILLING_TO_PERFORM, + "shadow context; no update referral" ); } #endif } diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index eb8a3ac4b6..2de5f3d94c 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -367,7 +367,7 @@ do_modify( if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref ); } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, - "referral missing" ); + "no global superior knowledge" ); } goto cleanup; } @@ -398,21 +398,25 @@ do_modify( modv = slapi_int_modifications2ldapmods( &modlist ); slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)modv ); - rs->sr_err = slapi_int_call_plugins( op->o_bd, SLAPI_PLUGIN_PRE_MODIFY_FN, pb ); + rs->sr_err = slapi_int_call_plugins( op->o_bd, + SLAPI_PLUGIN_PRE_MODIFY_FN, pb ); if ( rs->sr_err < 0 ) { /* * A preoperation plugin failure will abort the * entire operation. */ #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, INFO, "do_modify: modify preoperation plugin " - "failed\n", 0, 0, 0 ); + LDAP_LOG( OPERATION, INFO, + "do_modify: modify preoperation plugin failed\n", + 0, 0, 0 ); #else - Debug(LDAP_DEBUG_TRACE, "do_modify: modify preoperation plugin failed.\n", - 0, 0, 0); + Debug(LDAP_DEBUG_TRACE, + "do_modify: modify preoperation plugin failed.\n", + 0, 0, 0); #endif - if ( ( slapi_pblock_get( op->o_pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || - rs->sr_err == LDAP_SUCCESS ) { + if ( ( slapi_pblock_get( op->o_pb, SLAPI_RESULT_CODE, + (void *)&rs->sr_err ) != 0 ) || rs->sr_err == LDAP_SUCCESS ) + { rs->sr_err = LDAP_OTHER; } slapi_int_free_ldapmods( modv ); @@ -463,8 +467,7 @@ do_modify( * because it accepts each modify request */ #ifndef SLAPD_MULTIMASTER - if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ) && - ( !op->o_bd->be_update_ndn.bv_len || repl_user )) + if ( !SLAP_SHADOW(op->o_bd) || repl_user ) #else if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) #endif @@ -512,18 +515,8 @@ do_modify( #ifndef SLAPD_MULTIMASTER /* send a referral */ } else { - BerVarray defref = NULL; - if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { - syncinfo_t *si; - LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) { - struct berval tmpbv; - ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] ); - ber_bvarray_add( &defref, &tmpbv ); - } - } else { - defref = op->o_bd->be_update_refs - ? op->o_bd->be_update_refs : default_referral; - } + BerVarray defref = op->o_bd->be_update_refs + ? op->o_bd->be_update_refs : default_referral; if ( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, NULL, &op->o_req_dn, @@ -535,9 +528,8 @@ do_modify( ber_bvarray_free( rs->sr_ref ); } } else { - send_ldap_error( op, rs, - LDAP_UNWILLING_TO_PERFORM, - "referral missing" ); + send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, + "shadow context; no update referral" ); } #endif } diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index ea8dd0e612..6c133312c6 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -277,7 +277,8 @@ do_modrdn( * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ - if ( (op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 )) == NULL ) { + op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 ); + if ( op->o_bd == NULL ) { rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); if (!rs->sr_ref) rs->sr_ref = default_referral; @@ -289,7 +290,7 @@ do_modrdn( if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref ); } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, - "referral missing" ); + "no global superior knowledge" ); } goto cleanup; } @@ -363,8 +364,7 @@ do_modrdn( /* do the update here */ int repl_user = be_isupdate( op->o_bd, &op->o_ndn ); #ifndef SLAPD_MULTIMASTER - if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo ) && - ( !op->o_bd->be_update_ndn.bv_len || repl_user )) + if ( !SLAP_SHADOW(op->o_bd) || repl_user ) #else if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) #endif @@ -415,18 +415,9 @@ do_modrdn( #ifndef SLAPD_MULTIMASTER } else { - BerVarray defref = NULL; - if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { - syncinfo_t *si; - LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) { - struct berval tmpbv; - ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] ); - ber_bvarray_add( &defref, &tmpbv ); - } - } else { - defref = op->o_bd->be_update_refs - ? op->o_bd->be_update_refs : default_referral; - } + BerVarray defref = op->o_bd->be_update_refs + ? op->o_bd->be_update_refs : default_referral; + if ( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); @@ -437,9 +428,8 @@ do_modrdn( if (rs->sr_ref != defref) ber_bvarray_free( rs->sr_ref ); } else { - send_ldap_error( op, rs, - LDAP_UNWILLING_TO_PERFORM, - "referral missing" ); + send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, + "shadow context; no update referral" ); } #endif } diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index bfb271b675..49e315ab8b 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -110,23 +110,25 @@ int passwd_extop( #ifndef SLAPD_MULTIMASTER /* This does not apply to multi-master case */ - if( op->o_bd->be_update_ndn.bv_len || - !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { + if(!( !SLAP_SHADOW( op->o_bd ) || be_isupdate( op->o_bd, &op->o_ndn ))) { /* we SHOULD return a referral in this case */ - BerVarray defref = NULL; - if ( !LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) { - syncinfo_t *si; - LDAP_STAILQ_FOREACH( si, &op->o_bd->be_syncinfo, si_next ) { - struct berval tmpbv; - ber_dupbv( &tmpbv, &si->si_provideruri_bv[0] ); - ber_bvarray_add( &defref, &tmpbv ); - } - } else { - defref = referral_rewrite( op->o_bd->be_update_refs, + BerVarray defref = op->o_bd->be_update_refs + ? op->o_bd->be_update_refs : default_referral; + + if( defref != NULL ) { + rs->sr_ref = referral_rewrite( op->o_bd->be_update_refs, NULL, NULL, LDAP_SCOPE_DEFAULT ); + if(rs->sr_ref) { + rs->sr_flags |= REP_REF_MUSTBEFREED; + } else { + rs->sr_ref = defref; + } + return LDAP_REFERRAL; + } - rs->sr_ref = defref; - return LDAP_REFERRAL; + + rs->sr_text = "shadow context; no update referral"; + return LDAP_UNWILLING_TO_PERFORM; } #endif /* !SLAPD_MULTIMASTER */ diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 17824d5126..3091d0b8c9 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -351,7 +351,7 @@ send_ldap_response( if (op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2 ) { - rc = ber_printf( ber, "t{ess" /*"}}"*/, + rc = ber_printf( ber, "t{ess" /*"}"*/, rs->sr_tag, rs->sr_err, rs->sr_matched == NULL ? "" : rs->sr_matched, rs->sr_text == NULL ? "" : rs->sr_text ); @@ -409,7 +409,9 @@ send_ldap_response( } #ifdef LDAP_CONNECTIONLESS - if( op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1 ) { + if( op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2 + && rc != -1 ) + { rc = ber_printf( ber, /*"{"*/ "N}" ); } #endif @@ -426,7 +428,9 @@ send_ldap_response( #ifdef LDAP_CONNECTIONLESS if (!op->o_conn || op->o_conn->c_is_udp == 0) #endif - ber_free_buf( ber ); + { + ber_free_buf( ber ); + } goto cleanup; } @@ -435,7 +439,9 @@ send_ldap_response( #ifdef LDAP_CONNECTIONLESS if (!op->o_conn || op->o_conn->c_is_udp == 0) #endif - ber_free_buf( ber ); + { + ber_free_buf( ber ); + } if ( bytes < 0 ) { #ifdef NEW_LOGGING @@ -454,7 +460,8 @@ send_ldap_response( #ifdef LDAP_SLAPI if ( op->o_pb ) { slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)rs->sr_err ); - slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, (void *)rs->sr_matched ); + slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, + (void *)rs->sr_matched ); slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, (void *)rs->sr_text ); } #endif /* LDAP_SLAPI */ @@ -475,6 +482,11 @@ cleanup: rs->sr_matched = NULL; } + if ( rs->sr_ref && rs->sr_flags & REP_REF_MUSTBEFREED ) { + ber_bvarray_free( rs->sr_ref ); + rs->sr_ref = NULL; + } + clean2: if (op->o_callback) { slap_callback *sc = op->o_callback; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 0edeca7d2b..f56fb0617e 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1662,9 +1662,10 @@ typedef struct slap_rep { rep_search_s sru_search; } sr_un; slap_mask_t sr_flags; -#define REP_ENTRY_MODIFIABLE 0x00000001 -#define REP_ENTRY_MUSTBEFREED 0x00000002 -#define REP_MATCHED_MUSTBEFREED 0x00000010 +#define REP_ENTRY_MODIFIABLE 0x0001U +#define REP_ENTRY_MUSTBEFREED 0x0002U +#define REP_MATCHED_MUSTBEFREED 0x0010U +#define REP_REF_MUSTBEFREED 0x0020U } SlapReply; /* short hands for response members */ -- 2.39.5