VERSION.sh
by Noriko Hosoi
VERSION.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 6b5b8b7df36690807ceb06185be3c2abdf19e166
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Fri Jul 15 10:52:02 2016 -0700
bump version to 1.3.5.11
diff --git a/VERSION.sh b/VERSION.sh
index 818869c..fb72bed 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=3
-VERSION_MAINT=5.10
+VERSION_MAINT=5.11
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=`date -u +%Y%m%d%H%M%S`
7 years, 8 months
ldap/servers ldap/systools
by Noriko Hosoi
ldap/servers/slapd/agtmmap.c | 1 +
ldap/servers/slapd/back-ldbm/cache.c | 6 ++++--
ldap/servers/slapd/detach.c | 3 ++-
ldap/systools/idsktune.c | 4 ++++
4 files changed, 11 insertions(+), 3 deletions(-)
New commits:
commit 381caf52a06ad8cefa9daa99586878249a4aa4f2
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Jul 14 19:09:21 2016 -0700
Ticket #48919 - Compiler warnings while building 389-ds-base on RHEL7
Description: Fixing additional covscan errors.
1. RESOURCE_LEAK
ldap/servers/slapd/agtmmap.c
agt_mopen_stats - leaked_handle: Handle variable "fd" going out of scope leaks the handle.
2. CHECKED_RETURN
ldap/servers/slapd/back-ldbm/cache.c
entrycache_return - check_return: Calling "remove_hash" without checking return value
3. NULL_RETURNS
ldap/systools/idsktune.c
linux_check_cpu_features - dereference: Dereferencing a pointer that might be null "cpuinfo" when calling "fclose".
4. UNINIT
ldap/servers/slapd/detach.c
detach - uninit_use: Using uninitialized value "rc".
https://fedorahosted.org/389/ticket/48919
diff --git a/ldap/servers/slapd/agtmmap.c b/ldap/servers/slapd/agtmmap.c
index 629bc1b..b9d66d9 100644
--- a/ldap/servers/slapd/agtmmap.c
+++ b/ldap/servers/slapd/agtmmap.c
@@ -167,6 +167,7 @@ agt_mopen_stats (char * statsfile, int mode, int *hdl)
#endif
rc = err;
free (buf);
+ close(fd);
goto bail;
}
free (buf);
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index bb4e55e..015cd48 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -1142,7 +1142,9 @@ entrycache_return(struct cache *cache, struct backentry **bep)
* so we need to remove the entry from the DN cache because
* we don't/can't always call cache_remove().
*/
- remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn));
+ if (remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn)) == 0) {
+ LOG("entrycache_return: failed to remove %s from dn table\n", ndn, 0, 0);
+ }
}
backentry_free(bep);
} else {
@@ -1392,7 +1394,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state,
return 0;
}
if(remove_hash(cache->c_dntable, (void *)ndn, strlen(ndn)) == 0){
- LOG("entrycache_add_int: failed to remove %s from dn table\n", 0, 0, 0);
+ LOG("entrycache_add_int: failed to remove %s from dn table\n", ndn, 0, 0);
}
e->ep_state |= ENTRY_STATE_NOTINCACHE;
cache_unlock(cache);
diff --git a/ldap/servers/slapd/detach.c b/ldap/servers/slapd/detach.c
index 54c6028..84a9eef 100644
--- a/ldap/servers/slapd/detach.c
+++ b/ldap/servers/slapd/detach.c
@@ -48,7 +48,8 @@ int
detach( int slapd_exemode, int importexport_encrypt,
int s_port, daemon_ports_t *ports_info )
{
- int i, sd, rc;
+ int i, sd;
+ int rc = 0;
char *workingdir = 0;
char *errorlog = 0;
char *ptr = 0;
diff --git a/ldap/systools/idsktune.c b/ldap/systools/idsktune.c
index 4c96529..08b7f12 100644
--- a/ldap/systools/idsktune.c
+++ b/ldap/systools/idsktune.c
@@ -875,6 +875,10 @@ linux_check_cpu_features(void)
char *token = NULL;
size_t size = 0;
int found = 0;
+ if (NULL == cpuinfo) {
+ printf("ERROR: Unable to check cpu features since opening \"/proc/cpuinfo\" failed.\n");
+ return;
+ }
while(getline(&arg, &size, cpuinfo) != -1)
{
if (strncmp("flags", arg, 5) == 0) {
7 years, 8 months
ldap/servers ldap/systools
by Noriko Hosoi
ldap/servers/slapd/attrsyntax.c | 4 ----
ldap/servers/slapd/detach.c | 2 +-
ldap/systools/idsktune.c | 2 --
3 files changed, 1 insertion(+), 7 deletions(-)
New commits:
commit 7c9853e07a85db3b46cd1eb6eacdacf3f17c39a0
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Jul 14 16:35:38 2016 -0700
Ticket #48919 - Compiler warnings while building 389-ds-base on RHEL7
Description: Fixing additional complier warnings.
1. ldap/servers/slapd/attrsyntax.c
attr_syntax_force_to_delete(struct asyntaxinfo *asip, void *arg)
This function does not care the attr_syntax_enum_flaginfo.
2. ldap/servers/slapd/detach.c
Let detach use the rc which must be 0 (success).
3. ldap/systools/idsktune.c
Removing #define _GNU_SOURCE from idsktune.c.
The macro is defined in config.h generated by configure.
$ egrep _GNU_SOURCE config.h
#define _GNU_SOURCE 1
https://fedorahosted.org/389/ticket/48919
Reviewed by wibrown(a)redhat.com (Thanks, William!)
diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c
index 8b2a77a..aec6d21 100644
--- a/ldap/servers/slapd/attrsyntax.c
+++ b/ldap/servers/slapd/attrsyntax.c
@@ -1390,11 +1390,7 @@ attr_syntax_delete_if_not_flagged(struct asyntaxinfo *asip, void *arg)
static int
attr_syntax_force_to_delete(struct asyntaxinfo *asip, void *arg)
{
- struct attr_syntax_enum_flaginfo *fi;
-
PR_ASSERT( asip != NULL );
- fi = (struct attr_syntax_enum_flaginfo *)arg;
- PR_ASSERT( fi != NULL );
attr_syntax_delete_no_lock( asip, PR_FALSE, 0 );
return ATTR_SYNTAX_ENUM_REMOVE;
diff --git a/ldap/servers/slapd/detach.c b/ldap/servers/slapd/detach.c
index b055a5c..54c6028 100644
--- a/ldap/servers/slapd/detach.c
+++ b/ldap/servers/slapd/detach.c
@@ -133,7 +133,7 @@ detach( int slapd_exemode, int importexport_encrypt,
}
(void) SIGNAL( SIGPIPE, SIG_IGN );
- return 0;
+ return rc;
}
/*
diff --git a/ldap/systools/idsktune.c b/ldap/systools/idsktune.c
index ad6a39e..4c96529 100644
--- a/ldap/systools/idsktune.c
+++ b/ldap/systools/idsktune.c
@@ -11,8 +11,6 @@
# include <config.h>
#endif
-#define _GNU_SOURCE
-
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* Don't forget to update build_date when the patch sets are updated.
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
7 years, 8 months
ldap/systools
by Noriko Hosoi
ldap/systools/idsktune.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 975e0fae044a08d2755b2394bac09d722bd1bae0
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Jul 14 15:36:03 2016 -0700
Ticket 48925 - slapd crash with SIGILL: Dsktune should detect lack of CMPXCHG16B
Description: escaping '"' in the ERROR message.
Reviewed by: one-line rule
diff --git a/ldap/systools/idsktune.c b/ldap/systools/idsktune.c
index b6c352a..ad6a39e 100644
--- a/ldap/systools/idsktune.c
+++ b/ldap/systools/idsktune.c
@@ -895,7 +895,7 @@ linux_check_cpu_features(void)
if (found == 0) {
flag_os_bad = 1;
printf("ERROR: This system does not support CMPXCHG16B instruction (cpuflag cx16).\n");
- printf(" nsslapd-enable-nunc-stans must be set to "off" on this system. \n");
+ printf(" nsslapd-enable-nunc-stans must be set to \"off\" on this system. \n");
printf(" In a future release of Directory Server this platform will NOT be supported.\n\n");
}
7 years, 8 months
ldap/systools
by William Brown
ldap/systools/idsktune.c | 40 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
New commits:
commit 5eb19778f7939967e8ca714c4d4cb03ffa11064d
Author: William Brown <firstyear(a)redhat.com>
Date: Thu Jul 14 13:47:11 2016 +1000
Ticket 48925 - slapd crash with SIGILL: Dsktune should detect lack of CMPXCHG16B
Bug Description: On older AMD the CMPXCHG16B is not present. This is critical
to the correct operation of lfds. Without out it we are unable to use nunc-stans
Fix Description: dsktune should warn if CMPXCHG16B (flag cx16) is not present.
In a future release we will NOT allow installation upon a platform that lacks
this instruction.
https://fedorahosted.org/389/ticket/48925
Author: wibrown
Review by: nhosoi (Thank you!)
diff --git a/ldap/systools/idsktune.c b/ldap/systools/idsktune.c
index c7e76e7..b6c352a 100644
--- a/ldap/systools/idsktune.c
+++ b/ldap/systools/idsktune.c
@@ -11,11 +11,12 @@
# include <config.h>
#endif
+#define _GNU_SOURCE
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* Don't forget to update build_date when the patch sets are updated.
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-static char *build_date = "23-FEBRUARY-2012";
+static char *build_date = "14-JULY-2016";
#if defined(linux) || defined(__linux) || defined(__linux__)
#define IDDS_LINUX_INCLUDE 1
@@ -32,10 +33,12 @@ static char *build_date = "23-FEBRUARY-2012";
#include <sys/resource.h>
#include <unistd.h>
#endif
+
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
+
#if !defined(__VMS) && !defined(IDDS_LINUX_INCLUDE)
#if defined(__hpux) && defined(f_type)
#undef f_type
@@ -864,6 +867,39 @@ done:
free(cmd);
}
}
+
+
+static void
+linux_check_cpu_features(void)
+{
+ FILE *cpuinfo = fopen("/proc/cpuinfo", "rb");
+ char *arg = 0;
+ char *token = NULL;
+ size_t size = 0;
+ int found = 0;
+ while(getline(&arg, &size, cpuinfo) != -1)
+ {
+ if (strncmp("flags", arg, 5) == 0) {
+ token = strtok(arg, " ");
+ while (token != NULL) {
+ if (strncmp(token, "cx16", 4) == 0) {
+ found += 1;
+ }
+ token = strtok(NULL, " ");
+ }
+ }
+ }
+ free(arg);
+ fclose(cpuinfo);
+
+ if (found == 0) {
+ flag_os_bad = 1;
+ printf("ERROR: This system does not support CMPXCHG16B instruction (cpuflag cx16).\n");
+ printf(" nsslapd-enable-nunc-stans must be set to "off" on this system. \n");
+ printf(" In a future release of Directory Server this platform will NOT be supported.\n\n");
+ }
+
+}
#endif /* IDDS_LINUX_INCLUDE */
@@ -976,6 +1012,8 @@ static void gen_tests (void)
#if defined(IDDS_LINUX_INCLUDE)
linux_check_release();
+
+ linux_check_cpu_features();
#endif
7 years, 8 months
Branch '389-ds-base-1.3.4' - 2 commits - dirsrvtests/tests ldap/servers
by Noriko Hosoi
dirsrvtests/tests/tickets/ticket1347760_test.py | 440 ++++++++++++++++++++++++
ldap/servers/slapd/back-ldbm/dn2entry.c | 17
ldap/servers/slapd/back-ldbm/findentry.c | 139 +++++--
ldap/servers/slapd/back-ldbm/ldbm_add.c | 21 -
ldap/servers/slapd/back-ldbm/ldbm_bind.c | 11
ldap/servers/slapd/back-ldbm/ldbm_compare.c | 2
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 9
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 18
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 15
ldap/servers/slapd/back-ldbm/ldbm_search.c | 2
ldap/servers/slapd/back-ldbm/misc.c | 2
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 14
ldap/servers/slapd/back-ldbm/vlv_srch.c | 2
ldap/servers/slapd/bind.c | 75 ++--
ldap/servers/slapd/defbackend.c | 82 ++++
ldap/servers/slapd/result.c | 16
16 files changed, 751 insertions(+), 114 deletions(-)
New commits:
commit b338616f66d4d51536b94edd9ae7f0dd10fbebd0
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Jul 12 14:33:17 2016 -0700
Bug 1347760 - CI test: test case for bug 1347760
Description: Information disclosure via repeated use of LDAP ADD operation, etc.
(cherry picked from commit 8bfe4bbf3d61d4eaf4abac6515c95b38ac39b195)
diff --git a/dirsrvtests/tests/tickets/ticket1347760_test.py b/dirsrvtests/tests/tickets/ticket1347760_test.py
new file mode 100644
index 0000000..d2e9e37
--- /dev/null
+++ b/dirsrvtests/tests/tickets/ticket1347760_test.py
@@ -0,0 +1,440 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+import sys
+import time
+import ldap
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+
+CONFIG_DN = 'cn=config'
+BOU = 'BOU'
+BINDOU = 'ou=%s,%s' % (BOU, DEFAULT_SUFFIX)
+BUID = 'buser123'
+TUID = 'tuser0'
+BINDDN = 'uid=%s,%s' % (BUID, BINDOU)
+BINDPW = BUID
+TESTDN = 'uid=%s,ou=people,%s' % (TUID, DEFAULT_SUFFIX)
+TESTPW = TUID
+BOGUSDN = 'uid=bogus,%s' % DEFAULT_SUFFIX
+BOGUSDN2 = 'uid=bogus,ou=people,%s' % DEFAULT_SUFFIX
+BOGUSSUFFIX = 'uid=bogus,ou=people,dc=bogus'
+GROUPOU = 'ou=groups,%s' % DEFAULT_SUFFIX
+BOGUSOU = 'ou=OU,%s' % DEFAULT_SUFFIX
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+ global installation1_prefix
+ if installation1_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+ # Creating standalone instance ...
+ standalone = DirSrv(verbose=False)
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ standalone.delete()
+ standalone.create()
+ standalone.open()
+
+ # Delete each instance in the end
+# def fin():
+# standalone.delete()
+# request.addfinalizer(fin)
+
+ # Clear out the tmp dir
+ standalone.clearTmpDir(__file__)
+
+ return TopologyStandalone(standalone)
+
+def pattern_accesslog(file, log_pattern):
+ try:
+ pattern_accesslog.last_pos += 1
+ except AttributeError:
+ pattern_accesslog.last_pos = 0
+
+ found = None
+ file.seek(pattern_accesslog.last_pos)
+
+ # Use a while true iteration because 'for line in file: hit a
+ # python bug that break file.tell()
+ while True:
+ line = file.readline()
+ found = log_pattern.search(line)
+ if ((line == '') or (found)):
+ break
+
+ pattern_accesslog.last_pos = file.tell()
+ if found:
+ return line
+ else:
+ return None
+
+def check_op_result(server, op, dn, superior, exists, rc):
+ targetdn = dn
+ if op == 'search':
+ if exists:
+ opstr = 'Searching existing entry'
+ else:
+ opstr = 'Searching non-existing entry'
+ elif op == 'add':
+ if exists:
+ opstr = 'Adding existing entry'
+ else:
+ opstr = 'Adding non-existing entry'
+ elif op == 'modify':
+ if exists:
+ opstr = 'Modifying existing entry'
+ else:
+ opstr = 'Modifying non-existing entry'
+ elif op == 'modrdn':
+ if superior != None:
+ targetdn = superior
+ if exists:
+ opstr = 'Moving to existing superior'
+ else:
+ opstr = 'Moving to non-existing superior'
+ else:
+ if exists:
+ opstr = 'Renaming existing entry'
+ else:
+ opstr = 'Renaming non-existing entry'
+ elif op == 'delete':
+ if exists:
+ opstr = 'Deleting existing entry'
+ else:
+ opstr = 'Deleting non-existing entry'
+
+ if ldap.SUCCESS == rc:
+ expstr = 'be ok'
+ else:
+ expstr = 'fail with %s' % rc.__name__
+
+ log.info('%s %s, which should %s.' % (opstr, targetdn, expstr))
+ hit = 0
+ try:
+ if op == 'search':
+ centry = server.search_s(dn, ldap.SCOPE_BASE, 'objectclass=*')
+ elif op == 'add':
+ server.add_s(Entry((dn, {'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'test entry'})))
+ elif op == 'modify':
+ server.modify_s(dn, [(ldap.MOD_REPLACE, 'description', 'test')])
+ elif op == 'modrdn':
+ if superior != None:
+ server.rename_s(dn, 'uid=new', newsuperior=superior, delold=1)
+ else:
+ server.rename_s(dn, 'uid=new', delold=1)
+ elif op == 'delete':
+ server.delete_s(dn)
+ else:
+ log.fatal('Unknown operation %s' % op)
+ assert False
+ except ldap.LDAPError as e:
+ hit = 1
+ log.info("Exception (expected): %s" % type(e).__name__)
+ log.info('Desc ' + e.message['desc'])
+ assert isinstance(e, rc)
+ if e.message.has_key('matched'):
+ log.info('Matched is returned: ' + e.message['matched'])
+ if rc != ldap.NO_SUCH_OBJECT:
+ assert False
+
+ if ldap.SUCCESS == rc:
+ if op == 'search':
+ log.info('Search should return none')
+ assert len(centry) == 0
+ else:
+ if 0 == hit:
+ log.info('Expected to fail with %s, but passed' % rc.__name__)
+ assert False
+
+ log.info('PASSED\n')
+
+def test_ticket1347760(topology):
+ """
+ Prevent revealing the entry info to whom has no access rights.
+ """
+ log.info('Testing Bug 1347760 - Information disclosure via repeated use of LDAP ADD operation, etc.')
+
+ log.info('Disabling accesslog logbuffering')
+ topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-accesslog-logbuffering', 'off')])
+
+ log.info('Bind as {%s,%s}' % (DN_DM, PASSWORD))
+ topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+
+ log.info('Adding ou=%s a bind user belongs to.' % BOU)
+ topology.standalone.add_s(Entry((BINDOU, {
+ 'objectclass': 'top organizationalunit'.split(),
+ 'ou': BOU})))
+
+ log.info('Adding a bind user.')
+ topology.standalone.add_s(Entry((BINDDN,
+ {'objectclass': "top person organizationalPerson inetOrgPerson".split(),
+ 'cn': 'bind user',
+ 'sn': 'user',
+ 'userPassword': BINDPW})))
+
+ log.info('Adding a test user.')
+ topology.standalone.add_s(Entry((TESTDN,
+ {'objectclass': "top person organizationalPerson inetOrgPerson".split(),
+ 'cn': 'test user',
+ 'sn': 'user',
+ 'userPassword': TESTPW})))
+
+ log.info('Deleting aci in %s.' % DEFAULT_SUFFIX)
+ topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_DELETE, 'aci', None)])
+
+ log.info('Bind case 1. the bind user has no rights to read the entry itself, bind should be successful.')
+ log.info('Bind as {%s,%s} who has no access rights.' % (BINDDN, BINDPW))
+ try:
+ topology.standalone.simple_bind_s(BINDDN, BINDPW)
+ except ldap.LDAPError as e:
+ log.info('Desc ' + e.message['desc'])
+ assert False
+
+ file_path = os.path.join(topology.standalone.prefix, 'var/log/dirsrv/slapd-%s/access' % topology.standalone.serverid)
+ file_obj = open(file_path, "r")
+ log.info('Access log path: %s' % file_path)
+
+ log.info('Bind case 2-1. the bind user does not exist, bind should fail with error %s' % ldap.INVALID_CREDENTIALS.__name__)
+ log.info('Bind as {%s,%s} who does not exist.' % (BOGUSDN, 'bogus'))
+ try:
+ topology.standalone.simple_bind_s(BOGUSDN, 'bogus')
+ except ldap.LDAPError as e:
+ log.info("Exception (expected): %s" % type(e).__name__)
+ log.info('Desc ' + e.message['desc'])
+ assert isinstance(e, ldap.INVALID_CREDENTIALS)
+ regex = re.compile('No such entry')
+ cause = pattern_accesslog(file_obj, regex)
+ if cause == None:
+ log.fatal('Cause not found - %s' % cause)
+ assert False
+ else:
+ log.info('Cause found - %s' % cause)
+
+ log.info('Bind case 2-2. the bind user\'s suffix does not exist, bind should fail with error %s' % ldap.INVALID_CREDENTIALS.__name__)
+ log.info('Bind as {%s,%s} who does not exist.' % (BOGUSSUFFIX, 'bogus'))
+ try:
+ topology.standalone.simple_bind_s(BOGUSSUFFIX, 'bogus')
+ except ldap.LDAPError as e:
+ log.info("Exception (expected): %s" % type(e).__name__)
+ log.info('Desc ' + e.message['desc'])
+ assert isinstance(e, ldap.INVALID_CREDENTIALS)
+ regex = re.compile('No such suffix')
+ cause = pattern_accesslog(file_obj, regex)
+ if cause == None:
+ log.fatal('Cause not found - %s' % cause)
+ assert False
+ else:
+ log.info('Cause found - %s' % cause)
+
+ log.info('Bind case 2-3. the bind user\'s password is wrong, bind should fail with error %s' % ldap.INVALID_CREDENTIALS.__name__)
+ log.info('Bind as {%s,%s} who does not exist.' % (BINDDN, 'bogus'))
+ try:
+ topology.standalone.simple_bind_s(BINDDN, 'bogus')
+ except ldap.LDAPError as e:
+ log.info("Exception (expected): %s" % type(e).__name__)
+ log.info('Desc ' + e.message['desc'])
+ assert isinstance(e, ldap.INVALID_CREDENTIALS)
+ regex = re.compile('Invalid credentials')
+ cause = pattern_accesslog(file_obj, regex)
+ if cause == None:
+ log.fatal('Cause not found - %s' % cause)
+ assert False
+ else:
+ log.info('Cause found - %s' % cause)
+
+ log.info('Adding aci for %s to %s.' % (BINDDN, BINDOU))
+ acival = '(targetattr="*")(version 3.0; acl "%s"; allow(all) userdn = "ldap:///%s";)' % (BUID, BINDDN)
+ log.info('aci: %s' % acival)
+ log.info('Bind as {%s,%s}' % (DN_DM, PASSWORD))
+ topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+ topology.standalone.modify_s(BINDOU, [(ldap.MOD_ADD, 'aci', acival)])
+
+ log.info('Bind case 3. the bind user has the right to read the entry itself, bind should be successful.')
+ log.info('Bind as {%s,%s} which should be ok.\n' % (BINDDN, BINDPW))
+ topology.standalone.simple_bind_s(BINDDN, BINDPW)
+
+ log.info('The following operations are against the subtree the bind user %s has no rights.' % BINDDN)
+ # Search
+ exists = True
+ rc = ldap.SUCCESS
+ log.info('Search case 1. the bind user has no rights to read the search entry, it should return no search results with %s' % rc)
+ check_op_result(topology.standalone, 'search', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.SUCCESS
+ log.info('Search case 2-1. the search entry does not exist, the search should return no search results with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'search', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.SUCCESS
+ log.info('Search case 2-2. the search entry does not exist, the search should return no search results with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'search', BOGUSDN2, None, exists, rc)
+
+ # Add
+ exists = True
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Add case 1. the bind user has no rights AND the adding entry exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'add', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Add case 2-1. the bind user has no rights AND the adding entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'add', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Add case 2-2. the bind user has no rights AND the adding entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'add', BOGUSDN2, None, exists, rc)
+
+ # Modify
+ exists = True
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modify case 1. the bind user has no rights AND the modifying entry exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modify', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modify case 2-1. the bind user has no rights AND the modifying entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modify', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modify case 2-2. the bind user has no rights AND the modifying entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modify', BOGUSDN2, None, exists, rc)
+
+ # Modrdn
+ exists = True
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 1. the bind user has no rights AND the renaming entry exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 2-1. the bind user has no rights AND the renaming entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 2-2. the bind user has no rights AND the renaming entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', BOGUSDN2, None, exists, rc)
+
+ exists = True
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 3. the bind user has no rights AND the node moving an entry to exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', TESTDN, GROUPOU, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 4-1. the bind user has no rights AND the node moving an entry to does not, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', TESTDN, BOGUSOU, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 4-2. the bind user has no rights AND the node moving an entry to does not, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', TESTDN, BOGUSOU, exists, rc)
+
+ # Delete
+ exists = True
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Delete case 1. the bind user has no rights AND the deleting entry exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'delete', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Delete case 2-1. the bind user has no rights AND the deleting entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'delete', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Delete case 2-2. the bind user has no rights AND the deleting entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'delete', BOGUSDN2, None, exists, rc)
+
+ log.info('EXTRA: Check no regressions')
+ log.info('Adding aci for %s to %s.' % (BINDDN, DEFAULT_SUFFIX))
+ acival = '(targetattr="*")(version 3.0; acl "%s-all"; allow(all) userdn = "ldap:///%s";)' % (BUID, BINDDN)
+ log.info('Bind as {%s,%s}' % (DN_DM, PASSWORD))
+ topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+ topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', acival)])
+
+ log.info('Bind as {%s,%s}.' % (BINDDN, BINDPW))
+ try:
+ topology.standalone.simple_bind_s(BINDDN, BINDPW)
+ except ldap.LDAPError as e:
+ log.info('Desc ' + e.message['desc'])
+ assert False
+
+ exists = False
+ rc = ldap.NO_SUCH_OBJECT
+ log.info('Search case. the search entry does not exist, the search should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'search', BOGUSDN2, None, exists, rc)
+ file_obj.close()
+
+ exists = True
+ rc = ldap.ALREADY_EXISTS
+ log.info('Add case. the adding entry already exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'add', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.NO_SUCH_OBJECT
+ log.info('Modify case. the modifying entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modify', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.NO_SUCH_OBJECT
+ log.info('Modrdn case 1. the renaming entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.NO_SUCH_OBJECT
+ log.info('Modrdn case 2. the node moving an entry to does not, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', TESTDN, BOGUSOU, exists, rc)
+
+ exists = False
+ rc = ldap.NO_SUCH_OBJECT
+ log.info('Delete case. the deleting entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'delete', BOGUSDN, None, exists, rc)
+
+ log.info('SUCCESS')
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
commit bd0bf95baa1c2807e144efbd30bad45237fd53e1
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Jul 14 10:37:19 2016 -0700
Subject: [PATCH 1/2] Bug 1347760 - CVE-2016-4992 389-ds-base: Information
disclosure via repeated use of LDAP ADD operation, etc.
Description: If a bind user has no rights, it should not disclose
any information including the existence of the entry.
Fix description:
1) ALREADY_EXISTS in add -- If to be added entry is found existing
in ldbm_back_add, it checks the ACI and if there is no rights,
it returns INSUFFICIENT_ACCESS instead of ALREADY_EXISTS.
2) NO_SUCH_OBJECT in other update operations -- If the target entry
is found not existing, it checks the ancestor entry's access
rights in find_entry. If it is not allowed to access the subtree,
it returns INSUFFICIENT_ACCESS instead of NO_SUC_OBJECT. Plus,
it supresses the "Matched" ancestor message.
3) NO_SUCH_OBJECT in search -- If a bind entry has no rights to read
a subtree, it returns no search results with SUCCESS. It should
be applied to the no existing subtree if the bind entry has no
rights to the super tree.
4) If bind fails because of the non-existence of the bind user or
the parent nodes, the bind returns LDAP_INVALID_CREDENTIALS to
the client with no other information.
The detailed cause is logged in the access log as follows:
RESULT err=49 .. etime=0 - No such suffix (<given suffix>)
RESULT err=49 .. etime=0 - Invalid credentials
RESULT err=49 .. etime=0 - No such entry
diff --git a/ldap/servers/slapd/back-ldbm/dn2entry.c b/ldap/servers/slapd/back-ldbm/dn2entry.c
index 6d1d92f..7656688 100644
--- a/ldap/servers/slapd/back-ldbm/dn2entry.c
+++ b/ldap/servers/slapd/back-ldbm/dn2entry.c
@@ -151,14 +151,15 @@ struct backentry *
dn2ancestor(
Slapi_Backend *be,
const Slapi_DN *sdn,
- Slapi_DN *ancestordn,
+ Slapi_DN *ancestordn,
back_txn *txn,
- int *err
+ int *err,
+ int allow_suffix
)
{
- struct backentry *e = NULL;
+ struct backentry *e = NULL;
- LDAPDebug( LDAP_DEBUG_TRACE, "=> dn2ancestor \"%s\"\n", slapi_sdn_get_dn(sdn), 0, 0 );
+ LDAPDebug( LDAP_DEBUG_TRACE, "=> dn2ancestor \"%s\"\n", slapi_sdn_get_dn(sdn), 0, 0 );
/* first, check to see if the given sdn is empty or a root suffix of the
given backend - if so, it has no parent */
@@ -190,7 +191,13 @@ dn2ancestor(
*/
/* stop when we get to "", or a backend suffix point */
- while (!e && !slapi_sdn_isempty(&ancestorndn) && !slapi_be_issuffix( be, &ancestorndn )) {
+ while (!e && !slapi_sdn_isempty(&ancestorndn)) {
+ if (!allow_suffix) {
+ /* Original behavior. */
+ if (slapi_be_issuffix(be, &ancestorndn)) {
+ break;
+ }
+ }
/* find the entry - it uses the ndn, so no further conversion is necessary */
e= dn2entry(be,&ancestorndn,txn,err);
if (!e) {
diff --git a/ldap/servers/slapd/back-ldbm/findentry.c b/ldap/servers/slapd/back-ldbm/findentry.c
index 4a574bf..8b842e3 100644
--- a/ldap/servers/slapd/back-ldbm/findentry.c
+++ b/ldap/servers/slapd/back-ldbm/findentry.c
@@ -16,8 +16,8 @@
#include "back-ldbm.h"
-static struct backentry *find_entry_internal_dn(Slapi_PBlock *pb, backend *be, const Slapi_DN *sdn, int lock, back_txn *txn, int flags);
-static struct backentry * find_entry_internal(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int lock, back_txn *txn, int flags);
+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);
+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);
/* The flags take these values */
#define FE_TOMBSTONE_INCLUDED TOMBSTONE_INCLUDED /* :1 defined in back-ldbm.h */
#define FE_REALLY_INTERNAL 0x2
@@ -27,7 +27,7 @@ check_entry_for_referral(Slapi_PBlock *pb, Slapi_Entry *entry, char *matched, co
{
int rc=0, i=0, numValues=0;
Slapi_Attr *attr;
- Slapi_Value *val=NULL;
+ Slapi_Value *val=NULL;
struct berval **refscopy=NULL;
struct berval **url=NULL;
@@ -80,12 +80,13 @@ out:
static struct backentry *
find_entry_internal_dn(
- Slapi_PBlock *pb,
+ Slapi_PBlock *pb,
backend *be,
const Slapi_DN *sdn,
int lock,
- back_txn *txn,
- int flags
+ back_txn *txn,
+ int flags,
+ int *rc /* return code */
)
{
struct backentry *e;
@@ -93,9 +94,14 @@ find_entry_internal_dn(
int err;
ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
size_t tries = 0;
+ int isroot = 0;
+ int op_type;
+ char *errbuf = NULL;
/* get the managedsait ldap message control */
- slapi_pblock_get( pb, SLAPI_MANAGEDSAIT, &managedsait );
+ slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait);
+ slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, &isroot);
+ slapi_pblock_get(pb, SLAPI_OPERATION_TYPE, &op_type);
while ( (tries < LDBM_CACHE_RETRY_COUNT) &&
(e = dn2entry_ext( be, sdn, txn, flags & TOMBSTONE_INCLUDED, &err ))
@@ -113,6 +119,9 @@ find_entry_internal_dn(
if(check_entry_for_referral(pb, e->ep_entry, NULL, "find_entry_internal_dn"))
{
CACHE_RETURN( &inst->inst_cache, &e );
+ if (rc) { /* if check_entry_for_referral returns non-zero, result is sent. */
+ *rc = FE_RC_SENT_RESULT;
+ }
return( NULL );
}
}
@@ -151,27 +160,89 @@ find_entry_internal_dn(
struct backentry *me;
Slapi_DN ancestorsdn;
slapi_sdn_init(&ancestorsdn);
- me= dn2ancestor(pb->pb_backend,sdn,&ancestorsdn,txn,&err);
+ me = dn2ancestor(pb->pb_backend, sdn, &ancestorsdn, txn, &err, 1 /* allow_suffix */);
if ( !managedsait && me != NULL ) {
/* if the entry is a referral send the referral */
if(check_entry_for_referral(pb, me->ep_entry, (char*)slapi_sdn_get_dn(&ancestorsdn), "find_entry_internal_dn"))
{
CACHE_RETURN( &inst->inst_cache, &me );
slapi_sdn_done(&ancestorsdn);
+ if (rc) { /* if check_entry_for_referral returns non-zero, result is sent. */
+ *rc = FE_RC_SENT_RESULT;
+ }
return( NULL );
}
/* else fall through to no such object */
}
/* entry not found */
- slapi_send_ldap_result( pb, ( 0 == err || DB_NOTFOUND == err ) ?
- LDAP_NO_SUCH_OBJECT : ( LDAP_INVALID_DN_SYNTAX == err ) ?
- LDAP_INVALID_DN_SYNTAX : LDAP_OPERATIONS_ERROR,
- (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL );
+ if ((0 == err) || (DB_NOTFOUND == err)) {
+ if (me && !isroot) {
+ /* If not root, you may not want to reveal it. */
+ int acl_type = -1;
+ int return_err = LDAP_NO_SUCH_OBJECT;
+ err = LDAP_SUCCESS;
+ switch (op_type) {
+ case SLAPI_OPERATION_ADD:
+ acl_type = SLAPI_ACL_ADD;
+ return_err = LDAP_INSUFFICIENT_ACCESS;
+ break;
+ case SLAPI_OPERATION_DELETE:
+ acl_type = SLAPI_ACL_DELETE;
+ return_err = LDAP_INSUFFICIENT_ACCESS;
+ break;
+ case SLAPI_OPERATION_MODDN:
+ acl_type = SLAPI_ACL_MODDN;
+ return_err = LDAP_INSUFFICIENT_ACCESS;
+ break;
+ case SLAPI_OPERATION_MODIFY:
+ acl_type = SLAPI_ACL_WRITE;
+ return_err = LDAP_INSUFFICIENT_ACCESS;
+ break;
+ case SLAPI_OPERATION_SEARCH:
+ case SLAPI_OPERATION_COMPARE:
+ return_err = LDAP_SUCCESS;
+ acl_type = SLAPI_ACL_READ;
+ break;
+ case SLAPI_OPERATION_BIND:
+ acl_type = -1; /* skip acl check. acl is not set up for bind. */
+ return_err = LDAP_INVALID_CREDENTIALS;
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "No such entry");
+ break;
+ }
+ if (acl_type > 0) {
+ err = plugin_call_acl_plugin(pb, me->ep_entry, NULL, NULL, acl_type,
+ ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
+ }
+ if (((acl_type > 0) && err) || (op_type == SLAPI_OPERATION_BIND)) {
+ /*
+ * Operations to be checked && ACL returns disallow.
+ * Not to disclose the info about the entry's existence,
+ * do not return the "matched" DN.
+ * Plus, the bind case returns LDAP_INAPPROPRIATE_AUTH.
+ */
+ slapi_send_ldap_result(pb, return_err, NULL, NULL, 0, NULL);
+ } else {
+ slapi_send_ldap_result(pb, LDAP_NO_SUCH_OBJECT,
+ (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL);
+ }
+ } else {
+ slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT,
+ (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL);
+ }
+ } else {
+ slapi_send_ldap_result( pb, ( LDAP_INVALID_DN_SYNTAX == err ) ?
+ LDAP_INVALID_DN_SYNTAX : LDAP_OPERATIONS_ERROR,
+ (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL );
+ }
+ if (rc) {
+ *rc = FE_RC_SENT_RESULT;
+ }
slapi_sdn_done(&ancestorsdn);
CACHE_RETURN( &inst->inst_cache, &me );
}
+ slapi_ch_free_string(&errbuf);
LDAPDebug( LDAP_DEBUG_TRACE, "<= find_entry_internal_dn not found (%s)\n",
slapi_sdn_get_dn(sdn), 0, 0 );
return( NULL );
@@ -183,11 +254,11 @@ find_entry_internal_dn(
*/
static struct backentry *
find_entry_internal_uniqueid(
- Slapi_PBlock *pb,
+ Slapi_PBlock *pb,
backend *be,
- const char *uniqueid,
+ const char *uniqueid,
int lock,
- back_txn *txn
+ back_txn *txn
)
{
ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
@@ -243,8 +314,9 @@ find_entry_internal(
Slapi_Backend *be,
const entry_address *addr,
int lock,
- back_txn *txn,
- int flags
+ back_txn *txn,
+ int flags,
+ int *rc
)
{
/* check if we should search based on uniqueid or dn */
@@ -261,11 +333,9 @@ find_entry_internal(
LDAPDebug( LDAP_DEBUG_TRACE, "=> find_entry_internal (dn=%s) lock %d\n",
slapi_sdn_get_dn(addr->sdn), lock, 0 );
if (addr->sdn) {
- entry = find_entry_internal_dn (pb, be, addr->sdn,
- lock, txn, flags);
+ entry = find_entry_internal_dn (pb, be, addr->sdn, lock, txn, flags, rc);
} else {
- LDAPDebug0Args( LDAP_DEBUG_ANY,
- "find_entry_internal: Null target dn\n" );
+ LDAPDebug0Args( LDAP_DEBUG_ANY, "find_entry_internal: Null target dn\n" );
}
LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= find_entry_internal\n" );
@@ -278,10 +348,11 @@ find_entry(
Slapi_PBlock *pb,
Slapi_Backend *be,
const entry_address *addr,
- back_txn *txn
+ back_txn *txn,
+ int *rc
)
{
- return( find_entry_internal( pb, be, addr, 0/*!lock*/, txn, 0/*flags*/ ) );
+ return(find_entry_internal(pb, be, addr, 0/*!lock*/, txn, 0/*flags*/, rc));
}
struct backentry *
@@ -289,10 +360,11 @@ find_entry2modify(
Slapi_PBlock *pb,
Slapi_Backend *be,
const entry_address *addr,
- back_txn *txn
+ back_txn *txn,
+ int *rc
)
{
- return( find_entry_internal( pb, be, addr, 1/*lock*/, txn, 0/*flags*/ ) );
+ return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, 0/*flags*/, rc));
}
/* New routines which do not do any referral stuff.
@@ -304,10 +376,11 @@ find_entry_only(
Slapi_PBlock *pb,
Slapi_Backend *be,
const entry_address *addr,
- back_txn *txn
+ back_txn *txn,
+ int *rc
)
{
- return( find_entry_internal( pb, be, addr, 0/*!lock*/, txn, FE_REALLY_INTERNAL ) );
+ return(find_entry_internal(pb, be, addr, 0/*!lock*/, txn, FE_REALLY_INTERNAL, rc));
}
struct backentry *
@@ -315,10 +388,11 @@ find_entry2modify_only(
Slapi_PBlock *pb,
Slapi_Backend *be,
const entry_address *addr,
- back_txn *txn
+ back_txn *txn,
+ int *rc
)
{
- return( find_entry_internal( pb, be, addr, 1/*lock*/, txn, FE_REALLY_INTERNAL ) );
+ return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, 0 /* to check aci, disable INTERNAL */, rc));
}
struct backentry *
@@ -327,10 +401,9 @@ find_entry2modify_only_ext(
Slapi_Backend *be,
const entry_address *addr,
int flags,
- back_txn *txn
-
+ back_txn *txn,
+ int *rc
)
{
- return( find_entry_internal( pb, be, addr, 1/*lock*/, txn,
- FE_REALLY_INTERNAL | flags ));
+ return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, FE_REALLY_INTERNAL | flags, rc));
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index 088f80c..c1bd188 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -93,6 +93,7 @@ ldbm_back_add( Slapi_PBlock *pb )
int myrc = 0;
PRUint64 conn_id;
int op_id;
+ int result_sent = 0;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
}
@@ -379,7 +380,7 @@ ldbm_back_add( Slapi_PBlock *pb )
addr.sdn = &parentsdn;
addr.udn = NULL;
addr.uniqueid = operation->o_params.p.p_add.parentuniqueid;
- parententry = find_entry2modify_only(pb,be,&addr,&txn);
+ parententry = find_entry2modify_only(pb, be, &addr, &txn, &result_sent);
if (parententry && parententry->ep_entry) {
if (!operation->o_params.p.p_add.parentuniqueid){
/* Set the parentuniqueid now */
@@ -431,6 +432,14 @@ ldbm_back_add( Slapi_PBlock *pb )
/* The entry already exists */
ldap_result_code = LDAP_ALREADY_EXISTS;
}
+ if ((LDAP_ALREADY_EXISTS == ldap_result_code) && !isroot && !is_replicated_operation) {
+ myrc = plugin_call_acl_plugin(pb, e, NULL, NULL, SLAPI_ACL_ADD,
+ ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
+ if (myrc) {
+ ldap_result_code = myrc;
+ ldap_result_message = errbuf;
+ }
+ }
goto error_return;
}
else
@@ -447,7 +456,7 @@ ldbm_back_add( Slapi_PBlock *pb )
Slapi_DN ancestorsdn;
struct backentry *ancestorentry;
slapi_sdn_init(&ancestorsdn);
- ancestorentry= dn2ancestor(pb->pb_backend,sdn,&ancestorsdn,&txn,&err);
+ ancestorentry = dn2ancestor(pb->pb_backend, sdn, &ancestorsdn, &txn, &err, 0);
slapi_sdn_done(&ancestorsdn);
if ( ancestorentry != NULL )
{
@@ -495,7 +504,7 @@ ldbm_back_add( Slapi_PBlock *pb )
addr.udn = NULL;
addr.sdn = NULL;
addr.uniqueid = (char *)slapi_entry_get_uniqueid(e); /* jcm - cast away const */
- tombstoneentry = find_entry2modify( pb, be, &addr, &txn );
+ tombstoneentry = find_entry2modify(pb, be, &addr, &txn, &result_sent);
if ( tombstoneentry==NULL )
{
ldap_result_code= -1;
@@ -712,7 +721,7 @@ ldbm_back_add( Slapi_PBlock *pb )
LDAPDebug1Arg(LDAP_DEBUG_BACKLDBM, "ldbm_add: Parent \"%s\" does not exist. "
"It might be a conflict entry.\n", slapi_sdn_get_dn(&parentsdn));
slapi_sdn_init(&ancestorsdn);
- ancestorentry = dn2ancestor(be, &parentsdn, &ancestorsdn, &txn, &err );
+ ancestorentry = dn2ancestor(be, &parentsdn, &ancestorsdn, &txn, &err, 1);
CACHE_RETURN( &inst->inst_cache, &ancestorentry );
ldap_result_code= LDAP_NO_SUCH_OBJECT;
@@ -1346,7 +1355,9 @@ common_return:
* And we don't want the supplier to halt sending the updates. */
ldap_result_code = LDAP_SUCCESS;
}
- slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn, ldap_result_message, 0, NULL );
+ if (!result_sent) {
+ slapi_send_ldap_result(pb, ldap_result_code, ldap_result_matcheddn, ldap_result_message, 0, NULL);
+ }
}
backentry_free(&originalentry);
backentry_free(&tmpentry);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_bind.c b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
index ea0df33..99a0818 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_bind.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
@@ -29,6 +29,7 @@ ldbm_back_bind( Slapi_PBlock *pb )
entry_address *addr;
back_txn txn = {NULL};
int rc = SLAPI_BIND_SUCCESS;
+ int result_sent = 0;
/* get parameters */
slapi_pblock_get( pb, SLAPI_BACKEND, &be );
@@ -63,8 +64,12 @@ ldbm_back_bind( Slapi_PBlock *pb )
* find the target entry. find_entry() takes care of referrals
* and sending errors if the entry does not exist.
*/
- if (( e = find_entry( pb, be, addr, &txn )) == NULL ) {
+ if ((e = find_entry( pb, be, addr, &txn, &result_sent)) == NULL) {
rc = SLAPI_BIND_FAIL;
+ /* In the failure case, the result is supposed to be sent in the backend. */
+ if (!result_sent) {
+ slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL);
+ }
goto bail;
}
@@ -82,8 +87,8 @@ ldbm_back_bind( Slapi_PBlock *pb )
bvals= attr_get_present_values(attr);
slapi_value_init_berval(&cv,cred);
if ( slapi_pw_find_sv( bvals, &cv ) != 0 ) {
- slapi_send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL,
- NULL, 0, NULL );
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials");
+ slapi_send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL );
CACHE_RETURN( &inst->inst_cache, &e );
value_done(&cv);
rc = SLAPI_BIND_FAIL;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_compare.c b/ldap/servers/slapd/back-ldbm/ldbm_compare.c
index e52cd6c..e9973a9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_compare.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_compare.c
@@ -56,7 +56,7 @@ ldbm_back_compare( Slapi_PBlock *pb )
/* get the namespace dn */
namespace_dn = (Slapi_DN*)slapi_be_getsuffix(be, 0);
- if ( (e = find_entry( pb, be, addr, &txn )) == NULL ) {
+ if ((e = find_entry(pb, be, addr, &txn, NULL)) == NULL) {
ret = -1; /* error result sent by find_entry() */
goto bail;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 5b24af2..f801e01 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -77,6 +77,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
int op_id;
ID ep_id = 0;
ID tomb_ep_id = 0;
+ int result_sent = 0;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
@@ -266,7 +267,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
* deleted. That is, the entry 'e' found with "addr" is a tomb-
* stone. If it is the case, we need to back off.
*/
- if ( (e = find_entry2modify( pb, be, addr, &txn )) == NULL )
+ if ((e = find_entry2modify(pb, be, addr, &txn, &result_sent)) == NULL)
{
ldap_result_code= LDAP_NO_SUCH_OBJECT;
retval = -1;
@@ -507,7 +508,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
parent_addr.uniqueid = NULL;
}
parent_addr.sdn = &parentsdn;
- parent = find_entry2modify_only_ext(pb, be, &parent_addr, TOMBSTONE_INCLUDED, &txn);
+ parent = find_entry2modify_only_ext(pb, be, &parent_addr, TOMBSTONE_INCLUDED, &txn, &result_sent);
}
if (parent) {
int isglue;
@@ -1466,7 +1467,9 @@ diskfull_return:
* And we don't want the supplier to halt sending the updates. */
ldap_result_code = LDAP_SUCCESS;
}
- slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
+ if (!result_sent) {
+ slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
+ }
}
slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_back_delete",
"conn=%lu op=%d modify_term: old_entry=0x%p, new_entry=0x%p, in_cache=%d\n",
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 27f5c74..bf4ec49 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -392,6 +392,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
int not_an_error = 0;
int fixup_tombstone = 0;
int ec_locked = 0;
+ int result_sent = 0;
slapi_pblock_get( pb, SLAPI_BACKEND, &be);
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
@@ -466,12 +467,12 @@ ldbm_back_modify( Slapi_PBlock *pb )
if ( MANAGE_ENTRY_BEFORE_DBLOCK(li)) {
/* find and lock the entry we are about to modify */
if (fixup_tombstone) {
- e = find_entry2modify_only_ext( pb, be, addr, TOMBSTONE_INCLUDED, &txn );
+ e = find_entry2modify_only_ext( pb, be, addr, TOMBSTONE_INCLUDED, &txn, &result_sent );
} else {
- e = find_entry2modify( pb, be, addr, &txn );
+ e = find_entry2modify( pb, be, addr, &txn, &result_sent );
}
if (e == NULL) {
- ldap_result_code= -1;
+ ldap_result_code = -1;
goto error_return; /* error result sent by find_entry2modify() */
}
}
@@ -551,12 +552,12 @@ ldbm_back_modify( Slapi_PBlock *pb )
if ( !MANAGE_ENTRY_BEFORE_DBLOCK(li)) {
/* find and lock the entry we are about to modify */
if (fixup_tombstone) {
- e = find_entry2modify_only_ext( pb, be, addr, TOMBSTONE_INCLUDED, &txn );
+ e = find_entry2modify_only_ext( pb, be, addr, TOMBSTONE_INCLUDED, &txn, &result_sent );
} else {
- e = find_entry2modify( pb, be, addr, &txn );
+ e = find_entry2modify( pb, be, addr, &txn, &result_sent );
}
if (e == NULL) {
- ldap_result_code= -1;
+ ldap_result_code = -1;
goto error_return; /* error result sent by find_entry2modify() */
}
}
@@ -963,7 +964,10 @@ common_return:
* And we don't want the supplier to halt sending the updates. */
ldap_result_code = LDAP_SUCCESS;
}
- slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
+ if (!result_sent) {
+ /* result is already sent in find_entry. */
+ slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
+ }
}
/* free our backups */
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index fd74d5f..38b58e7 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -95,6 +95,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
int myrc = 0;
PRUint64 conn_id;
int op_id;
+ int result_sent = 0;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
}
@@ -474,7 +475,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
/* find and lock the entry we are about to modify */
/* JCMREPL - Argh, what happens about the stinking referrals? */
slapi_pblock_get (pb, SLAPI_TARGET_ADDRESS, &old_addr);
- e = find_entry2modify( pb, be, old_addr, &txn );
+ e = find_entry2modify(pb, be, old_addr, &txn, &result_sent);
if ( e == NULL )
{
ldap_result_code= -1;
@@ -510,7 +511,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
} else {
oldparent_addr.uniqueid = NULL;
}
- parententry = find_entry2modify_only( pb, be, &oldparent_addr, &txn );
+ parententry = find_entry2modify_only(pb, be, &oldparent_addr, &txn, &result_sent);
modify_init(&parent_modify_context,parententry);
/* Fetch and lock the new parent of the entry that is moving */
@@ -520,7 +521,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
if (is_resurect_operation) {
newsuperior_addr->uniqueid = slapi_entry_attr_get_charptr(e->ep_entry, SLAPI_ATTR_VALUE_PARENT_UNIQUEID);
}
- newparententry = find_entry2modify_only( pb, be, newsuperior_addr, &txn );
+ newparententry = find_entry2modify_only(pb, be, newsuperior_addr, &txn, &result_sent);
slapi_ch_free_string(&newsuperior_addr->uniqueid);
modify_init(&newparent_modify_context,newparententry);
}
@@ -581,7 +582,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
Slapi_DN ancestorsdn;
struct backentry *ancestorentry;
slapi_sdn_init(&ancestorsdn);
- ancestorentry= dn2ancestor(be,&dn_newdn,&ancestorsdn,&txn,&err);
+ ancestorentry = dn2ancestor(be, &dn_newdn, &ancestorsdn, &txn, &err, 0);
CACHE_RETURN( &inst->inst_cache, &ancestorentry );
ldap_result_matcheddn= slapi_ch_strdup((char *) slapi_sdn_get_dn(&ancestorsdn));
ldap_result_code= LDAP_NO_SUCH_OBJECT;
@@ -1483,8 +1484,10 @@ common_return:
* And we don't want the supplier to halt sending the updates. */
ldap_result_code = LDAP_SUCCESS;
}
- slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn,
- ldap_result_message, 0,NULL );
+ if (!result_sent) {
+ slapi_send_ldap_result(pb, ldap_result_code, ldap_result_matcheddn,
+ ldap_result_message, 0, NULL);
+ }
}
slapi_mods_done(&smods_operation_wsi);
slapi_mods_done(&smods_generated);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index 535529c..cda1714 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -584,7 +584,7 @@ ldbm_back_search( Slapi_PBlock *pb )
}
else
{
- if ( ( e = find_entry( pb, be, addr, &txn )) == NULL )
+ if ((e = find_entry(pb, be, addr, &txn, NULL)) == NULL)
{
/* error or referral sent by find_entry */
return ldbm_back_search_cleanup(pb, li, sort_control,
diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c
index 77c1e70..516b32d 100644
--- a/ldap/servers/slapd/back-ldbm/misc.c
+++ b/ldap/servers/slapd/back-ldbm/misc.c
@@ -412,7 +412,7 @@ ldbm_txn_ruv_modify_context( Slapi_PBlock *pb, modify_context *mc )
/* Note: if we find the bentry, it will stay locked until someone calls
* modify_term on the mc we'll be associating the bentry with */
- bentry = find_entry2modify_only( pb, be, &bentry_addr, &txn );
+ bentry = find_entry2modify_only(pb, be, &bentry_addr, &txn, NULL);
if (NULL == bentry) {
/* Uh oh, we couldn't find and lock the RUV entry! */
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index 37f9f20..907e8fc 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -176,7 +176,7 @@ int ldbm_back_ctrl_info(Slapi_Backend *be, int cmd, void *info);
struct backentry *dn2entry(Slapi_Backend *be, const Slapi_DN *sdn, back_txn *txn, int *err);
struct backentry *dn2entry_ext(Slapi_Backend *be, const Slapi_DN *sdn, back_txn *txn, int flags, int *err);
struct backentry *dn2entry_or_ancestor(Slapi_Backend *be, const Slapi_DN *sdn, Slapi_DN *ancestor, back_txn *txn, int *err);
-struct backentry *dn2ancestor(Slapi_Backend *be,const Slapi_DN *sdn,Slapi_DN *ancestordn,back_txn *txn,int *err);
+struct backentry *dn2ancestor(Slapi_Backend *be,const Slapi_DN *sdn,Slapi_DN *ancestordn,back_txn *txn,int *err, int allow_suffix);
int get_copy_of_entry(Slapi_PBlock *pb, const entry_address *addr, back_txn *txn, int plock_parameter, int must_exist);
int get_copy_of_entry_ext(Slapi_PBlock *pb, ID id, const entry_address *addr, back_txn *txn, int plock_parameter, int must_exist);
void done_with_pblock_entry(Slapi_PBlock *pb, int plock_parameter);
@@ -196,11 +196,13 @@ IDList * filter_candidates_ext( Slapi_PBlock *pb, backend *be, const char *base,
/*
* findentry.c
*/
-struct backentry * find_entry2modify( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn );
-struct backentry * find_entry( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn );
-struct backentry * find_entry2modify_only( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn);
-struct backentry * find_entry2modify_only_ext( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int flags, back_txn *txn);
-struct backentry * find_entry_only( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn);
+/* Return code */
+#define FE_RC_SENT_RESULT 1
+struct backentry *find_entry2modify(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
+struct backentry *find_entry(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
+struct backentry *find_entry2modify_only(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
+struct backentry *find_entry2modify_only_ext(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int flags, back_txn *txn, int *rc);
+struct backentry *find_entry_only(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
int check_entry_for_referral(Slapi_PBlock *pb, Slapi_Entry *entry, char *matched, const char *callingfn);
/*
diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c
index fcd0c2d..df37821 100644
--- a/ldap/servers/slapd/back-ldbm/vlv_srch.c
+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c
@@ -162,7 +162,7 @@ vlvSearch_init(struct vlvSearch* p, Slapi_PBlock *pb, const Slapi_Entry *e, ldbm
addr.sdn = p->vlv_base;
addr.uniqueid = NULL;
- e = find_entry( pb, inst->inst_be, &addr, &txn );
+ e = find_entry(pb, inst->inst_be, &addr, &txn, NULL);
/* Check to see if the entry is absent. If it is, mark this search
* as not initialized */
if (NULL == e) {
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index f81edfb..6763fc3 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -438,8 +438,8 @@ do_bind( Slapi_PBlock *pb )
* to an LDAP DN, fail and return an invalidCredentials error.
*/
if ( NULL == pb->pb_conn->c_external_dn ) {
- send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL,
- "client certificate mapping failed", 0, NULL );
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Client certificate mapping failed");
+ send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "", 0, NULL);
/* call postop plugins */
plugin_call_plugins( pb, SLAPI_PLUGIN_POST_BIND_FN );
goto free_and_return;
@@ -556,33 +556,32 @@ do_bind( Slapi_PBlock *pb )
/* Check if simple binds are allowed over an insecure channel. We only check
* this for authenticated binds. */
} else if (config_get_require_secure_binds() == 1) {
- Connection *conn = NULL;
- int sasl_ssf = 0;
- int local_ssf = 0;
-
- /* Allow simple binds only for SSL/TLS established connections
- * or connections using SASL privacy layers */
- conn = pb->pb_conn;
- if ( slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) {
- slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
- "Could not get SASL SSF from connection\n" );
- sasl_ssf = 0;
- }
+ Connection *conn = NULL;
+ int sasl_ssf = 0;
+ int local_ssf = 0;
+
+ /* Allow simple binds only for SSL/TLS established connections
+ * or connections using SASL privacy layers */
+ conn = pb->pb_conn;
+ if ( slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) {
+ slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
+ "Could not get SASL SSF from connection\n" );
+ sasl_ssf = 0;
+ }
- if ( slapi_pblock_get(pb, SLAPI_CONN_LOCAL_SSF, &local_ssf) != 0) {
- slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
- "Could not get local SSF from connection\n" );
- local_ssf = 0;
- }
+ if ( slapi_pblock_get(pb, SLAPI_CONN_LOCAL_SSF, &local_ssf) != 0) {
+ slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
+ "Could not get local SSF from connection\n" );
+ local_ssf = 0;
+ }
- if (((conn->c_flags & CONN_FLAG_SSL) != CONN_FLAG_SSL) &&
- (sasl_ssf <= 1) && (local_ssf <= 1)) {
- send_ldap_result(pb, LDAP_CONFIDENTIALITY_REQUIRED, NULL,
- "Operation requires a secure connection",
- 0, NULL);
- slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
- goto free_and_return;
- }
+ if (((conn->c_flags & CONN_FLAG_SSL) != CONN_FLAG_SSL) &&
+ (sasl_ssf <= 1) && (local_ssf <= 1)) {
+ send_ldap_result(pb, LDAP_CONFIDENTIALITY_REQUIRED, NULL,
+ "Operation requires a secure connection", 0, NULL);
+ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
+ goto free_and_return;
+ }
}
break;
default:
@@ -627,6 +626,7 @@ do_bind( Slapi_PBlock *pb )
/*
* right dn, wrong passwd - reject with invalid credentials
*/
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials");
send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL );
/* increment BindSecurityErrorcount */
slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
@@ -686,7 +686,8 @@ do_bind( Slapi_PBlock *pb )
slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &pb_sdn);
if (!pb_sdn) {
PR_snprintf(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set NULL dn\n");
- send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errorbuf);
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
goto free_and_return;
} else if ((pb_sdn != sdn) || (sdn_updated = slapi_sdn_compare(original_sdn, pb_sdn))) {
/*
@@ -696,8 +697,10 @@ do_bind( Slapi_PBlock *pb )
sdn = pb_sdn;
dn = slapi_sdn_get_dn(sdn);
if (!dn) {
- PR_snprintf(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set corrupted dn\n");
- send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
+ const char *udn = slapi_sdn_get_udn(sdn);
+ PR_snprintf(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set corrupted dn %s\n", udn?udn:"");
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errorbuf);
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
goto free_and_return;
}
if (!sdn_updated) { /* pb_sdn != sdn; need to compare the dn's. */
@@ -711,7 +714,8 @@ do_bind( Slapi_PBlock *pb )
slapi_pblock_set( pb, SLAPI_BACKEND, be );
} else {
PR_snprintf(errorbuf, sizeof(errorbuf), "No matching backend for %s\n", dn);
- send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errorbuf);
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
goto free_and_return;
}
}
@@ -790,7 +794,8 @@ do_bind( Slapi_PBlock *pb )
goto account_locked;
}
} else {
- send_ldap_result(pb, LDAP_NO_SUCH_OBJECT, NULL, "", 0, NULL);
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "No such entry");
+ send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "", 0, NULL);
goto free_and_return;
}
}
@@ -850,8 +855,7 @@ account_locked:
* the front end.
*/
if ( rc == SLAPI_BIND_SUCCESS || rc == SLAPI_BIND_ANONYMOUS) {
- send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL,
- 0, NULL );
+ send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL );
}
slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, &rc );
@@ -876,8 +880,7 @@ free_and_return:;
slapi_sdn_free(&sdn);
slapi_ch_free_string( &saslmech );
slapi_ch_free( (void **)&cred.bv_val );
- if ( bind_target_entry != NULL )
- slapi_entry_free(bind_target_entry);
+ slapi_entry_free(bind_target_entry);
}
diff --git a/ldap/servers/slapd/defbackend.c b/ldap/servers/slapd/defbackend.c
index 7d73501..da4a701 100644
--- a/ldap/servers/slapd/defbackend.c
+++ b/ldap/servers/slapd/defbackend.c
@@ -171,6 +171,51 @@ defbackend_abandon( Slapi_PBlock *pb )
}
+#define DEFBE_NO_SUCH_SUFFIX "No such suffix"
+/*
+ * Generate a "No such suffix" return text
+ * Example:
+ * cn=X,dc=bogus,dc=com ==> "No such suffix (dc=bogus,dc=com)"
+ * if the last rdn starts with "dc=", print all last dc= rdn's.
+ * cn=X,cn=bogus ==> "No such suffix (cn=bogus)"
+ * otherwise, print the very last rdn.
+ * cn=X,z=bogus ==> "No such suffix (x=bogus)"
+ * it is true even if it is an invalid rdn.
+ * cn=X,bogus ==> "No such suffix (bogus)"
+ * another example of invalid rdn.
+ */
+static void
+_defbackend_gen_returntext(char *buffer, size_t buflen, char **dns)
+{
+ int dnidx;
+ int sidx;
+ struct suffix_repeat {
+ char *suffix;
+ int size;
+ } candidates[] = {
+ {"dc=", 3}, /* dc could be repeated. otherwise the last rdn is used. */
+ {NULL, 0}
+ };
+ PR_snprintf(buffer, buflen, "%s (", DEFBE_NO_SUCH_SUFFIX);
+ for (dnidx = 0; dns[dnidx]; dnidx++) ; /* finding the last */
+ dnidx--; /* last rdn */
+ for (sidx = 0; candidates[sidx].suffix; sidx++) {
+ if (!PL_strncasecmp(dns[dnidx], candidates[sidx].suffix, candidates[sidx].size)) {
+ while (!PL_strncasecmp(dns[--dnidx], candidates[sidx].suffix, candidates[sidx].size)) ;
+ PL_strcat(buffer, dns[++dnidx]); /* the first "dn=", e.g. */
+ for (++dnidx; dns[dnidx]; dnidx++) {
+ PL_strcat(buffer, ",");
+ PL_strcat(buffer, dns[dnidx]);
+ }
+ PL_strcat(buffer, ")");
+ return; /* finished the task */
+ }
+ }
+ PL_strcat(buffer, dns[dnidx]);
+ PL_strcat(buffer, ")");
+ return;
+}
+
static int
defbackend_bind( Slapi_PBlock *pb )
{
@@ -188,11 +233,40 @@ defbackend_bind( Slapi_PBlock *pb )
slapi_pblock_get( pb, SLAPI_BIND_METHOD, &method );
slapi_pblock_get( pb, SLAPI_BIND_CREDENTIALS, &cred );
if ( method == LDAP_AUTH_SIMPLE && cred->bv_len == 0 ) {
- slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds);
- rc = SLAPI_BIND_ANONYMOUS;
+ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds);
+ rc = SLAPI_BIND_ANONYMOUS;
} else {
- send_nobackend_ldap_result( pb );
- rc = SLAPI_BIND_FAIL;
+ Slapi_DN *sdn = NULL;
+ char *suffix = NULL;
+ char **dns = NULL;
+
+ if (pb->pb_op) {
+ sdn = operation_get_target_spec(pb->pb_op);
+ if (sdn) {
+ dns = slapi_ldap_explode_dn(slapi_sdn_get_dn(sdn), 0);
+ if (dns) {
+ size_t dnlen = slapi_sdn_get_ndn_len(sdn);
+ size_t len = dnlen + sizeof(DEFBE_NO_SUCH_SUFFIX) + 4;
+ suffix = slapi_ch_malloc(len);
+ if (dnlen) {
+ _defbackend_gen_returntext(suffix, len, dns);
+ } else {
+ PR_snprintf(suffix, len, "%s", DEFBE_NO_SUCH_SUFFIX);
+ }
+ }
+ }
+ }
+ if (suffix) {
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, suffix);
+ } else {
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, DEFBE_NO_SUCH_SUFFIX);
+ }
+ send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "", 0, NULL);
+ if (dns) {
+ slapi_ldap_value_free(dns);
+ }
+ slapi_ch_free_string(&suffix);
+ rc = SLAPI_BIND_FAIL;
}
return( rc );
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
index 34c4d41..66f2c6b 100644
--- a/ldap/servers/slapd/result.c
+++ b/ldap/servers/slapd/result.c
@@ -2058,14 +2058,26 @@ log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentrie
}
else if ( !internal_op )
{
+ char *pbtxt = NULL;
+ char *ext_str = NULL;
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &pbtxt);
+ if (pbtxt) {
+ ext_str = slapi_ch_smprintf(" - %s", pbtxt);
+ } else {
+ ext_str = "";
+ }
slapi_log_access( LDAP_DEBUG_STATS,
"conn=%" NSPRIu64 " op=%d RESULT err=%d"
- " tag=%" BERTAG_T " nentries=%d etime=%s%s%s\n",
+ " tag=%" BERTAG_T " nentries=%d etime=%s%s%s%s\n",
op->o_connid,
op->o_opid,
err, tag, nentries,
etime,
- notes_str, csn_str );
+ notes_str, csn_str, ext_str);
+ if (pbtxt) {
+ /* if !pbtxt ==> ext_str == "". Don't free ext_str. */
+ slapi_ch_free_string(&ext_str);
+ }
}
else
{
7 years, 8 months
ldap/servers
by Noriko Hosoi
ldap/servers/slapd/bind.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 590e2fb86ee2e1d6f169169c83917d18872a95d0
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Jul 14 10:33:15 2016 -0700
Bug 1347760 - CVE-2016-4992 389-ds-base: Information disclosure via repeated use of LDAP ADD operation, etc.
Description: Fixing a compiler warning.
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index b441615..702d4c2 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -697,7 +697,7 @@ do_bind( Slapi_PBlock *pb )
sdn = pb_sdn;
dn = slapi_sdn_get_dn(sdn);
if (!dn) {
- char *udn = slapi_sdn_get_udn(sdn);
+ const char *udn = slapi_sdn_get_udn(sdn);
slapi_create_errormsg(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set corrupted dn %s\n", udn?udn:"");
slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errorbuf);
send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
7 years, 8 months
2 commits - dirsrvtests/tests ldap/servers
by Noriko Hosoi
dirsrvtests/tests/tickets/ticket1347760_test.py | 440 ++++++++++++++++++++++++
ldap/servers/slapd/back-ldbm/dn2entry.c | 17
ldap/servers/slapd/back-ldbm/findentry.c | 139 +++++--
ldap/servers/slapd/back-ldbm/ldbm_add.c | 21 -
ldap/servers/slapd/back-ldbm/ldbm_bind.c | 11
ldap/servers/slapd/back-ldbm/ldbm_compare.c | 2
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 9
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 18
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 15
ldap/servers/slapd/back-ldbm/ldbm_search.c | 2
ldap/servers/slapd/back-ldbm/misc.c | 2
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 14
ldap/servers/slapd/back-ldbm/vlv_srch.c | 2
ldap/servers/slapd/bind.c | 75 ++--
ldap/servers/slapd/defbackend.c | 82 ++++
ldap/servers/slapd/result.c | 16
16 files changed, 751 insertions(+), 114 deletions(-)
New commits:
commit 27b8987108d875e3e9ee0d844548f8d94db350d1
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Jul 12 14:33:17 2016 -0700
Bug 1347760 - CI test: test case for bug 1347760
Description: Information disclosure via repeated use of LDAP ADD operation, etc.
diff --git a/dirsrvtests/tests/tickets/ticket1347760_test.py b/dirsrvtests/tests/tickets/ticket1347760_test.py
new file mode 100644
index 0000000..d2e9e37
--- /dev/null
+++ b/dirsrvtests/tests/tickets/ticket1347760_test.py
@@ -0,0 +1,440 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2016 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+import sys
+import time
+import ldap
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+
+CONFIG_DN = 'cn=config'
+BOU = 'BOU'
+BINDOU = 'ou=%s,%s' % (BOU, DEFAULT_SUFFIX)
+BUID = 'buser123'
+TUID = 'tuser0'
+BINDDN = 'uid=%s,%s' % (BUID, BINDOU)
+BINDPW = BUID
+TESTDN = 'uid=%s,ou=people,%s' % (TUID, DEFAULT_SUFFIX)
+TESTPW = TUID
+BOGUSDN = 'uid=bogus,%s' % DEFAULT_SUFFIX
+BOGUSDN2 = 'uid=bogus,ou=people,%s' % DEFAULT_SUFFIX
+BOGUSSUFFIX = 'uid=bogus,ou=people,dc=bogus'
+GROUPOU = 'ou=groups,%s' % DEFAULT_SUFFIX
+BOGUSOU = 'ou=OU,%s' % DEFAULT_SUFFIX
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+ global installation1_prefix
+ if installation1_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+ # Creating standalone instance ...
+ standalone = DirSrv(verbose=False)
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ standalone.delete()
+ standalone.create()
+ standalone.open()
+
+ # Delete each instance in the end
+# def fin():
+# standalone.delete()
+# request.addfinalizer(fin)
+
+ # Clear out the tmp dir
+ standalone.clearTmpDir(__file__)
+
+ return TopologyStandalone(standalone)
+
+def pattern_accesslog(file, log_pattern):
+ try:
+ pattern_accesslog.last_pos += 1
+ except AttributeError:
+ pattern_accesslog.last_pos = 0
+
+ found = None
+ file.seek(pattern_accesslog.last_pos)
+
+ # Use a while true iteration because 'for line in file: hit a
+ # python bug that break file.tell()
+ while True:
+ line = file.readline()
+ found = log_pattern.search(line)
+ if ((line == '') or (found)):
+ break
+
+ pattern_accesslog.last_pos = file.tell()
+ if found:
+ return line
+ else:
+ return None
+
+def check_op_result(server, op, dn, superior, exists, rc):
+ targetdn = dn
+ if op == 'search':
+ if exists:
+ opstr = 'Searching existing entry'
+ else:
+ opstr = 'Searching non-existing entry'
+ elif op == 'add':
+ if exists:
+ opstr = 'Adding existing entry'
+ else:
+ opstr = 'Adding non-existing entry'
+ elif op == 'modify':
+ if exists:
+ opstr = 'Modifying existing entry'
+ else:
+ opstr = 'Modifying non-existing entry'
+ elif op == 'modrdn':
+ if superior != None:
+ targetdn = superior
+ if exists:
+ opstr = 'Moving to existing superior'
+ else:
+ opstr = 'Moving to non-existing superior'
+ else:
+ if exists:
+ opstr = 'Renaming existing entry'
+ else:
+ opstr = 'Renaming non-existing entry'
+ elif op == 'delete':
+ if exists:
+ opstr = 'Deleting existing entry'
+ else:
+ opstr = 'Deleting non-existing entry'
+
+ if ldap.SUCCESS == rc:
+ expstr = 'be ok'
+ else:
+ expstr = 'fail with %s' % rc.__name__
+
+ log.info('%s %s, which should %s.' % (opstr, targetdn, expstr))
+ hit = 0
+ try:
+ if op == 'search':
+ centry = server.search_s(dn, ldap.SCOPE_BASE, 'objectclass=*')
+ elif op == 'add':
+ server.add_s(Entry((dn, {'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'test entry'})))
+ elif op == 'modify':
+ server.modify_s(dn, [(ldap.MOD_REPLACE, 'description', 'test')])
+ elif op == 'modrdn':
+ if superior != None:
+ server.rename_s(dn, 'uid=new', newsuperior=superior, delold=1)
+ else:
+ server.rename_s(dn, 'uid=new', delold=1)
+ elif op == 'delete':
+ server.delete_s(dn)
+ else:
+ log.fatal('Unknown operation %s' % op)
+ assert False
+ except ldap.LDAPError as e:
+ hit = 1
+ log.info("Exception (expected): %s" % type(e).__name__)
+ log.info('Desc ' + e.message['desc'])
+ assert isinstance(e, rc)
+ if e.message.has_key('matched'):
+ log.info('Matched is returned: ' + e.message['matched'])
+ if rc != ldap.NO_SUCH_OBJECT:
+ assert False
+
+ if ldap.SUCCESS == rc:
+ if op == 'search':
+ log.info('Search should return none')
+ assert len(centry) == 0
+ else:
+ if 0 == hit:
+ log.info('Expected to fail with %s, but passed' % rc.__name__)
+ assert False
+
+ log.info('PASSED\n')
+
+def test_ticket1347760(topology):
+ """
+ Prevent revealing the entry info to whom has no access rights.
+ """
+ log.info('Testing Bug 1347760 - Information disclosure via repeated use of LDAP ADD operation, etc.')
+
+ log.info('Disabling accesslog logbuffering')
+ topology.standalone.modify_s(CONFIG_DN, [(ldap.MOD_REPLACE, 'nsslapd-accesslog-logbuffering', 'off')])
+
+ log.info('Bind as {%s,%s}' % (DN_DM, PASSWORD))
+ topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+
+ log.info('Adding ou=%s a bind user belongs to.' % BOU)
+ topology.standalone.add_s(Entry((BINDOU, {
+ 'objectclass': 'top organizationalunit'.split(),
+ 'ou': BOU})))
+
+ log.info('Adding a bind user.')
+ topology.standalone.add_s(Entry((BINDDN,
+ {'objectclass': "top person organizationalPerson inetOrgPerson".split(),
+ 'cn': 'bind user',
+ 'sn': 'user',
+ 'userPassword': BINDPW})))
+
+ log.info('Adding a test user.')
+ topology.standalone.add_s(Entry((TESTDN,
+ {'objectclass': "top person organizationalPerson inetOrgPerson".split(),
+ 'cn': 'test user',
+ 'sn': 'user',
+ 'userPassword': TESTPW})))
+
+ log.info('Deleting aci in %s.' % DEFAULT_SUFFIX)
+ topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_DELETE, 'aci', None)])
+
+ log.info('Bind case 1. the bind user has no rights to read the entry itself, bind should be successful.')
+ log.info('Bind as {%s,%s} who has no access rights.' % (BINDDN, BINDPW))
+ try:
+ topology.standalone.simple_bind_s(BINDDN, BINDPW)
+ except ldap.LDAPError as e:
+ log.info('Desc ' + e.message['desc'])
+ assert False
+
+ file_path = os.path.join(topology.standalone.prefix, 'var/log/dirsrv/slapd-%s/access' % topology.standalone.serverid)
+ file_obj = open(file_path, "r")
+ log.info('Access log path: %s' % file_path)
+
+ log.info('Bind case 2-1. the bind user does not exist, bind should fail with error %s' % ldap.INVALID_CREDENTIALS.__name__)
+ log.info('Bind as {%s,%s} who does not exist.' % (BOGUSDN, 'bogus'))
+ try:
+ topology.standalone.simple_bind_s(BOGUSDN, 'bogus')
+ except ldap.LDAPError as e:
+ log.info("Exception (expected): %s" % type(e).__name__)
+ log.info('Desc ' + e.message['desc'])
+ assert isinstance(e, ldap.INVALID_CREDENTIALS)
+ regex = re.compile('No such entry')
+ cause = pattern_accesslog(file_obj, regex)
+ if cause == None:
+ log.fatal('Cause not found - %s' % cause)
+ assert False
+ else:
+ log.info('Cause found - %s' % cause)
+
+ log.info('Bind case 2-2. the bind user\'s suffix does not exist, bind should fail with error %s' % ldap.INVALID_CREDENTIALS.__name__)
+ log.info('Bind as {%s,%s} who does not exist.' % (BOGUSSUFFIX, 'bogus'))
+ try:
+ topology.standalone.simple_bind_s(BOGUSSUFFIX, 'bogus')
+ except ldap.LDAPError as e:
+ log.info("Exception (expected): %s" % type(e).__name__)
+ log.info('Desc ' + e.message['desc'])
+ assert isinstance(e, ldap.INVALID_CREDENTIALS)
+ regex = re.compile('No such suffix')
+ cause = pattern_accesslog(file_obj, regex)
+ if cause == None:
+ log.fatal('Cause not found - %s' % cause)
+ assert False
+ else:
+ log.info('Cause found - %s' % cause)
+
+ log.info('Bind case 2-3. the bind user\'s password is wrong, bind should fail with error %s' % ldap.INVALID_CREDENTIALS.__name__)
+ log.info('Bind as {%s,%s} who does not exist.' % (BINDDN, 'bogus'))
+ try:
+ topology.standalone.simple_bind_s(BINDDN, 'bogus')
+ except ldap.LDAPError as e:
+ log.info("Exception (expected): %s" % type(e).__name__)
+ log.info('Desc ' + e.message['desc'])
+ assert isinstance(e, ldap.INVALID_CREDENTIALS)
+ regex = re.compile('Invalid credentials')
+ cause = pattern_accesslog(file_obj, regex)
+ if cause == None:
+ log.fatal('Cause not found - %s' % cause)
+ assert False
+ else:
+ log.info('Cause found - %s' % cause)
+
+ log.info('Adding aci for %s to %s.' % (BINDDN, BINDOU))
+ acival = '(targetattr="*")(version 3.0; acl "%s"; allow(all) userdn = "ldap:///%s";)' % (BUID, BINDDN)
+ log.info('aci: %s' % acival)
+ log.info('Bind as {%s,%s}' % (DN_DM, PASSWORD))
+ topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+ topology.standalone.modify_s(BINDOU, [(ldap.MOD_ADD, 'aci', acival)])
+
+ log.info('Bind case 3. the bind user has the right to read the entry itself, bind should be successful.')
+ log.info('Bind as {%s,%s} which should be ok.\n' % (BINDDN, BINDPW))
+ topology.standalone.simple_bind_s(BINDDN, BINDPW)
+
+ log.info('The following operations are against the subtree the bind user %s has no rights.' % BINDDN)
+ # Search
+ exists = True
+ rc = ldap.SUCCESS
+ log.info('Search case 1. the bind user has no rights to read the search entry, it should return no search results with %s' % rc)
+ check_op_result(topology.standalone, 'search', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.SUCCESS
+ log.info('Search case 2-1. the search entry does not exist, the search should return no search results with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'search', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.SUCCESS
+ log.info('Search case 2-2. the search entry does not exist, the search should return no search results with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'search', BOGUSDN2, None, exists, rc)
+
+ # Add
+ exists = True
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Add case 1. the bind user has no rights AND the adding entry exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'add', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Add case 2-1. the bind user has no rights AND the adding entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'add', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Add case 2-2. the bind user has no rights AND the adding entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'add', BOGUSDN2, None, exists, rc)
+
+ # Modify
+ exists = True
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modify case 1. the bind user has no rights AND the modifying entry exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modify', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modify case 2-1. the bind user has no rights AND the modifying entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modify', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modify case 2-2. the bind user has no rights AND the modifying entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modify', BOGUSDN2, None, exists, rc)
+
+ # Modrdn
+ exists = True
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 1. the bind user has no rights AND the renaming entry exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 2-1. the bind user has no rights AND the renaming entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 2-2. the bind user has no rights AND the renaming entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', BOGUSDN2, None, exists, rc)
+
+ exists = True
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 3. the bind user has no rights AND the node moving an entry to exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', TESTDN, GROUPOU, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 4-1. the bind user has no rights AND the node moving an entry to does not, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', TESTDN, BOGUSOU, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Modrdn case 4-2. the bind user has no rights AND the node moving an entry to does not, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', TESTDN, BOGUSOU, exists, rc)
+
+ # Delete
+ exists = True
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Delete case 1. the bind user has no rights AND the deleting entry exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'delete', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Delete case 2-1. the bind user has no rights AND the deleting entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'delete', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.INSUFFICIENT_ACCESS
+ log.info('Delete case 2-2. the bind user has no rights AND the deleting entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'delete', BOGUSDN2, None, exists, rc)
+
+ log.info('EXTRA: Check no regressions')
+ log.info('Adding aci for %s to %s.' % (BINDDN, DEFAULT_SUFFIX))
+ acival = '(targetattr="*")(version 3.0; acl "%s-all"; allow(all) userdn = "ldap:///%s";)' % (BUID, BINDDN)
+ log.info('Bind as {%s,%s}' % (DN_DM, PASSWORD))
+ topology.standalone.simple_bind_s(DN_DM, PASSWORD)
+ topology.standalone.modify_s(DEFAULT_SUFFIX, [(ldap.MOD_ADD, 'aci', acival)])
+
+ log.info('Bind as {%s,%s}.' % (BINDDN, BINDPW))
+ try:
+ topology.standalone.simple_bind_s(BINDDN, BINDPW)
+ except ldap.LDAPError as e:
+ log.info('Desc ' + e.message['desc'])
+ assert False
+
+ exists = False
+ rc = ldap.NO_SUCH_OBJECT
+ log.info('Search case. the search entry does not exist, the search should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'search', BOGUSDN2, None, exists, rc)
+ file_obj.close()
+
+ exists = True
+ rc = ldap.ALREADY_EXISTS
+ log.info('Add case. the adding entry already exists, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'add', TESTDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.NO_SUCH_OBJECT
+ log.info('Modify case. the modifying entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modify', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.NO_SUCH_OBJECT
+ log.info('Modrdn case 1. the renaming entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', BOGUSDN, None, exists, rc)
+
+ exists = False
+ rc = ldap.NO_SUCH_OBJECT
+ log.info('Modrdn case 2. the node moving an entry to does not, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'modrdn', TESTDN, BOGUSOU, exists, rc)
+
+ exists = False
+ rc = ldap.NO_SUCH_OBJECT
+ log.info('Delete case. the deleting entry does not exist, it should fail with %s' % rc.__name__)
+ check_op_result(topology.standalone, 'delete', BOGUSDN, None, exists, rc)
+
+ log.info('SUCCESS')
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
commit 0b932d4b926d46ac5060f02617330dc444e06da1
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Jul 13 14:49:18 2016 -0700
Bug 1347760 - CVE-2016-4992 389-ds-base: Information disclosure via repeated use of LDAP ADD operation, etc.
Description: If a bind user has no rights, it should not disclose
any information including the existence of the entry.
Fix description:
1) ALREADY_EXISTS in add -- If to be added entry is found existing
in ldbm_back_add, it checks the ACI and if there is no rights,
it returns INSUFFICIENT_ACCESS instead of ALREADY_EXISTS.
2) NO_SUCH_OBJECT in other update operations -- If the target entry
is found not existing, it checks the ancestor entry's access
rights in find_entry. If it is not allowed to access the subtree,
it returns INSUFFICIENT_ACCESS instead of NO_SUC_OBJECT. Plus,
it supresses the "Matched" ancestor message.
3) NO_SUCH_OBJECT in search -- If a bind entry has no rights to read
a subtree, it returns no search results with SUCCESS. It should
be applied to the no existing subtree if the bind entry has no
rights to the super tree.
4) If bind fails because of the non-existence of the bind user or
the parent nodes, the bind returns LDAP_INVALID_CREDENTIALS to
the client with no other information.
The detailed cause is logged in the access log as follows:
RESULT err=49 .. etime=0 - No such suffix (<given suffix>)
RESULT err=49 .. etime=0 - Invalid credentials
RESULT err=49 .. etime=0 - No such entry
https://bugzilla.redhat.com/show_bug.cgi?id=1347760
Reviewed by lkrispen(a)redhat.com, mreynolds(a)redhat.com, and tbordaz(a)redhat.com.
Thank you!!!
diff --git a/ldap/servers/slapd/back-ldbm/dn2entry.c b/ldap/servers/slapd/back-ldbm/dn2entry.c
index 6d1d92f..7656688 100644
--- a/ldap/servers/slapd/back-ldbm/dn2entry.c
+++ b/ldap/servers/slapd/back-ldbm/dn2entry.c
@@ -151,14 +151,15 @@ struct backentry *
dn2ancestor(
Slapi_Backend *be,
const Slapi_DN *sdn,
- Slapi_DN *ancestordn,
+ Slapi_DN *ancestordn,
back_txn *txn,
- int *err
+ int *err,
+ int allow_suffix
)
{
- struct backentry *e = NULL;
+ struct backentry *e = NULL;
- LDAPDebug( LDAP_DEBUG_TRACE, "=> dn2ancestor \"%s\"\n", slapi_sdn_get_dn(sdn), 0, 0 );
+ LDAPDebug( LDAP_DEBUG_TRACE, "=> dn2ancestor \"%s\"\n", slapi_sdn_get_dn(sdn), 0, 0 );
/* first, check to see if the given sdn is empty or a root suffix of the
given backend - if so, it has no parent */
@@ -190,7 +191,13 @@ dn2ancestor(
*/
/* stop when we get to "", or a backend suffix point */
- while (!e && !slapi_sdn_isempty(&ancestorndn) && !slapi_be_issuffix( be, &ancestorndn )) {
+ while (!e && !slapi_sdn_isempty(&ancestorndn)) {
+ if (!allow_suffix) {
+ /* Original behavior. */
+ if (slapi_be_issuffix(be, &ancestorndn)) {
+ break;
+ }
+ }
/* find the entry - it uses the ndn, so no further conversion is necessary */
e= dn2entry(be,&ancestorndn,txn,err);
if (!e) {
diff --git a/ldap/servers/slapd/back-ldbm/findentry.c b/ldap/servers/slapd/back-ldbm/findentry.c
index 4a574bf..8b842e3 100644
--- a/ldap/servers/slapd/back-ldbm/findentry.c
+++ b/ldap/servers/slapd/back-ldbm/findentry.c
@@ -16,8 +16,8 @@
#include "back-ldbm.h"
-static struct backentry *find_entry_internal_dn(Slapi_PBlock *pb, backend *be, const Slapi_DN *sdn, int lock, back_txn *txn, int flags);
-static struct backentry * find_entry_internal(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int lock, back_txn *txn, int flags);
+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);
+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);
/* The flags take these values */
#define FE_TOMBSTONE_INCLUDED TOMBSTONE_INCLUDED /* :1 defined in back-ldbm.h */
#define FE_REALLY_INTERNAL 0x2
@@ -27,7 +27,7 @@ check_entry_for_referral(Slapi_PBlock *pb, Slapi_Entry *entry, char *matched, co
{
int rc=0, i=0, numValues=0;
Slapi_Attr *attr;
- Slapi_Value *val=NULL;
+ Slapi_Value *val=NULL;
struct berval **refscopy=NULL;
struct berval **url=NULL;
@@ -80,12 +80,13 @@ out:
static struct backentry *
find_entry_internal_dn(
- Slapi_PBlock *pb,
+ Slapi_PBlock *pb,
backend *be,
const Slapi_DN *sdn,
int lock,
- back_txn *txn,
- int flags
+ back_txn *txn,
+ int flags,
+ int *rc /* return code */
)
{
struct backentry *e;
@@ -93,9 +94,14 @@ find_entry_internal_dn(
int err;
ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
size_t tries = 0;
+ int isroot = 0;
+ int op_type;
+ char *errbuf = NULL;
/* get the managedsait ldap message control */
- slapi_pblock_get( pb, SLAPI_MANAGEDSAIT, &managedsait );
+ slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait);
+ slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, &isroot);
+ slapi_pblock_get(pb, SLAPI_OPERATION_TYPE, &op_type);
while ( (tries < LDBM_CACHE_RETRY_COUNT) &&
(e = dn2entry_ext( be, sdn, txn, flags & TOMBSTONE_INCLUDED, &err ))
@@ -113,6 +119,9 @@ find_entry_internal_dn(
if(check_entry_for_referral(pb, e->ep_entry, NULL, "find_entry_internal_dn"))
{
CACHE_RETURN( &inst->inst_cache, &e );
+ if (rc) { /* if check_entry_for_referral returns non-zero, result is sent. */
+ *rc = FE_RC_SENT_RESULT;
+ }
return( NULL );
}
}
@@ -151,27 +160,89 @@ find_entry_internal_dn(
struct backentry *me;
Slapi_DN ancestorsdn;
slapi_sdn_init(&ancestorsdn);
- me= dn2ancestor(pb->pb_backend,sdn,&ancestorsdn,txn,&err);
+ me = dn2ancestor(pb->pb_backend, sdn, &ancestorsdn, txn, &err, 1 /* allow_suffix */);
if ( !managedsait && me != NULL ) {
/* if the entry is a referral send the referral */
if(check_entry_for_referral(pb, me->ep_entry, (char*)slapi_sdn_get_dn(&ancestorsdn), "find_entry_internal_dn"))
{
CACHE_RETURN( &inst->inst_cache, &me );
slapi_sdn_done(&ancestorsdn);
+ if (rc) { /* if check_entry_for_referral returns non-zero, result is sent. */
+ *rc = FE_RC_SENT_RESULT;
+ }
return( NULL );
}
/* else fall through to no such object */
}
/* entry not found */
- slapi_send_ldap_result( pb, ( 0 == err || DB_NOTFOUND == err ) ?
- LDAP_NO_SUCH_OBJECT : ( LDAP_INVALID_DN_SYNTAX == err ) ?
- LDAP_INVALID_DN_SYNTAX : LDAP_OPERATIONS_ERROR,
- (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL );
+ if ((0 == err) || (DB_NOTFOUND == err)) {
+ if (me && !isroot) {
+ /* If not root, you may not want to reveal it. */
+ int acl_type = -1;
+ int return_err = LDAP_NO_SUCH_OBJECT;
+ err = LDAP_SUCCESS;
+ switch (op_type) {
+ case SLAPI_OPERATION_ADD:
+ acl_type = SLAPI_ACL_ADD;
+ return_err = LDAP_INSUFFICIENT_ACCESS;
+ break;
+ case SLAPI_OPERATION_DELETE:
+ acl_type = SLAPI_ACL_DELETE;
+ return_err = LDAP_INSUFFICIENT_ACCESS;
+ break;
+ case SLAPI_OPERATION_MODDN:
+ acl_type = SLAPI_ACL_MODDN;
+ return_err = LDAP_INSUFFICIENT_ACCESS;
+ break;
+ case SLAPI_OPERATION_MODIFY:
+ acl_type = SLAPI_ACL_WRITE;
+ return_err = LDAP_INSUFFICIENT_ACCESS;
+ break;
+ case SLAPI_OPERATION_SEARCH:
+ case SLAPI_OPERATION_COMPARE:
+ return_err = LDAP_SUCCESS;
+ acl_type = SLAPI_ACL_READ;
+ break;
+ case SLAPI_OPERATION_BIND:
+ acl_type = -1; /* skip acl check. acl is not set up for bind. */
+ return_err = LDAP_INVALID_CREDENTIALS;
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "No such entry");
+ break;
+ }
+ if (acl_type > 0) {
+ err = plugin_call_acl_plugin(pb, me->ep_entry, NULL, NULL, acl_type,
+ ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
+ }
+ if (((acl_type > 0) && err) || (op_type == SLAPI_OPERATION_BIND)) {
+ /*
+ * Operations to be checked && ACL returns disallow.
+ * Not to disclose the info about the entry's existence,
+ * do not return the "matched" DN.
+ * Plus, the bind case returns LDAP_INAPPROPRIATE_AUTH.
+ */
+ slapi_send_ldap_result(pb, return_err, NULL, NULL, 0, NULL);
+ } else {
+ slapi_send_ldap_result(pb, LDAP_NO_SUCH_OBJECT,
+ (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL);
+ }
+ } else {
+ slapi_send_ldap_result( pb, LDAP_NO_SUCH_OBJECT,
+ (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL);
+ }
+ } else {
+ slapi_send_ldap_result( pb, ( LDAP_INVALID_DN_SYNTAX == err ) ?
+ LDAP_INVALID_DN_SYNTAX : LDAP_OPERATIONS_ERROR,
+ (char*)slapi_sdn_get_dn(&ancestorsdn), NULL, 0, NULL );
+ }
+ if (rc) {
+ *rc = FE_RC_SENT_RESULT;
+ }
slapi_sdn_done(&ancestorsdn);
CACHE_RETURN( &inst->inst_cache, &me );
}
+ slapi_ch_free_string(&errbuf);
LDAPDebug( LDAP_DEBUG_TRACE, "<= find_entry_internal_dn not found (%s)\n",
slapi_sdn_get_dn(sdn), 0, 0 );
return( NULL );
@@ -183,11 +254,11 @@ find_entry_internal_dn(
*/
static struct backentry *
find_entry_internal_uniqueid(
- Slapi_PBlock *pb,
+ Slapi_PBlock *pb,
backend *be,
- const char *uniqueid,
+ const char *uniqueid,
int lock,
- back_txn *txn
+ back_txn *txn
)
{
ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
@@ -243,8 +314,9 @@ find_entry_internal(
Slapi_Backend *be,
const entry_address *addr,
int lock,
- back_txn *txn,
- int flags
+ back_txn *txn,
+ int flags,
+ int *rc
)
{
/* check if we should search based on uniqueid or dn */
@@ -261,11 +333,9 @@ find_entry_internal(
LDAPDebug( LDAP_DEBUG_TRACE, "=> find_entry_internal (dn=%s) lock %d\n",
slapi_sdn_get_dn(addr->sdn), lock, 0 );
if (addr->sdn) {
- entry = find_entry_internal_dn (pb, be, addr->sdn,
- lock, txn, flags);
+ entry = find_entry_internal_dn (pb, be, addr->sdn, lock, txn, flags, rc);
} else {
- LDAPDebug0Args( LDAP_DEBUG_ANY,
- "find_entry_internal: Null target dn\n" );
+ LDAPDebug0Args( LDAP_DEBUG_ANY, "find_entry_internal: Null target dn\n" );
}
LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= find_entry_internal\n" );
@@ -278,10 +348,11 @@ find_entry(
Slapi_PBlock *pb,
Slapi_Backend *be,
const entry_address *addr,
- back_txn *txn
+ back_txn *txn,
+ int *rc
)
{
- return( find_entry_internal( pb, be, addr, 0/*!lock*/, txn, 0/*flags*/ ) );
+ return(find_entry_internal(pb, be, addr, 0/*!lock*/, txn, 0/*flags*/, rc));
}
struct backentry *
@@ -289,10 +360,11 @@ find_entry2modify(
Slapi_PBlock *pb,
Slapi_Backend *be,
const entry_address *addr,
- back_txn *txn
+ back_txn *txn,
+ int *rc
)
{
- return( find_entry_internal( pb, be, addr, 1/*lock*/, txn, 0/*flags*/ ) );
+ return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, 0/*flags*/, rc));
}
/* New routines which do not do any referral stuff.
@@ -304,10 +376,11 @@ find_entry_only(
Slapi_PBlock *pb,
Slapi_Backend *be,
const entry_address *addr,
- back_txn *txn
+ back_txn *txn,
+ int *rc
)
{
- return( find_entry_internal( pb, be, addr, 0/*!lock*/, txn, FE_REALLY_INTERNAL ) );
+ return(find_entry_internal(pb, be, addr, 0/*!lock*/, txn, FE_REALLY_INTERNAL, rc));
}
struct backentry *
@@ -315,10 +388,11 @@ find_entry2modify_only(
Slapi_PBlock *pb,
Slapi_Backend *be,
const entry_address *addr,
- back_txn *txn
+ back_txn *txn,
+ int *rc
)
{
- return( find_entry_internal( pb, be, addr, 1/*lock*/, txn, FE_REALLY_INTERNAL ) );
+ return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, 0 /* to check aci, disable INTERNAL */, rc));
}
struct backentry *
@@ -327,10 +401,9 @@ find_entry2modify_only_ext(
Slapi_Backend *be,
const entry_address *addr,
int flags,
- back_txn *txn
-
+ back_txn *txn,
+ int *rc
)
{
- return( find_entry_internal( pb, be, addr, 1/*lock*/, txn,
- FE_REALLY_INTERNAL | flags ));
+ return(find_entry_internal(pb, be, addr, 1/*lock*/, txn, FE_REALLY_INTERNAL | flags, rc));
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index 7eb8fe9..f462376 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -93,6 +93,7 @@ ldbm_back_add( Slapi_PBlock *pb )
int myrc = 0;
PRUint64 conn_id;
int op_id;
+ int result_sent = 0;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
}
@@ -379,7 +380,7 @@ ldbm_back_add( Slapi_PBlock *pb )
addr.sdn = &parentsdn;
addr.udn = NULL;
addr.uniqueid = operation->o_params.p.p_add.parentuniqueid;
- parententry = find_entry2modify_only(pb,be,&addr,&txn);
+ parententry = find_entry2modify_only(pb, be, &addr, &txn, &result_sent);
if (parententry && parententry->ep_entry) {
if (!operation->o_params.p.p_add.parentuniqueid){
/* Set the parentuniqueid now */
@@ -431,6 +432,14 @@ ldbm_back_add( Slapi_PBlock *pb )
/* The entry already exists */
ldap_result_code = LDAP_ALREADY_EXISTS;
}
+ if ((LDAP_ALREADY_EXISTS == ldap_result_code) && !isroot && !is_replicated_operation) {
+ myrc = plugin_call_acl_plugin(pb, e, NULL, NULL, SLAPI_ACL_ADD,
+ ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
+ if (myrc) {
+ ldap_result_code = myrc;
+ ldap_result_message = errbuf;
+ }
+ }
goto error_return;
}
else
@@ -447,7 +456,7 @@ ldbm_back_add( Slapi_PBlock *pb )
Slapi_DN ancestorsdn;
struct backentry *ancestorentry;
slapi_sdn_init(&ancestorsdn);
- ancestorentry= dn2ancestor(pb->pb_backend,sdn,&ancestorsdn,&txn,&err);
+ ancestorentry = dn2ancestor(pb->pb_backend, sdn, &ancestorsdn, &txn, &err, 0);
slapi_sdn_done(&ancestorsdn);
if ( ancestorentry != NULL )
{
@@ -495,7 +504,7 @@ ldbm_back_add( Slapi_PBlock *pb )
addr.udn = NULL;
addr.sdn = NULL;
addr.uniqueid = (char *)slapi_entry_get_uniqueid(e); /* jcm - cast away const */
- tombstoneentry = find_entry2modify( pb, be, &addr, &txn );
+ tombstoneentry = find_entry2modify(pb, be, &addr, &txn, &result_sent);
if ( tombstoneentry==NULL )
{
ldap_result_code= -1;
@@ -712,7 +721,7 @@ ldbm_back_add( Slapi_PBlock *pb )
LDAPDebug1Arg(LDAP_DEBUG_BACKLDBM, "ldbm_add: Parent \"%s\" does not exist. "
"It might be a conflict entry.\n", slapi_sdn_get_dn(&parentsdn));
slapi_sdn_init(&ancestorsdn);
- ancestorentry = dn2ancestor(be, &parentsdn, &ancestorsdn, &txn, &err );
+ ancestorentry = dn2ancestor(be, &parentsdn, &ancestorsdn, &txn, &err, 1);
CACHE_RETURN( &inst->inst_cache, &ancestorentry );
ldap_result_code= LDAP_NO_SUCH_OBJECT;
@@ -1349,7 +1358,9 @@ common_return:
* And we don't want the supplier to halt sending the updates. */
ldap_result_code = LDAP_SUCCESS;
}
- slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn, ldap_result_message, 0, NULL );
+ if (!result_sent) {
+ slapi_send_ldap_result(pb, ldap_result_code, ldap_result_matcheddn, ldap_result_message, 0, NULL);
+ }
}
backentry_free(&originalentry);
backentry_free(&tmpentry);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_bind.c b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
index ea0df33..99a0818 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_bind.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
@@ -29,6 +29,7 @@ ldbm_back_bind( Slapi_PBlock *pb )
entry_address *addr;
back_txn txn = {NULL};
int rc = SLAPI_BIND_SUCCESS;
+ int result_sent = 0;
/* get parameters */
slapi_pblock_get( pb, SLAPI_BACKEND, &be );
@@ -63,8 +64,12 @@ ldbm_back_bind( Slapi_PBlock *pb )
* find the target entry. find_entry() takes care of referrals
* and sending errors if the entry does not exist.
*/
- if (( e = find_entry( pb, be, addr, &txn )) == NULL ) {
+ if ((e = find_entry( pb, be, addr, &txn, &result_sent)) == NULL) {
rc = SLAPI_BIND_FAIL;
+ /* In the failure case, the result is supposed to be sent in the backend. */
+ if (!result_sent) {
+ slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL);
+ }
goto bail;
}
@@ -82,8 +87,8 @@ ldbm_back_bind( Slapi_PBlock *pb )
bvals= attr_get_present_values(attr);
slapi_value_init_berval(&cv,cred);
if ( slapi_pw_find_sv( bvals, &cv ) != 0 ) {
- slapi_send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL,
- NULL, 0, NULL );
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials");
+ slapi_send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL );
CACHE_RETURN( &inst->inst_cache, &e );
value_done(&cv);
rc = SLAPI_BIND_FAIL;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_compare.c b/ldap/servers/slapd/back-ldbm/ldbm_compare.c
index e52cd6c..e9973a9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_compare.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_compare.c
@@ -56,7 +56,7 @@ ldbm_back_compare( Slapi_PBlock *pb )
/* get the namespace dn */
namespace_dn = (Slapi_DN*)slapi_be_getsuffix(be, 0);
- if ( (e = find_entry( pb, be, addr, &txn )) == NULL ) {
+ if ((e = find_entry(pb, be, addr, &txn, NULL)) == NULL) {
ret = -1; /* error result sent by find_entry() */
goto bail;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 5b24af2..f801e01 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -77,6 +77,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
int op_id;
ID ep_id = 0;
ID tomb_ep_id = 0;
+ int result_sent = 0;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
@@ -266,7 +267,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
* deleted. That is, the entry 'e' found with "addr" is a tomb-
* stone. If it is the case, we need to back off.
*/
- if ( (e = find_entry2modify( pb, be, addr, &txn )) == NULL )
+ if ((e = find_entry2modify(pb, be, addr, &txn, &result_sent)) == NULL)
{
ldap_result_code= LDAP_NO_SUCH_OBJECT;
retval = -1;
@@ -507,7 +508,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
parent_addr.uniqueid = NULL;
}
parent_addr.sdn = &parentsdn;
- parent = find_entry2modify_only_ext(pb, be, &parent_addr, TOMBSTONE_INCLUDED, &txn);
+ parent = find_entry2modify_only_ext(pb, be, &parent_addr, TOMBSTONE_INCLUDED, &txn, &result_sent);
}
if (parent) {
int isglue;
@@ -1466,7 +1467,9 @@ diskfull_return:
* And we don't want the supplier to halt sending the updates. */
ldap_result_code = LDAP_SUCCESS;
}
- slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
+ if (!result_sent) {
+ slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
+ }
}
slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_back_delete",
"conn=%lu op=%d modify_term: old_entry=0x%p, new_entry=0x%p, in_cache=%d\n",
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 9b3062c..34d9861 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -392,6 +392,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
int not_an_error = 0;
int fixup_tombstone = 0;
int ec_locked = 0;
+ int result_sent = 0;
slapi_pblock_get( pb, SLAPI_BACKEND, &be);
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
@@ -466,12 +467,12 @@ ldbm_back_modify( Slapi_PBlock *pb )
if ( MANAGE_ENTRY_BEFORE_DBLOCK(li)) {
/* find and lock the entry we are about to modify */
if (fixup_tombstone) {
- e = find_entry2modify_only_ext( pb, be, addr, TOMBSTONE_INCLUDED, &txn );
+ e = find_entry2modify_only_ext( pb, be, addr, TOMBSTONE_INCLUDED, &txn, &result_sent );
} else {
- e = find_entry2modify( pb, be, addr, &txn );
+ e = find_entry2modify( pb, be, addr, &txn, &result_sent );
}
if (e == NULL) {
- ldap_result_code= -1;
+ ldap_result_code = -1;
goto error_return; /* error result sent by find_entry2modify() */
}
}
@@ -551,12 +552,12 @@ ldbm_back_modify( Slapi_PBlock *pb )
if ( !MANAGE_ENTRY_BEFORE_DBLOCK(li)) {
/* find and lock the entry we are about to modify */
if (fixup_tombstone) {
- e = find_entry2modify_only_ext( pb, be, addr, TOMBSTONE_INCLUDED, &txn );
+ e = find_entry2modify_only_ext( pb, be, addr, TOMBSTONE_INCLUDED, &txn, &result_sent );
} else {
- e = find_entry2modify( pb, be, addr, &txn );
+ e = find_entry2modify( pb, be, addr, &txn, &result_sent );
}
if (e == NULL) {
- ldap_result_code= -1;
+ ldap_result_code = -1;
goto error_return; /* error result sent by find_entry2modify() */
}
}
@@ -966,7 +967,10 @@ common_return:
* And we don't want the supplier to halt sending the updates. */
ldap_result_code = LDAP_SUCCESS;
}
- slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
+ if (!result_sent) {
+ /* result is already sent in find_entry. */
+ slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
+ }
}
/* free our backups */
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index c0cd2ab..f934305 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -95,6 +95,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
int myrc = 0;
PRUint64 conn_id;
int op_id;
+ int result_sent = 0;
if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
conn_id = 0; /* connection is NULL */
}
@@ -474,7 +475,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
/* find and lock the entry we are about to modify */
/* JCMREPL - Argh, what happens about the stinking referrals? */
slapi_pblock_get (pb, SLAPI_TARGET_ADDRESS, &old_addr);
- e = find_entry2modify( pb, be, old_addr, &txn );
+ e = find_entry2modify(pb, be, old_addr, &txn, &result_sent);
if ( e == NULL )
{
ldap_result_code= -1;
@@ -510,7 +511,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
} else {
oldparent_addr.uniqueid = NULL;
}
- parententry = find_entry2modify_only( pb, be, &oldparent_addr, &txn );
+ parententry = find_entry2modify_only(pb, be, &oldparent_addr, &txn, &result_sent);
modify_init(&parent_modify_context,parententry);
/* Fetch and lock the new parent of the entry that is moving */
@@ -520,7 +521,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
if (is_resurect_operation) {
newsuperior_addr->uniqueid = slapi_entry_attr_get_charptr(e->ep_entry, SLAPI_ATTR_VALUE_PARENT_UNIQUEID);
}
- newparententry = find_entry2modify_only( pb, be, newsuperior_addr, &txn );
+ newparententry = find_entry2modify_only(pb, be, newsuperior_addr, &txn, &result_sent);
slapi_ch_free_string(&newsuperior_addr->uniqueid);
modify_init(&newparent_modify_context,newparententry);
}
@@ -581,7 +582,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
Slapi_DN ancestorsdn;
struct backentry *ancestorentry;
slapi_sdn_init(&ancestorsdn);
- ancestorentry= dn2ancestor(be,&dn_newdn,&ancestorsdn,&txn,&err);
+ ancestorentry = dn2ancestor(be, &dn_newdn, &ancestorsdn, &txn, &err, 0);
CACHE_RETURN( &inst->inst_cache, &ancestorentry );
ldap_result_matcheddn= slapi_ch_strdup((char *) slapi_sdn_get_dn(&ancestorsdn));
ldap_result_code= LDAP_NO_SUCH_OBJECT;
@@ -1486,8 +1487,10 @@ common_return:
* And we don't want the supplier to halt sending the updates. */
ldap_result_code = LDAP_SUCCESS;
}
- slapi_send_ldap_result( pb, ldap_result_code, ldap_result_matcheddn,
- ldap_result_message, 0,NULL );
+ if (!result_sent) {
+ slapi_send_ldap_result(pb, ldap_result_code, ldap_result_matcheddn,
+ ldap_result_message, 0, NULL);
+ }
}
slapi_mods_done(&smods_operation_wsi);
slapi_mods_done(&smods_generated);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index 535529c..cda1714 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -584,7 +584,7 @@ ldbm_back_search( Slapi_PBlock *pb )
}
else
{
- if ( ( e = find_entry( pb, be, addr, &txn )) == NULL )
+ if ((e = find_entry(pb, be, addr, &txn, NULL)) == NULL)
{
/* error or referral sent by find_entry */
return ldbm_back_search_cleanup(pb, li, sort_control,
diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c
index 77c1e70..516b32d 100644
--- a/ldap/servers/slapd/back-ldbm/misc.c
+++ b/ldap/servers/slapd/back-ldbm/misc.c
@@ -412,7 +412,7 @@ ldbm_txn_ruv_modify_context( Slapi_PBlock *pb, modify_context *mc )
/* Note: if we find the bentry, it will stay locked until someone calls
* modify_term on the mc we'll be associating the bentry with */
- bentry = find_entry2modify_only( pb, be, &bentry_addr, &txn );
+ bentry = find_entry2modify_only(pb, be, &bentry_addr, &txn, NULL);
if (NULL == bentry) {
/* Uh oh, we couldn't find and lock the RUV entry! */
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index 86e2237..8c813dd 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -174,7 +174,7 @@ int ldbm_back_ctrl_info(Slapi_Backend *be, int cmd, void *info);
struct backentry *dn2entry(Slapi_Backend *be, const Slapi_DN *sdn, back_txn *txn, int *err);
struct backentry *dn2entry_ext(Slapi_Backend *be, const Slapi_DN *sdn, back_txn *txn, int flags, int *err);
struct backentry *dn2entry_or_ancestor(Slapi_Backend *be, const Slapi_DN *sdn, Slapi_DN *ancestor, back_txn *txn, int *err);
-struct backentry *dn2ancestor(Slapi_Backend *be,const Slapi_DN *sdn,Slapi_DN *ancestordn,back_txn *txn,int *err);
+struct backentry *dn2ancestor(Slapi_Backend *be,const Slapi_DN *sdn,Slapi_DN *ancestordn,back_txn *txn,int *err, int allow_suffix);
int get_copy_of_entry(Slapi_PBlock *pb, const entry_address *addr, back_txn *txn, int plock_parameter, int must_exist);
int get_copy_of_entry_ext(Slapi_PBlock *pb, ID id, const entry_address *addr, back_txn *txn, int plock_parameter, int must_exist);
void done_with_pblock_entry(Slapi_PBlock *pb, int plock_parameter);
@@ -194,11 +194,13 @@ IDList * filter_candidates_ext( Slapi_PBlock *pb, backend *be, const char *base,
/*
* findentry.c
*/
-struct backentry * find_entry2modify( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn );
-struct backentry * find_entry( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn );
-struct backentry * find_entry2modify_only( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn);
-struct backentry * find_entry2modify_only_ext( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int flags, back_txn *txn);
-struct backentry * find_entry_only( Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn);
+/* Return code */
+#define FE_RC_SENT_RESULT 1
+struct backentry *find_entry2modify(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
+struct backentry *find_entry(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
+struct backentry *find_entry2modify_only(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
+struct backentry *find_entry2modify_only_ext(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, int flags, back_txn *txn, int *rc);
+struct backentry *find_entry_only(Slapi_PBlock *pb, Slapi_Backend *be, const entry_address *addr, back_txn *txn, int *rc);
int check_entry_for_referral(Slapi_PBlock *pb, Slapi_Entry *entry, char *matched, const char *callingfn);
/*
diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c
index fcd0c2d..df37821 100644
--- a/ldap/servers/slapd/back-ldbm/vlv_srch.c
+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c
@@ -162,7 +162,7 @@ vlvSearch_init(struct vlvSearch* p, Slapi_PBlock *pb, const Slapi_Entry *e, ldbm
addr.sdn = p->vlv_base;
addr.uniqueid = NULL;
- e = find_entry( pb, inst->inst_be, &addr, &txn );
+ e = find_entry(pb, inst->inst_be, &addr, &txn, NULL);
/* Check to see if the entry is absent. If it is, mark this search
* as not initialized */
if (NULL == e) {
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index 1ffec4e..b441615 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -438,8 +438,8 @@ do_bind( Slapi_PBlock *pb )
* to an LDAP DN, fail and return an invalidCredentials error.
*/
if ( NULL == pb->pb_conn->c_external_dn ) {
- send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL,
- "client certificate mapping failed", 0, NULL );
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Client certificate mapping failed");
+ send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "", 0, NULL);
/* call postop plugins */
plugin_call_plugins( pb, SLAPI_PLUGIN_POST_BIND_FN );
goto free_and_return;
@@ -556,33 +556,32 @@ do_bind( Slapi_PBlock *pb )
/* Check if simple binds are allowed over an insecure channel. We only check
* this for authenticated binds. */
} else if (config_get_require_secure_binds() == 1) {
- Connection *conn = NULL;
- int sasl_ssf = 0;
- int local_ssf = 0;
-
- /* Allow simple binds only for SSL/TLS established connections
- * or connections using SASL privacy layers */
- conn = pb->pb_conn;
- if ( slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) {
- slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
- "Could not get SASL SSF from connection\n" );
- sasl_ssf = 0;
- }
+ Connection *conn = NULL;
+ int sasl_ssf = 0;
+ int local_ssf = 0;
+
+ /* Allow simple binds only for SSL/TLS established connections
+ * or connections using SASL privacy layers */
+ conn = pb->pb_conn;
+ if ( slapi_pblock_get(pb, SLAPI_CONN_SASL_SSF, &sasl_ssf) != 0) {
+ slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
+ "Could not get SASL SSF from connection\n" );
+ sasl_ssf = 0;
+ }
- if ( slapi_pblock_get(pb, SLAPI_CONN_LOCAL_SSF, &local_ssf) != 0) {
- slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
- "Could not get local SSF from connection\n" );
- local_ssf = 0;
- }
+ if ( slapi_pblock_get(pb, SLAPI_CONN_LOCAL_SSF, &local_ssf) != 0) {
+ slapi_log_error( SLAPI_LOG_PLUGIN, "do_bind",
+ "Could not get local SSF from connection\n" );
+ local_ssf = 0;
+ }
- if (((conn->c_flags & CONN_FLAG_SSL) != CONN_FLAG_SSL) &&
- (sasl_ssf <= 1) && (local_ssf <= 1)) {
- send_ldap_result(pb, LDAP_CONFIDENTIALITY_REQUIRED, NULL,
- "Operation requires a secure connection",
- 0, NULL);
- slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
- goto free_and_return;
- }
+ if (((conn->c_flags & CONN_FLAG_SSL) != CONN_FLAG_SSL) &&
+ (sasl_ssf <= 1) && (local_ssf <= 1)) {
+ send_ldap_result(pb, LDAP_CONFIDENTIALITY_REQUIRED, NULL,
+ "Operation requires a secure connection", 0, NULL);
+ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
+ goto free_and_return;
+ }
}
break;
default:
@@ -627,6 +626,7 @@ do_bind( Slapi_PBlock *pb )
/*
* right dn, wrong passwd - reject with invalid credentials
*/
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials");
send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL );
/* increment BindSecurityErrorcount */
slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsBindSecurityErrors);
@@ -686,7 +686,8 @@ do_bind( Slapi_PBlock *pb )
slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &pb_sdn);
if (!pb_sdn) {
slapi_create_errormsg(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set NULL dn\n");
- send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errorbuf);
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
goto free_and_return;
} else if ((pb_sdn != sdn) || (sdn_updated = slapi_sdn_compare(original_sdn, pb_sdn))) {
/*
@@ -696,8 +697,10 @@ do_bind( Slapi_PBlock *pb )
sdn = pb_sdn;
dn = slapi_sdn_get_dn(sdn);
if (!dn) {
- slapi_create_errormsg(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set corrupted dn\n");
- send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
+ char *udn = slapi_sdn_get_udn(sdn);
+ slapi_create_errormsg(errorbuf, sizeof(errorbuf), "Pre-bind plug-in set corrupted dn %s\n", udn?udn:"");
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errorbuf);
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
goto free_and_return;
}
if (!sdn_updated) { /* pb_sdn != sdn; need to compare the dn's. */
@@ -711,7 +714,8 @@ do_bind( Slapi_PBlock *pb )
slapi_pblock_set( pb, SLAPI_BACKEND, be );
} else {
slapi_create_errormsg(errorbuf, sizeof(errorbuf), "No matching backend for %s\n", dn);
- send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, errorbuf, 0, NULL);
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errorbuf);
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
goto free_and_return;
}
}
@@ -790,7 +794,8 @@ do_bind( Slapi_PBlock *pb )
goto account_locked;
}
} else {
- send_ldap_result(pb, LDAP_NO_SUCH_OBJECT, NULL, "", 0, NULL);
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "No such entry");
+ send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "", 0, NULL);
goto free_and_return;
}
}
@@ -850,8 +855,7 @@ account_locked:
* the front end.
*/
if ( rc == SLAPI_BIND_SUCCESS || rc == SLAPI_BIND_ANONYMOUS) {
- send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL,
- 0, NULL );
+ send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL );
}
slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, &rc );
@@ -876,8 +880,7 @@ free_and_return:;
slapi_sdn_free(&sdn);
slapi_ch_free_string( &saslmech );
slapi_ch_free( (void **)&cred.bv_val );
- if ( bind_target_entry != NULL )
- slapi_entry_free(bind_target_entry);
+ slapi_entry_free(bind_target_entry);
}
diff --git a/ldap/servers/slapd/defbackend.c b/ldap/servers/slapd/defbackend.c
index 7d73501..da4a701 100644
--- a/ldap/servers/slapd/defbackend.c
+++ b/ldap/servers/slapd/defbackend.c
@@ -171,6 +171,51 @@ defbackend_abandon( Slapi_PBlock *pb )
}
+#define DEFBE_NO_SUCH_SUFFIX "No such suffix"
+/*
+ * Generate a "No such suffix" return text
+ * Example:
+ * cn=X,dc=bogus,dc=com ==> "No such suffix (dc=bogus,dc=com)"
+ * if the last rdn starts with "dc=", print all last dc= rdn's.
+ * cn=X,cn=bogus ==> "No such suffix (cn=bogus)"
+ * otherwise, print the very last rdn.
+ * cn=X,z=bogus ==> "No such suffix (x=bogus)"
+ * it is true even if it is an invalid rdn.
+ * cn=X,bogus ==> "No such suffix (bogus)"
+ * another example of invalid rdn.
+ */
+static void
+_defbackend_gen_returntext(char *buffer, size_t buflen, char **dns)
+{
+ int dnidx;
+ int sidx;
+ struct suffix_repeat {
+ char *suffix;
+ int size;
+ } candidates[] = {
+ {"dc=", 3}, /* dc could be repeated. otherwise the last rdn is used. */
+ {NULL, 0}
+ };
+ PR_snprintf(buffer, buflen, "%s (", DEFBE_NO_SUCH_SUFFIX);
+ for (dnidx = 0; dns[dnidx]; dnidx++) ; /* finding the last */
+ dnidx--; /* last rdn */
+ for (sidx = 0; candidates[sidx].suffix; sidx++) {
+ if (!PL_strncasecmp(dns[dnidx], candidates[sidx].suffix, candidates[sidx].size)) {
+ while (!PL_strncasecmp(dns[--dnidx], candidates[sidx].suffix, candidates[sidx].size)) ;
+ PL_strcat(buffer, dns[++dnidx]); /* the first "dn=", e.g. */
+ for (++dnidx; dns[dnidx]; dnidx++) {
+ PL_strcat(buffer, ",");
+ PL_strcat(buffer, dns[dnidx]);
+ }
+ PL_strcat(buffer, ")");
+ return; /* finished the task */
+ }
+ }
+ PL_strcat(buffer, dns[dnidx]);
+ PL_strcat(buffer, ")");
+ return;
+}
+
static int
defbackend_bind( Slapi_PBlock *pb )
{
@@ -188,11 +233,40 @@ defbackend_bind( Slapi_PBlock *pb )
slapi_pblock_get( pb, SLAPI_BIND_METHOD, &method );
slapi_pblock_get( pb, SLAPI_BIND_CREDENTIALS, &cred );
if ( method == LDAP_AUTH_SIMPLE && cred->bv_len == 0 ) {
- slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds);
- rc = SLAPI_BIND_ANONYMOUS;
+ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAnonymousBinds);
+ rc = SLAPI_BIND_ANONYMOUS;
} else {
- send_nobackend_ldap_result( pb );
- rc = SLAPI_BIND_FAIL;
+ Slapi_DN *sdn = NULL;
+ char *suffix = NULL;
+ char **dns = NULL;
+
+ if (pb->pb_op) {
+ sdn = operation_get_target_spec(pb->pb_op);
+ if (sdn) {
+ dns = slapi_ldap_explode_dn(slapi_sdn_get_dn(sdn), 0);
+ if (dns) {
+ size_t dnlen = slapi_sdn_get_ndn_len(sdn);
+ size_t len = dnlen + sizeof(DEFBE_NO_SUCH_SUFFIX) + 4;
+ suffix = slapi_ch_malloc(len);
+ if (dnlen) {
+ _defbackend_gen_returntext(suffix, len, dns);
+ } else {
+ PR_snprintf(suffix, len, "%s", DEFBE_NO_SUCH_SUFFIX);
+ }
+ }
+ }
+ }
+ if (suffix) {
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, suffix);
+ } else {
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, DEFBE_NO_SUCH_SUFFIX);
+ }
+ send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, "", 0, NULL);
+ if (dns) {
+ slapi_ldap_value_free(dns);
+ }
+ slapi_ch_free_string(&suffix);
+ rc = SLAPI_BIND_FAIL;
}
return( rc );
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
index 506da92..c2a0206 100644
--- a/ldap/servers/slapd/result.c
+++ b/ldap/servers/slapd/result.c
@@ -2067,14 +2067,26 @@ log_result( Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentrie
}
else if ( !internal_op )
{
+ char *pbtxt = NULL;
+ char *ext_str = NULL;
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &pbtxt);
+ if (pbtxt) {
+ ext_str = slapi_ch_smprintf(" - %s", pbtxt);
+ } else {
+ ext_str = "";
+ }
slapi_log_access( LDAP_DEBUG_STATS,
"conn=%" NSPRIu64 " op=%d RESULT err=%d"
- " tag=%" BERTAG_T " nentries=%d etime=%s%s%s\n",
+ " tag=%" BERTAG_T " nentries=%d etime=%s%s%s%s\n",
op->o_connid,
op->o_opid,
err, tag, nentries,
etime,
- notes_str, csn_str );
+ notes_str, csn_str, ext_str);
+ if (pbtxt) {
+ /* if !pbtxt ==> ext_str == "". Don't free ext_str. */
+ slapi_ch_free_string(&ext_str);
+ }
}
else
{
7 years, 8 months
ldap/servers lib/base
by Noriko Hosoi
ldap/servers/plugins/acl/acllas.c | 1
ldap/servers/slapd/agtmmap.c | 10 ++++++++-
ldap/servers/slapd/back-ldbm/idl_new.c | 4 +--
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 5 ++++
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 15 +++++++++----
ldap/servers/slapd/detach.c | 11 ++++++----
ldap/servers/slapd/localhost.c | 10 ++++++---
ldap/servers/slapd/protect_db.c | 22 +++++++++++++-------
ldap/servers/slapd/protect_db.h | 3 ++
ldap/servers/slapd/saslbind.c | 3 ++
ldap/servers/slapd/tools/ldclt/ldapfct.c | 5 +++-
ldap/servers/slapd/tools/ldif.c | 5 +++-
ldap/servers/slapd/tools/mmldif.c | 20 ++++++++++--------
ldap/servers/slapd/util.c | 9 +++++---
ldap/servers/snmp/main.c | 15 ++++++++++---
lib/base/file.cpp | 1
lib/base/fsmutex.cpp | 10 ++++++---
17 files changed, 106 insertions(+), 43 deletions(-)
New commits:
commit 18c6029f64c48b330a101cbadceb8293d39bf5e2
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Jul 13 18:59:01 2016 -0700
Ticket #48919 - Compiler warnings while building 389-ds-base on RHEL7
Description: Cleaned up warnings from gcc and clang.
https://fedorahosted.org/389/ticket/48919
Reviewed by wibrown(a)redhat.com (Thank you, William!!)
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
index ff9b450..47ac0b8 100644
--- a/ldap/servers/plugins/acl/acllas.c
+++ b/ldap/servers/plugins/acl/acllas.c
@@ -190,7 +190,6 @@ extern int ldapu_member_certificate_match (void* cert, const char* desc);
/****************************************************************************/
/* Defines, Constants, ande Declarations */
/****************************************************************************/
-static char* const type_objectClass = "objectclass";
static char* const filter_groups = "(|(objectclass=groupOfNames) (objectclass=groupOfUniqueNames)(objectclass=groupOfCertificates)(objectclass=groupOfURLs))";
static char* const type_member = "member";
static char* const type_uniquemember = "uniquemember";
diff --git a/ldap/servers/slapd/agtmmap.c b/ldap/servers/slapd/agtmmap.c
index 6f72d57..629bc1b 100644
--- a/ldap/servers/slapd/agtmmap.c
+++ b/ldap/servers/slapd/agtmmap.c
@@ -160,7 +160,15 @@ agt_mopen_stats (char * statsfile, int mode, int *hdl)
{
/* Without this we will get segv when we try to read/write later */
buf = calloc (1, sz);
- (void)write (fd, buf, sz);
+ if (write(fd, buf, sz) < 0) {
+ err = errno;
+#if (0)
+ fprintf (stderr, "write failed errno=%d from %s(line: %d)\n", err, __FILE__, __LINE__);
+#endif
+ rc = err;
+ free (buf);
+ goto bail;
+ }
free (buf);
}
diff --git a/ldap/servers/slapd/back-ldbm/idl_new.c b/ldap/servers/slapd/back-ldbm/idl_new.c
index 63df49f..a8d76d8 100644
--- a/ldap/servers/slapd/back-ldbm/idl_new.c
+++ b/ldap/servers/slapd/back-ldbm/idl_new.c
@@ -403,8 +403,8 @@ idl_new_range_fetch(
time_t curtime;
void *saved_key = NULL;
int coreop = operator & SLAPI_OP_RANGE;
- ID key;
- ID suffix;
+ ID key = 0xff; /* random- to suppress compiler warning */
+ ID suffix = 0; /* random- to suppress compiler warning */
idl_range_id_pair *leftover = NULL;
size_t leftoverlen = 32;
int leftovercnt = 0;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
index 9302410..698be66 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
@@ -1155,6 +1155,11 @@ ldbm_instance_post_delete_instance_entry_callback(Slapi_PBlock *pb, Slapi_Entry*
rc = PR_Delete(dbp);
}
PR_ASSERT(rc == 0);
+ if (rc != 0) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_instance_post_delete_instance_entry_callback:"
+ " failed to delete %s\n", dbp);
+ }
PR_smprintf_free(dbp);
}
PR_CloseDir(dirhandle);
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 0b2eab2..52338c2 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -1009,7 +1009,6 @@ export_one_entry(struct ldbminfo *li,
}
slapi_ch_free_string(&pw);
}
- rc = 0;
data.data = slapi_entry2str_with_options(expargs->ep->ep_entry,
&len, expargs->options);
data.size = len + 1;
@@ -1018,10 +1017,14 @@ export_one_entry(struct ldbminfo *li,
char idstr[32];
sprintf(idstr, "# entry-id: %lu\n", (u_long)expargs->ep->ep_id);
- write(expargs->fd, idstr, strlen(idstr));
+ rc = write(expargs->fd, idstr, strlen(idstr));
+ PR_ASSERT(rc > 0);
}
- write(expargs->fd, data.data, len);
- write(expargs->fd, "\n", 1);
+ rc = write(expargs->fd, data.data, len);
+ PR_ASSERT(rc > 0);
+ rc = write(expargs->fd, "\n", 1);
+ PR_ASSERT(rc > 0);
+ rc = 0;
if ((*expargs->cnt) % 1000 == 0) {
int percent;
@@ -1350,7 +1353,9 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
*/
sprintf(vstr, "version: %d\n\n", myversion);
- write(fd, vstr, strlen(vstr));
+ rc = write(fd, vstr, strlen(vstr));
+ PR_ASSERT(rc > 0);
+ rc = 0;
}
eargs.decrypt = decrypt;
diff --git a/ldap/servers/slapd/detach.c b/ldap/servers/slapd/detach.c
index b5af952..b055a5c 100644
--- a/ldap/servers/slapd/detach.c
+++ b/ldap/servers/slapd/detach.c
@@ -48,7 +48,7 @@ int
detach( int slapd_exemode, int importexport_encrypt,
int s_port, daemon_ports_t *ports_info )
{
- int i, sd;
+ int i, sd, rc;
char *workingdir = 0;
char *errorlog = 0;
char *ptr = 0;
@@ -84,13 +84,15 @@ detach( int slapd_exemode, int importexport_encrypt,
if ( NULL == workingdir ) {
errorlog = config_get_errorlog();
if ( NULL == errorlog ) {
- (void) chdir( "/" );
+ rc = chdir( "/" );
+ PR_ASSERT(rc == 0);
} else {
if ((ptr = strrchr(errorlog, '/')) ||
(ptr = strrchr(errorlog, '\\'))) {
*ptr = 0;
}
- (void) chdir( errorlog );
+ rc = chdir( errorlog );
+ PR_ASSERT(rc == 0);
config_set_workingdir(CONFIG_WORKINGDIR_ATTRIBUTE, errorlog, NULL, 1);
slapi_ch_free_string(&errorlog);
}
@@ -99,7 +101,8 @@ detach( int slapd_exemode, int importexport_encrypt,
if (config_set_workingdir(CONFIG_WORKINGDIR_ATTRIBUTE, workingdir, NULL, 0) == LDAP_OPERATIONS_ERROR) {
return 1;
}
- (void) chdir( workingdir );
+ rc = chdir( workingdir );
+ PR_ASSERT(rc == 0);
slapi_ch_free_string(&workingdir);
}
diff --git a/ldap/servers/slapd/localhost.c b/ldap/servers/slapd/localhost.c
index 2c40493..7b4e903 100644
--- a/ldap/servers/slapd/localhost.c
+++ b/ldap/servers/slapd/localhost.c
@@ -118,9 +118,13 @@ find_localhost_DNS()
#ifndef NO_DOMAINNAME
if (domain == NULL) {
/* No domain found. Try getdomainname. */
- getdomainname (line, sizeof(line));
- LDAPDebug (LDAP_DEBUG_CONFIG, "getdomainname(%s)\n", line, 0, 0);
- if (line[0] != 0) {
+ line[0] = '\0';
+ if (getdomainname(line, sizeof(line)) < 0) { /* failure */
+ slapi_log_error(SLAPI_LOG_FATAL, "localhost_DNS", "getdomainname failed\n");
+ } else {
+ slapi_log_error(SLAPI_LOG_CONFIG, "localhost_DNS", "getdomainname(%s)\n", line);
+ }
+ if (line[0] != '\0') {
domain = &line[0];
}
}
diff --git a/ldap/servers/slapd/protect_db.c b/ldap/servers/slapd/protect_db.c
index b22daa1..4579852 100644
--- a/ldap/servers/slapd/protect_db.c
+++ b/ldap/servers/slapd/protect_db.c
@@ -42,7 +42,7 @@ grab_lockfile()
{
pid_t pid, owning_pid;
char lockfile[MAXPATHLEN];
- int fd, x;
+ int fd, x, rc;
int removed_lockfile = 0;
struct timeval t;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -60,8 +60,12 @@ grab_lockfile()
/* Try to grab it */
if ((fd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0644)) != -1) {
/* We got the lock, write our pid to the file */
- write(fd, (void *) &pid, sizeof(pid_t));
- close(fd);
+ rc = write(fd, (void *) &pid, sizeof(pid_t));
+ close(fd);
+ if (rc < 0) {
+ fprintf(stderr, ERROR_WRITING_LOCKFILE, lockfile);
+ return rc;
+ }
return 0;
}
@@ -74,13 +78,17 @@ grab_lockfile()
while(1) {
/* Try to grab the lockfile NUM_TRIES times waiting WAIT_TIME milliseconds after each try */
- t.tv_sec = 0;
- t.tv_usec = WAIT_TIME * 1000;
+ t.tv_sec = 0;
+ t.tv_usec = WAIT_TIME * 1000;
for(x = 0; x < NUM_TRIES; x++) {
if ((fd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0644)) != -1) {
/* Got the lock */
- write(fd, (void *) &pid, sizeof(pid_t));
- close(fd);
+ rc = write(fd, (void *) &pid, sizeof(pid_t));
+ close(fd);
+ if (rc < 0) {
+ fprintf(stderr, ERROR_WRITING_LOCKFILE, lockfile);
+ return rc;
+ }
return 0;
}
select(0, NULL, NULL, NULL, &t);
diff --git a/ldap/servers/slapd/protect_db.h b/ldap/servers/slapd/protect_db.h
index 0f729a2..66adfb3 100644
--- a/ldap/servers/slapd/protect_db.h
+++ b/ldap/servers/slapd/protect_db.h
@@ -26,6 +26,9 @@ void remove_slapd_process();
#define ERROR_ACCESSING_LOCKFILE "Error - Problem accessing the lockfile %s\n"
/* name of lockfile */
+#define ERROR_WRITING_LOCKFILE "Error - Problem writing the lockfile %s\n"
+ /* name of lockfile */
+
#define LOCKFILE_DEAD_OWNER "Error - The lockfile, %s, is held by process %d,\nwhich no longer seems to be running. If this is\nthe case, please remove the lockfile\n"
/* name of lockfile, pid of owning process */
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
index eb68209..37175f4 100644
--- a/ldap/servers/slapd/saslbind.c
+++ b/ldap/servers/slapd/saslbind.c
@@ -547,6 +547,9 @@ int ids_sasl_init(void)
LDAPDebug( LDAP_DEBUG_TRACE, "=> ids_sasl_init\n", 0, 0, 0 );
PR_ASSERT(inited == 0);
+ if (inited != 0) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "ids_sasl_init is called more than once.\n");
+ }
inited = 1;
serverfqdn = get_localhost_DNS();
diff --git a/ldap/servers/slapd/tools/ldclt/ldapfct.c b/ldap/servers/slapd/tools/ldclt/ldapfct.c
index e13983d..f084cb4 100644
--- a/ldap/servers/slapd/tools/ldclt/ldapfct.c
+++ b/ldap/servers/slapd/tools/ldclt/ldapfct.c
@@ -2552,7 +2552,10 @@ int ldclt_write_genldif_nb;
void
ldclt_flush_genldif (void)
{
- write (mctx.genldifFile, ldclt_write_genldif_buf, ldclt_write_genldif_nb);
+ if (write (mctx.genldifFile, ldclt_write_genldif_buf, ldclt_write_genldif_nb) < 0) {
+ printf("ldclt[%d]: ldclt_flush_genldif: Failed to write (%s) error=%d\n",
+ mctx.pid, ldclt_write_genldif_buf, errno);
+ }
ldclt_write_genldif_pt = ldclt_write_genldif_buf;
ldclt_write_genldif_nb = 0;
}
diff --git a/ldap/servers/slapd/tools/ldif.c b/ldap/servers/slapd/tools/ldif.c
index 1050fbd..5973c6b 100644
--- a/ldap/servers/slapd/tools/ldif.c
+++ b/ldap/servers/slapd/tools/ldif.c
@@ -132,7 +132,10 @@ int main( int argc, char **argv )
free( buf );
return( 1 );
}
- (void)fgets(buf+curlen, maxlen/2 + 1, stdin);
+ if (NULL == fgets(buf+curlen, maxlen/2 + 1, stdin)) {
+ /* no more input to read. */
+ break;
+ }
}
/* we have a full line, chop potential newline and turn into ldif */
if( buf[curlen-1] == '\n' )
diff --git a/ldap/servers/slapd/tools/mmldif.c b/ldap/servers/slapd/tools/mmldif.c
index 1f846d0..ddfaf6c 100644
--- a/ldap/servers/slapd/tools/mmldif.c
+++ b/ldap/servers/slapd/tools/mmldif.c
@@ -766,8 +766,7 @@ readrec(edfFILE * edf1, attrib1_t ** attrib)
while (*vptr == ' ') vptr++; /* skip optional spaces */
b64 = initDec64((unsigned char *)att->value, 0x20000);
if (Dec64(b64, (unsigned char *) vptr)) {
- LDAPDebug(LDAP_DEBUG_TRACE, "%s\n invalid input line\n",
- line, 0, 0);
+ LDAPDebug(LDAP_DEBUG_TRACE, "%s\n invalid input line\n", line, 0, 0);
continue; /* invalid line, but we'll just skip it */
}
toolong = FALSE;
@@ -775,7 +774,11 @@ readrec(edfFILE * edf1, attrib1_t ** attrib)
lookahead = fgetc(edf1->fp);
if (lookahead != ' ')
break;
- (void)fgets(line, sizeof(line), edf1->fp);
+ line[0] = '\0';
+ if (NULL == fgets(line, sizeof(line), edf1->fp)) {
+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "readrec: failed to read line\n");
+ break;
+ }
len = strlen(line);
for (lptr = line+len-1; len; len--, lptr--) {
if ((*lptr != '\n') && (*lptr != '\r'))
@@ -785,16 +788,14 @@ readrec(edfFILE * edf1, attrib1_t ** attrib)
rc = Dec64(b64, (unsigned char *)line);
if (rc == -1)
{
- LDAPDebug(LDAP_DEBUG_TRACE,
- "%s\n invalid input line\n", line, 0, 0);
+ LDAPDebug(LDAP_DEBUG_TRACE, "%s\n invalid input line\n", line, 0, 0);
continue; /* invalid line, but we'll just skip it */
}
if (rc) {
if (!toolong) {
toolong = TRUE;
- LDAPDebug(LDAP_DEBUG_TRACE,
- "%s\n line too long\n", line, 0, 0);
+ LDAPDebug(LDAP_DEBUG_TRACE, "%s\n line too long\n", line, 0, 0);
}
continue;
}
@@ -813,7 +814,10 @@ readrec(edfFILE * edf1, attrib1_t ** attrib)
lookahead = fgetc(edf1->fp);
if (lookahead != ' ')
break;
- (void)fgets(line, sizeof(line), edf1->fp);
+ if (NULL == fgets(line, sizeof(line), edf1->fp)) {
+ LDAPDebug0Args(LDAP_DEBUG_TRACE, "readrec: failed to read line\n");
+ break;
+ }
len = strlen(line);
for (lptr = line+len-1; len; len--, lptr--) {
if ((*lptr != '\n') && (*lptr != '\r'))
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
index a5327d1..1ebdf2e 100644
--- a/ldap/servers/slapd/util.c
+++ b/ldap/servers/slapd/util.c
@@ -1592,7 +1592,9 @@ int util_info_sys_pages(size_t *pagesize, size_t *pages, size_t *procpages, size
return 1;
}
while (! feof(f)) {
- fgets(s, 79, f);
+ if (!fgets(s, 79, f)) {
+ break; /* error or eof */
+ }
if (feof(f)) {
break;
}
@@ -1614,8 +1616,9 @@ int util_info_sys_pages(size_t *pagesize, size_t *pages, size_t *procpages, size
return 1;
}
while (! feof(fm)) {
- fgets(s, 79, fm);
- /* Is this really needed? */
+ if (!fgets(s, 79, fm)) {
+ break; /* error or eof */
+ }
if (feof(fm)) {
break;
}
diff --git a/ldap/servers/snmp/main.c b/ldap/servers/snmp/main.c
index 3f96627..ea5050b 100644
--- a/ldap/servers/snmp/main.c
+++ b/ldap/servers/snmp/main.c
@@ -44,7 +44,7 @@ main (int argc, char *argv[]) {
netsnmp_log_handler *log_hdl = NULL;
int c, log_level = LOG_WARNING;
struct stat logdir_s;
- pid_t child_pid;
+ pid_t child_pid = 0;
FILE *pid_fp;
/* Load options */
@@ -74,7 +74,11 @@ main (int argc, char *argv[]) {
/* check if we're already running as another process */
if ((pid_fp = fopen(pidfile, "r")) != NULL) {
- fscanf(pid_fp, "%d", &child_pid);
+ int rc = fscanf(pid_fp, "%d", &child_pid);
+ if ((rc == 0) || (rc == EOF)) {
+ printf("ldap-agent: Failed to get pid from %s\n", pidfile);
+ exit(1);
+ }
fclose(pid_fp);
if (kill(child_pid, SIGUSR1) == 0) {
printf("ldap-agent: Already running as pid %d!\n", child_pid);
@@ -145,6 +149,7 @@ main (int argc, char *argv[]) {
/* run as a daemon */
if (netsnmp_daemonize(0, 0)) {
int i;
+ int rc;
/* sleep to allow pidfile to be created by child */
for (i=0; i < 3; i++) {
@@ -159,7 +164,11 @@ main (int argc, char *argv[]) {
exit(1);
}
- fscanf(pid_fp, "%d", &child_pid);
+ rc = fscanf(pid_fp, "%d", &child_pid);
+ if ((rc == 0) || (rc == EOF)) {
+ printf("ldap-agent: Failed to get pid from %s\n", pidfile);
+ exit(1);
+ }
fclose(pid_fp);
printf("ldap-agent: Started as pid %d\n", child_pid);
exit(0);
diff --git a/lib/base/file.cpp b/lib/base/file.cpp
index 8c9274a..ad4333e 100644
--- a/lib/base/file.cpp
+++ b/lib/base/file.cpp
@@ -38,7 +38,6 @@ extern "C" char *nscperror_lookup(int err);
/* PRFileDesc * SYS_ERROR_FD = NULL; */
const int errbuf_size = 256;
-const unsigned int LOCKFILERANGE=0x7FFFFFFF;
PRLock *_atomic_write_lock = NULL;
/* --------------------------------- stat --------------------------------- */
diff --git a/lib/base/fsmutex.cpp b/lib/base/fsmutex.cpp
index e8f2aff..a0e30fd 100644
--- a/lib/base/fsmutex.cpp
+++ b/lib/base/fsmutex.cpp
@@ -85,11 +85,15 @@ fsmutex_init(char *name, int number, int flags)
NSAPI_PUBLIC void
fsmutex_setowner(FSMUTEX fsm, uid_t uid, gid_t gid)
{
- if(!geteuid())
- (void) chown( ((fsmutex_s *)fsm)->id, uid, gid);
+ if(!geteuid()) {
+ int rc = chown( ((fsmutex_s *)fsm)->id, uid, gid);
+ PR_ASSERT(rc == 0);
+ if (rc != 0 ) {
+ return; /* just to suppress compiler warning... */
+ }
+ }
}
-
/* -------------------------- fsmutex_terminate --------------------------- */
static void
7 years, 8 months
Branch '389-ds-base-1.3.4' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/back-ldbm/ldbm_index_config.c | 6 ++++++
1 file changed, 6 insertions(+)
New commits:
commit a64a2e9b9ea231550c3b380249ebb7ab715c4d32
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Wed Jul 13 16:24:19 2016 -0400
Ticket 48922 - Fix crash when deleting backend while import is running
Bug Description: If you delete a backend from the config while an
import is running the server can crash.
Fix Description: When deleting a backend from the config wait for the
backend instance to not be busy before removing the
indexes. Otherwise the dbenv is not stable and this
can cause the crash.
https://fedorahosted.org/389/ticket/48922
Reviewed by: nhosoi(Thanks!)
(cherry picked from commit 6c77c37ae5ce847ffa2bd75287dbd157c2f2d6af)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
index 42c8ffe..bbdb13c 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
@@ -151,6 +151,12 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Sla
rc = SLAPI_DSE_CALLBACK_ERROR;
goto bail;
}
+
+ while(is_instance_busy(inst)){
+ /* Wait for import/indexing job to complete */
+ DS_Sleep(PR_SecondsToInterval(1));
+ }
+
*returncode = LDAP_SUCCESS;
slapi_entry_attr_find(e, "cn", &attr);
7 years, 8 months