Commit b008f1e8 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Sync with HEAD

parent 4b6b0e90
......@@ -80,6 +80,12 @@ int protocol = -1;
int verbose = 0;
int version = 0;
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
int chaining = 0;
static int chainingResolve = -1;
static int chainingContinuation = -1;
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
/* Set in main() */
char *prog = NULL;
......@@ -107,6 +113,11 @@ N_(" [!]noop\n")
#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
N_(" ppolicy\n")
#endif
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
N_(" [!]chaining[=<resolveBehavior>[/<continuationBehavior>]]\n")
N_(" one of \"chainingPreferred\", \"chainingRequired\",\n")
N_(" \"referralsPreferred\", \"referralsRequired\"\n")
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
N_(" [!]postread[=<attrs>] (a comma-separated attribute list)\n")
N_(" [!]preread[=<attrs>] (a comma-separated attribute list)\n"),
N_(" -f file read operations from `file'\n"),
......@@ -286,6 +297,52 @@ tool_args( int argc, char **argv )
postread = 1 + crit;
postread_attrs = cvalue;
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
} else if ( strcasecmp( control, "chaining" ) == 0 ) {
chaining = 1 + crit;
if ( cvalue != NULL ) {
char *continuation;
continuation = strchr( cvalue, '/' );
if ( continuation ) {
/* FIXME: this makes sense only in searches */
*continuation++ = '\0';
if ( strcasecmp( continuation, "chainingPreferred" ) == 0 ) {
chainingContinuation = LDAP_CHAINING_PREFERRED;
} else if ( strcasecmp( continuation, "chainingRequired" ) == 0 ) {
chainingContinuation = LDAP_CHAINING_REQUIRED;
} else if ( strcasecmp( continuation, "referralsPreferred" ) == 0 ) {
chainingContinuation = LDAP_REFERRALS_PREFERRED;
} else if ( strcasecmp( continuation, "referralsRequired" ) == 0 ) {
chainingContinuation = LDAP_REFERRALS_REQUIRED;
} else {
fprintf( stderr,
"chaining behavior control "
"continuation value \"%s\" invalid\n",
continuation );
exit( EXIT_FAILURE );
}
}
if ( strcasecmp( cvalue, "chainingPreferred" ) == 0 ) {
chainingResolve = LDAP_CHAINING_PREFERRED;
} else if ( strcasecmp( cvalue, "chainingRequired" ) == 0 ) {
chainingResolve = LDAP_CHAINING_REQUIRED;
} else if ( strcasecmp( cvalue, "referralsPreferred" ) == 0 ) {
chainingResolve = LDAP_REFERRALS_PREFERRED;
} else if ( strcasecmp( cvalue, "referralsRequired" ) == 0 ) {
chainingResolve = LDAP_REFERRALS_REQUIRED;
} else {
fprintf( stderr,
"chaining behavior control "
"resolve value \"%s\" invalid\n",
cvalue);
exit( EXIT_FAILURE );
}
}
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
} else {
fprintf( stderr, "Invalid general control name: %s\n",
control );
......@@ -867,7 +924,7 @@ void
tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
{
int i = 0, j, crit = 0, err;
LDAPControl c[8], **ctrls;
LDAPControl c[9], **ctrls;
ctrls = (LDAPControl**) malloc(sizeof(c) + (count+1)*sizeof(LDAPControl*));
if ( ctrls == NULL ) {
......@@ -915,8 +972,7 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
if ( manageDSAit ) {
c[i].ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
c[i].ldctl_value.bv_val = NULL;
c[i].ldctl_value.bv_len = 0;
BER_BVZERO( &c[i].ldctl_value );
c[i].ldctl_iscritical = manageDSAit > 1;
ctrls[i] = &c[i];
i++;
......@@ -924,8 +980,7 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
if ( noop ) {
c[i].ldctl_oid = LDAP_CONTROL_NOOP;
c[i].ldctl_value.bv_val = NULL;
c[i].ldctl_value.bv_len = 0;
BER_BVZERO( &c[i].ldctl_value );
c[i].ldctl_iscritical = noop > 1;
ctrls[i] = &c[i];
i++;
......@@ -991,6 +1046,52 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
if( attrs ) ldap_charray_free( attrs );
}
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
if ( chaining ) {
if ( chainingResolve > -1 ) {
BerElementBuffer berbuf;
BerElement *ber = (BerElement *)&berbuf;
ber_init2( ber, NULL, LBER_USE_DER );
err = ber_printf( ber, "{e" /* } */, chainingResolve );
if ( err == -1 ) {
ber_free( ber, 1 );
fprintf( stderr, _("Chaining behavior control encoding error!\n") );
exit( EXIT_FAILURE );
}
if ( chainingContinuation > -1 ) {
err = ber_printf( ber, "e", chainingContinuation );
if ( err == -1 ) {
ber_free( ber, 1 );
fprintf( stderr, _("Chaining behavior control encoding error!\n") );
exit( EXIT_FAILURE );
}
}
err = ber_printf( ber, /* { */ "N}" );
if ( err == -1 ) {
ber_free( ber, 1 );
fprintf( stderr, _("Chaining behavior control encoding error!\n") );
exit( EXIT_FAILURE );
}
if ( ber_flatten2( ber, &c[i].ldctl_value, 0 ) == -1 ) {
exit( EXIT_FAILURE );
}
} else {
BER_BVZERO( &c[i].ldctl_value );
}
c[i].ldctl_oid = LDAP_CONTROL_X_CHAINING_BEHAVIOR;
c[i].ldctl_iscritical = chaining > 1;
ctrls[i] = &c[i];
i++;
}
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
while ( count-- ) {
ctrls[i++] = extra_c++;
}
......
......@@ -49,6 +49,9 @@ extern int manageDSAit;
extern int noop;
extern int ppolicy;
extern int preread, postread;
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
extern int chaining;
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
extern int not;
extern int want_bindpw;
......
......@@ -379,7 +379,7 @@ handle_private_option( int i )
if( crit ) subentries *= -1;
#endif
} else if ( strcasecmp( control, "sync" ) == 0 ) {
} else if ( strcasecmp( control, "sync" ) == 0 ) {
char *cookiep;
char *slimitp;
if ( ldapsync ) {
......@@ -664,31 +664,34 @@ getNextPage:
#ifdef LDAP_CONTROL_PAGEDRESULTS
|| pagedResults
#endif
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
|| chaining
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
|| ldapsync
|| subentries || valuesReturnFilter )
{
int err;
int i=0;
LDAPControl c[6];
LDAPControl c[10];
#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
if ( domainScope ) {
c[i].ldctl_oid = LDAP_CONTROL_X_DOMAIN_SCOPE;
c[i].ldctl_value.bv_val = NULL;
c[i].ldctl_value.bv_len = 0;
c[i].ldctl_iscritical = domainScope > 1;
i++;
}
if ( domainScope ) {
c[i].ldctl_oid = LDAP_CONTROL_X_DOMAIN_SCOPE;
c[i].ldctl_value.bv_val = NULL;
c[i].ldctl_value.bv_len = 0;
c[i].ldctl_iscritical = domainScope > 1;
i++;
}
#endif
#ifdef LDAP_CONTROL_SUBENTRIES
if ( subentries ) {
if (( seber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
if (( seber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
return EXIT_FAILURE;
}
err = ber_printf( seber, "b", abs(subentries) == 1 ? 0 : 1 );
if ( err == -1 ) {
if ( err == -1 ) {
ber_free( seber, 1 );
fprintf( stderr, _("Subentries control encoding error!\n") );
return EXIT_FAILURE;
......
......@@ -73,12 +73,6 @@ results if the data comes from a transaction that is later aborted.
In this case, the modified data is discarded and a subsequent search
will return a different result.
.TP
.B fasttool
Disables transaction logging when using the slapadd/slapindex tools,
using the DB_TXN_NOT_DURABLE flag. Does not affect normal slapd operation,
but will improve the performance of slapadd/slapindex.
See the Berkeley DB reference guide for more details.
.TP
.B idlcachesize <integer>
Specify the size of the in-memory index cache, in index slots. The
default is zero. A larger value will speed up frequent searches of
......
......@@ -277,6 +277,18 @@ typedef struct ldapcontrol {
#define LDAP_SEARCH_FLAG_DOMAIN_SCOPE 1 /* do not generate referrals */
#define LDAP_SEARCH_FLAG_PHANTOM_ROOT 2 /* search all NCs subordinate to base */
/* LDAP Chaining Behavior Control *//* work in progress */
/* <draft-sermersheim-ldap-chaining>;
* see also LDAP_REQUIRES_CHAINING, LDAP_CANNOT_CHAIN */
#ifdef LDAP_DEVEL
#define LDAP_CONTROL_X_CHAINING_BEHAVIOR "1.3.6.1.4.1.4203.666.11.3"
#define LDAP_CHAINING_PREFERRED 0
#define LDAP_CHAINING_REQUIRED 1
#define LDAP_REFERRALS_PREFERRED 2
#define LDAP_REFERRALS_REQUIRED 3
#endif
/* LDAP Unsolicited Notifications */
#define LDAP_NOTICE_OF_DISCONNECTION "1.3.6.1.4.1.1466.20036" /* RFC 2251 */
#define LDAP_NOTICE_DISCONNECT LDAP_NOTICE_OF_DISCONNECTION
......@@ -550,6 +562,13 @@ typedef struct ldapcontrol {
/* for the Assertion control */
#define LDAP_ASSERTION_FAILED 0x410f
/* for the Chaining Behavior control (consecutive result codes requested;
* see <draft-sermersheim-ldap-chaining> ) */
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
#define LDAP_REQUIRES_CHAINING 0x4110
#define LDAP_CANNOT_CHAIN 0x4111
#endif
/* API Error Codes
*
* Based on draft-ietf-ldap-c-api-xx
......
......@@ -317,6 +317,8 @@ void *slapi_get_object_extension(int objecttype, void *object,
void slapi_set_object_extension(int objecttype, void *object,
int extensionhandle, void *extension);
int slapi_x_backend_get_flags( const Slapi_Backend *be, unsigned long *flags );
/* parameters currently supported */
/*
......@@ -330,6 +332,20 @@ void slapi_set_object_extension(int objecttype, void *object,
#define SLAPI_ATTR_FLAG_COLLECTIVE 0x0080
#define SLAPI_ATTR_FLAG_NOUSERMOD 0x0100
/*
* Backend flags returned by slapi_x_backend_get_flags()
*/
#define SLAPI_BACKEND_FLAG_NOLASTMOD 0x0001U
#define SLAPI_BACKEND_FLAG_NO_SCHEMA_CHECK 0x0002U
#define SLAPI_BACKEND_FLAG_GLUE_INSTANCE 0x0010U /* a glue backend */
#define SLAPI_BACKEND_FLAG_GLUE_SUBORDINATE 0x0020U /* child of a glue hierarchy */
#define SLAPI_BACKEND_FLAG_GLUE_LINKED 0x0040U /* child is connected to parent */
#define SLAPI_BACKEND_FLAG_OVERLAY 0x0080U /* this db struct is an overlay */
#define SLAPI_BACKEND_FLAG_GLOBAL_OVERLAY 0x0100U /* this db struct is a global overlay */
#define SLAPI_BACKEND_FLAG_SHADOW 0x8000U /* a shadow */
#define SLAPI_BACKEND_FLAG_SYNC_SHADOW 0x1000U /* a sync shadow */
#define SLAPI_BACKEND_FLAG_SLURP_SHADOW 0x2000U /* a slurp shadow */
/*
* ACL levels
*/
......
......@@ -1125,7 +1125,7 @@ re_encode_request( LDAP *ld,
scope = LDAP_SCOPE_BASE;
break;
case LDAP_SCOPE_SUBTREE:
#ifdef LDAP_FEATURE_SUBORDINATE_SCOPE
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
#endif
scope = LDAP_SCOPE_SUBTREE;
......
......@@ -509,7 +509,7 @@ desc2str_len( LDAPURLDesc *u )
case LDAP_SCOPE_BASE:
case LDAP_SCOPE_ONELEVEL:
case LDAP_SCOPE_SUBTREE:
#ifdef LDAP_FEATURE_SUBORDINATE_SCOPE
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
#endif
switch ( u->lud_scope ) {
......@@ -525,7 +525,7 @@ desc2str_len( LDAPURLDesc *u )
len += STRLENOF( "sub" );
break;
#ifdef LDAP_FEATURE_SUBORDINATE_SCOPE
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
len += STRLENOF( "subordinate" );
break;
......@@ -597,7 +597,7 @@ desc2str( LDAPURLDesc *u, char *s, int len )
case LDAP_SCOPE_BASE:
case LDAP_SCOPE_ONELEVEL:
case LDAP_SCOPE_SUBTREE:
#ifdef LDAP_FEATURE_SUBORDINATE_SCOPE
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
#endif
gotscope = 1;
......@@ -690,7 +690,7 @@ desc2str( LDAPURLDesc *u, char *s, int len )
len -= STRLENOF("sub");
break;
#ifdef LDAP_FEATURE_SUBORDINATE_SCOPE
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
strcpy( &s[sofar], "children" );
sofar += STRLENOF("children");
......
......@@ -63,15 +63,6 @@ bdb_db_config(
} else if ( strcasecmp( argv[0], "dbnosync" ) == 0 ) {
bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC;
/* slapadd/slapindex logging configuration */
} else if ( strcasecmp( argv[0], "fasttool" ) == 0 ) {
if ( slapMode & SLAP_TOOL_MODE )
#if DB_VERSION_FULL >= 0x04030015
bdb->bi_dbenv_xflags |= DB_LOG_INMEMORY;
#else
bdb->bi_dbenv_xflags |= DB_TXN_NOT_DURABLE;
#endif
/* slapindex algorithm tuning */
} else if ( strcasecmp( argv[0], "linearindex" ) == 0 ) {
bdb->bi_linear_index = 1;
......
......@@ -41,27 +41,6 @@ struct berval bdb_uuid = BER_BVNULL;
typedef void * db_malloc(size_t);
typedef void * db_realloc(void *, size_t);
#if 0
static int
bdb_open( BackendInfo *bi )
{
return 0;
}
static int
bdb_destroy( BackendInfo *bi )
{
return 0;
}
static int
bdb_close( BackendInfo *bi )
{
/* terminate the underlying database system */
return 0;
}
#endif
static int
bdb_db_init( BackendDB *be )
{
......@@ -140,7 +119,7 @@ bdb_db_open( BackendDB *be )
flags = DB_INIT_MPOOL | DB_THREAD | DB_CREATE;
if ( !( slapMode & SLAP_TOOL_QUICK ))
if ( !( slapMode & SLAP_TOOL_QUICK ))
flags |= DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN;
#if 0
......@@ -386,7 +365,6 @@ if ( !( slapMode & SLAP_TOOL_QUICK ))
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
}
/* <insert> open (and create) index databases */
return 0;
}
......@@ -583,11 +561,6 @@ bdb_back_initialize(
bi->bi_op_unbind = 0;
#if 0 /* DELETE ME */
bi->bi_op_abandon = bdb_abandon;
bi->bi_op_cancel = bdb_cancel;
#endif
bi->bi_extended = bdb_extended;
bi->bi_chk_referrals = bdb_referrals;
......
......@@ -404,6 +404,8 @@ ldap_back_dobind_int(
ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
if ( !lc->lc_bound ) {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
/*
* FIXME: we need to let clients use proxyAuthz
* otherwise we cannot do symmetric pools of servers;
......@@ -419,11 +421,17 @@ ldap_back_dobind_int(
/*
* if no bind took place yet, but the connection is bound
* and the "idassert-authcDN" (or other ID) is set,
* then bind as the asserting ideintity and explicitly
* then bind as the asserting identity and explicitly
* add the proxyAuthz control to every operation with the
* dn bound to the connection as control value.
* This is done also if this is the authrizing backend,
* but the "override" flag is given to idassert.
* It allows to use SASL bind and yet proxyAuthz users
*/
if ( op->o_conn != NULL && BER_BVISNULL( &lc->lc_bound_ndn ) ) {
if ( op->o_conn != NULL &&
( BER_BVISNULL( &lc->lc_bound_ndn ) ||
( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
{
(void)ldap_back_proxy_authz_bind( lc, op, rs );
goto done;
}
......
......@@ -29,7 +29,35 @@
#include "slap.h"
#include "back-ldap.h"
static BackendInfo *lback;
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
#define SLAP_CH_RESOLVE_SHIFT SLAP_CONTROL_SHIFT
#define SLAP_CH_RESOLVE_MASK (0x3 << SLAP_CH_RESOLVE_SHIFT)
#define SLAP_CH_RESOLVE_CHAINING_PREFERRED (LDAP_CHAINING_PREFERRED << SLAP_CH_RESOLVE_SHIFT)
#define SLAP_CH_RESOLVE_CHAINING_REQUIRED (LDAP_CHAINING_REQUIRED << SLAP_CH_RESOLVE_SHIFT)
#define SLAP_CH_RESOLVE_REFERRALS_PREFERRED (LDAP_REFERRALS_PREFERRED << SLAP_CH_RESOLVE_SHIFT)
#define SLAP_CH_RESOLVE_REFERRALS_REQUIRED (LDAP_REFERRALS_REQUIRED << SLAP_CH_RESOLVE_SHIFT)
#define SLAP_CH_RESOLVE_DEFAULT SLAP_CH_RESOLVE_CHAINING_PREFERRED
#define SLAP_CH_CONTINUATION_SHIFT (SLAP_CH_RESOLVE_SHIFT + 2)
#define SLAP_CH_CONTINUATION_MASK (0x3 << SLAP_CH_CONTINUATION_SHIFT)
#define SLAP_CH_CONTINUATION_CHAINING_PREFERRED (LDAP_CHAINING_PREFERRED << SLAP_CH_CONTINUATION_SHIFT)
#define SLAP_CH_CONTINUATION_CHAINING_REQUIRED (LDAP_CHAINING_REQUIRED << SLAP_CH_CONTINUATION_SHIFT)
#define SLAP_CH_CONTINUATION_REFERRALS_PREFERRED (LDAP_REFERRALS_PREFERRED << SLAP_CH_CONTINUATION_SHIFT)
#define SLAP_CH_CONTINUATION_REFERRALS_REQUIRED (LDAP_REFERRALS_REQUIRED << SLAP_CH_CONTINUATION_SHIFT)
#define SLAP_CH_CONTINUATION_DEFAULT SLAP_CH_CONTINUATION_CHAINING_PREFERRED
#define o_chaining o_ctrlflag[sc_chainingBehavior]
#define get_chaining(op) ((op)->o_chaining & SLAP_CONTROL_MASK)
#define get_chainingBehavior(op) ((op)->o_chaining & (SLAP_CH_RESOLVE_MASK|SLAP_CH_CONTINUATION_MASK))
#define get_resolveBehavior(op) ((op)->o_chaining & SLAP_CH_RESOLVE_MASK)
#define get_continuationBehavior(op) ((op)->o_chaining & SLAP_CH_CONTINUATION_MASK)
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
#define LDAP_CH_NONE ((void *)(0))
#define LDAP_CH_RES ((void *)(1))
#define LDAP_CH_ERR ((void *)(2))
static int sc_chainingBehavior;
static BackendInfo *lback;
static int
ldap_chain_operational( Operation *op, SlapReply *rs )
......@@ -58,6 +86,11 @@ ldap_chain_cb_search_response( Operation *op, SlapReply *rs )
{
assert( op->o_tag == LDAP_REQ_SEARCH );
/* if in error, don't proceed any further */
if ( op->o_callback->sc_private == LDAP_CH_ERR ) {
return 0;
}
if ( rs->sr_type == REP_SEARCH ) {
Attribute **ap = &rs->sr_entry->e_attrs;
......@@ -79,9 +112,27 @@ ldap_chain_cb_search_response( Operation *op, SlapReply *rs )
return SLAP_CB_CONTINUE;
} else if ( rs->sr_type == REP_SEARCHREF ) {
/* if we get it here, it means the library was unable
* to chase the referral... */
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
if ( get_chaining( op ) > SLAP_CONTROL_IGNORED ) {
switch ( get_continuationBehavior( op ) ) {
case SLAP_CH_RESOLVE_CHAINING_REQUIRED:
op->o_callback->sc_private = LDAP_CH_ERR;
return -1;
default:
break;
}
}
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
return SLAP_CB_CONTINUE;
} else if ( rs->sr_type == REP_RESULT ) {
/* back-ldap tried to send result */
op->o_callback->sc_private = (void *)(1);
op->o_callback->sc_private = LDAP_CH_RES;
}
return 0;
......@@ -94,8 +145,13 @@ ldap_chain_cb_search_response( Operation *op, SlapReply *rs )
static int
ldap_chain_cb_response( Operation *op, SlapReply *rs )
{
/* if in error, don't proceed any further */
if ( op->o_callback->sc_private == LDAP_CH_ERR ) {
return 0;
}
if ( rs->sr_type == REP_RESULT ) {
op->o_callback->sc_private = (void *)(1);
op->o_callback->sc_private = LDAP_CH_RES;
} else if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH )
{
......@@ -115,7 +171,9 @@ ldap_chain_op(
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
struct ldapinfo li, *lip = (struct ldapinfo *)on->on_bi.bi_private;
int rc;
/* NOTE: returned if ref is empty... */
int rc = LDAP_OTHER;
if ( lip->url != NULL ) {
op->o_bd->be_private = on->on_bi.bi_private;
......@@ -204,10 +262,44 @@ ldap_chain_response( Operation *op, SlapReply *rs )
struct ldapinfo li, *lip = (struct ldapinfo *)on->on_bi.bi_private;
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
int sr_err = rs->sr_err;
slap_reply_t sr_type = rs->sr_type;
slap_mask_t chain_mask = 0;
ber_len_t chain_shift = 0;
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
if ( rs->sr_err != LDAP_REFERRAL && rs->sr_type != REP_SEARCHREF ) {
return SLAP_CB_CONTINUE;
}
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
if ( rs->sr_err == LDAP_REFERRAL && get_chaining( op ) > SLAP_CONTROL_IGNORED ) {
switch ( get_resolveBehavior( op ) ) {
case SLAP_CH_RESOLVE_REFERRALS_PREFERRED:
case SLAP_CH_RESOLVE_REFERRALS_REQUIRED:
return SLAP_CB_CONTINUE;
default:
chain_mask = SLAP_CH_RESOLVE_MASK;
chain_shift = SLAP_CH_RESOLVE_SHIFT;
break;
}
} else if ( rs->sr_type == REP_SEARCHREF && get_chaining( op ) > SLAP_CONTROL_IGNORED ) {
switch ( get_continuationBehavior( op ) ) {
case SLAP_CH_CONTINUATION_REFERRALS_PREFERRED:
case SLAP_CH_CONTINUATION_REFERRALS_REQUIRED:
return SLAP_CB_CONTINUE;
default:
chain_mask = SLAP_CH_CONTINUATION_MASK;
chain_shift = SLAP_CH_CONTINUATION_SHIFT;
break;
}
}
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
/*
* TODO: add checks on who/when chain operations; e.g.:
* a) what identities are authorized
......@@ -254,6 +346,14 @@ ldap_chain_response( Operation *op, SlapReply *rs )
char textbuf[ SLAP_TEXT_BUFLEN ];
size_t textlen = sizeof( textbuf );
#if 0
/* FIXME: op->o_bd is still set to the BackendDB
* structure of the database that tried to handle
* the operation and actually returned a referral
* ... */
assert( SLAP_DBFLAGS( op->o_bd ) & SLAP_DBFLAG_GLOBAL_OVERLAY );
#endif
/* global overlay: create entry */
/* NOTE: this is a hack to use the chain overlay
* as global. I expect to be able to remove this
......@@ -362,6 +462,8 @@ ldap_chain_response( Operation *op, SlapReply *rs )
if ( rc == LDAP_SUCCESS && rs->sr_err == LDAP_SUCCESS ) {
break;
}
rc = rs->sr_err;
}
op->o_req_dn = odn;
......@@ -393,12 +495,38 @@ ldap_chain_response( Operation *op, SlapReply *rs )
break;
}
if ( sc2.sc_private == NULL<