mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-27 10:09:43 -05:00
add cancel strategies (ITS#4560)
This commit is contained in:
parent
e5fc7845fc
commit
e5c173691d
16 changed files with 310 additions and 55 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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]> <real", 2, 3, 0,
|
||||
ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
|
||||
ldap_back_cf_gen, NULL, NULL, NULL },
|
||||
|
|
@ -294,6 +303,7 @@ static ConfigOCs ldapocs[] = {
|
|||
"$ olcDbTimeout "
|
||||
"$ olcDbIdleTimeout "
|
||||
"$ olcDbSingleConn "
|
||||
"$ olcDbCancel "
|
||||
") )",
|
||||
Cft_Database, ldapcfg},
|
||||
{ NULL, 0, NULL }
|
||||
|
|
@ -317,12 +327,20 @@ static slap_verbmasks tls_mode[] = {
|
|||
};
|
||||
|
||||
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 },
|
||||
|
|
@ -548,7 +566,7 @@ ldap_back_cf_gen( ConfigArgs *c )
|
|||
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 );
|
||||
|
|
@ -643,6 +661,23 @@ ldap_back_cf_gen( ConfigArgs *c )
|
|||
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 );
|
||||
|
|
@ -711,6 +746,7 @@ ldap_back_cf_gen( ConfigArgs *c )
|
|||
case LDAP_BACK_CFG_CHASE:
|
||||
case LDAP_BACK_CFG_T_F:
|
||||
case LDAP_BACK_CFG_WHOAMI:
|
||||
case LDAP_BACK_CFG_CANCEL:
|
||||
rc = 1;
|
||||
break;
|
||||
|
||||
|
|
@ -1258,14 +1294,41 @@ done_url:;
|
|||
}
|
||||
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 ) {
|
||||
|
|
@ -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 "
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 ...
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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 ?
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue