#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;
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,
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";
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
"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]> <real", 2, 3, 0,
ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
ldap_back_cf_gen, NULL, NULL, NULL },
"$ olcDbTimeout "
"$ olcDbIdleTimeout "
"$ olcDbSingleConn "
+ "$ olcDbCancel "
") )",
Cft_Database, ldapcfg},
{ NULL, 0, NULL }
};
static slap_verbmasks t_f_mode[] = {
- { BER_BVC( "yes" ), LDAP_BACK_F_SUPPORT_T_F },
- { BER_BVC( "discover" ), LDAP_BACK_F_SUPPORT_T_F_DISCOVER },
+ { BER_BVC( "yes" ), LDAP_BACK_F_T_F },
+ { BER_BVC( "discover" ), LDAP_BACK_F_T_F_DISCOVER },
{ BER_BVC( "no" ), LDAP_BACK_F_NONE },
{ BER_BVNULL, 0 }
};
+static slap_verbmasks cancel_mode[] = {
+ { BER_BVC( "ignore" ), LDAP_BACK_F_CANCEL_IGNORE },
+ { BER_BVC( "exop" ), LDAP_BACK_F_CANCEL_EXOP },
+ { BER_BVC( "exop-discover" ), LDAP_BACK_F_CANCEL_EXOP_DISCOVER },
+ { BER_BVC( "abandon" ), LDAP_BACK_F_CANCEL_ABANDON },
+ { BER_BVNULL, 0 }
+};
+
static slap_cf_aux_table timeout_table[] = {
{ BER_BVC("add="), 0 * sizeof( time_t ), 'u', 0, NULL },
{ BER_BVC("delete="), 1 * sizeof( time_t ), 'u', 0, NULL },
break;
case LDAP_BACK_CFG_T_F:
- enum_to_verb( t_f_mode, (li->li_flags & LDAP_BACK_F_SUPPORT_T_F_MASK), &bv );
+ enum_to_verb( t_f_mode, (li->li_flags & LDAP_BACK_F_T_F_MASK2), &bv );
if ( BER_BVISNULL( &bv ) ) {
/* there's something wrong... */
assert( 0 );
c->value_int = LDAP_BACK_SINGLECONN( li );
break;
+ case LDAP_BACK_CFG_CANCEL: {
+ slap_mask_t mask = LDAP_BACK_F_CANCEL_MASK2;
+
+ if ( LDAP_BACK_CANCEL_DISCOVER( li ) ) {
+ mask &= ~LDAP_BACK_F_CANCEL_EXOP;
+ }
+ enum_to_verb( cancel_mode, (li->li_flags & mask), &bv );
+ if ( BER_BVISNULL( &bv ) ) {
+ /* there's something wrong... */
+ assert( 0 );
+ rc = 1;
+
+ } else {
+ value_add_one( &c->rvalue_vals, &bv );
+ }
+ } break;
+
default:
/* FIXME: we need to handle all... */
assert( 0 );
case LDAP_BACK_CFG_CHASE:
case LDAP_BACK_CFG_T_F:
case LDAP_BACK_CFG_WHOAMI:
+ case LDAP_BACK_CFG_CANCEL:
rc = 1;
break;
}
break;
- case LDAP_BACK_CFG_T_F:
+ case LDAP_BACK_CFG_T_F: {
+ slap_mask_t mask;
+
i = verb_to_mask( c->argv[1], t_f_mode );
if ( BER_BVISNULL( &t_f_mode[i].word ) ) {
return 1;
}
- li->li_flags &= ~LDAP_BACK_F_SUPPORT_T_F_MASK;
- li->li_flags |= t_f_mode[i].mask;
- break;
+
+ mask = t_f_mode[i].mask;
+
+ if ( LDAP_BACK_ISOPEN( li )
+ && mask == LDAP_BACK_F_T_F_DISCOVER
+ && !LDAP_BACK_T_F( 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_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 ) {
}
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 "
}
#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;
}
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 );
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 {
} 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 {
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;
}
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;
}
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;
}
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;
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;
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,
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;
}
&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 ),
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;
}
&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 ),
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 ...
*/
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,
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 ?
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;
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;
}
}
}
/* 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;
}
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;
}
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;
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;
/* 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;
}
}