From e5c173691dfbaff552b351da929d61bf08713990 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 20 May 2006 14:29:01 +0000 Subject: [PATCH] add cancel strategies (ITS#4560) --- servers/slapd/back-ldap/back-ldap.h | 47 ++++++++--- servers/slapd/back-ldap/bind.c | 31 +++++++- servers/slapd/back-ldap/config.c | 113 +++++++++++++++++++++++++-- servers/slapd/back-ldap/init.c | 19 ++++- servers/slapd/back-ldap/proto-ldap.h | 1 + servers/slapd/back-ldap/search.c | 10 +-- servers/slapd/back-meta/add.c | 3 +- servers/slapd/back-meta/back-meta.h | 20 +++++ servers/slapd/back-meta/bind.c | 43 +++++++++- servers/slapd/back-meta/config.c | 41 +++++++++- servers/slapd/back-meta/delete.c | 3 +- servers/slapd/back-meta/init.c | 16 +++- servers/slapd/back-meta/map.c | 4 +- servers/slapd/back-meta/modify.c | 3 +- servers/slapd/back-meta/modrdn.c | 3 +- servers/slapd/back-meta/search.c | 8 +- 16 files changed, 310 insertions(+), 55 deletions(-) diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index e8e73cc462..197b745576 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -176,34 +176,57 @@ typedef struct ldapinfo_t { #define LDAP_BACK_RETRY_DEFAULT (3) unsigned li_flags; -#define LDAP_BACK_F_NONE 0x0000U -#define LDAP_BACK_F_SAVECRED 0x0001U -#define LDAP_BACK_F_USE_TLS 0x0002U -#define LDAP_BACK_F_PROPAGATE_TLS 0x0004U -#define LDAP_BACK_F_TLS_CRITICAL 0x0008U +#define LDAP_BACK_F_NONE (0x0000U) +#define LDAP_BACK_F_SAVECRED (0x0001U) +#define LDAP_BACK_F_USE_TLS (0x0002U) +#define LDAP_BACK_F_PROPAGATE_TLS (0x0004U) +#define LDAP_BACK_F_TLS_CRITICAL (0x0008U) #define LDAP_BACK_F_TLS_USE_MASK (LDAP_BACK_F_USE_TLS|LDAP_BACK_F_TLS_CRITICAL) #define LDAP_BACK_F_TLS_PROPAGATE_MASK (LDAP_BACK_F_PROPAGATE_TLS|LDAP_BACK_F_TLS_CRITICAL) #define LDAP_BACK_F_TLS_MASK (LDAP_BACK_F_TLS_USE_MASK|LDAP_BACK_F_TLS_PROPAGATE_MASK) -#define LDAP_BACK_F_CHASE_REFERRALS 0x0010U -#define LDAP_BACK_F_PROXY_WHOAMI 0x0020U +#define LDAP_BACK_F_CHASE_REFERRALS (0x0010U) +#define LDAP_BACK_F_PROXY_WHOAMI (0x0020U) -#define LDAP_BACK_F_SUPPORT_T_F_DISCOVER 0x0040U -#define LDAP_BACK_F_SUPPORT_T_F 0x0080U -#define LDAP_BACK_F_SUPPORT_T_F_MASK (LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER) +#define LDAP_BACK_F_T_F (0x0040U) +#define LDAP_BACK_F_T_F_DISCOVER (0x0080U) +#define LDAP_BACK_F_T_F_MASK (LDAP_BACK_F_T_F) +#define LDAP_BACK_F_T_F_MASK2 (LDAP_BACK_F_T_F_MASK|LDAP_BACK_F_T_F_DISCOVER) -#define LDAP_BACK_F_MONITOR 0x0100U -#define LDAP_BACK_F_SINGLECONN 0x0200U +#define LDAP_BACK_F_MONITOR (0x0100U) +#define LDAP_BACK_F_SINGLECONN (0x0200U) + +#define LDAP_BACK_F_ISOPEN (0x0400U) + +#define LDAP_BACK_F_CANCEL_ABANDON (0x0000U) +#define LDAP_BACK_F_CANCEL_IGNORE (0x1000U) +#define LDAP_BACK_F_CANCEL_EXOP (0x2000U) +#define LDAP_BACK_F_CANCEL_EXOP_DISCOVER (0x4000U) +#define LDAP_BACK_F_CANCEL_MASK (LDAP_BACK_F_CANCEL_IGNORE|LDAP_BACK_F_CANCEL_EXOP) +#define LDAP_BACK_F_CANCEL_MASK2 (LDAP_BACK_F_CANCEL_MASK|LDAP_BACK_F_CANCEL_EXOP_DISCOVER) #define LDAP_BACK_ISSET(li,f) ( ( (li)->li_flags & (f) ) == (f) ) +#define LDAP_BACK_ISMASK(li,m,f) ( ( (li)->li_flags & (m) ) == (f) ) + #define LDAP_BACK_SAVECRED(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_SAVECRED ) #define LDAP_BACK_USE_TLS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_USE_TLS ) #define LDAP_BACK_PROPAGATE_TLS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_PROPAGATE_TLS ) #define LDAP_BACK_TLS_CRITICAL(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_TLS_CRITICAL ) #define LDAP_BACK_CHASE_REFERRALS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_CHASE_REFERRALS ) #define LDAP_BACK_PROXY_WHOAMI(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_PROXY_WHOAMI ) + +#define LDAP_BACK_T_F(li) LDAP_BACK_ISMASK( (li), LDAP_BACK_F_T_F_MASK, LDAP_BACK_F_T_F ) +#define LDAP_BACK_T_F_DISCOVER(li) LDAP_BACK_ISMASK( (li), LDAP_BACK_F_T_F_MASK2, LDAP_BACK_F_T_F_DISCOVER ) + #define LDAP_BACK_MONITOR(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_MONITOR ) #define LDAP_BACK_SINGLECONN(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_SINGLECONN ) +#define LDAP_BACK_ISOPEN(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_ISOPEN ) + +#define LDAP_BACK_ABANDON(li) LDAP_BACK_ISMASK( (li), LDAP_BACK_F_CANCEL_MASK, LDAP_BACK_F_CANCEL_ABANDON ) +#define LDAP_BACK_IGNORE(li) LDAP_BACK_ISMASK( (li), LDAP_BACK_F_CANCEL_MASK, LDAP_BACK_F_CANCEL_IGNORE ) +#define LDAP_BACK_CANCEL(li) LDAP_BACK_ISMASK( (li), LDAP_BACK_F_CANCEL_MASK, LDAP_BACK_F_CANCEL_EXOP ) +#define LDAP_BACK_CANCEL_DISCOVER(li) LDAP_BACK_ISMASK( (li), LDAP_BACK_F_CANCEL_MASK2, LDAP_BACK_F_CANCEL_EXOP_DISCOVER ) + int li_version; ldap_avl_info_t li_conninfo; diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 11f55d21f1..74626b493c 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -1114,6 +1114,35 @@ ldap_back_default_urllist( return LDAP_SUCCESS; } +int +ldap_back_cancel( + ldapconn_t *lc, + Operation *op, + SlapReply *rs, + ber_int_t msgid, + ldap_back_send_t sendok ) +{ + ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; + + /* default behavior */ + if ( LDAP_BACK_ABANDON( li ) ) { + return ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL ); + } + + if ( LDAP_BACK_IGNORE( li ) ) { + return LDAP_SUCCESS; + } + + if ( LDAP_BACK_CANCEL( li ) ) { + /* FIXME: asynchronous? */ + return ldap_cancel_s( lc->lc_ld, msgid, NULL, NULL ); + } + + assert( 0 ); + + return LDAP_OTHER; +} + int ldap_back_op_result( ldapconn_t *lc, @@ -1157,7 +1186,7 @@ retry:; switch ( rc ) { case 0: if ( timeout ) { - (void)ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL ); + (void)ldap_back_cancel( lc, op, rs, msgid, sendok ); rs->sr_err = op->o_protocol >= LDAP_VERSION3 ? LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR; rs->sr_text = "Operation timed out"; diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index d270b40eab..02b475ca76 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -65,6 +65,7 @@ enum { LDAP_BACK_CFG_NETWORK_TIMEOUT, LDAP_BACK_CFG_VERSION, LDAP_BACK_CFG_SINGLECONN, + LDAP_BACK_CFG_CANCEL, LDAP_BACK_CFG_REWRITE, LDAP_BACK_CFG_LAST @@ -259,6 +260,14 @@ static ConfigTable ldapcfg[] = { "SYNTAX OMsBoolean " "SINGLE-VALUE )", NULL, NULL }, + { "cancel", "ABANDON|ignore|exop", 2, 0, 0, + ARG_MAGIC|LDAP_BACK_CFG_CANCEL, + ldap_back_cf_gen, "( OLcfgDbAt:3.20 " + "NAME 'olcDbCancel' " + "DESC 'abandon/ignore/exop operations when appropriate' " + "SYNTAX OMsDirectoryString " + "SINGLE-VALUE )", + NULL, NULL }, { "suffixmassage", "[virtual]> log, c->msg, 0 ); + return 1; + } + + rc = slap_discover_feature( li->li_uri, li->li_version, + slap_schema.si_ad_supportedFeatures->ad_cname.bv_val, + LDAP_FEATURE_ABSOLUTE_FILTERS ); + if ( rc == LDAP_COMPARE_TRUE ) { + mask |= LDAP_BACK_F_T_F; + } + } + + li->li_flags &= ~LDAP_BACK_F_T_F_MASK2; + li->li_flags |= mask; + } break; case LDAP_BACK_CFG_WHOAMI: if ( c->argc == 1 || c->value_int ) { @@ -1362,6 +1425,42 @@ done_url:; } break; + case LDAP_BACK_CFG_CANCEL: { + slap_mask_t mask; + + i = verb_to_mask( c->argv[1], cancel_mode ); + if ( BER_BVISNULL( &cancel_mode[i].word ) ) { + return 1; + } + + mask = cancel_mode[i].mask; + + if ( LDAP_BACK_ISOPEN( li ) + && mask == LDAP_BACK_F_CANCEL_EXOP_DISCOVER + && !LDAP_BACK_CANCEL( li ) ) + { + int rc; + + if ( li->li_uri == NULL ) { + snprintf( c->msg, sizeof( c->msg ), + "need URI to discover \"cancel\" support " + "in \"cancel exop-discover\"" ); + Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 ); + return 1; + } + + rc = slap_discover_feature( li->li_uri, li->li_version, + slap_schema.si_ad_supportedExtension->ad_cname.bv_val, + LDAP_EXOP_CANCEL ); + if ( rc == LDAP_COMPARE_TRUE ) { + mask |= LDAP_BACK_F_CANCEL_EXOP; + } + } + + li->li_flags &= ~LDAP_BACK_F_CANCEL_MASK2; + li->li_flags |= mask; + } break; + case LDAP_BACK_CFG_REWRITE: snprintf( c->msg, sizeof( c->msg ), "rewrite/remap capabilities have been moved " diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index 765f201c21..71e13be91c 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -200,19 +200,30 @@ ldap_back_db_open( BackendDB *be ) } #endif /* SLAPD_MONITOR */ - if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER ) { + if ( LDAP_BACK_T_F_DISCOVER( li ) && !LDAP_BACK_T_F( li ) ) { int rc; - li->li_flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER; - rc = slap_discover_feature( li->li_uri, li->li_version, slap_schema.si_ad_supportedFeatures->ad_cname.bv_val, LDAP_FEATURE_ABSOLUTE_FILTERS ); if ( rc == LDAP_COMPARE_TRUE ) { - li->li_flags |= LDAP_BACK_F_SUPPORT_T_F; + li->li_flags |= LDAP_BACK_F_T_F; } } + if ( LDAP_BACK_CANCEL_DISCOVER( li ) && !LDAP_BACK_CANCEL( li ) ) { + int rc; + + rc = slap_discover_feature( li->li_uri, li->li_version, + slap_schema.si_ad_supportedExtension->ad_cname.bv_val, + LDAP_EXOP_CANCEL ); + if ( rc == LDAP_COMPARE_TRUE ) { + li->li_flags |= LDAP_BACK_F_CANCEL_EXOP; + } + } + + li->li_flags |= LDAP_BACK_F_ISOPEN; + return 0; } diff --git a/servers/slapd/back-ldap/proto-ldap.h b/servers/slapd/back-ldap/proto-ldap.h index 05d6883254..1be04ec5f6 100644 --- a/servers/slapd/back-ldap/proto-ldap.h +++ b/servers/slapd/back-ldap/proto-ldap.h @@ -56,6 +56,7 @@ int ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_s int ldap_back_map_result( SlapReply *rs ); int ldap_back_op_result( ldapconn_t *lc, Operation *op, SlapReply *rs, ber_int_t msgid, time_t timeout, ldap_back_send_t sendok ); +int ldap_back_cancel( ldapconn_t *lc, Operation *op, SlapReply *rs, ber_int_t msgid, ldap_back_send_t sendok ); int ldap_back_init_cf( BackendInfo *bi ); diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index ec68159ccf..4fa338b0d7 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -75,7 +75,7 @@ ldap_back_munge_filter( if ( strncmp( ptr, bv_true.bv_val, bv_true.bv_len ) == 0 ) { oldbv = &bv_true; - if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F ) { + if ( LDAP_BACK_T_F( li ) ) { newbv = &bv_t; } else { @@ -85,7 +85,7 @@ ldap_back_munge_filter( } else if ( strncmp( ptr, bv_false.bv_val, bv_false.bv_len ) == 0 ) { oldbv = &bv_false; - if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F ) { + if ( LDAP_BACK_T_F( li ) ) { newbv = &bv_f; } else { @@ -264,7 +264,7 @@ retry: if ( rc > 0 ) { ldap_msgfree( res ); } - ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL ); + (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); rc = SLAPD_ABANDON; goto finish; } @@ -277,7 +277,7 @@ retry: if ( op->ors_tlimit != SLAP_NO_LIMIT && slap_get_time() > stoptime ) { - ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL ); + (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); rc = rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; goto finish; } @@ -320,7 +320,7 @@ retry: if ( rc == LDAP_UNAVAILABLE ) { rc = rs->sr_err = LDAP_OTHER; } else { - ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL ); + (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); } goto finish; } diff --git a/servers/slapd/back-meta/add.c b/servers/slapd/back-meta/add.c index 02a0093d5c..5835012a87 100644 --- a/servers/slapd/back-meta/add.c +++ b/servers/slapd/back-meta/add.c @@ -195,8 +195,7 @@ retry:; break; case 0: - ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld, - msgid, NULL, NULL ); + (void)meta_back_cancel( mc, op, rs, msgid, candidate, LDAP_BACK_DONTSEND ); rs->sr_err = op->o_protocol >= LDAP_VERSION3 ? LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR; break; diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 0516f619f3..a8c969ba34 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -228,6 +228,17 @@ typedef struct metatarget_t { struct ldaprwmap mt_rwmap; unsigned mt_flags; +#define META_BACK_TGT_ISSET(mt,f) ( ( (mt)->mt_flags & (f) ) == (f) ) +#define META_BACK_TGT_ISMASK(mt,m,f) ( ( (mt)->mt_flags & (m) ) == (f) ) + +#define META_BACK_TGT_T_F(mt) META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_T_F_MASK, LDAP_BACK_F_T_F ) +#define META_BACK_TGT_T_F_DISCOVER(mt) META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_T_F_MASK2, LDAP_BACK_F_T_F_DISCOVER ) + +#define META_BACK_TGT_ABANDON(mt) META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_CANCEL_MASK, LDAP_BACK_F_CANCEL_ABANDON ) +#define META_BACK_TGT_IGNORE(mt) META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_CANCEL_MASK, LDAP_BACK_F_CANCEL_IGNORE ) +#define META_BACK_TGT_CANCEL(mt) META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_CANCEL_MASK, LDAP_BACK_F_CANCEL_EXOP ) +#define META_BACK_TGT_CANCEL_DISCOVER(mt) META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_CANCEL_MASK2, LDAP_BACK_F_CANCEL_EXOP_DISCOVER ) + int mt_version; time_t mt_network_timeout; struct timeval mt_bind_timeout; @@ -354,6 +365,15 @@ meta_back_single_dobind( int retries, int dolock ); +extern int +meta_back_cancel( + metaconn_t *mc, + Operation *op, + SlapReply *rs, + ber_int_t msgid, + int candidate, + ldap_back_send_t sendok ); + extern int meta_back_op_result( metaconn_t *mc, diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index cd79a04ced..560fad0a0f 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -376,7 +376,7 @@ retry:; rs->sr_err = LDAP_BUSY; if ( rebinding ) { - ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL ); + (void)meta_back_cancel( mc, op, rs, msgid, candidate, LDAP_BACK_DONTSEND ); break; } @@ -393,7 +393,7 @@ retry:; &rs->sr_err ); if ( rebinding ) { - ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL ); + (void)meta_back_cancel( mc, op, rs, msgid, candidate, LDAP_BACK_DONTSEND ); } snprintf( buf, sizeof( buf ), @@ -552,7 +552,7 @@ retry:; rc = LDAP_BUSY; if ( rebinding ) { - ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL ); + (void)meta_back_cancel( mc, op, rs, msgid, candidate, LDAP_BACK_DONTSEND ); break; } @@ -569,7 +569,7 @@ retry:; &rs->sr_err ); if ( rebinding ) { - ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL ); + (void)meta_back_cancel( mc, op, rs, msgid, candidate, LDAP_BACK_DONTSEND ); } snprintf( buf, sizeof( buf ), @@ -887,6 +887,41 @@ meta_back_default_urllist( return LDAP_SUCCESS; } +int +meta_back_cancel( + metaconn_t *mc, + Operation *op, + SlapReply *rs, + ber_int_t msgid, + int candidate, + ldap_back_send_t sendok ) +{ + metainfo_t *mi = (metainfo_t *)op->o_bd->be_private; + + metatarget_t *mt = mi->mi_targets[ candidate ]; + metasingleconn_t *msc = &mc->mc_conns[ candidate ]; + + /* default behavior */ + if ( META_BACK_TGT_ABANDON( mt ) ) { + return ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL ); + } + + if ( META_BACK_TGT_IGNORE( mt ) ) { + return LDAP_SUCCESS; + } + + if ( META_BACK_TGT_CANCEL( mt ) ) { + /* FIXME: asynchronous? */ + return ldap_cancel_s( msc->msc_ld, msgid, NULL, NULL ); + } + + assert( 0 ); + + return LDAP_OTHER; +} + + + /* * FIXME: error return must be handled in a cleaner way ... */ diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index abd351e70d..e93bd6c41d 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -734,16 +734,16 @@ meta_back_db_config( switch ( check_true_false( argv[ 1 ] ) ) { case 0: - *flagsp &= ~(LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER); + *flagsp &= ~LDAP_BACK_F_T_F_MASK2; break; case 1: - *flagsp |= LDAP_BACK_F_SUPPORT_T_F; + *flagsp |= LDAP_BACK_F_T_F; break; default: if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) { - *flagsp |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER; + *flagsp |= LDAP_BACK_F_T_F_DISCOVER; } else { Debug( LDAP_DEBUG_ANY, @@ -833,6 +833,41 @@ meta_back_db_config( return 1; } + } else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) { + unsigned flag = 0; + unsigned *flagsp = mi->mi_ntargets ? + &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags + : &mi->mi_flags; + + if ( argc != 2 ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: \"cancel {abandon|ignore|exop}\" takes 1 argument\n", + fname, lineno, 0 ); + return( 1 ); + } + + if ( strcasecmp( argv[ 1 ], "abandon" ) == 0 ) { + flag = LDAP_BACK_F_CANCEL_ABANDON; + + } else if ( strcasecmp( argv[ 1 ], "ignore" ) == 0 ) { + flag = LDAP_BACK_F_CANCEL_IGNORE; + + } else if ( strcasecmp( argv[ 1 ], "exop" ) == 0 ) { + flag = LDAP_BACK_F_CANCEL_EXOP; + + } else if ( strcasecmp( argv[ 1 ], "exop-discover" ) == 0 ) { + flag = LDAP_BACK_F_CANCEL_EXOP_DISCOVER; + + } else { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: \"cancel {abandon|ignore|exop[-discover]}\": unknown mode \"%s\" \n", + fname, lineno, argv[ 1 ] ); + return( 1 ); + } + + *flagsp &= ~LDAP_BACK_F_CANCEL_MASK2; + *flagsp |= flag; + } else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) { char *sep; time_t *tv = mi->mi_ntargets ? diff --git a/servers/slapd/back-meta/delete.c b/servers/slapd/back-meta/delete.c index 4d23793a83..b660c76dc0 100644 --- a/servers/slapd/back-meta/delete.c +++ b/servers/slapd/back-meta/delete.c @@ -94,8 +94,7 @@ retry:; break; case 0: - ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld, - msgid, NULL, NULL ); + (void)meta_back_cancel( mc, op, rs, msgid, candidate, LDAP_BACK_DONTSEND ); rs->sr_err = op->o_protocol >= LDAP_VERSION3 ? LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR; break; diff --git a/servers/slapd/back-meta/init.c b/servers/slapd/back-meta/init.c index 09f7007afc..5462a6fc44 100644 --- a/servers/slapd/back-meta/init.c +++ b/servers/slapd/back-meta/init.c @@ -130,15 +130,23 @@ meta_back_db_open( for ( i = 0; i < mi->mi_ntargets; i++ ) { metatarget_t *mt = mi->mi_targets[ i ]; - if ( mt->mt_flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER ) - { - mt->mt_flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER; + if ( META_BACK_TGT_T_F_DISCOVER( mt ) ) { rc = slap_discover_feature( mt->mt_uri, mt->mt_version, slap_schema.si_ad_supportedFeatures->ad_cname.bv_val, LDAP_FEATURE_ABSOLUTE_FILTERS ); if ( rc == LDAP_COMPARE_TRUE ) { - mt->mt_flags |= LDAP_BACK_F_SUPPORT_T_F; + mt->mt_flags |= LDAP_BACK_F_T_F; + } + } + + if ( META_BACK_TGT_CANCEL_DISCOVER( mt ) ) { + rc = slap_discover_feature( mt->mt_uri, + mt->mt_version, + slap_schema.si_ad_supportedExtension->ad_cname.bv_val, + LDAP_EXOP_CANCEL ); + if ( rc == LDAP_COMPARE_TRUE ) { + mt->mt_flags |= LDAP_BACK_F_CANCEL_EXOP; } } } diff --git a/servers/slapd/back-meta/map.c b/servers/slapd/back-meta/map.c index 912bd1671d..0f01e6bfc5 100644 --- a/servers/slapd/back-meta/map.c +++ b/servers/slapd/back-meta/map.c @@ -516,7 +516,7 @@ ldap_back_int_filter_map_rewrite( /* FIXME: treat UNDEFINED as FALSE */ case SLAPD_COMPARE_UNDEFINED: computed:; - if ( dc->target->mt_flags & LDAP_BACK_F_SUPPORT_T_F ) { + if ( META_BACK_TGT_T_F( dc->target ) ) { tmp = &ber_bvtf_false; break; } @@ -524,7 +524,7 @@ computed:; break; case LDAP_COMPARE_TRUE: - if ( dc->target->mt_flags & LDAP_BACK_F_SUPPORT_T_F ) { + if ( META_BACK_TGT_T_F( dc->target ) ) { tmp = &ber_bvtf_true; break; } diff --git a/servers/slapd/back-meta/modify.c b/servers/slapd/back-meta/modify.c index 2e11c5b696..3ef81f1192 100644 --- a/servers/slapd/back-meta/modify.c +++ b/servers/slapd/back-meta/modify.c @@ -203,8 +203,7 @@ retry:; break; case 0: - ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld, - msgid, NULL, NULL ); + (void)meta_back_cancel( mc, op, rs, msgid, candidate, LDAP_BACK_DONTSEND ); rs->sr_err = op->o_protocol >= LDAP_VERSION3 ? LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR; maperr = 0; diff --git a/servers/slapd/back-meta/modrdn.c b/servers/slapd/back-meta/modrdn.c index 2c7d603b2b..3d94f1083e 100644 --- a/servers/slapd/back-meta/modrdn.c +++ b/servers/slapd/back-meta/modrdn.c @@ -149,8 +149,7 @@ retry:; break; case 0: - ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld, - msgid, NULL, NULL ); + (void)meta_back_cancel( mc, op, rs, msgid, candidate, LDAP_BACK_DONTSEND ); rs->sr_err = op->o_protocol >= LDAP_VERSION3 ? LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR; break; diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 45c16240bd..50519be3f2 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -1072,13 +1072,11 @@ really_bad:; /* check for abandon */ if ( op->o_abandon || doabandon ) { for ( i = 0; i < mi->mi_ntargets; i++ ) { - metasingleconn_t *msc = &mc->mc_conns[ i ]; - if ( candidates[ i ].sr_msgid != META_MSGID_IGNORE ) { - ldap_abandon_ext( msc->msc_ld, - candidates[ i ].sr_msgid, - NULL, NULL ); + (void)meta_back_cancel( mc, op, rs, + candidates[ i ].sr_msgid, i, + LDAP_BACK_DONTSEND ); candidates[ i ].sr_msgid = META_MSGID_IGNORE; } } -- 2.39.5