Commit f06b7e6e authored by Mathieu Parent's avatar Mathieu Parent

Update upstream source from tag 'upstream/1.4.6'

Update to upstream version '1.4.6'
with Debian dir b6d24dd7da6af5321245899875d16bbd07699cf0
parents 653c5868 6bdf80a4
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
......@@ -520,6 +520,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
control->ctxid_len);
if (control->contextId == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
} else {
......@@ -534,13 +535,20 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) {
struct ldb_dirsync_control *control;
const char *p;
char cookie[1024];
char *cookie = NULL;
int crit, max_attrs, ret;
uint32_t flags;
cookie[0] = '\0';
cookie = talloc_zero_array(ctrl, char,
strlen(control_strings) + 1);
if (cookie == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]);
ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
ret = sscanf(p, "%d:%u:%d:%[^$]", &crit, &flags, &max_attrs, cookie);
if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) {
ldb_set_errstring(ldb,
......@@ -561,6 +569,11 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
ctrl->oid = LDB_CONTROL_DIRSYNC_OID;
ctrl->critical = crit;
control = talloc(ctrl, struct ldb_dirsync_control);
if (control == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control->flags = flags;
control->max_attributes = max_attrs;
if (*cookie) {
......@@ -575,6 +588,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
if (control->cookie == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
} else {
......@@ -582,17 +596,25 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
control->cookie_len = 0;
}
ctrl->data = control;
TALLOC_FREE(cookie);
return ctrl;
}
if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_EX_NAME) == 0) {
struct ldb_dirsync_control *control;
const char *p;
char cookie[1024];
char *cookie = NULL;
int crit, max_attrs, ret;
uint32_t flags;
cookie[0] = '\0';
cookie = talloc_zero_array(ctrl, char,
strlen(control_strings) + 1);
if (cookie == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_EX_NAME)]);
ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
......@@ -615,6 +637,11 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
ctrl->oid = LDB_CONTROL_DIRSYNC_EX_OID;
ctrl->critical = crit;
control = talloc(ctrl, struct ldb_dirsync_control);
if (control == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control->flags = flags;
control->max_attributes = max_attrs;
if (*cookie) {
......@@ -630,6 +657,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
if (control->cookie == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
} else {
......@@ -637,6 +665,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
control->cookie_len = 0;
}
ctrl->data = control;
TALLOC_FREE(cookie);
return ctrl;
}
......@@ -662,6 +691,11 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
ctrl->oid = LDB_CONTROL_ASQ_OID;
ctrl->critical = crit;
control = talloc(ctrl, struct ldb_asq_control);
if (control == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control->request = 1;
control->source_attribute = talloc_strdup(control, attr);
control->src_attr_len = strlen(attr);
......@@ -693,6 +727,11 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
control = NULL;
} else {
control = talloc(ctrl, struct ldb_extended_dn_control);
if (control == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control->type = type;
}
......@@ -723,6 +762,12 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
ctrl->oid = LDB_CONTROL_SD_FLAGS_OID;
ctrl->critical = crit;
control = talloc(ctrl, struct ldb_sd_flags_control);
if (control == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control->secinfo_flags = secinfo_flags;
ctrl->data = control;
......@@ -749,6 +794,12 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
ctrl->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
ctrl->critical = crit;
control = talloc(ctrl, struct ldb_search_options_control);
if (control == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control->search_options = search_options;
ctrl->data = control;
......@@ -865,6 +916,12 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
ctrl->oid = LDB_CONTROL_PAGED_RESULTS_OID;
ctrl->critical = crit;
control = talloc(ctrl, struct ldb_paged_control);
if (control == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control->size = size;
if (cookie[0] != '\0') {
int len = ldb_base64_decode(cookie);
......@@ -879,6 +936,7 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
control->cookie = talloc_memdup(control, cookie, control->cookie_len);
if (control->cookie == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
} else {
......@@ -912,12 +970,36 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
ctrl->oid = LDB_CONTROL_SERVER_SORT_OID;
ctrl->critical = crit;
control = talloc_array(ctrl, struct ldb_server_sort_control *, 2);
if (control == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control[0] = talloc(control, struct ldb_server_sort_control);
if (control[0] == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control[0]->attributeName = talloc_strdup(control, attr);
if (rule[0])
if (control[0]->attributeName == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
if (rule[0]) {
control[0]->orderingRule = talloc_strdup(control, rule);
else
if (control[0]->orderingRule == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
} else {
control[0]->orderingRule = NULL;
}
control[0]->reverse = rev;
control[1] = NULL;
ctrl->data = control;
......@@ -1179,7 +1261,19 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
ctrl->oid = LDB_CONTROL_VERIFY_NAME_OID;
ctrl->critical = crit;
control = talloc(ctrl, struct ldb_verify_name_control);
if (control == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control->gc = talloc_strdup(control, gc);
if (control->gc == NULL) {
ldb_oom(ldb);
talloc_free(ctrl);
return NULL;
}
control->gc_len = strlen(gc);
control->flags = flags;
ctrl->data = control;
......
......@@ -244,6 +244,11 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
uint8_t *save_p = NULL;
unsigned int c = 0;
if (tree->operation != LDB_OP_SUBSTRING) {
*matched = false;
return LDB_ERR_INAPPROPRIATE_MATCHING;
}
a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr);
if (!a) {
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
......@@ -306,14 +311,38 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
p = memmem((const void *)val.data,val.length,
(const void *)cnk.data, cnk.length);
if (p == NULL) goto mismatch;
/*
* At this point we know cnk.length <= val.length as
* otherwise there could be no match
*/
if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) {
uint8_t *g;
uint8_t *end = val.data + val.length;
do { /* greedy */
g = memmem(p + cnk.length,
val.length - (p - val.data),
(const uint8_t *)cnk.data,
cnk.length);
if (g) p = g;
/*
* haystack is a valid pointer in val
* because the memmem() can only
* succeed if the needle (cnk.length)
* is <= haystacklen
*
* p will be a pointer at least
* cnk.length from the end of haystack
*/
uint8_t *haystack
= p + cnk.length;
size_t haystacklen
= end - (haystack);
g = memmem(haystack,
haystacklen,
(const uint8_t *)cnk.data,
cnk.length);
if (g) {
p = g;
}
} while(g);
}
val.length = val.length - (p - (uint8_t *)(val.data)) - cnk.length;
......@@ -324,7 +353,7 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
}
/* last chunk may not have reached end of string */
if ( (! tree->u.substring.end_with_wildcard) && (*(val.data) != 0) ) goto mismatch;
if ( (! tree->u.substring.end_with_wildcard) && (val.length != 0) ) goto mismatch;
talloc_free(save_p);
*matched = true;
return LDB_SUCCESS;
......
......@@ -389,7 +389,7 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char *
struct ldb_parse_tree *ret;
enum ldb_parse_op filtertype;
ret = talloc(mem_ctx, struct ldb_parse_tree);
ret = talloc_zero(mem_ctx, struct ldb_parse_tree);
if (!ret) {
errno = ENOMEM;
return NULL;
......
......@@ -2031,13 +2031,23 @@ int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count)
}
/*
* Here we load the index for the tree.
*
* We only care if this is successful, if the
* index can't trim the result list down then
* the ONELEVEL index is still good enough.
*/
ret = ltdb_index_dn(ac->module, ltdb, ac->tree,
idx_one_tree_list);
/*
* We can stop if we're sure the object doesn't exist
*/
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
talloc_free(idx_one_tree_list);
talloc_free(dn_list);
return LDB_ERR_NO_SUCH_OBJECT;
}
/* We only care if this is successful, if the
* index can't trim the result list down then
* the ONELEVEL index is still good enough.
*/
if (ret == LDB_SUCCESS) {
if (!list_intersect(ldb, ltdb,
dn_list,
......
......@@ -89,6 +89,9 @@ static struct ldb_message_element *PyObject_AsMessageElement(
#define PyStr_AsUTF8 PyUnicode_AsUTF8
#define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
#define PyInt_FromLong PyLong_FromLong
#define PYARG_STR_UNI "es"
#else
#define PyStr_Check PyString_Check
#define PyStr_FromString PyString_FromString
......@@ -97,6 +100,8 @@ static struct ldb_message_element *PyObject_AsMessageElement(
#define PyStr_FromFormatV PyString_FromFormatV
#define PyStr_AsUTF8 PyString_AsString
#define PYARG_STR_UNI "et"
const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr);
const char *
PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr)
......@@ -865,7 +870,7 @@ static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwa
PyLdbDnObject *py_ret = NULL;
const char * const kwnames[] = { "ldb", "dn", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oes",
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI,
discard_const_p(char *, kwnames),
&py_ldb, "utf8", &str))
goto out;
......
/*
* Tests exercising the ldb match operations.
*
*
* Copyright (C) Catalyst.NET Ltd 2017
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* from cmocka.c:
* These headers or their equivalents should be included prior to
* including
* this header file.
*
* #include <stdarg.h>
* #include <stddef.h>
* #include <setjmp.h>
*
* This allows test applications to use custom definitions of C standard
* library functions and types.
*/
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <setjmp.h>
#include <cmocka.h>
#include "../common/ldb_match.c"
#include "../include/ldb.h"
struct ldbtest_ctx {
struct tevent_context *ev;
struct ldb_context *ldb;
};
static int ldb_test_canonicalise(
struct ldb_context *ldb,
void *mem_ctx,
const struct ldb_val *in,
struct ldb_val *out)
{
out->length = in->length;
out->data = in->data;
return 0;
}
static int setup(void **state)
{
struct ldbtest_ctx *test_ctx;
struct ldb_schema_syntax *syntax = NULL;
int ret;
test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
assert_non_null(test_ctx);
test_ctx->ev = tevent_context_init(test_ctx);
assert_non_null(test_ctx->ev);
test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
assert_non_null(test_ctx->ldb);
syntax = talloc_zero(test_ctx, struct ldb_schema_syntax);
assert_non_null(syntax);
syntax->canonicalise_fn = ldb_test_canonicalise;
ret = ldb_schema_attribute_add_with_syntax(
test_ctx->ldb, "a", LDB_ATTR_FLAG_FIXED, syntax);
assert_int_equal(LDB_SUCCESS, ret);
*state = test_ctx;
return 0;
}
static int teardown(void **state)
{
talloc_free(*state);
return 0;
}
/*
* The wild card pattern "attribute=*" is parsed as an LDB_OP_PRESENT operation
* rather than a LDB_OP_????
*
* This test serves to document that behaviour, and to confirm that
* ldb_wildcard_compare handles this case appropriately.
*/
static void test_wildcard_match_star(void **state)
{
struct ldbtest_ctx *ctx = *state;
bool matched = false;
int ret;
uint8_t value[] = "The value.......end";
struct ldb_val val = {
.data = value,
.length = (sizeof(value))
};
struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "a=*");
assert_non_null(tree);
ret = ldb_wildcard_compare(ctx->ldb, tree, val, &matched);
assert_false(matched);
assert_int_equal(LDB_ERR_INAPPROPRIATE_MATCHING, ret);
}
/*
* Test basic wild card matching
*
*/
static void test_wildcard_match(void **state)
{
struct ldbtest_ctx *ctx = *state;
bool matched = false;
uint8_t value[] = "The value.......end";
struct ldb_val val = {
.data = value,
.length = (sizeof(value))
};
struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "objectClass=*end");
assert_non_null(tree);
ldb_wildcard_compare(ctx->ldb, tree, val, &matched);
assert_true(matched);
}
/*
* ldb_handler_copy and ldb_val_dup over allocate by one and add a trailing '\0'
* to the data, to make them safe to use the C string functions on.
*
* However testing for the trailing '\0' is not the correct way to test for
* the end of a value, the length should be checked instead.
*/
static void test_wildcard_match_end_condition(void **state)
{
struct ldbtest_ctx *ctx = *state;
bool matched = false;
uint8_t value[] = "hellomynameisbobx";
struct ldb_val val = {
.data = talloc_memdup(NULL, value, sizeof(value)),
.length = (sizeof(value) - 2)
};
struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "a=*hello*mynameis*bob");
assert_non_null(tree);
ldb_wildcard_compare(ctx->ldb, tree, val, &matched);
assert_true(matched);
}
/*
* Note: to run under valgrind use:
* valgrind \
* --suppressions=lib/ldb/tests/ldb_match_test.valgrind \
* bin/ldb_match_test
*/
int main(int argc, const char **argv)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(
test_wildcard_match_star,
setup,
teardown),
cmocka_unit_test_setup_teardown(
test_wildcard_match,
setup,
teardown),
cmocka_unit_test_setup_teardown(
test_wildcard_match_end_condition,
setup,
teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}
{
Memory allocated in set-up
Memcheck:Leak
match-leak-kinds: possible
fun:malloc
...
fun:setup
}
{
Memory allocated by ldb_init
Memcheck:Leak
match-leak-kinds: possible
fun:malloc
...
fun:ldb_init
}
......@@ -141,6 +141,21 @@ class SimpleLdb(LdbBaseTest):
l = ldb.Ldb(self.url(), flags=self.flags())
dn = ldb.Dn(l, (b'a=' + b'\xc4\x85\xc4\x87\xc4\x99\xc5\x82\xc5\x84\xc3\xb3\xc5\x9b\xc5\xba\xc5\xbc').decode('utf8'))
def test_utf8_encoded_ldb_Dn(self):
l = ldb.Ldb(self.url(), flags=self.flags())
dn_encoded_utf8 = b'a=' + b'\xc4\x85\xc4\x87\xc4\x99\xc5\x82\xc5\x84\xc3\xb3\xc5\x9b\xc5\xba\xc5\xbc'
try:
dn = ldb.Dn(l, dn_encoded_utf8)
except UnicodeDecodeError as e:
raise
except TypeError as te:
if PY3:
p3errors = ["argument 2 must be str, not bytes",
"Can't convert 'bytes' object to str implicitly"]
self.assertIn(str(te), p3errors)
else:
raise
def test_search_attrs(self):
l = ldb.Ldb(self.url(), flags=self.flags())
self.assertEqual(len(l.search(ldb.Dn(l, ""), ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0)
......
#!/usr/bin/env python
APPNAME = 'ldb'
VERSION = '1.4.3'
VERSION = '1.4.6'
blddir = 'bin'
......@@ -500,6 +500,11 @@ def build(bld):
deps='cmocka ldb',
install=False)
bld.SAMBA_BINARY('ldb_match_test',
source='tests/ldb_match_test.c',
deps='cmocka ldb',
install=False)
if bld.CONFIG_SET('HAVE_LMDB'):
bld.SAMBA_BINARY('ldb_mdb_mod_op_test',
source='tests/ldb_mod_op_test.c',
......@@ -567,7 +572,8 @@ def test(ctx):
# we don't want to run ldb_lmdb_size_test (which proves we can
# fit > 4G of data into the DB), it would fill up the disk on
# many of our test instances
'ldb_mdb_kv_ops_test']
'ldb_mdb_kv_ops_test',
'ldb_match_test']
for test_exe in test_exes:
cmd = os.path.join(Utils.g_module.blddir, test_exe)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment