Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joe Martin
OpenLDAP
Commits
6fd784d4
Commit
6fd784d4
authored
Aug 13, 2009
by
Quanah Gibson-Mount
Browse files
ITS#6133
parent
cb886840
Changes
4
Hide whitespace changes
Inline
Side-by-side
CHANGES
View file @
6fd784d4
...
...
@@ -11,6 +11,7 @@ OpenLDAP 2.4.18 Engineering
Fixed slapd subordinate needs a suffix (ITS#6216)
Fixed slapd tools to properly close database (ITS#6214)
Fixed slapd-ndb startup (ITS#6203)
Fixed slapd-relay various issues (ITS#6133)
Fixed slapo-unique filter matching (ITS#6077)
Fixed tools off by one error (ITS#6233)
Fixed tools resource leaks (ITS#6145)
...
...
servers/slapd/back-relay/back-relay.h
View file @
6fd784d4
...
...
@@ -28,12 +28,24 @@
LDAP_BEGIN_DECL
typedef
enum
relay_operation_e
{
relay_op_entry_get
=
op_last
,
relay_op_entry_release
,
relay_op_has_subordinates
,
relay_op_last
}
relay_operation_t
;
typedef
struct
relay_back_info
{
BackendDB
*
ri_bd
;
struct
berval
ri_realsuffix
;
int
ri_massage
;
}
relay_back_info
;
/* Pad relay_back_info if needed to create valid OpExtra key addresses */
#define RELAY_INFO_SIZE \
(sizeof(relay_back_info) > (size_t) relay_op_last ? \
sizeof(relay_back_info) : (size_t) relay_op_last )
LDAP_END_DECL
#endif
/* SLAPD_RELAY_H */
servers/slapd/back-relay/init.c
View file @
6fd784d4
...
...
@@ -151,27 +151,18 @@ relay_back_initialize( BackendInfo *bi )
bi
->
bi_db_destroy
=
relay_back_db_destroy
;
bi
->
bi_op_bind
=
relay_back_op_bind
;
bi
->
bi_op_unbind
=
relay_back_op_unbind
;
bi
->
bi_op_search
=
relay_back_op_search
;
bi
->
bi_op_compare
=
relay_back_op_compare
;
bi
->
bi_op_modify
=
relay_back_op_modify
;
bi
->
bi_op_modrdn
=
relay_back_op_modrdn
;
bi
->
bi_op_add
=
relay_back_op_add
;
bi
->
bi_op_delete
=
relay_back_op_delete
;
bi
->
bi_op_abandon
=
relay_back_op_abandon
;
bi
->
bi_op_cancel
=
relay_back_op_cancel
;
bi
->
bi_extended
=
relay_back_op_extended
;
bi
->
bi_entry_release_rw
=
relay_back_entry_release_rw
;
bi
->
bi_entry_get_rw
=
relay_back_entry_get_rw
;
#if 0 /* see comment in op.c */
bi->bi_chk_referrals = relay_back_chk_referrals;
#endif
bi
->
bi_operational
=
relay_back_operational
;
bi
->
bi_has_subordinates
=
relay_back_has_subordinates
;
bi
->
bi_connection_init
=
relay_back_connection_init
;
bi
->
bi_connection_destroy
=
relay_back_connection_destroy
;
bi
->
bi_cf_ocs
=
relayocs
;
return
config_register_schema
(
relaycfg
,
relayocs
);
...
...
@@ -184,7 +175,7 @@ relay_back_db_init( Backend *be, ConfigReply *cr)
be
->
be_private
=
NULL
;
ri
=
(
relay_back_info
*
)
ch_calloc
(
1
,
sizeof
(
relay_back_info
)
);
ri
=
(
relay_back_info
*
)
ch_calloc
(
1
,
RELAY_INFO_SIZE
);
if
(
ri
==
NULL
)
{
return
-
1
;
}
...
...
@@ -261,4 +252,3 @@ relay_back_db_destroy( Backend *be, ConfigReply *cr)
SLAP_BACKEND_INIT_MODULE
(
relay
)
#endif
/* SLAPD_RELAY == SLAPD_MOD_DYNAMIC */
servers/slapd/back-relay/op.c
View file @
6fd784d4
...
...
@@ -26,17 +26,48 @@
#include "slap.h"
#include "back-relay.h"
#define RB_ERR_MASK (0x0000FFFFU)
#define RB_ERR (0x10000000U)
#define RB_UNSUPPORTED_FLAG (0x20000000U)
#define RB_REFERRAL (0x40000000U)
#define RB_SEND (0x80000000U)
#define RB_UNSUPPORTED (LDAP_UNWILLING_TO_PERFORM|RB_ERR|RB_UNSUPPORTED_FLAG)
#define RB_UNSUPPORTED_SEND (RB_UNSUPPORTED|RB_SEND)
#define RB_REFERRAL_SEND (RB_REFERRAL|RB_SEND)
#define RB_ERR_SEND (RB_ERR|RB_SEND)
#define RB_ERR_REFERRAL_SEND (RB_ERR|RB_REFERRAL|RB_SEND)
/* Results when no real database (.rf_bd) or operation handler (.rf_op) */
static
const
struct
relay_fail_modes_s
{
slap_mask_t
rf_bd
,
rf_op
;
#define RB_ERR_MASK 0x0000FFFFU
/* bitmask for default return value */
#define RB_BDERR 0x80000000U
/* use .rf_bd's default return value */
#define RB_OPERR 0x40000000U
/* set rs->sr_err = .rf_op return value */
#define RB_REF 0x20000000U
/* use default_referral if available */
#define RB_SEND 0x10000000U
/* send result; RB_??ERR is also set */
#define RB_SENDREF 0
/*unused*/
/* like RB_SEND when referral found */
#define RB_NO_BIND (RB_OPERR | LDAP_INVALID_CREDENTIALS)
#define RB_NOT_SUPP (RB_OPERR | LDAP_UNWILLING_TO_PERFORM)
#define RB_NO_OBJ (RB_REF | LDAP_NO_SUCH_OBJECT)
#define RB_CHK_REF (RB_REF | RB_SENDREF | LDAP_SUCCESS)
}
relay_fail_modes
[
relay_op_last
]
=
{
/* .rf_bd is unused when zero, otherwise both fields have RB_BDERR */
# define RB_OP(b, o) { (b) | RB_BD2ERR(b), (o) | RB_BD2ERR(b) }
# define RB_BD2ERR(b) ((b) ? RB_BDERR : 0)
/* indexed by slap_operation_t: */
RB_OP
(
RB_NO_BIND
|
RB_SEND
,
RB_NO_BIND
|
RB_SEND
),
/* Bind */
RB_OP
(
0
,
LDAP_SUCCESS
),
/* Unbind: unused */
RB_OP
(
RB_NO_OBJ
|
RB_SEND
,
RB_NOT_SUPP
|
RB_SEND
),
/* Search */
RB_OP
(
RB_NO_OBJ
|
RB_SEND
,
SLAP_CB_CONTINUE
),
/* Compare */
RB_OP
(
RB_NO_OBJ
|
RB_SEND
,
RB_NOT_SUPP
|
RB_SEND
),
/* Modify */
RB_OP
(
RB_NO_OBJ
|
RB_SEND
,
RB_NOT_SUPP
|
RB_SEND
),
/* Modrdn */
RB_OP
(
RB_NO_OBJ
|
RB_SEND
,
RB_NOT_SUPP
|
RB_SEND
),
/* Add */
RB_OP
(
RB_NO_OBJ
|
RB_SEND
,
RB_NOT_SUPP
|
RB_SEND
),
/* Delete */
RB_OP
(
0
,
LDAP_SUCCESS
),
/* Abandon:unused */
RB_OP
(
RB_NO_OBJ
,
RB_NOT_SUPP
),
/* Extended */
RB_OP
(
0
,
SLAP_CB_CONTINUE
),
/* Cancel: unused */
RB_OP
(
0
,
LDAP_SUCCESS
),
/* operational */
RB_OP
(
RB_CHK_REF
,
LDAP_SUCCESS
),
/* chk_referrals:unused*/
RB_OP
(
0
,
SLAP_CB_CONTINUE
),
/* chk_controls:unused */
/* additional relay_operation_t indexes from back-relay.h: */
RB_OP
(
0
,
0
/*unused*/
),
/* entry_get = op_last */
RB_OP
(
0
,
0
/*unused*/
),
/* entry_release */
RB_OP
(
0
,
0
/*unused*/
),
/* has_subordinates */
};
/*
* Callbacks: Caller set op->o_bd to underlying BackendDB and sc_private
* to Relay BackendDB. sc_response swaps them, sc_cleanup swaps them back.
*/
static
int
relay_back_swap_bd
(
Operation
*
op
,
SlapReply
*
rs
)
{
...
...
@@ -59,102 +90,116 @@ relay_back_swap_bd( Operation *op, SlapReply *rs )
}
/*
* selects the backend if not enforced at config;
* in case of failure, behaves based on err:
* -1 don't send result
* LDAP_SUCCESS don't send result; may send referral if dosend
* any valid error send as error result if dosend
* Select the backend database with the operation's DN. On failure,
* set/send results depending on operation type <which>'s fail_modes.
*/
static
BackendDB
*
relay_back_select_backend
(
Operation
*
op
,
SlapReply
*
rs
,
slap_mask_t
fail_mode
)
relay_back_select_backend
(
Operation
*
op
,
SlapReply
*
rs
,
int
which
)
{
relay_back_info
*
ri
=
(
relay_back_info
*
)
op
->
o_bd
->
be_private
;
BackendDB
*
bd
=
ri
->
ri_bd
;
int
rc
=
(
fail_mode
&
RB_ERR_MASK
);
OpExtra
*
oex
;
char
*
key
=
(
char
*
)
op
->
o_bd
->
be_private
;
BackendDB
*
bd
=
((
relay_back_info
*
)
key
)
->
ri_bd
;
slap_mask_t
fail_mode
=
relay_fail_modes
[
which
].
rf_bd
;
int
useDN
=
0
,
rc
=
(
fail_mode
&
RB_ERR_MASK
);
if
(
bd
==
NULL
&&
!
BER_BVISNULL
(
&
op
->
o_req_ndn
)
)
{
useDN
=
1
;
bd
=
select_backend
(
&
op
->
o_req_ndn
,
1
);
if
(
bd
->
be_private
==
op
->
o_bd
->
be_private
)
{
Debug
(
LDAP_DEBUG_ANY
,
"%s: back-relay for DN=
\"
%s
\"
would call self.
\n
"
,
op
->
o_log_prefix
,
op
->
o_req_dn
.
bv_val
,
0
);
if
(
fail_mode
&
RB_ERR
)
{
rs
->
sr_err
=
rc
;
if
(
fail_mode
&
RB_SEND
)
{
send_ldap_result
(
op
,
rs
);
}
}
return
NULL
;
}
}
if
(
bd
==
NULL
)
{
if
(
(
fail_mode
&
RB_REFERRAL
)
&&
(
fail_mode
&
RB_SEND
)
&&
!
BER_BVISNULL
(
&
op
->
o_req_ndn
)
&&
default_referral
)
{
rs
->
sr_err
=
LDAP_REFERRAL
;
/* if we set sr_err to LDAP_REFERRAL,
* we must provide one */
rs
->
sr_ref
=
referral_rewrite
(
default_referral
,
NULL
,
&
op
->
o_req_dn
,
LDAP_SCOPE_DEFAULT
);
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
(
bd
!=
NULL
)
{
key
+=
which
;
/* <relay, op type> key from RELAY_WRAP_OP() */
LDAP_SLIST_FOREACH
(
oex
,
&
op
->
o_extra
,
oe_next
)
{
if
(
oex
->
oe_key
==
key
)
break
;
}
if
(
oex
==
NULL
)
{
return
bd
;
}
return
NULL
;
bd
=
NULL
;
Debug
(
LDAP_DEBUG_ANY
,
"%s: back-relay for DN=
\"
%s
\"
would call self.
\n
"
,
op
->
o_log_prefix
,
op
->
o_req_dn
.
bv_val
,
0
);
}
else
if
(
useDN
&&
(
fail_mode
&
RB_REF
)
&&
default_referral
)
{
rc
=
LDAP_REFERRAL
;
/* if we set sr_err to LDAP_REFERRAL, we must provide one */
rs
->
sr_ref
=
referral_rewrite
(
default_referral
,
NULL
,
&
op
->
o_req_dn
,
op
->
o_tag
==
LDAP_REQ_SEARCH
?
op
->
ors_scope
:
LDAP_SCOPE_DEFAULT
);
if
(
rs
->
sr_ref
!=
NULL
)
{
rs
->
sr_flags
|=
REP_REF_MUSTBEFREED
;
}
else
{
rs
->
sr_ref
=
default_referral
;
}
/* NOTE: err is LDAP_INVALID_CREDENTIALS for bind,
* LDAP_NO_SUCH_OBJECT for other operations.
* noSuchObject cannot be returned by bind */
if
(
fail_mode
&
RB_SENDREF
)
fail_mode
=
(
RB_BDERR
|
RB_SEND
);
}
if
(
fail_mode
&
RB_BDERR
)
{
rs
->
sr_err
=
rc
;
if
(
fail_mode
&
RB_SEND
)
{
send_ldap_result
(
op
,
rs
);
}
}
return
bd
;
return
NULL
;
}
/*
* Forward <act> on <op> to database <bd>, with <relay, op type>-specific
* key in op->o_extra so relay_back_select_backend() can catch recursion.
*/
#define RELAY_WRAP_OP( op, bd, which, act ) { \
OpExtraDB wrap_oex; \
BackendDB *const wrap_bd = (op)->o_bd; \
wrap_oex.oe_db = wrap_bd; \
wrap_oex.oe.oe_key = (char *) wrap_bd->be_private + (which); \
LDAP_SLIST_INSERT_HEAD( &(op)->o_extra, &wrap_oex.oe, oe_next ); \
(op)->o_bd = (bd); \
act; \
(op)->o_bd = wrap_bd; \
LDAP_SLIST_REMOVE( &(op)->o_extra, &wrap_oex.oe, OpExtra, oe_next ); \
}
/*
* Forward backend function #<which> on <op> to operation DN's database
* like RELAY_WRAP_OP, after setting up callbacks. If no database or no
* backend function, set/send results depending on <which>'s fail_modes.
*/
static
int
relay_back_op
(
Operation
*
op
,
SlapReply
*
rs
,
BackendDB
*
bd
,
BI_op_func
*
func
,
slap_mask_t
fail_mode
)
relay_back_op
(
Operation
*
op
,
SlapReply
*
rs
,
int
which
)
{
int
rc
=
(
fail_mode
&
RB_ERR_MASK
);
BackendDB
*
bd
;
BI_op_bind
*
func
;
slap_mask_t
fail_mode
=
relay_fail_modes
[
which
].
rf_op
;
int
rc
=
(
fail_mode
&
RB_ERR_MASK
);
bd
=
relay_back_select_backend
(
op
,
rs
,
which
);
if
(
bd
==
NULL
)
{
if
(
fail_mode
&
RB_BDERR
)
return
rs
->
sr_err
;
/* sr_err was set above */
if
(
func
)
{
BackendDB
*
be
=
op
->
o_bd
;
}
else
if
(
(
func
=
(
&
bd
->
be_bind
)[
which
])
!=
0
)
{
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
func
(
op
,
rs
);
op
->
o_bd
=
be
;
RELAY_WRAP_OP
(
op
,
bd
,
which
,
{
rc
=
func
(
op
,
rs
);
})
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
}
else
if
(
fail_mode
&
RB_ERR
)
{
}
else
if
(
fail_mode
&
RB_
OP
ERR
)
{
rs
->
sr_err
=
rc
;
if
(
fail_mode
&
RB_UNSUPPORTED_FLAG
)
{
if
(
rc
==
LDAP_UNWILLING_TO_PERFORM
)
{
rs
->
sr_text
=
"operation not supported within naming context"
;
}
...
...
@@ -166,11 +211,10 @@ relay_back_op(
return
rc
;
}
int
relay_back_op_bind
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
/* allow rootdn as a means to auth without the need to actually
* contact the proxied DSA */
switch
(
be_rootdn_bind
(
op
,
rs
)
)
{
...
...
@@ -181,227 +225,64 @@ relay_back_op_bind( Operation *op, SlapReply *rs )
return
rs
->
sr_err
;
}
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_INVALID_CREDENTIALS
|
RB_ERR_SEND
)
);
if
(
bd
==
NULL
)
{
return
rs
->
sr_err
;
}
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_bind
,
(
LDAP_INVALID_CREDENTIALS
|
RB_ERR_SEND
)
);
}
int
relay_back_op_unbind
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
0
);
if
(
bd
!=
NULL
)
{
(
void
)
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_unbind
,
0
);
}
return
0
;
}
int
relay_back_op_search
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
rs
->
sr_err
;
}
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_search
,
RB_UNSUPPORTED_SEND
);
return
relay_back_op
(
op
,
rs
,
op_bind
);
}
int
relay_back_op_compare
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
rs
->
sr_err
;
}
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_compare
,
(
SLAP_CB_CONTINUE
|
RB_ERR
)
);
}
int
relay_back_op_modify
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
rs
->
sr_err
;
}
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_modify
,
RB_UNSUPPORTED_SEND
);
}
int
relay_back_op_modrdn
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
rs
->
sr_err
;
}
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_modrdn
,
RB_UNSUPPORTED_SEND
);
}
int
relay_back_op_add
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
rs
->
sr_err
;
}
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_add
,
RB_UNSUPPORTED_SEND
);
}
int
relay_back_op_delete
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
rs
->
sr_err
;
}
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_delete
,
RB_UNSUPPORTED_SEND
);
}
int
relay_back_op_abandon
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
0
);
if
(
bd
==
NULL
)
{
return
rs
->
sr_err
;
}
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_abandon
,
0
);
}
int
relay_back_op_cancel
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
int
rc
;
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_CANNOT_CANCEL
|
RB_ERR
)
);
if
(
bd
==
NULL
)
{
if
(
op
->
o_cancel
==
SLAP_CANCEL_REQ
)
{
op
->
o_cancel
=
LDAP_CANNOT_CANCEL
;
}
return
rs
->
sr_err
;
}
rc
=
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_cancel
,
(
LDAP_CANNOT_CANCEL
|
RB_ERR
)
);
if
(
rc
==
LDAP_CANNOT_CANCEL
&&
op
->
o_cancel
==
SLAP_CANCEL_REQ
)
{
op
->
o_cancel
=
LDAP_CANNOT_CANCEL
;
}
return
rc
;
}
int
relay_back_op_extended
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR
|
RB_REFERRAL
)
);
if
(
bd
==
NULL
)
{
return
rs
->
sr_err
;
}
#define RELAY_DEFOP(func, which) \
int func( Operation *op, SlapReply *rs ) \
{ return relay_back_op( op, rs, which ); }
RELAY_DEFOP
(
relay_back_op_search
,
op_search
)
RELAY_DEFOP
(
relay_back_op_compare
,
op_compare
)
RELAY_DEFOP
(
relay_back_op_modify
,
op_modify
)
RELAY_DEFOP
(
relay_back_op_modrdn
,
op_modrdn
)
RELAY_DEFOP
(
relay_back_op_add
,
op_add
)
RELAY_DEFOP
(
relay_back_op_delete
,
op_delete
)
RELAY_DEFOP
(
relay_back_op_extended
,
op_extended
)
RELAY_DEFOP
(
relay_back_operational
,
op_aux_operational
)
/* Abandon, Cancel, Unbind and some DN-less calls like be_connection_init
* need no extra handling: slapd already calls them for all databases.
*/
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_extended
,
RB_UNSUPPORTED
);
}
int
relay_back_entry_release_rw
(
Operation
*
op
,
Entry
*
e
,
int
rw
)
{
relay_back_info
*
ri
=
(
relay_back_info
*
)
op
->
o_bd
->
be_private
;
BackendDB
*
bd
;
int
rc
=
1
;
bd
=
ri
->
ri_bd
;
if
(
bd
==
NULL
)
{
bd
=
select_backend
(
&
op
->
o_req_ndn
,
1
);
if
(
bd
==
NULL
)
{
return
1
;
}
}
if
(
bd
->
be_release
)
{
BackendDB
*
be
=
op
->
o_bd
;
op
->
o_bd
=
bd
;
rc
=
bd
->
be_release
(
op
,
e
,
rw
);
op
->
o_bd
=
be
;
int
rc
=
LDAP_UNWILLING_TO_PERFORM
;
bd
=
relay_back_select_backend
(
op
,
NULL
,
relay_op_entry_release
);
if
(
bd
&&
bd
->
be_release
)
{
RELAY_WRAP_OP
(
op
,
bd
,
relay_op_entry_release
,
{
rc
=
bd
->
be_release
(
op
,
e
,
rw
);
});
}
else
if
(
e
->
e_private
==
NULL
)
{
entry_free
(
e
);
rc
=
LDAP_SUCCESS
;
}
return
rc
;
}
int
relay_back_entry_get_rw
(
Operation
*
op
,
struct
berval
*
ndn
,
ObjectClass
*
oc
,
AttributeDescription
*
at
,
int
rw
,
Entry
**
e
)
{
relay_back_info
*
ri
=
(
relay_back_info
*
)
op
->
o_bd
->
be_private
;
BackendDB
*
bd
;
int
rc
=
1
;
bd
=
ri
->
ri_bd
;
if
(
bd
==
NULL
)
{
bd
=
select_backend
(
&
op
->
o_req_ndn
,
1
);
if
(
bd
==
NULL
)
{
return
1
;
}
}
if
(
bd
->
be_fetch
)
{
BackendDB
*
be
=
op
->
o_bd
;
int
rc
=
LDAP_NO_SUCH_OBJECT
;
op
->
o_bd
=
bd
;
rc
=
bd
->
be_fetch
(
op
,
ndn
,
oc
,
at
,
rw
,
e
);
op
->
o_bd
=
be
;
bd
=
relay_back_select_backend
(
op
,
NULL
,
relay_op_entry_get
);
if
(
bd
&&
bd
->
be_fetch
)
{
RELAY_WRAP_OP
(
op
,
bd
,
relay_op_entry_get
,
{
rc
=
bd
->
be_fetch
(
op
,
ndn
,
oc
,
at
,
rw
,
e
);
});
}
return
rc
;
}
#if 0 /* Give the RB_SENDREF flag a nonzero value if implementing this */
/*
* NOTE: even the existence of this function is questionable: we cannot
* pass the bi_chk_referrals() call thru the rwm overlay because there
...
...
@@ -409,109 +290,25 @@ relay_back_entry_get_rw( Operation *op, struct berval *ndn,
* is passing the target database a DN that likely does not belong to its
* naming context... mmmh.
*/
int
relay_back_chk_referrals
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_SUCCESS
|
RB_ERR_REFERRAL_SEND
)
);
/* FIXME: this test only works if there are no overlays, so
* it is nearly useless; if made stricter, no nested back-relays
* can be instantiated... too bad. */
if
(
bd
==
NULL
||
bd
==
op
->
o_bd
)
{
return
0
;
}
/* no nested back-relays... */
if
(
overlay_is_over
(
bd
)
)
{
slap_overinfo
*
oi
=
(
slap_overinfo
*
)
bd
->
bd_info
->
bi_private
;
if
(
oi
->
oi_orig
==
op
->
o_bd
->
bd_info
)
{
return
0
;
}