Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joe Martin
OpenLDAP
Commits
fcdcc290
Commit
fcdcc290
authored
Feb 12, 2008
by
Quanah Gibson-Mount
Browse files
ITS#5328
ITS#4937
parent
c0b54eb3
Changes
3
Hide whitespace changes
Inline
Side-by-side
CHANGES
View file @
fcdcc290
...
...
@@ -26,6 +26,7 @@ OpenLDAP 2.4.8 Engineering
Added slapd-bdb/slapd-hdb DB encryption (ITS#5359)
Fixed slapd-ldif delete (ITS#5265)
Fixed slapd-monitor crash (ITS#5311)
Fixed slapd-relay compare (ITS#4937)
Added slapd-sock (ITS#4094)
Added slapo-autogroup contrib module (ITS#5145)
Added slapo-constraint cross-attribute constraints (ITS#4987)
...
...
servers/slapd/back-relay/op.c
View file @
fcdcc290
...
...
@@ -25,6 +25,17 @@
#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)
static
int
relay_back_swap_bd
(
Operation
*
op
,
SlapReply
*
rs
)
{
...
...
@@ -37,451 +48,302 @@ relay_back_swap_bd( Operation *op, SlapReply *rs )
return
SLAP_CB_CONTINUE
;
}
static
void
relay_back_add_cb
(
slap_callback
*
cb
,
Operation
*
op
)
{
cb
->
sc_next
=
op
->
o_callback
;
cb
->
sc_response
=
relay_back_swap_bd
;
cb
->
sc_cleanup
=
relay_back_swap_bd
;
cb
->
sc_private
=
op
->
o_bd
;
op
->
o_callback
=
cb
;
}
#define relay_back_add_cb( cb, op ) \
{ \
(cb)->sc_next = (op)->o_callback; \
(cb)->sc_response = relay_back_swap_bd; \
(cb)->sc_cleanup = relay_back_swap_bd; \
(cb)->sc_private = (op)->o_bd; \
(op)->o_callback = (cb); \
}
/*
* 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
* any valid error send as error result
* LDAP_SUCCESS don't send result; may send referral
if dosend
* any valid error send as error result
if dosend
*/
static
BackendDB
*
relay_back_select_backend
(
Operation
*
op
,
SlapReply
*
rs
,
int
err
,
int
dosend
)
relay_back_select_backend
(
Operation
*
op
,
SlapReply
*
rs
,
slap_mask_t
fail_mode
)
{
relay_back_info
*
ri
=
(
relay_back_info
*
)
op
->
o_bd
->
be_private
;
BackendDB
*
bd
=
ri
->
ri_bd
;
int
rc
=
(
fail_mode
&
RB_ERR_MASK
);
if
(
bd
==
NULL
&&
!
BER_BVISNULL
(
&
op
->
o_req_ndn
)
)
{
bd
=
select_backend
(
&
op
->
o_req_ndn
,
1
);
if
(
bd
==
op
->
o_bd
)
{
if
(
err
>
LDAP_SUCCESS
&&
dosend
)
{
send_ldap_error
(
op
,
rs
,
LDAP_UNWILLING_TO_PERFORM
,
"back-relay would call self"
);
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
&&
err
>
-
1
)
{
if
(
default_referral
)
{
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
(
dosend
)
{
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 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
;
}
}
else
{
/* NOTE: err is LDAP_INVALID_CREDENTIALS for bind,
* LDAP_NO_SUCH_OBJECT for other operations.
* noSuchObject cannot be returned by bind */
rs
->
sr_err
=
err
;
if
(
dosend
)
{
send_ldap_result
(
op
,
rs
);
send_ldap_result
(
op
,
rs
);
if
(
rs
->
sr_ref
!=
default_referral
)
{
ber_bvarray_free
(
rs
->
sr_ref
);
}
return
NULL
;
}
/* NOTE: err is LDAP_INVALID_CREDENTIALS for bind,
* LDAP_NO_SUCH_OBJECT for other operations.
* noSuchObject cannot be returned by bind */
rs
->
sr_err
=
rc
;
if
(
fail_mode
&
RB_SEND
)
{
send_ldap_result
(
op
,
rs
);
}
}
return
bd
;
}
int
relay_back_op_bind
(
Operation
*
op
,
SlapReply
*
rs
)
static
int
relay_back_op
(
Operation
*
op
,
SlapReply
*
rs
,
BackendDB
*
bd
,
BI_op_func
*
func
,
slap_mask_t
fail_mode
)
{
BackendDB
*
bd
;
int
rc
=
1
;
/* allow rootdn as a means to auth without the need to actually
* contact the proxied DSA */
switch
(
be_rootdn_bind
(
op
,
rs
)
)
{
case
SLAP_CB_CONTINUE
:
break
;
default:
return
rs
->
sr_err
;
}
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_INVALID_CREDENTIALS
,
1
);
if
(
bd
==
NULL
)
{
return
rc
;
}
int
rc
=
(
fail_mode
&
RB_ERR_MASK
);
if
(
bd
->
be_bind
)
{
if
(
func
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
bd
->
be_bind
(
op
,
rs
);
rc
=
func
(
op
,
rs
);
op
->
o_bd
=
be
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
}
else
{
send_ldap_error
(
op
,
rs
,
LDAP_UNWILLING_TO_PERFORM
,
"operation not supported "
"within naming context"
);
}
else
if
(
fail_mode
&
RB_ERR
)
{
rs
->
sr_err
=
rc
;
if
(
fail_mode
&
RB_UNSUPPORTED_FLAG
)
{
rs
->
sr_text
=
"operation not supported within naming context"
;
}
if
(
fail_mode
&
RB_SEND
)
{
send_ldap_result
(
op
,
rs
);
}
}
return
rc
;
}
int
relay_back_op_
un
bind
(
Operation
*
op
,
SlapReply
*
rs
)
relay_back_op_bind
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
int
rc
=
1
;
BackendDB
*
bd
;
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_SUCCESS
,
0
);
if
(
bd
==
NULL
)
{
return
1
;
/* allow rootdn as a means to auth without the need to actually
* contact the proxied DSA */
switch
(
be_rootdn_bind
(
op
,
rs
)
)
{
case
SLAP_CB_CONTINUE
:
break
;
default:
return
rs
->
sr_err
;
}
if
(
bd
&&
bd
->
be_unbind
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_INVALID_CREDENTIALS
|
RB_ERR_SEND
)
);
if
(
bd
==
NULL
)
{
return
rs
->
sr_err
;
}
relay_back_add_cb
(
&
cb
,
op
);
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_bind
,
(
LDAP_INVALID_CREDENTIALS
|
RB_ERR_SEND
)
);
}
op
->
o_bd
=
bd
;
rc
=
bd
->
be_unbind
(
op
,
rs
);
op
->
o_bd
=
be
;
int
relay_back_op_unbind
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
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
;
int
rc
=
1
;
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_NO_SUCH_OBJECT
,
1
);
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
1
;
}
if
(
bd
->
be_search
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
bd
->
be_search
(
op
,
rs
);
op
->
o_bd
=
be
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
}
else
{
send_ldap_error
(
op
,
rs
,
LDAP_UNWILLING_TO_PERFORM
,
"operation not supported "
"within naming context"
);
return
rs
->
sr_err
;
}
return
r
c
;
return
r
elay_back_op
(
op
,
rs
,
bd
,
bd
->
be_search
,
RB_UNSUPPORTED_SEND
);
}
int
relay_back_op_compare
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
int
rc
=
1
;
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_NO_SUCH_OBJECT
,
1
);
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
1
;
}
if
(
bd
->
be_compare
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
bd
->
be_compare
(
op
,
rs
);
op
->
o_bd
=
be
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
}
else
{
send_ldap_error
(
op
,
rs
,
LDAP_UNWILLING_TO_PERFORM
,
"operation not supported "
"within naming context"
);
return
rs
->
sr_err
;
}
return
r
c
;
return
r
elay_back_op
(
op
,
rs
,
bd
,
bd
->
be_compare
,
(
SLAP_CB_CONTINUE
|
RB_ERR
)
);
}
int
relay_back_op_modify
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
int
rc
=
1
;
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_NO_SUCH_OBJECT
,
1
);
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
1
;
}
if
(
bd
->
be_modify
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
bd
->
be_modify
(
op
,
rs
);
op
->
o_bd
=
be
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
}
else
{
send_ldap_error
(
op
,
rs
,
LDAP_UNWILLING_TO_PERFORM
,
"operation not supported "
"within naming context"
);
return
rs
->
sr_err
;
}
return
r
c
;
return
r
elay_back_op
(
op
,
rs
,
bd
,
bd
->
be_modify
,
RB_UNSUPPORTED_SEND
);
}
int
relay_back_op_modrdn
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
int
rc
=
1
;
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_NO_SUCH_OBJECT
,
1
);
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
1
;
}
if
(
bd
->
be_modrdn
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
bd
->
be_modrdn
(
op
,
rs
);
op
->
o_bd
=
be
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
}
else
{
send_ldap_error
(
op
,
rs
,
LDAP_UNWILLING_TO_PERFORM
,
"operation not supported "
"within naming context"
);
return
rs
->
sr_err
;
}
return
r
c
;
return
r
elay_back_op
(
op
,
rs
,
bd
,
bd
->
be_modrdn
,
RB_UNSUPPORTED_SEND
);
}
int
relay_back_op_add
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
int
rc
=
1
;
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_NO_SUCH_OBJECT
,
1
);
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
1
;
}
if
(
bd
->
be_add
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
bd
->
be_add
(
op
,
rs
);
op
->
o_bd
=
be
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
}
else
{
send_ldap_error
(
op
,
rs
,
LDAP_UNWILLING_TO_PERFORM
,
"operation not supported "
"within naming context"
);
return
rs
->
sr_err
;
}
return
r
c
;
return
r
elay_back_op
(
op
,
rs
,
bd
,
bd
->
be_add
,
RB_UNSUPPORTED_SEND
);
}
int
relay_back_op_delete
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
int
rc
=
1
;
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_NO_SUCH_OBJECT
,
1
);
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR_REFERRAL_SEND
)
);
if
(
bd
==
NULL
)
{
return
1
;
}
if
(
bd
->
be_delete
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
bd
->
be_delete
(
op
,
rs
);
op
->
o_bd
=
be
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
return
rs
->
sr_err
;
}
return
r
c
;
return
r
elay_back_op
(
op
,
rs
,
bd
,
bd
->
be_delete
,
RB_UNSUPPORTED_SEND
);
}
int
relay_back_op_abandon
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
int
rc
=
1
;
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_SUCCESS
,
0
);
bd
=
relay_back_select_backend
(
op
,
rs
,
0
);
if
(
bd
==
NULL
)
{
return
1
;
}
if
(
bd
->
be_abandon
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
bd
->
be_abandon
(
op
,
rs
);
op
->
o_bd
=
be
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
return
rs
->
sr_err
;
}
return
rc
;
return
relay_back_op
(
op
,
rs
,
bd
,
bd
->
be_abandon
,
0
);
}
int
relay_back_op_cancel
(
Operation
*
op
,
SlapReply
*
rs
)
{
BackendDB
*
bd
;
int
rc
=
1
;
int
rc
;
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_CANNOT_CANCEL
,
0
);
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_CANNOT_CANCEL
|
RB_ERR
)
);
if
(
bd
==
NULL
)
{
return
1
;
}
if
(
bd
->
be_cancel
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
bd
->
be_cancel
(
op
,
rs
);
op
->
o_bd
=
be
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
if
(
op
->
o_cancel
==
SLAP_CANCEL_REQ
)
{
op
->
o_cancel
=
LDAP_CANNOT_CANCEL
;
}
return
rs
->
sr_err
;
}
}
else
{
send_ldap_error
(
op
,
rs
,
LDAP_UNWILLING_TO_PERFORM
,
"operation not supported "
"within naming context"
);
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
;
int
rc
=
1
;
bd
=
relay_back_select_backend
(
op
,
rs
,
LDAP_NO_SUCH_OBJECT
,
0
);
bd
=
relay_back_select_backend
(
op
,
rs
,
(
LDAP_NO_SUCH_OBJECT
|
RB_ERR
|
RB_REFERRAL
)
);
if
(
bd
==
NULL
)
{
return
1
;
}
if
(
bd
->
be_extended
)
{
BackendDB
*
be
=
op
->
o_bd
;
slap_callback
cb
;
relay_back_add_cb
(
&
cb
,
op
);
op
->
o_bd
=
bd
;
rc
=
bd
->
be_extended
(
op
,
rs
);
op
->
o_bd
=
be
;
if
(
op
->
o_callback
==
&
cb
)
{
op
->
o_callback
=
op
->
o_callback
->
sc_next
;
}
}
else
{
send_ldap_error
(
op
,
rs
,
LDAP_UNWILLING_TO_PERFORM
,
"operation not supported "
"within naming context"
);
return
rs
->
sr_err
;
}