|
|
dc8c34 |
From 9cbd265f317febe4811a47db6efb2b5e3c0ed8ca Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Noriko Hosoi <nhosoi@redhat.com>
|
|
|
dc8c34 |
Date: Thu, 1 Sep 2016 16:02:53 -0700
|
|
|
dc8c34 |
Subject: [PATCH 391/394] Subject: [PATCH] Bug 1358559 - CVE-2016-4992
|
|
|
dc8c34 |
389-ds-base: Information disclosure via repeated use of LDAP ADD operation,
|
|
|
dc8c34 |
etc.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
0. Backported the Bug-1347760 patches from the master branch to 1.2.11.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
1. Description: If a bind user has no rights, it should not disclose
|
|
|
dc8c34 |
any information including the existence of the entry.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Fix description:
|
|
|
dc8c34 |
1) ALREADY_EXISTS in add -- If to be added entry is found existing
|
|
|
dc8c34 |
in ldbm_back_add, it checks the ACI and if there is no rights,
|
|
|
dc8c34 |
it returns INSUFFICIENT_ACCESS instead of ALREADY_EXISTS.
|
|
|
dc8c34 |
2) NO_SUCH_OBJECT in other update operations -- If the target entry
|
|
|
dc8c34 |
is found not existing, it checks the ancestor entry's access
|
|
|
dc8c34 |
rights in find_entry. If it is not allowed to access the subtree,
|
|
|
dc8c34 |
it returns INSUFFICIENT_ACCESS instead of NO_SUC_OBJECT. Plus,
|
|
|
dc8c34 |
it supresses the "Matched" ancestor message.
|
|
|
dc8c34 |
3) NO_SUCH_OBJECT in search -- If a bind entry has no rights to read
|
|
|
dc8c34 |
a subtree, it returns no search results with SUCCESS. It should
|
|
|
dc8c34 |
be applied to the no existing subtree if the bind entry has no
|
|
|
dc8c34 |
rights to the super tree.
|
|
|
dc8c34 |
4) If bind fails because of the non-existence of the bind user or
|
|
|
dc8c34 |
the parent nodes, the bind returns LDAP_INVALID_CREDENTIALS to
|
|
|
dc8c34 |
the client with no other information.
|
|
|
dc8c34 |
The detailed cause is logged in the access log as follows:
|
|
|
dc8c34 |
RESULT err=49 .. etime=0 - No such suffix (<given suffix>)
|
|
|
dc8c34 |
RESULT err=49 .. etime=0 - Invalid credentials
|
|
|
dc8c34 |
RESULT err=49 .. etime=0 - No such entry
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed by lkrispen@redhat.com, mreynolds@redhat.com, and tbordaz@redhat.com.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
2. Description:
|
|
|
dc8c34 |
1. When an account is inactivated, the error UNWILLING_TO_PERFORM with
|
|
|
dc8c34 |
the inactivated message should be returned only when the bind is
|
|
|
dc8c34 |
successful.
|
|
|
dc8c34 |
2. When SASL bind fails, instead of returning the cause of the failure
|
|
|
dc8c34 |
directly to the client, but logging it in the access log.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed by wibrown@redhat.com (Thank you, William!)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
3. Description: do not overwrite rc used to decide if bind was successful.
|
|
|
dc8c34 |
When the bind is through ldapi/autobind, an entry does not exist to be
|
|
|
dc8c34 |
checked with slapi_check_account_lock. In that case, a variable rc is
|
|
|
dc8c34 |
not supposed to be modified which confuses the following code path.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed by nhosoi@redhat.com.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://bugzilla.redhat.com/show_bug.cgi?id=1358559
|
|
|
dc8c34 |
(cherry picked from commit 8078a9e5d067e85dbf1817f5620ecd50cde3f5c2)
|
|
|
dc8c34 |
(cherry picked from commit 3927f4f8c331c33eeeb773ebf762a51d5e303484)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/dn2entry.c | 17 ++-
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/findentry.c | 139 +++++++++++++++++++------
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/ldbm_add.c | 21 +++-
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/ldbm_bind.c | 11 +-
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/ldbm_compare.c | 2 +-
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 9 +-
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 5 +-
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 17 +--
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/ldbm_search.c | 2 +-
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/misc.c | 2 +-
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 14 +--
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/vlv_srch.c | 2 +-
|
|
|
dc8c34 |
ldap/servers/slapd/bind.c | 120 +++++++++++----------
|
|
|
dc8c34 |
ldap/servers/slapd/defbackend.c | 82 ++++++++++++++-
|
|
|
dc8c34 |
ldap/servers/slapd/result.c | 16 ++-
|
|
|
dc8c34 |
ldap/servers/slapd/saslbind.c | 4 +-
|
|
|
dc8c34 |
16 files changed, 324 insertions(+), 139 deletions(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/dn2entry.c b/ldap/servers/slapd/back-ldbm/dn2entry.c
|
|
|
dc8c34 |
index 3cf37b6..c7c3ec2 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/dn2entry.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/dn2entry.c
|
|
|
dc8c34 |
@@ -180,14 +180,15 @@ struct backentry *
|
|
|
dc8c34 |
dn2ancestor(
|
|
|
dc8c34 |
Slapi_Backend *be,
|
|
|
dc8c34 |
const Slapi_DN *sdn,
|
|
|
dc8c34 |
- Slapi_DN *ancestordn,
|
|
|
dc8c34 |
+ Slapi_DN *ancestordn,
|
|
|
dc8c34 |
back_txn *txn,
|
|
|
dc8c34 |
- int *err
|
|
|
dc8c34 |
+ int *err,
|
|
|
dc8c34 |
+ int allow_suffix
|
|
|
dc8c34 |
)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- struct backentry *e = NULL;
|
|
|
dc8c34 |
+ struct backentry *e = NULL;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- LDAPDebug( LDAP_DEBUG_TRACE, "=> dn2ancestor \"%s\"\n", slapi_sdn_get_dn(sdn), 0, 0 );
|
|
|
dc8c34 |
+ LDAPDebug( LDAP_DEBUG_TRACE, "=> dn2ancestor \"%s\"\n", slapi_sdn_get_dn(sdn), 0, 0 );
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* first, check to see if the given sdn is empty or a root suffix of the
|
|
|
dc8c34 |
given backend - if so, it has no parent */
|
|
|
dc8c34 |
@@ -219,7 +220,13 @@ dn2ancestor(
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* stop when we get to "", or a backend suffix point */
|
|
|
dc8c34 |
- while (!e && !slapi_sdn_isempty(&ancestorndn) && !slapi_be_issuffix( be, &ancestorndn )) {
|
|
|
dc8c34 |
+ while (!e && !slapi_sdn_isempty(&ancestorndn)) {
|
|
|
dc8c34 |
+ if (!allow_suffix) {
|
|
|
dc8c34 |
+ /* Original behavior. */
|
|
|
dc8c34 |
+ if (slapi_be_issuffix(be, &ancestorndn)) {
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
/* find the entry - it uses the ndn, so no further conversion is necessary */
|
|
|
dc8c34 |
e= dn2entry(be,&ancestorndn,txn,err);
|
|
|
dc8c34 |
if (!e) {
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/findentry.c b/ldap/servers/slapd/back-ldbm/findentry.c
|
|
|
dc8c34 |
index 7174c08..a667ff8 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/findentry.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/findentry.c
|
|
|
dc8c34 |
@@ -45,8 +45,8 @@
|
|
|
dc8c34 |
#include "back-ldbm.h"
|
|
|
dc8c34 |
|
|
|
dc8c34 |
|
|
|
dc8c34 |
-static struct backentry *find_entry_internal_dn(Slapi_PBlock *pb, backend *be, const Slapi_DN *sdn, int lock, back_txn *txn, int flags);
|
|
|
dc8c34 |
-static struct backentry * find_entry_internal(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int lock, back_txn *txn, int flags);
|
|
|
dc8c34 |
+static struct backentry *find_entry_internal_dn(Slapi_PBlock *pb, backend *be, const Slapi_DN *sdn, int lock, back_txn *txn, int flags, int *rc);
|
|
|
dc8c34 |
+static struct backentry * find_entry_internal(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int lock, back_txn *txn, int flags, int *rc);
|
|
|
dc8c34 |
/* The flags take these values */
|
|
|
dc8c34 |
#define FE_TOMBSTONE_INCLUDED TOMBSTONE_INCLUDED /* :1 defined in back-ldbm.h */
|
|
|
dc8c34 |
#define FE_REALLY_INTERNAL 0x2
|
|
|
dc8c34 |
@@ -56,7 +56,7 @@ check_entry_for_referral(Slapi_PBlock *pb, Slapi_Entry *entry, char *matched, co
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
int rc=0, i=0, numValues=0;
|
|
|
dc8c34 |
Slapi_Attr *attr;
|
|
|
dc8c34 |
- Slapi_Value *val=NULL;
|
|
|
dc8c34 |
+ Slapi_Value *val=NULL;
|
|
|
dc8c34 |
struct berval **refscopy=NULL;
|
|
|
dc8c34 |
struct berval **url=NULL;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -109,12 +109,13 @@ out:
|
|
|
dc8c34 |
|
|
|
dc8c34 |
static struct backentry *
|
|
|
dc8c34 |
find_entry_internal_dn(
|
|
|
dc8c34 |
- Slapi_PBlock *pb,
|
|
|
dc8c34 |
+ Slapi_PBlock *pb,
|
|
|
dc8c34 |
backend *be,
|
|
|
dc8c34 |
const Slapi_DN *sdn,
|
|
|
dc8c34 |
int lock,
|
|
|
dc8c34 |
- back_txn *txn,
|
|
|
dc8c34 |
- int flags
|
|
|
dc8c34 |
+ back_txn *txn,
|
|
|
dc8c34 |
+ int flags,
|
|
|
dc8c34 |
+ int *rc /* return code */
|
|
|
dc8c34 |
)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
struct backentry *e;
|
|
|
dc8c34 |
@@ -122,9 +123,14 @@ find_entry_internal_dn(
|
|
|
dc8c34 |
int err;
|
|
|
dc8c34 |
ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
|
|
|
dc8c34 |
size_t tries = 0;
|
|
|
dc8c34 |
+ int isroot = 0;
|
|
|
dc8c34 |
+ int op_type;
|
|
|
dc8c34 |
+ char *errbuf = NULL;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* get the managedsait ldap message control */
|
|
|
dc8c34 |
- slapi_pblock_get( pb, SLAPI_MANAGEDSAIT, &managedsait );
|
|
|
dc8c34 |
+ slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait);
|
|
|
dc8c34 |
+ slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, &isroot);
|
|
|
dc8c34 |
+ slapi_pblock_get(pb, SLAPI_OPERATION_TYPE, &op_type);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
while ( (tries < LDBM_CACHE_RETRY_COUNT) &&
|
|
|
dc8c34 |
(e = dn2entry_ext( be, sdn, txn, flags & TOMBSTONE_INCLUDED, &err ))
|
|
|
dc8c34 |
@@ -142,6 +148,9 @@ find_entry_internal_dn(
|
|
|
dc8c34 |
if(check_entry_for_referral(pb, e->ep_entry, NULL, "find_entry_internal_dn"))
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
CACHE_RETURN( &inst->inst_cache, &e );
|
|
|
dc8c34 |
+ if (rc) { /* if check_entry_for_referral returns non-zero, result is sent. */
|
|
|
dc8c34 |
+ *rc = FE_RC_SENT_RESULT;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
return( NULL );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -180,27 +189,89 @@ find_entry_internal_dn(
|
|
|
dc8c34 |
struct backentry *me;
|
|
|
dc8c34 |
Slapi_DN ancestorsdn;
|
|
|
dc8c34 |
slapi_sdn_init(&ancestorsdn);
|
|
|
dc8c34 |
- me= dn2ancestor(pb->pb_backend,sdn,&ancestorsdn,txn,&err;;
|
|
|
dc8c34 |
+ me = dn2ancestor(pb->pb_backend, sdn, &ancestorsdn, txn, &err, 1 /* allow_suffix */);
|
|
|
dc8c34 |
if ( !managedsait && me != NULL ) {
|
|
|
dc8c34 |
/* if the entry is a referral send the referral */
|
|
|
dc8c34 |
if(check_entry_for_referral(pb, me->ep_entry, (char*)slapi_sdn_get_dn(&ancestorsdn), "find_entry_internal_dn"))
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
CACHE_RETURN( &inst->inst_cache, &me );
|
|
|
dc8c34 |
slapi_sdn_done(&ancestorsdn);
|
|
|
dc8c34 |
+ if (rc) { /* if check_entry_for_referral returns non-zero, result is sent. */
|
|
|
dc8c34 |
+ *rc = FE_RC_SENT_RESULT;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
return( NULL );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
/* else fall through to no such object */
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* entry not found */
|
|
|
dc8c34 |
- slapi_send_ldap_result( pb, ( 0 == err || DB_NOTFOUND == err ) ?
|
|
|
dc8c34 |
- LDAP_NO_SUCH_OBJECT : ( LDAP_INVALID_DN_SYNTAX == err ) ?
|
|
|
dc8c34 |
- LDAP_INVALID_DN_SYNTAX : LDAP_OPERATIONS_ERROR,
|
|
|
dc8c34 |
- (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL );
|
|
|
dc8c34 |
+ if ((0 == err) || (DB_NOTFOUND == err)) {
|
|
|
dc8c34 |
+ if (me && !isroot) {
|
|
|
dc8c34 |
+ /* If not root, you may not want to reveal it. */
|
|
|
dc8c34 |
+ int acl_type = -1;
|
|
|
dc8c34 |
+ int return_err = LDAP_NO_SUCH_OBJECT;
|
|
|
dc8c34 |
+ err = LDAP_SUCCESS;
|
|
|
dc8c34 |
+ switch (op_type) {
|
|
|
dc8c34 |
+ case SLAPI_OPERATION_ADD:
|
|
|
dc8c34 |
+ acl_type = SLAPI_ACL_ADD;
|
|
|
dc8c34 |
+ return_err = LDAP_INSUFFICIENT_ACCESS;
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ case SLAPI_OPERATION_DELETE:
|
|
|
dc8c34 |
+ acl_type = SLAPI_ACL_DELETE;
|
|
|
dc8c34 |
+ return_err = LDAP_INSUFFICIENT_ACCESS;
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ case SLAPI_OPERATION_MODDN:
|
|
|
dc8c34 |
+ acl_type = SLAPI_ACL_WRITE;
|
|
|
dc8c34 |
+ return_err = LDAP_INSUFFICIENT_ACCESS;
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ case SLAPI_OPERATION_MODIFY:
|
|
|
dc8c34 |
+ acl_type = SLAPI_ACL_WRITE;
|
|
|
dc8c34 |
+ return_err = LDAP_INSUFFICIENT_ACCESS;
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ case SLAPI_OPERATION_SEARCH:
|
|
|
dc8c34 |
+ case SLAPI_OPERATION_COMPARE:
|
|
|
dc8c34 |
+ return_err = LDAP_SUCCESS;
|
|
|
dc8c34 |
+ acl_type = SLAPI_ACL_READ;
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ case SLAPI_OPERATION_BIND:
|
|
|
dc8c34 |
+ acl_type = -1; /* skip acl check. acl is not set up for bind. */
|
|
|
dc8c34 |
+ return_err = LDAP_INVALID_CREDENTIALS;
|
|
|
dc8c34 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "No such entry");
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (acl_type > 0) {
|
|
|
dc8c34 |
+ err = plugin_call_acl_plugin(pb, me->ep_entry, NULL, NULL, acl_type,
|
|
|
dc8c34 |
+ ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (((acl_type > 0) && err) || (op_type == SLAPI_OPERATION_BIND)) {
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Operations to be checked && ACL returns disallow.
|
|
|
dc8c34 |
+ * Not to disclose the info about the entry's existence,
|
|
|
dc8c34 |
+ * do not return the "matched" DN.
|
|
|
dc8c34 |
+ * Plus, the bind case returns LDAP_INAPPROPRIATE_AUTH.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ slapi_send_ldap_result(pb, return_err, NULL, NULL, 0, NULL);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ slapi_send_ldap_result(pb, LDAP_NO_SUCH_OBJECT,
|
|
|
dc8c34 |
+ (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT,
|
|
|
dc8c34 |
+ (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ slapi_send_ldap_result( pb, ( LDAP_INVALID_DN_SYNTAX == err ) ?
|
|
|
dc8c34 |
+ LDAP_INVALID_DN_SYNTAX : LDAP_OPERATIONS_ERROR,
|
|
|
dc8c34 |
+ (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL );
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (rc) {
|
|
|
dc8c34 |
+ *rc = FE_RC_SENT_RESULT;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
slapi_sdn_done(&ancestorsdn);
|
|
|
dc8c34 |
CACHE_RETURN( &inst->inst_cache, &me );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+ slapi_ch_free_string(&errbuf);
|
|
|
dc8c34 |
LDAPDebug( LDAP_DEBUG_TRACE, "<= find_entry_internal_dn not found (%s)\n",
|
|
|
dc8c34 |
slapi_sdn_get_dn(sdn), 0, 0 );
|
|
|
dc8c34 |
return( NULL );
|
|
|
dc8c34 |
@@ -212,11 +283,11 @@ find_entry_internal_dn(
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
static struct backentry *
|
|
|
dc8c34 |
find_entry_internal_uniqueid(
|
|
|
dc8c34 |
- Slapi_PBlock *pb,
|
|
|
dc8c34 |
+ Slapi_PBlock *pb,
|
|
|
dc8c34 |
backend *be,
|
|
|
dc8c34 |
- const char *uniqueid,
|
|
|
dc8c34 |
+ const char *uniqueid,
|
|
|
dc8c34 |
int lock,
|
|
|
dc8c34 |
- back_txn *txn
|
|
|
dc8c34 |
+ back_txn *txn
|
|
|
dc8c34 |
)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
|
|
|
dc8c34 |
@@ -272,8 +343,9 @@ find_entry_internal(
|
|
|
dc8c34 |
Slapi_Backend *be,
|
|
|
dc8c34 |
const entry_address *addr,
|
|
|
dc8c34 |
int lock,
|
|
|
dc8c34 |
- back_txn *txn,
|
|
|
dc8c34 |
- int flags
|
|
|
dc8c34 |
+ back_txn *txn,
|
|
|
dc8c34 |
+ int flags,
|
|
|
dc8c34 |
+ int *rc
|
|
|
dc8c34 |
)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
/* check if we should search based on uniqueid or dn */
|
|
|
dc8c34 |
@@ -290,11 +362,9 @@ find_entry_internal(
|
|
|
dc8c34 |
LDAPDebug( LDAP_DEBUG_TRACE, "=> find_entry_internal (dn=%s) lock %d\n",
|
|
|
dc8c34 |
slapi_sdn_get_dn(addr->sdn), lock, 0 );
|
|
|
dc8c34 |
if (addr->sdn) {
|
|
|
dc8c34 |
- entry = find_entry_internal_dn (pb, be, addr->sdn,
|
|
|
dc8c34 |
- lock, txn, flags);
|
|
|
dc8c34 |
+ entry = find_entry_internal_dn (pb, be, addr->sdn, lock, txn, flags, rc);
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
- LDAPDebug0Args( LDAP_DEBUG_ANY,
|
|
|
dc8c34 |
- "find_entry_internal: Null target dn\n" );
|
|
|
dc8c34 |
+ LDAPDebug0Args( LDAP_DEBUG_ANY, "find_entry_internal: Null target dn\n" );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= find_entry_internal\n" );
|
|
|
dc8c34 |
@@ -307,10 +377,11 @@ find_entry(
|
|
|
dc8c34 |
Slapi_PBlock *pb,
|
|
|
dc8c34 |
Slapi_Backend *be,
|
|
|
dc8c34 |
const entry_address *addr,
|
|
|
dc8c34 |
- back_txn *txn
|
|
|
dc8c34 |
+ back_txn *txn,
|
|
|
dc8c34 |
+ int *rc
|
|
|
dc8c34 |
)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- return( find_entry_internal( pb, be, addr, 0/*!lock*/, txn, 0/*flags*/ ) );
|
|
|
dc8c34 |
+ return(find_entry_internal(pb, be, addr, 0/*!lock*/, txn, 0/*flags*/, rc));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
struct backentry *
|
|
|
dc8c34 |
@@ -318,10 +389,11 @@ find_entry2modify(
|
|
|
dc8c34 |
Slapi_PBlock *pb,
|
|
|
dc8c34 |
Slapi_Backend *be,
|
|
|
dc8c34 |
const entry_address *addr,
|
|
|
dc8c34 |
- back_txn *txn
|
|
|
dc8c34 |
+ back_txn *txn,
|
|
|
dc8c34 |
+ int *rc
|
|
|
dc8c34 |
)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- return( find_entry_internal( pb, be, addr, 1/*lock*/, txn, 0/*flags*/ ) );
|
|
|
dc8c34 |
+ return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, 0/*flags*/, rc));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* New routines which do not do any referral stuff.
|
|
|
dc8c34 |
@@ -333,10 +405,11 @@ find_entry_only(
|
|
|
dc8c34 |
Slapi_PBlock *pb,
|
|
|
dc8c34 |
Slapi_Backend *be,
|
|
|
dc8c34 |
const entry_address *addr,
|
|
|
dc8c34 |
- back_txn *txn
|
|
|
dc8c34 |
+ back_txn *txn,
|
|
|
dc8c34 |
+ int *rc
|
|
|
dc8c34 |
)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- return( find_entry_internal( pb, be, addr, 0/*!lock*/, txn, FE_REALLY_INTERNAL ) );
|
|
|
dc8c34 |
+ return(find_entry_internal(pb, be, addr, 0/*!lock*/, txn, FE_REALLY_INTERNAL, rc));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
struct backentry *
|
|
|
dc8c34 |
@@ -344,10 +417,11 @@ find_entry2modify_only(
|
|
|
dc8c34 |
Slapi_PBlock *pb,
|
|
|
dc8c34 |
Slapi_Backend *be,
|
|
|
dc8c34 |
const entry_address *addr,
|
|
|
dc8c34 |
- back_txn *txn
|
|
|
dc8c34 |
+ back_txn *txn,
|
|
|
dc8c34 |
+ int *rc
|
|
|
dc8c34 |
)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- return( find_entry_internal( pb, be, addr, 1/*lock*/, txn, FE_REALLY_INTERNAL ) );
|
|
|
dc8c34 |
+ return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, 0 /* to check aci, disable INTERNAL */, rc));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
struct backentry *
|
|
|
dc8c34 |
@@ -356,10 +430,9 @@ find_entry2modify_only_ext(
|
|
|
dc8c34 |
Slapi_Backend *be,
|
|
|
dc8c34 |
const entry_address *addr,
|
|
|
dc8c34 |
int flags,
|
|
|
dc8c34 |
- back_txn *txn
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
+ back_txn *txn,
|
|
|
dc8c34 |
+ int *rc
|
|
|
dc8c34 |
)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- return( find_entry_internal( pb, be, addr, 1/*lock*/, txn,
|
|
|
dc8c34 |
- FE_REALLY_INTERNAL | flags ));
|
|
|
dc8c34 |
+ return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, FE_REALLY_INTERNAL | flags, rc));
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
|
|
dc8c34 |
index b915bfe..30fb8f2 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
|
|
dc8c34 |
@@ -118,6 +118,7 @@ ldbm_back_add( Slapi_PBlock *pb )
|
|
|
dc8c34 |
int parent_switched = 0;
|
|
|
dc8c34 |
int noabort = 1;
|
|
|
dc8c34 |
const char *dn = NULL;
|
|
|
dc8c34 |
+ int result_sent = 0;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
|
|
|
dc8c34 |
slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e );
|
|
|
dc8c34 |
@@ -302,7 +303,7 @@ ldbm_back_add( Slapi_PBlock *pb )
|
|
|
dc8c34 |
addr.sdn = &parentsdn;
|
|
|
dc8c34 |
addr.udn = NULL;
|
|
|
dc8c34 |
addr.uniqueid = operation->o_params.p.p_add.parentuniqueid;
|
|
|
dc8c34 |
- parententry = find_entry2modify_only(pb,be,&addr,&txn);
|
|
|
dc8c34 |
+ parententry = find_entry2modify_only(pb, be, &addr, &txn, &result_sent);
|
|
|
dc8c34 |
if (parententry && parententry->ep_entry) {
|
|
|
dc8c34 |
if (!operation->o_params.p.p_add.parentuniqueid){
|
|
|
dc8c34 |
/* Set the parentuniqueid now */
|
|
|
dc8c34 |
@@ -356,6 +357,14 @@ ldbm_back_add( Slapi_PBlock *pb )
|
|
|
dc8c34 |
/* The entry already exists */
|
|
|
dc8c34 |
ldap_result_code = LDAP_ALREADY_EXISTS;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ if ((LDAP_ALREADY_EXISTS == ldap_result_code) && !isroot && !is_replicated_operation) {
|
|
|
dc8c34 |
+ int myrc = plugin_call_acl_plugin(pb, e, NULL, NULL, SLAPI_ACL_ADD,
|
|
|
dc8c34 |
+ ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
|
|
|
dc8c34 |
+ if (myrc) {
|
|
|
dc8c34 |
+ ldap_result_code = myrc;
|
|
|
dc8c34 |
+ ldap_result_message = errbuf;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
goto error_return;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
else
|
|
|
dc8c34 |
@@ -372,7 +381,7 @@ ldbm_back_add( Slapi_PBlock *pb )
|
|
|
dc8c34 |
Slapi_DN ancestorsdn;
|
|
|
dc8c34 |
struct backentry *ancestorentry;
|
|
|
dc8c34 |
slapi_sdn_init(&ancestorsdn);
|
|
|
dc8c34 |
- ancestorentry= dn2ancestor(pb->pb_backend,sdn,&ancestorsdn,&txn,&err;;
|
|
|
dc8c34 |
+ ancestorentry = dn2ancestor(pb->pb_backend, sdn, &ancestorsdn, &txn, &err, 0);
|
|
|
dc8c34 |
slapi_sdn_done(&ancestorsdn);
|
|
|
dc8c34 |
if ( ancestorentry != NULL )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -419,7 +428,7 @@ ldbm_back_add( Slapi_PBlock *pb )
|
|
|
dc8c34 |
addr.udn = NULL;
|
|
|
dc8c34 |
addr.sdn = NULL;
|
|
|
dc8c34 |
addr.uniqueid = (char *)slapi_entry_get_uniqueid(e); /* jcm - cast away const */
|
|
|
dc8c34 |
- tombstoneentry = find_entry2modify( pb, be, &addr, &txn );
|
|
|
dc8c34 |
+ tombstoneentry = find_entry2modify(pb, be, &addr, &txn, &result_sent);
|
|
|
dc8c34 |
if ( tombstoneentry==NULL )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
ldap_result_code= -1;
|
|
|
dc8c34 |
@@ -617,7 +626,7 @@ ldbm_back_add( Slapi_PBlock *pb )
|
|
|
dc8c34 |
"It might be a conflict entry.\n", slapi_sdn_get_dn(&parentsdn));
|
|
|
dc8c34 |
|
|
|
dc8c34 |
slapi_sdn_init(&ancestorsdn);
|
|
|
dc8c34 |
- ancestorentry = dn2ancestor(be, &parentsdn, &ancestorsdn, &txn, &err );
|
|
|
dc8c34 |
+ ancestorentry = dn2ancestor(be, &parentsdn, &ancestorsdn, &txn, &err, 1);
|
|
|
dc8c34 |
CACHE_RETURN( &inst->inst_cache, &ancestorentry );
|
|
|
dc8c34 |
|
|
|
dc8c34 |
ldap_result_code= LDAP_NO_SUCH_OBJECT;
|
|
|
dc8c34 |
@@ -1257,7 +1266,9 @@ common_return:
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
if(ldap_result_code!=-1)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn, ldap_result_message, 0, NULL );
|
|
|
dc8c34 |
+ if (!result_sent) {
|
|
|
dc8c34 |
+ slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn, ldap_result_message, 0, NULL );
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
backentry_free(&originalentry);
|
|
|
dc8c34 |
backentry_free(&tmpentry);
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_bind.c b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
|
|
|
dc8c34 |
index 24c0b4f..00a2021 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_bind.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
|
|
|
dc8c34 |
@@ -211,6 +211,7 @@ ldbm_back_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
Slapi_Value **bvals;
|
|
|
dc8c34 |
entry_address *addr;
|
|
|
dc8c34 |
back_txn txn = {NULL};
|
|
|
dc8c34 |
+ int result_sent = 0;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* get parameters */
|
|
|
dc8c34 |
slapi_pblock_get( pb, SLAPI_BACKEND, &be );
|
|
|
dc8c34 |
@@ -236,7 +237,11 @@ ldbm_back_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
* find the target entry. find_entry() takes care of referrals
|
|
|
dc8c34 |
* and sending errors if the entry does not exist.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
- if (( e = find_entry( pb, be, addr, &txn )) == NULL ) {
|
|
|
dc8c34 |
+ if ((e = find_entry( pb, be, addr, &txn, &result_sent)) == NULL) {
|
|
|
dc8c34 |
+ /* In the failure case, the result is supposed to be sent in the backend. */
|
|
|
dc8c34 |
+ if (!result_sent) {
|
|
|
dc8c34 |
+ slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
return( SLAPI_BIND_FAIL );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -265,8 +270,8 @@ ldbm_back_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
break;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
#endif
|
|
|
dc8c34 |
- slapi_send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL,
|
|
|
dc8c34 |
- NULL, 0, NULL );
|
|
|
dc8c34 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials");
|
|
|
dc8c34 |
+ slapi_send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL );
|
|
|
dc8c34 |
CACHE_RETURN( &inst->inst_cache, &e );
|
|
|
dc8c34 |
value_done(&cv;;
|
|
|
dc8c34 |
return( SLAPI_BIND_FAIL );
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_compare.c b/ldap/servers/slapd/back-ldbm/ldbm_compare.c
|
|
|
dc8c34 |
index e9761ec..1849fc4 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_compare.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_compare.c
|
|
|
dc8c34 |
@@ -78,7 +78,7 @@ ldbm_back_compare( Slapi_PBlock *pb )
|
|
|
dc8c34 |
/* get the namespace dn */
|
|
|
dc8c34 |
namespace_dn = (Slapi_DN*)slapi_be_getsuffix(be, 0);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if ( (e = find_entry( pb, be, addr, &txn )) == NULL ) {
|
|
|
dc8c34 |
+ if ((e = find_entry(pb, be, addr, &txn, NULL)) == NULL) {
|
|
|
dc8c34 |
return( -1 ); /* error result sent by find_entry() */
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
|
|
dc8c34 |
index f30e2a6..4113da2 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
|
|
dc8c34 |
@@ -100,6 +100,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
|
|
|
dc8c34 |
int free_delete_existing_entry = 0;
|
|
|
dc8c34 |
ID ep_id = 0;
|
|
|
dc8c34 |
ID tomb_ep_id = 0;
|
|
|
dc8c34 |
+ int result_sent = 0;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
slapi_pblock_get( pb, SLAPI_BACKEND, &be);
|
|
|
dc8c34 |
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
|
|
|
dc8c34 |
@@ -188,7 +189,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
|
|
|
dc8c34 |
* deleted. That is, the entry 'e' found with "addr" is a tomb-
|
|
|
dc8c34 |
* stone. If it is the case, we need to back off.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
- if ( (e = find_entry2modify( pb, be, addr, &txn )) == NULL )
|
|
|
dc8c34 |
+ if ((e = find_entry2modify(pb, be, addr, &txn, &result_sent)) == NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
ldap_result_code= LDAP_NO_SUCH_OBJECT;
|
|
|
dc8c34 |
/* retval is -1 */
|
|
|
dc8c34 |
@@ -398,7 +399,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
|
|
|
dc8c34 |
parent_addr.uniqueid = NULL;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
parent_addr.sdn = &parentsdn;
|
|
|
dc8c34 |
- parent = find_entry2modify_only_ext(pb, be, &parent_addr, TOMBSTONE_INCLUDED, &txn);
|
|
|
dc8c34 |
+ parent = find_entry2modify_only_ext(pb, be, &parent_addr, TOMBSTONE_INCLUDED, &txn, &result_sent);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
if (parent) {
|
|
|
dc8c34 |
int isglue;
|
|
|
dc8c34 |
@@ -1323,7 +1324,9 @@ common_return:
|
|
|
dc8c34 |
diskfull_return:
|
|
|
dc8c34 |
if(ldap_result_code!=-1)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
|
|
|
dc8c34 |
+ if (!result_sent) {
|
|
|
dc8c34 |
+ slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
modify_term(&parent_modify_c, be);
|
|
|
dc8c34 |
if(dblock_acquired)
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
|
|
|
dc8c34 |
index 15cfe2c..e5b3cf2 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
|
|
|
dc8c34 |
@@ -388,6 +388,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
|
|
|
dc8c34 |
int opreturn = 0;
|
|
|
dc8c34 |
int mod_count = 0;
|
|
|
dc8c34 |
int ec_locked = 0;
|
|
|
dc8c34 |
+ int result_sent = 0;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
slapi_pblock_get( pb, SLAPI_BACKEND, &be);
|
|
|
dc8c34 |
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
|
|
|
dc8c34 |
@@ -447,7 +448,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* find and lock the entry we are about to modify */
|
|
|
dc8c34 |
- if ( (e = find_entry2modify( pb, be, addr, &txn )) == NULL ) {
|
|
|
dc8c34 |
+ if ( (e = find_entry2modify( pb, be, addr, &txn, &result_sent )) == NULL ) {
|
|
|
dc8c34 |
ldap_result_code= -1;
|
|
|
dc8c34 |
goto error_return; /* error result sent by find_entry2modify() */
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -890,7 +891,7 @@ common_return:
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
dblayer_unlock_backend(be);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- if(ldap_result_code!=-1)
|
|
|
dc8c34 |
+ if ((ldap_result_code!=-1) && !result_sent)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
|
|
dc8c34 |
index d8379ab..0fa72bf 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
|
|
dc8c34 |
@@ -120,6 +120,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
|
|
|
dc8c34 |
char *newrdn = NULL;
|
|
|
dc8c34 |
int opreturn = 0;
|
|
|
dc8c34 |
int free_modrdn_existing_entry = 0;
|
|
|
dc8c34 |
+ int result_sent = 0;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* sdn & parentsdn need to be initialized before "goto *_return" */
|
|
|
dc8c34 |
slapi_sdn_init(&dn_newdn);
|
|
|
dc8c34 |
@@ -352,7 +353,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
|
|
|
dc8c34 |
/* find and lock the entry we are about to modify */
|
|
|
dc8c34 |
/* JCMREPL - Argh, what happens about the stinking referrals? */
|
|
|
dc8c34 |
slapi_pblock_get (pb, SLAPI_TARGET_ADDRESS, &old_addr);
|
|
|
dc8c34 |
- e = find_entry2modify( pb, be, old_addr, &txn );
|
|
|
dc8c34 |
+ e = find_entry2modify( pb, be, old_addr, &txn, &result_sent );
|
|
|
dc8c34 |
if ( e == NULL )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
ldap_result_code= -1;
|
|
|
dc8c34 |
@@ -389,7 +390,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
oldparent_addr.uniqueid = NULL;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- parententry = find_entry2modify_only( pb, be, &oldparent_addr, &txn );
|
|
|
dc8c34 |
+ parententry = find_entry2modify_only( pb, be, &oldparent_addr, &txn, &result_sent );
|
|
|
dc8c34 |
modify_init(&parent_modify_context,parententry);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* Fetch and lock the new parent of the entry that is moving */
|
|
|
dc8c34 |
@@ -399,7 +400,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
|
|
|
dc8c34 |
if (is_resurect_operation) {
|
|
|
dc8c34 |
newsuperior_addr->uniqueid = slapi_entry_attr_get_charptr(e->ep_entry, SLAPI_ATTR_VALUE_PARENT_UNIQUEID);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- newparententry = find_entry2modify_only( pb, be, newsuperior_addr, &txn );
|
|
|
dc8c34 |
+ newparententry = find_entry2modify_only( pb, be, newsuperior_addr, &txn, &result_sent );
|
|
|
dc8c34 |
slapi_ch_free_string(&newsuperior_addr->uniqueid);
|
|
|
dc8c34 |
modify_init(&newparent_modify_context,newparententry);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -460,7 +461,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
|
|
|
dc8c34 |
Slapi_DN ancestorsdn;
|
|
|
dc8c34 |
struct backentry *ancestorentry;
|
|
|
dc8c34 |
slapi_sdn_init(&ancestorsdn);
|
|
|
dc8c34 |
- ancestorentry= dn2ancestor(be,&dn_newdn,&ancestorsdn,&txn,&err;;
|
|
|
dc8c34 |
+ ancestorentry = dn2ancestor(be, &dn_newdn, &ancestorsdn, &txn, &err, 0);
|
|
|
dc8c34 |
CACHE_RETURN( &inst->inst_cache, &ancestorentry );
|
|
|
dc8c34 |
ldap_result_matcheddn= slapi_ch_strdup((char *) slapi_sdn_get_dn(&ancestorsdn));
|
|
|
dc8c34 |
ldap_result_code= LDAP_NO_SUCH_OBJECT;
|
|
|
dc8c34 |
@@ -1418,10 +1419,10 @@ common_return:
|
|
|
dc8c34 |
modify_term(&ruv_c, be);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if (ldap_result_code!=-1)
|
|
|
dc8c34 |
- {
|
|
|
dc8c34 |
- slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn,
|
|
|
dc8c34 |
- ldap_result_message, 0,NULL );
|
|
|
dc8c34 |
+ if ((ldap_result_code!=-1) && !result_sent)
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
+ slapi_send_ldap_result(pb, ldap_result_code, ldap_result_matcheddn,
|
|
|
dc8c34 |
+ ldap_result_message, 0, NULL);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
slapi_mods_done(&smods_operation_wsi);
|
|
|
dc8c34 |
slapi_mods_done(&smods_generated);
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
|
|
|
dc8c34 |
index bbcbe0e..d468481 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
|
|
|
dc8c34 |
@@ -603,7 +603,7 @@ ldbm_back_search( Slapi_PBlock *pb )
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
else
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- if ( ( e = find_entry( pb, be, addr, &txn )) == NULL )
|
|
|
dc8c34 |
+ if ((e = find_entry(pb, be, addr, &txn, NULL)) == NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
/* error or referral sent by find_entry */
|
|
|
dc8c34 |
return ldbm_back_search_cleanup(pb, li, sort_control,
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c
|
|
|
dc8c34 |
index 7a90742..11e97bc 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/misc.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/misc.c
|
|
|
dc8c34 |
@@ -433,7 +433,7 @@ ldbm_txn_ruv_modify_context( Slapi_PBlock *pb, modify_context *mc )
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* Note: if we find the bentry, it will stay locked until someone calls
|
|
|
dc8c34 |
* modify_term on the mc we'll be associating the bentry with */
|
|
|
dc8c34 |
- bentry = find_entry2modify_only( pb, be, &bentry_addr, &txn );
|
|
|
dc8c34 |
+ bentry = find_entry2modify_only(pb, be, &bentry_addr, &txn, NULL);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if (NULL == bentry) {
|
|
|
dc8c34 |
/* Uh oh, we couldn't find and lock the RUV entry! */
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
|
|
|
dc8c34 |
index 688f293..eeeb7eb 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
|
|
|
dc8c34 |
@@ -190,7 +190,7 @@ int ldbm_back_ctrl_info(Slapi_Backend *be, int cmd, void *info);
|
|
|
dc8c34 |
struct backentry *dn2entry(Slapi_Backend *be, const Slapi_DN *sdn, back_txn *txn, int *err);
|
|
|
dc8c34 |
struct backentry *dn2entry_ext(Slapi_Backend *be, const Slapi_DN *sdn, back_txn *txn, int flags, int *err);
|
|
|
dc8c34 |
struct backentry *dn2entry_or_ancestor(Slapi_Backend *be, const Slapi_DN *sdn, Slapi_DN *ancestor, back_txn *txn, int *err);
|
|
|
dc8c34 |
-struct backentry *dn2ancestor(Slapi_Backend *be,const Slapi_DN *sdn,Slapi_DN *ancestordn,back_txn *txn,int *err);
|
|
|
dc8c34 |
+struct backentry *dn2ancestor(Slapi_Backend *be,const Slapi_DN *sdn,Slapi_DN *ancestordn,back_txn *txn,int *err, int allow_suffix);
|
|
|
dc8c34 |
int get_copy_of_entry(Slapi_PBlock *pb, const entry_address *addr, back_txn *txn, int plock_parameter, int must_exist);
|
|
|
dc8c34 |
int get_copy_of_entry_ext(Slapi_PBlock *pb, ID id, const entry_address *addr, back_txn *txn, int plock_parameter, int must_exist);
|
|
|
dc8c34 |
void done_with_pblock_entry(Slapi_PBlock *pb, int plock_parameter);
|
|
|
dc8c34 |
@@ -210,11 +210,13 @@ IDList * filter_candidates_ext( Slapi_PBlock *pb, backend *be, const char *base,
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
* findentry.c
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
-struct backentry * find_entry2modify( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn );
|
|
|
dc8c34 |
-struct backentry * find_entry( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn );
|
|
|
dc8c34 |
-struct backentry * find_entry2modify_only( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn);
|
|
|
dc8c34 |
-struct backentry * find_entry2modify_only_ext( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int flags, back_txn *txn);
|
|
|
dc8c34 |
-struct backentry * find_entry_only( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn);
|
|
|
dc8c34 |
+/* Return code */
|
|
|
dc8c34 |
+#define FE_RC_SENT_RESULT 1
|
|
|
dc8c34 |
+struct backentry *find_entry2modify(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
|
|
|
dc8c34 |
+struct backentry *find_entry(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
|
|
|
dc8c34 |
+struct backentry *find_entry2modify_only(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
|
|
|
dc8c34 |
+struct backentry *find_entry2modify_only_ext(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int flags, back_txn *txn, int *rc);
|
|
|
dc8c34 |
+struct backentry *find_entry_only(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
|
|
|
dc8c34 |
int check_entry_for_referral(Slapi_PBlock *pb, Slapi_Entry *entry, char *matched, const char *callingfn);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c
|
|
|
dc8c34 |
index d7e28c1..8edf295 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/vlv_srch.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c
|
|
|
dc8c34 |
@@ -191,7 +191,7 @@ vlvSearch_init(struct vlvSearch* p, Slapi_PBlock *pb, const Slapi_Entry *e, ldbm
|
|
|
dc8c34 |
|
|
|
dc8c34 |
addr.sdn = p->vlv_base;
|
|
|
dc8c34 |
addr.uniqueid = NULL;
|
|
|
dc8c34 |
- e = find_entry( pb, inst->inst_be, &addr, &txn );
|
|
|
dc8c34 |
+ e = find_entry(pb, inst->inst_be, &addr, &txn, NULL);
|
|
|
dc8c34 |
/* Check to see if the entry is absent. If it is, mark this search
|
|
|
dc8c34 |
* as not initialized */
|
|
|
dc8c34 |
if (NULL == e) {
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
|
|
|
dc8c34 |
index bc8040f..eb6ee83 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/bind.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/bind.c
|
|
|
dc8c34 |
@@ -470,8 +470,8 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
* to an LDAP DN, fail and return an invalidCredentials error.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
if ( NULL == pb->pb_conn->c_external_dn ) {
|
|
|
dc8c34 |
- send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL,
|
|
|
dc8c34 |
- "client certificate mapping failed", 0, NULL );
|
|
|
dc8c34 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Client certificate mapping failed");
|
|
|
dc8c34 |
+ send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "", 0, NULL);
|
|
|
dc8c34 |
/* call postop plugins */
|
|
|
dc8c34 |
plugin_call_plugins( pb, SLAPI_PLUGIN_POST_BIND_FN );
|
|
|
dc8c34 |
goto free_and_return;
|
|
|
dc8c34 |
@@ -588,33 +588,32 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
/* Check if simple binds are allowed over an insecure channel. We only check
|
|
|
dc8c34 |
* this for authenticated binds. */
|
|
|
dc8c34 |
} else if (config_get_require_secure_binds() == 1) {
|
|
|
dc8c34 |
- Connection *conn = NULL;
|
|
|
dc8c34 |
- int sasl_ssf = 0;
|
|
|
dc8c34 |
- int local_ssf = 0;
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- /* Allow simple binds only for SSL/TLS established connections
|
|
|
dc8c34 |
- * or connections using SASL privacy layers */
|
|
|
dc8c34 |
- conn = pb->pb_conn;
|
|
|
dc8c34 |
- if ( slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) {
|
|
|
dc8c34 |
- slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
|
|
|
dc8c34 |
- "Could not get SASL SSF from connection\n" );
|
|
|
dc8c34 |
- sasl_ssf = 0;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
+ Connection *conn = NULL;
|
|
|
dc8c34 |
+ int sasl_ssf = 0;
|
|
|
dc8c34 |
+ int local_ssf = 0;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /* Allow simple binds only for SSL/TLS established connections
|
|
|
dc8c34 |
+ * or connections using SASL privacy layers */
|
|
|
dc8c34 |
+ conn = pb->pb_conn;
|
|
|
dc8c34 |
+ if ( slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) {
|
|
|
dc8c34 |
+ slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
|
|
|
dc8c34 |
+ "Could not get SASL SSF from connection\n" );
|
|
|
dc8c34 |
+ sasl_ssf = 0;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if ( slapi_pblock_get(pb, SLAPI_CONN_LOCAL_SSF, &local_ssf) != 0) {
|
|
|
dc8c34 |
- slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
|
|
|
dc8c34 |
- "Could not get local SSF from connection\n" );
|
|
|
dc8c34 |
- local_ssf = 0;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
+ if ( slapi_pblock_get(pb, SLAPI_CONN_LOCAL_SSF, &local_ssf) != 0) {
|
|
|
dc8c34 |
+ slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
|
|
|
dc8c34 |
+ "Could not get local SSF from connection\n" );
|
|
|
dc8c34 |
+ local_ssf = 0;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if (((conn->c_flags & CONN_FLAG_SSL) != CONN_FLAG_SSL) &&
|
|
|
dc8c34 |
- (sasl_ssf <= 1) && (local_ssf <= 1)) {
|
|
|
dc8c34 |
- send_ldap_result(pb, LDAP_CONFIDENTIALITY_REQUIRED, NULL,
|
|
|
dc8c34 |
- "Operation requires a secure connection",
|
|
|
dc8c34 |
- 0, NULL);
|
|
|
dc8c34 |
- slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
|
|
|
dc8c34 |
- goto free_and_return;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
+ if (((conn->c_flags & CONN_FLAG_SSL) != CONN_FLAG_SSL) &&
|
|
|
dc8c34 |
+ (sasl_ssf <= 1) && (local_ssf <= 1)) {
|
|
|
dc8c34 |
+ send_ldap_result(pb, LDAP_CONFIDENTIALITY_REQUIRED, NULL,
|
|
|
dc8c34 |
+ "Operation requires a secure connection", 0, NULL);
|
|
|
dc8c34 |
+ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
|
|
|
dc8c34 |
+ goto free_and_return;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
break;
|
|
|
dc8c34 |
default:
|
|
|
dc8c34 |
@@ -659,6 +658,7 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
* right dn, wrong passwd - reject with invalid credentials
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials");
|
|
|
dc8c34 |
send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL );
|
|
|
dc8c34 |
/* increment BindSecurityErrorcount */
|
|
|
dc8c34 |
slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
|
|
|
dc8c34 |
@@ -681,6 +681,7 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
/* call postop plugins */
|
|
|
dc8c34 |
plugin_call_plugins( pb, SLAPI_PLUGIN_POST_BIND_FN );
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Pre-bind plug-in failed");
|
|
|
dc8c34 |
send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
goto free_and_return;
|
|
|
dc8c34 |
@@ -713,31 +714,11 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN )
|
|
|
dc8c34 |
== 0 ) {
|
|
|
dc8c34 |
rc = 0;
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- /*
|
|
|
dc8c34 |
- * Is this account locked ?
|
|
|
dc8c34 |
- * could be locked through the account inactivation
|
|
|
dc8c34 |
- * or by the password policy
|
|
|
dc8c34 |
- *
|
|
|
dc8c34 |
- * rc=0: account not locked
|
|
|
dc8c34 |
- * rc=1: account locked, can not bind, result has been sent
|
|
|
dc8c34 |
- * rc!=0 and rc!=1: error. Result was not sent, lets be_bind
|
|
|
dc8c34 |
- * deal with it.
|
|
|
dc8c34 |
- *
|
|
|
dc8c34 |
- */
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- /* get the entry now, so that we can give it to slapi_check_account_lock and reslimit_update_from_dn */
|
|
|
dc8c34 |
- if (! slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
|
|
dc8c34 |
- bind_target_entry = get_entry(pb, slapi_sdn_get_ndn(sdn));
|
|
|
dc8c34 |
- rc = slapi_check_account_lock ( pb, bind_target_entry, pw_response_requested, 1, 1);
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
slapi_pblock_set( pb, SLAPI_PLUGIN, be->be_database );
|
|
|
dc8c34 |
set_db_default_result_handlers(pb);
|
|
|
dc8c34 |
- if ( (rc != 1) &&
|
|
|
dc8c34 |
- (auto_bind ||
|
|
|
dc8c34 |
- (((rc = (*be->be_bind)( pb )) == SLAPI_BIND_SUCCESS) ||
|
|
|
dc8c34 |
- (rc == SLAPI_BIND_ANONYMOUS))) ) {
|
|
|
dc8c34 |
+ if (auto_bind ||
|
|
|
dc8c34 |
+ (((rc = (*be->be_bind)( pb )) == SLAPI_BIND_SUCCESS) ||
|
|
|
dc8c34 |
+ (rc == SLAPI_BIND_ANONYMOUS))) {
|
|
|
dc8c34 |
long t;
|
|
|
dc8c34 |
char* authtype = NULL;
|
|
|
dc8c34 |
/* rc is SLAPI_BIND_SUCCESS or SLAPI_BIND_ANONYMOUS */
|
|
|
dc8c34 |
@@ -770,6 +751,28 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ( rc == SLAPI_BIND_SUCCESS ) {
|
|
|
dc8c34 |
int myrc = 0;
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Is this account locked ?
|
|
|
dc8c34 |
+ * could be locked through the account inactivation
|
|
|
dc8c34 |
+ * or by the password policy
|
|
|
dc8c34 |
+ *
|
|
|
dc8c34 |
+ * rc=0: account not locked
|
|
|
dc8c34 |
+ * rc=1: account locked, can not bind, result has been sent
|
|
|
dc8c34 |
+ * rc!=0 and rc!=1: error. Result was not sent, lets be_bind
|
|
|
dc8c34 |
+ * deal with it.
|
|
|
dc8c34 |
+ *
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /* get the entry now, so that we can give it to slapi_check_account_lock and reslimit_update_from_dn */
|
|
|
dc8c34 |
+ if (! slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
|
|
dc8c34 |
+ bind_target_entry = get_entry(pb, slapi_sdn_get_ndn(sdn));
|
|
|
dc8c34 |
+ myrc = slapi_check_account_lock ( pb, bind_target_entry, pw_response_requested, 1, 1);
|
|
|
dc8c34 |
+ if (1 == myrc) { /* account is locked */
|
|
|
dc8c34 |
+ rc = myrc;
|
|
|
dc8c34 |
+ goto account_locked;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ myrc = 0;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
if (!auto_bind) {
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
* There could be a race that bind_target_entry was not added
|
|
|
dc8c34 |
@@ -780,14 +783,9 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
if (!slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA) &&
|
|
|
dc8c34 |
!bind_target_entry) {
|
|
|
dc8c34 |
bind_target_entry = get_entry(pb, slapi_sdn_get_ndn(sdn));
|
|
|
dc8c34 |
- if (bind_target_entry) {
|
|
|
dc8c34 |
- myrc = slapi_check_account_lock(pb, bind_target_entry,
|
|
|
dc8c34 |
- pw_response_requested, 1, 1);
|
|
|
dc8c34 |
- if (1 == myrc) { /* account is locked */
|
|
|
dc8c34 |
- goto account_locked;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
- } else {
|
|
|
dc8c34 |
- send_ldap_result(pb, LDAP_NO_SUCH_OBJECT, NULL, "", 0, NULL);
|
|
|
dc8c34 |
+ if (!bind_target_entry) {
|
|
|
dc8c34 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "No such entry");
|
|
|
dc8c34 |
+ send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "", 0, NULL);
|
|
|
dc8c34 |
goto free_and_return;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -847,8 +845,7 @@ account_locked:
|
|
|
dc8c34 |
* the front end.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
if ( rc == SLAPI_BIND_SUCCESS || rc == SLAPI_BIND_ANONYMOUS) {
|
|
|
dc8c34 |
- send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL,
|
|
|
dc8c34 |
- 0, NULL );
|
|
|
dc8c34 |
+ send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, &rc );
|
|
|
dc8c34 |
@@ -871,8 +868,7 @@ free_and_return:;
|
|
|
dc8c34 |
slapi_sdn_free(&sdn;;
|
|
|
dc8c34 |
slapi_ch_free_string( &saslmech );
|
|
|
dc8c34 |
slapi_ch_free( (void **)&cred.bv_val );
|
|
|
dc8c34 |
- if ( bind_target_entry != NULL )
|
|
|
dc8c34 |
- slapi_entry_free(bind_target_entry);
|
|
|
dc8c34 |
+ slapi_entry_free(bind_target_entry);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/defbackend.c b/ldap/servers/slapd/defbackend.c
|
|
|
dc8c34 |
index dd948d0..13d5919 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/defbackend.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/defbackend.c
|
|
|
dc8c34 |
@@ -200,6 +200,51 @@ defbackend_abandon( Slapi_PBlock *pb )
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+#define DEFBE_NO_SUCH_SUFFIX "No such suffix"
|
|
|
dc8c34 |
+/*
|
|
|
dc8c34 |
+ * Generate a "No such suffix" return text
|
|
|
dc8c34 |
+ * Example:
|
|
|
dc8c34 |
+ * cn=X,dc=bogus,dc=com ==> "No such suffix (dc=bogus,dc=com)"
|
|
|
dc8c34 |
+ * if the last rdn starts with "dc=", print all last dc= rdn's.
|
|
|
dc8c34 |
+ * cn=X,cn=bogus ==> "No such suffix (cn=bogus)"
|
|
|
dc8c34 |
+ * otherwise, print the very last rdn.
|
|
|
dc8c34 |
+ * cn=X,z=bogus ==> "No such suffix (x=bogus)"
|
|
|
dc8c34 |
+ * it is true even if it is an invalid rdn.
|
|
|
dc8c34 |
+ * cn=X,bogus ==> "No such suffix (bogus)"
|
|
|
dc8c34 |
+ * another example of invalid rdn.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+static void
|
|
|
dc8c34 |
+_defbackend_gen_returntext(char *buffer, size_t buflen, char **dns)
|
|
|
dc8c34 |
+{
|
|
|
dc8c34 |
+ int dnidx;
|
|
|
dc8c34 |
+ int sidx;
|
|
|
dc8c34 |
+ struct suffix_repeat {
|
|
|
dc8c34 |
+ char *suffix;
|
|
|
dc8c34 |
+ int size;
|
|
|
dc8c34 |
+ } candidates[] = {
|
|
|
dc8c34 |
+ {"dc=", 3}, /* dc could be repeated. otherwise the last rdn is used. */
|
|
|
dc8c34 |
+ {NULL, 0}
|
|
|
dc8c34 |
+ };
|
|
|
dc8c34 |
+ PR_snprintf(buffer, buflen, "%s (", DEFBE_NO_SUCH_SUFFIX);
|
|
|
dc8c34 |
+ for (dnidx = 0; dns[dnidx]; dnidx++) ; /* finding the last */
|
|
|
dc8c34 |
+ dnidx--; /* last rdn */
|
|
|
dc8c34 |
+ for (sidx = 0; candidates[sidx].suffix; sidx++) {
|
|
|
dc8c34 |
+ if (!PL_strncasecmp(dns[dnidx], candidates[sidx].suffix, candidates[sidx].size)) {
|
|
|
dc8c34 |
+ while (!PL_strncasecmp(dns[--dnidx], candidates[sidx].suffix, candidates[sidx].size)) ;
|
|
|
dc8c34 |
+ PL_strcat(buffer, dns[++dnidx]); /* the first "dn=", e.g. */
|
|
|
dc8c34 |
+ for (++dnidx; dns[dnidx]; dnidx++) {
|
|
|
dc8c34 |
+ PL_strcat(buffer, ",");
|
|
|
dc8c34 |
+ PL_strcat(buffer, dns[dnidx]);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ PL_strcat(buffer, ")");
|
|
|
dc8c34 |
+ return; /* finished the task */
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ PL_strcat(buffer, dns[dnidx]);
|
|
|
dc8c34 |
+ PL_strcat(buffer, ")");
|
|
|
dc8c34 |
+ return;
|
|
|
dc8c34 |
+}
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
static int
|
|
|
dc8c34 |
defbackend_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -216,11 +261,40 @@ defbackend_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
slapi_pblock_get( pb, SLAPI_BIND_METHOD, &method );
|
|
|
dc8c34 |
slapi_pblock_get( pb, SLAPI_BIND_CREDENTIALS, &cred );
|
|
|
dc8c34 |
if ( method == LDAP_AUTH_SIMPLE && cred->bv_len == 0 ) {
|
|
|
dc8c34 |
- slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds);
|
|
|
dc8c34 |
- rc = SLAPI_BIND_ANONYMOUS;
|
|
|
dc8c34 |
+ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds);
|
|
|
dc8c34 |
+ rc = SLAPI_BIND_ANONYMOUS;
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
- send_nobackend_ldap_result( pb );
|
|
|
dc8c34 |
- rc = SLAPI_BIND_FAIL;
|
|
|
dc8c34 |
+ Slapi_DN *sdn = NULL;
|
|
|
dc8c34 |
+ char *suffix = NULL;
|
|
|
dc8c34 |
+ char **dns = NULL;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if (pb->pb_op) {
|
|
|
dc8c34 |
+ sdn = operation_get_target_spec(pb->pb_op);
|
|
|
dc8c34 |
+ if (sdn) {
|
|
|
dc8c34 |
+ dns = slapi_ldap_explode_dn(slapi_sdn_get_dn(sdn), 0);
|
|
|
dc8c34 |
+ if (dns) {
|
|
|
dc8c34 |
+ size_t dnlen = slapi_sdn_get_ndn_len(sdn);
|
|
|
dc8c34 |
+ size_t len = dnlen + sizeof(DEFBE_NO_SUCH_SUFFIX) + 4;
|
|
|
dc8c34 |
+ suffix = slapi_ch_malloc(len);
|
|
|
dc8c34 |
+ if (dnlen) {
|
|
|
dc8c34 |
+ _defbackend_gen_returntext(suffix, len, dns);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ PR_snprintf(suffix, len, "%s", DEFBE_NO_SUCH_SUFFIX);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (suffix) {
|
|
|
dc8c34 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, suffix);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, DEFBE_NO_SUCH_SUFFIX);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "", 0, NULL);
|
|
|
dc8c34 |
+ if (dns) {
|
|
|
dc8c34 |
+ slapi_ldap_value_free(dns);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ slapi_ch_free_string(&suffix);
|
|
|
dc8c34 |
+ rc = SLAPI_BIND_FAIL;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
return( rc );
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
|
|
|
dc8c34 |
index 6ed6c55..c385368 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/result.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/result.c
|
|
|
dc8c34 |
@@ -1815,14 +1815,26 @@ log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag,
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
if ( !internal_op )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
+ char *pbtxt = NULL;
|
|
|
dc8c34 |
+ char *ext_str = NULL;
|
|
|
dc8c34 |
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &pbtxt);
|
|
|
dc8c34 |
+ if (pbtxt) {
|
|
|
dc8c34 |
+ ext_str = slapi_ch_smprintf(" - %s", pbtxt);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ ext_str = "";
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
slapi_log_access( LDAP_DEBUG_STATS,
|
|
|
dc8c34 |
"conn=%" NSPRIu64 " op=%d RESULT err=%d"
|
|
|
dc8c34 |
- " tag=%" BERTAG_T " nentries=%d etime=%s%s%s\n",
|
|
|
dc8c34 |
+ " tag=%" BERTAG_T " nentries=%d etime=%s%s%s%s\n",
|
|
|
dc8c34 |
op->o_connid,
|
|
|
dc8c34 |
op->o_opid,
|
|
|
dc8c34 |
err, tag, nentries,
|
|
|
dc8c34 |
etime,
|
|
|
dc8c34 |
- notes_str, csn_str );
|
|
|
dc8c34 |
+ notes_str, csn_str, ext_str );
|
|
|
dc8c34 |
+ if (pbtxt) {
|
|
|
dc8c34 |
+ /* if !pbtxt ==> ext_str == "". Don't free ext_str. */
|
|
|
dc8c34 |
+ slapi_ch_free_string(&ext_str);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
else
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
|
|
|
dc8c34 |
index c1e5f2b..5ef098e 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/saslbind.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/saslbind.c
|
|
|
dc8c34 |
@@ -1049,8 +1049,8 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
|
|
|
dc8c34 |
errstr = sasl_errdetail(sasl_conn);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
PR_ExitMonitor(pb->pb_conn->c_mutex); /* BIG LOCK */
|
|
|
dc8c34 |
- send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL,
|
|
|
dc8c34 |
- (char*)errstr, 0, NULL);
|
|
|
dc8c34 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, (void *)errstr);
|
|
|
dc8c34 |
+ send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
|
|
|
dc8c34 |
break;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
2.4.11
|
|
|
dc8c34 |
|