From 43a694ab071f32609c0ea5c086d2a43f22c2ba55 Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Date: Tue, 8 Dec 2020 22:00:55 +1300
Subject: [PATCH 01/17] CVE-2020-25718 ldb/attrib_handler casefold: simplify
 space dropping

As seen in CVE-2021-20277, ldb_handler_fold() has been making mistakes
when collapsing spaces down to a single space.

This patch fixes the way it handles internal spaces (CVE-2021-20277
was about leading spaces), and involves a rewrite of the parsing loop.

The bug has a detailed description of the problem.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14656

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>

Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Wed Apr  7 03:16:39 UTC 2021 on sn-devel-184

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit  24ddc1ca9cad95673bdd8023d99867707b37085f)
---
 ldb/common/attrib_handlers.c | 53 +++++++++++++++-----------------
 ldb/tests/ldb_match_test.c   |  2 ++
 2 files changed, 27 insertions(+), 28 deletions(-)

diff --git ldb/common/attrib_handlers.c ldb/common/attrib_handlers.c
index c6ef5ad477b..f0fd4f50d8d 100644
--- ldb/common/attrib_handlers.c
+++ ldb/common/attrib_handlers.c
@@ -54,8 +54,8 @@ int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx,
 int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
 			    const struct ldb_val *in, struct ldb_val *out)
 {
-	char *s, *t;
-	size_t l;
+	char *s, *t, *start;
+	bool in_space;
 
 	if (!in || !out || !(in->data)) {
 		return -1;
@@ -67,36 +67,33 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
 		return -1;
 	}
 
-	s = (char *)(out->data);
-	
-	/* remove trailing spaces if any */
-	l = strlen(s);
-	while (l > 0 && s[l - 1] == ' ') l--;
-	s[l] = '\0';
-	
-	/* remove leading spaces if any */
-	if (*s == ' ') {
-		for (t = s; *s == ' '; s++, l--) ;
-
-		/* remove leading spaces by moving down the string */
-		memmove(t, s, l);
-
-		s = t;
+	start = (char *)(out->data);
+	in_space = true;
+	t = start;
+	for (s = start; *s != '\0'; s++) {
+		if (*s == ' ') {
+			if (in_space) {
+				/*
+				 * We already have one (or this is the start)
+				 * and we don't want to add more
+				 */
+				continue;
+			}
+			in_space = true;
+		} else {
+			in_space = false;
+		}
+		*t = *s;
+		t++;
 	}
 
-	/* check middle spaces */
-	while ((t = strchr(s, ' ')) != NULL) {
-		for (s = t; *s == ' '; s++) ;
-
-		if ((s - t) > 1) {
-			l = strlen(s);
-
-			/* remove all spaces but one by moving down the string */
-			memmove(t + 1, s, l);
-		}
+	if (in_space && t != start) {
+		/* the loop will have left a single trailing space */
+		t--;
 	}
+	*t = '\0';
 
-	out->length = strlen((char *)out->data);
+	out->length = t - start;
 	return 0;
 }
 
diff --git ldb/tests/ldb_match_test.c ldb/tests/ldb_match_test.c
index fbf4106fa78..eb5d9fcee20 100644
--- ldb/tests/ldb_match_test.c
+++ ldb/tests/ldb_match_test.c
@@ -183,6 +183,8 @@ static void test_wildcard_match(void **state)
 	struct wildcard_test tests[] = {
 		TEST_ENTRY("                     1  0", "1*0*", true, true),
 		TEST_ENTRY("                     1  0", "1 *0", true, true),
+		TEST_ENTRY("                     1  0", "*1 0", true, true),
+		TEST_ENTRY("1    0", "*1 0", true, true),
 		TEST_ENTRY("The value.......end", "*end", true, true),
 		TEST_ENTRY("The value.......end", "*fend", false, true),
 		TEST_ENTRY("The value.......end", "*eel", false, true),
-- 
2.31.1


From 57edef488c9656405e8790d3650db43ac55e4f87 Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Date: Wed, 3 Mar 2021 19:17:36 +1300
Subject: [PATCH 02/17] CVE-2020-25718 ldb_match: trailing chunk must match end
 of string
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

A wildcard search is divided into chunks by the asterisks. While most
chunks match the first suitable string, the last chunk matches the
last possible string (unless there is a trailing asterisk, in which
case this distinction is moot).

We always knew this in our hearts, but we tried to do it in a funny
complicated way that stepped through the string, comparing here and
there, leading to CVE-2019-3824 and missed matches (bug 14044).

With this patch, we just jump to the end of the string and compare it.
As well as being correct, this should also improve performance, as the
previous algorithm involved a quadratic loop of erroneous memmem()s.

See https://tools.ietf.org/html/rfc4517

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14044

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Björn Jacke <bjacke@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit cc098f1cad04b2cfec4ddd6b2511cd5a600f31c6)
---
 ldb/common/ldb_match.c | 80 +++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 45 deletions(-)

diff --git ldb/common/ldb_match.c ldb/common/ldb_match.c
index 829afa77e71..da595615bd9 100644
--- ldb/common/ldb_match.c
+++ ldb/common/ldb_match.c
@@ -295,8 +295,9 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
 		uint8_t *p;
 
 		chunk = tree->u.substring.chunks[c];
-		if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch;
-
+		if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) {
+			goto mismatch;
+		}
 		/*
 		 * Empty strings are returned as length 0. Ensure
 		 * we can cope with this.
@@ -304,52 +305,41 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
 		if (cnk.length == 0) {
 			goto mismatch;
 		}
-		/*
-		 * Values might be binary blobs. Don't use string
-		 * search, but memory search instead.
-		 */
-		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 (cnk.length > val.length) {
+			goto mismatch;
+		}
 
-		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 */
-
-				/*
-				 * 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);
+		if ( (tree->u.substring.chunks[c + 1]) == NULL &&
+		     (! tree->u.substring.end_with_wildcard) ) {
+			/*
+			 * The last bit, after all the asterisks, must match
+			 * exactly the last bit of the string.
+			 */
+			int cmp;
+			p = val.data + val.length - cnk.length;
+			cmp = memcmp(p,
+				     cnk.data,
+				     cnk.length);
+			if (cmp != 0) {
+				goto mismatch;
+			}
+		} else {
+			/*
+			 * Values might be binary blobs. Don't use string
+			 * search, but memory search instead.
+			 */
+			p = memmem((const void *)val.data, val.length,
+				   (const void *)cnk.data, cnk.length);
+			if (p == NULL) {
+				goto mismatch;
+			}
+			/* move val to the end of the match */
+			p += cnk.length;
+			val.length -= (p - val.data);
+			val.data = p;
 		}
-		val.length = val.length - (p - (uint8_t *)(val.data)) - cnk.length;
-		val.data = (uint8_t *)(p + cnk.length);
 		c++;
-		talloc_free(cnk.data);
-		cnk.data = NULL;
+		TALLOC_FREE(cnk.data);
 	}
 
 	/* last chunk may not have reached end of string */
-- 
2.31.1


From ce82d524e92c64f03f1df3bee864c0d0ebc96185 Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Date: Sat, 6 Mar 2021 16:05:15 +1300
Subject: [PATCH 03/17] CVE-2020-25718 ldb: fix ldb_comparison_fold off-by-one
 overrun

We run one character over in comparing all the bytes in two ldb_vals.

In almost all circumstances both ldb_vals would have an allocated '\0'
in the overrun position, but it is best not to rely on that.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit 2b2f4f519454beb6f2a46705675a62274019fc09)
---
 ldb/common/attrib_handlers.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git ldb/common/attrib_handlers.c ldb/common/attrib_handlers.c
index f0fd4f50d8d..6a885065f77 100644
--- ldb/common/attrib_handlers.c
+++ ldb/common/attrib_handlers.c
@@ -334,8 +334,8 @@ int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx,
 		if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2))
 			break;
 		if (*s1 == ' ') {
-			while (n1 && s1[0] == s1[1]) { s1++; n1--; }
-			while (n2 && s2[0] == s2[1]) { s2++; n2--; }
+			while (n1 > 1 && s1[0] == s1[1]) { s1++; n1--; }
+			while (n2 > 1 && s2[0] == s2[1]) { s2++; n2--; }
 		}
 		s1++; s2++;
 		n1--; n2--;
-- 
2.31.1


From ec3689104015d3ac53e17a930e1b2c104a4f9720 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Tue, 19 Jan 2021 16:53:55 +0100
Subject: [PATCH 04/17] CVE-2020-25718 pyldb: catch potential overflow error in
 py_timestring
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Pair-Programmed-With: Björn Baumbach <bb@sernet.de>

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Björn Baumbach <bb@sernet.de>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit 71e8b24b8a031de26b21539e36a60f459257d2fd)
---
 ldb/common/ldb_msg.c    |  1 +
 ldb/pyldb.c             |  7 +++++++
 ldb/tests/python/api.py | 19 +++++++++++++++++++
 3 files changed, 27 insertions(+)

diff --git ldb/common/ldb_msg.c ldb/common/ldb_msg.c
index 7131f013f71..57dfc5a04c2 100644
--- ldb/common/ldb_msg.c
+++ ldb/common/ldb_msg.c
@@ -1272,6 +1272,7 @@ char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t)
 
 	if (r != 17) {
 		talloc_free(ts);
+		errno = EOVERFLOW;
 		return NULL;
 	}
 
diff --git ldb/pyldb.c ldb/pyldb.c
index d093daedf5c..257351b2bc4 100644
--- ldb/pyldb.c
+++ ldb/pyldb.c
@@ -4227,6 +4227,13 @@ static PyObject *py_timestring(PyObject *module, PyObject *args)
 	if (!PyArg_ParseTuple(args, "l", &t_val))
 		return NULL;
 	tresult = ldb_timestring(NULL, (time_t) t_val);
+	if (tresult == NULL) {
+		/*
+		 * Most likely EOVERFLOW from gmtime()
+		 */
+		PyErr_SetFromErrno(PyExc_OSError);
+		return NULL;
+	}
 	ret = PyUnicode_FromString(tresult);
 	talloc_free(tresult);
 	return ret;
diff --git ldb/tests/python/api.py ldb/tests/python/api.py
index 675b5859af8..8d154aac6ad 100755
--- ldb/tests/python/api.py
+++ ldb/tests/python/api.py
@@ -5,10 +5,12 @@
 import os
 from unittest import TestCase
 import sys
+sys.path.insert(0, "bin/python")
 import gc
 import time
 import ldb
 import shutil
+import errno
 
 PY3 = sys.version_info > (3, 0)
 
@@ -42,10 +44,27 @@ class NoContextTests(TestCase):
         self.assertEqual("19700101000000.0Z", ldb.timestring(0))
         self.assertEqual("20071119191012.0Z", ldb.timestring(1195499412))
 
+        self.assertEqual("00000101000000.0Z", ldb.timestring(-62167219200))
+        self.assertEqual("99991231235959.0Z", ldb.timestring(253402300799))
+
+        # should result with OSError EOVERFLOW from gmtime()
+        with self.assertRaises(OSError) as err:
+            ldb.timestring(-62167219201)
+        self.assertEqual(err.exception.errno, errno.EOVERFLOW)
+        with self.assertRaises(OSError) as err:
+            ldb.timestring(253402300800)
+        self.assertEqual(err.exception.errno, errno.EOVERFLOW)
+        with self.assertRaises(OSError) as err:
+            ldb.timestring(0x7fffffffffffffff)
+        self.assertEqual(err.exception.errno, errno.EOVERFLOW)
+
     def test_string_to_time(self):
         self.assertEqual(0, ldb.string_to_time("19700101000000.0Z"))
         self.assertEqual(1195499412, ldb.string_to_time("20071119191012.0Z"))
 
+        self.assertEqual(-62167219200, ldb.string_to_time("00000101000000.0Z"))
+        self.assertEqual(253402300799, ldb.string_to_time("99991231235959.0Z"))
+
     def test_binary_encode(self):
         encoded = ldb.binary_encode(b'test\\x')
         decoded = ldb.binary_decode(encoded)
-- 
2.31.1


From 430d0813d7c2886c3dd8de01c760ab2c1a504036 Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Date: Wed, 3 Mar 2021 19:54:37 +1300
Subject: [PATCH 05/17] CVE-2020-25718 ldb_match: remove redundant check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

We already ensure the no-trailing-asterisk case ends at the end of the
string.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14044

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Björn Jacke <bjacke@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit fa93339978040eab52b2722c1716028b48d8d084)
---
 ldb/common/ldb_match.c | 2 --
 1 file changed, 2 deletions(-)

diff --git ldb/common/ldb_match.c ldb/common/ldb_match.c
index da595615bd9..2f4d41f3441 100644
--- ldb/common/ldb_match.c
+++ ldb/common/ldb_match.c
@@ -342,8 +342,6 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
 		TALLOC_FREE(cnk.data);
 	}
 
-	/* last chunk may not have reached end of string */
-	if ( (! tree->u.substring.end_with_wildcard) && (val.length != 0) ) goto mismatch;
 	talloc_free(save_p);
 	*matched = true;
 	return LDB_SUCCESS;
-- 
2.31.1


From 4b28c16baa364246d4110cd424a0ba2559b5fa3d Mon Sep 17 00:00:00 2001
From: Joseph Sutton <josephsutton@catalyst.net.nz>
Date: Fri, 28 May 2021 14:15:43 +1200
Subject: [PATCH 06/17] CVE-2020-25718 pyldb: Fix Message.items() for a message
 containing elements

Previously, message elements were being freed before the call to
Py_BuildValue(), resulting in an exception being raised. Additionally,
only the first element of the returned list was ever assigned to.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit 3e4ec0a90a222c1cff4a91912afc703ca4cbbb0e)
---
 ldb/pyldb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git ldb/pyldb.c ldb/pyldb.c
index 257351b2bc4..df7c5c54eaa 100644
--- ldb/pyldb.c
+++ ldb/pyldb.c
@@ -3535,13 +3535,13 @@ static PyObject *py_ldb_msg_items(PyLdbMessageObject *self,
 		PyObject *value = NULL;
 		PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
 		int res = 0;
-		Py_CLEAR(py_el);
 		value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
+		Py_CLEAR(py_el);
 		if (value == NULL ) {
 			Py_CLEAR(l);
 			return NULL;
 		}
-		res = PyList_SetItem(l, 0, value);
+		res = PyList_SetItem(l, j, value);
 		if (res == -1) {
 			Py_CLEAR(l);
 			return NULL;
-- 
2.31.1


From c71ea698e4e89ca2d3c57bf3aad3caca4d44795d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 1 Feb 2021 14:21:21 +0100
Subject: [PATCH 07/17] CVE-2020-25718 lib:ldb: Add missing break in switch
 statement

error: unannotated fall-through between switch labels [-Werror,-Wimplicit-fallthrough]

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit 1ffacac547a8ce29c6696dda73991a8db7e34dfd)
---
 ldb/ldb_map/ldb_map_inbound.c | 1 +
 1 file changed, 1 insertion(+)

diff --git ldb/ldb_map/ldb_map_inbound.c ldb/ldb_map/ldb_map_inbound.c
index 861c4c1622d..324295737da 100644
--- ldb/ldb_map/ldb_map_inbound.c
+++ ldb/ldb_map/ldb_map_inbound.c
@@ -262,6 +262,7 @@ static int map_search_self_callback(struct ldb_request *req, struct ldb_reply *a
 						LDB_ERR_OPERATIONS_ERROR);
 		}
 
+		break;
 	default:
 		/* ignore referrals */
 		break;
-- 
2.31.1


From b3b6ef4bfcd831d5485112a7208948c74338d529 Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Date: Sat, 19 Dec 2020 11:43:56 +1300
Subject: [PATCH 08/17] CVE-2020-25718 ldb.h: remove undefined async_ctx
 function signatures

These functions do not exist.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit 1a05b58edaf96e7da707f9ad0a237551dbe13eb5)
---
 ldb/include/ldb.h | 12 ------------
 1 file changed, 12 deletions(-)

diff --git ldb/include/ldb.h ldb/include/ldb.h
index 7f53e6420e1..f5f02c9a344 100644
--- ldb/include/ldb.h
+++ ldb/include/ldb.h
@@ -1093,18 +1093,6 @@ int ldb_global_init(void);
 */
 struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx);
 
-typedef void (*ldb_async_timeout_fn) (void *);
-typedef bool (*ldb_async_callback_fn) (void *);
-typedef int (*ldb_async_ctx_add_op_fn)(void *, time_t, void *, ldb_async_timeout_fn, ldb_async_callback_fn);
-typedef int (*ldb_async_ctx_wait_op_fn)(void *);
-
-void ldb_async_ctx_set_private_data(struct ldb_context *ldb,
-					void *private_data);
-void ldb_async_ctx_set_add_op(struct ldb_context *ldb,
-				ldb_async_ctx_add_op_fn add_op);
-void ldb_async_ctx_set_wait_op(struct ldb_context *ldb,
-				ldb_async_ctx_wait_op_fn wait_op);
-
 /**
    Connect to a database.
 
-- 
2.31.1


From 2985d5e1adc22bd57350baa8e198b853639ffc99 Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Date: Sat, 6 Mar 2021 09:57:44 +1300
Subject: [PATCH 09/17] CVE-2020-25718 ldb: correct comments in attrib_handers
 val_to_int64

c.f. the identical static function in ldb-samba/ldif_handlers.c

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit 46e6f6ef8436df7e083f34556c25f66f65ea1ce5)
---
 ldb/common/attrib_handlers.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git ldb/common/attrib_handlers.c ldb/common/attrib_handlers.c
index 6a885065f77..febf2f414ca 100644
--- ldb/common/attrib_handlers.c
+++ ldb/common/attrib_handlers.c
@@ -97,7 +97,7 @@ int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx,
 	return 0;
 }
 
-/* length limited conversion of a ldb_val to a int32_t */
+/* length limited conversion of a ldb_val to an int64_t */
 static int val_to_int64(const struct ldb_val *in, int64_t *v)
 {
 	char *end;
@@ -110,8 +110,6 @@ static int val_to_int64(const struct ldb_val *in, int64_t *v)
 	strncpy(buf, (char *)in->data, in->length);
 	buf[in->length] = 0;
 
-	/* We've to use "strtoll" here to have the intended overflows.
-	 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
 	*v = (int64_t) strtoll(buf, &end, 0);
 	if (*end != 0) {
 		return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
-- 
2.31.1


From 6a69e7566c36101670f0d6efd94a032d8d1a9c98 Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Date: Fri, 29 Jan 2021 13:49:02 +1300
Subject: [PATCH 10/17] CVE-2020-25718 ldb: improve comments for
 ldb_module_connect_backend()

There is no flags argument.
There are more URI forms.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit 48068a58df0313cd904f27e2c918ee10275ae373)
---
 ldb/common/ldb_modules.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git ldb/common/ldb_modules.c ldb/common/ldb_modules.c
index cc067abdfe0..4366f05e066 100644
--- ldb/common/ldb_modules.c
+++ ldb/common/ldb_modules.c
@@ -173,11 +173,15 @@ int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn, bool
 
 /*
    Return the ldb module form of a database.
-   The URL can either be one of the following forms
-   ldb://path
-   ldapi://path
-
-   flags is made up of LDB_FLG_*
+   The URL looks something like this:
+     tdb://PATH
+     ldb://PATH
+     mdb://PATH
+     ldapi://PATH
+     PATH          (unadorned PATH defaults to tdb://)
+
+   for a complete list of backends (including possibly unmaintained ones) grep
+   for calls to ldb_register_backend().
 
    the options are passed uninterpreted to the backend, and are
    backend specific.
-- 
2.31.1


From 72f4a5849c61a960518c59ed80cfc7240bb2a9b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Baumbach?= <bb@sernet.de>
Date: Mon, 18 Jan 2021 16:48:21 +0100
Subject: [PATCH 11/17] CVE-2020-25718 pyldb: fix a typo
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Björn Baumbach <bb@sernet.de>
Reviewed-by: Rowland penny <rpenny@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit 6fcde09f093db5d26c582a3c28531265f06b9fde)
---
 ldb/pyldb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git ldb/pyldb.c ldb/pyldb.c
index df7c5c54eaa..3f4b0c7a45c 100644
--- ldb/pyldb.c
+++ ldb/pyldb.c
@@ -4314,7 +4314,7 @@ static PyMethodDef py_ldb_global_methods[] = {
 		"S.string_to_time(string) -> int\n\n"
 		"Parse a LDAP time string into a UNIX timestamp." },
 	{ "valid_attr_name", py_valid_attr_name, METH_VARARGS,
-		"S.valid_attr_name(name) -> bool\n\nn"
+		"S.valid_attr_name(name) -> bool\n\n"
 		"Check whether the supplied name is a valid attribute name." },
 	{ "binary_encode", py_binary_encode, METH_VARARGS,
 		"S.binary_encode(string) -> string\n\n"
-- 
2.31.1


From 6999e294a533b94c52014825fd971a3eda837c72 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 17 Dec 2020 11:56:08 +0100
Subject: [PATCH 12/17] CVE-2020-25718 lib:ldb: Use C99 initializers for
 builtin_popt_options[]

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit a593065c7f22e17434f33d0132cc6a7073acf414)
---
 ldb/tools/cmdline.c | 250 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 225 insertions(+), 25 deletions(-)

diff --git ldb/tools/cmdline.c ldb/tools/cmdline.c
index c32470864d4..affce47ac84 100644
--- ldb/tools/cmdline.c
+++ ldb/tools/cmdline.c
@@ -34,31 +34,231 @@ enum ldb_cmdline_options { CMDLINE_RELAX=1 };
 
 static struct poptOption builtin_popt_options[] = {
 	POPT_AUTOHELP
-	{ "url",       'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" },
-	{ "basedn",    'b', POPT_ARG_STRING, &options.basedn, 0, "base DN", "DN" },
-	{ "editor",    'e', POPT_ARG_STRING, &options.editor, 0, "external editor", "PROGRAM" },
-	{ "scope",     's', POPT_ARG_STRING, NULL, 's', "search scope", "SCOPE" },
-	{ "verbose",   'v', POPT_ARG_NONE, NULL, 'v', "increase verbosity", NULL },
-	{ "trace",     0,   POPT_ARG_NONE, &options.tracing, 0, "enable tracing", NULL },
-	{ "interactive", 'i', POPT_ARG_NONE, &options.interactive, 0, "input from stdin", NULL },
-	{ "recursive", 'r', POPT_ARG_NONE, &options.recursive, 0, "recursive delete", NULL },
-	{ "modules-path", 0, POPT_ARG_STRING, &options.modules_path, 0, "modules path", "PATH" },
-	{ "num-searches", 0, POPT_ARG_INT, &options.num_searches, 0, "number of test searches", NULL },
-	{ "num-records", 0, POPT_ARG_INT, &options.num_records, 0, "number of test records", NULL },
-	{ "all", 'a',    POPT_ARG_NONE, &options.all_records, 0, "(|(objectClass=*)(distinguishedName=*))", NULL },
-	{ "nosync", 0,   POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL },
-	{ "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL },
-	{ NULL,    'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" },
-	{ "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL },
-	{ "show-binary", 0, POPT_ARG_NONE, &options.show_binary, 0, "display binary LDIF", NULL },
-	{ "paged", 0, POPT_ARG_NONE, NULL, 'P', "use a paged search", NULL },
-	{ "show-deleted", 0, POPT_ARG_NONE, NULL, 'D', "show deleted objects", NULL },
-	{ "show-recycled", 0, POPT_ARG_NONE, NULL, 'R', "show recycled objects", NULL },
-	{ "show-deactivated-link", 0, POPT_ARG_NONE, NULL, 'd', "show deactivated links", NULL },
-	{ "reveal", 0, POPT_ARG_NONE, NULL, 'r', "reveal ldb internals", NULL },
-	{ "relax", 0, POPT_ARG_NONE, NULL, CMDLINE_RELAX, "pass relax control", NULL },
-	{ "cross-ncs", 0, POPT_ARG_NONE, NULL, 'N', "search across NC boundaries", NULL },
-	{ "extended-dn", 0, POPT_ARG_NONE, NULL, 'E', "show extended DNs", NULL },
+	{
+		.longName   = "url",
+		.shortName  = 'H',
+		.argInfo    = POPT_ARG_STRING,
+		.arg        = &options.url,
+		.val        = 0,
+		.descrip    = "database URL",
+		.argDescrip = "URL"
+	},
+	{
+		.longName   = "basedn",
+		.shortName  = 'b',
+		.argInfo    = POPT_ARG_STRING,
+		.arg        = &options.basedn,
+		.val        = 0,
+		.descrip    = "base DN",
+		.argDescrip = "DN"
+	},
+	{
+		.longName   = "editor",
+		.shortName  = 'e',
+		.argInfo    = POPT_ARG_STRING,
+		.arg        = &options.editor,
+		.val        = 0,
+		.descrip    = "external editor",
+		.argDescrip = "PROGRAM"
+	},
+	{
+		.longName   = "scope",
+		.shortName  = 's',
+		.argInfo    = POPT_ARG_STRING,
+		.arg        = NULL,
+		.val        = 's',
+		.descrip    = "search scope",
+		.argDescrip = "SCOPE"
+	},
+	{
+		.longName   = "verbose",
+		.shortName  = 'v',
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = NULL,
+		.val        = 'v',
+		.descrip    = "increase verbosity",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "trace",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = &options.tracing,
+		.val        = 0,
+		.descrip    = "enable tracing",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "interactive",
+		.shortName  = 'i',
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = &options.interactive,
+		.val        = 0,
+		.descrip    = "input from stdin",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "recursive",
+		.shortName  = 'r',
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = &options.recursive,
+		.val        = 0,
+		.descrip    = "recursive delete",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "modules-path",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_STRING,
+		.arg        = &options.modules_path,
+		.val        = 0,
+		.descrip    = "modules path",
+		.argDescrip = "PATH"
+	},
+	{
+		.longName   = "num-searches",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_INT,
+		.arg        = &options.num_searches,
+		.val        = 0,
+		.descrip    = "number of test searches",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "num-records",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_INT,
+		.arg        = &options.num_records,
+		.val        = 0,
+		.descrip    = "number of test records",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "all",
+		.shortName  = 'a',
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = &options.all_records,
+		.val        = 0,
+		.descrip    = "(|(objectClass=*)(distinguishedName=*))",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "nosync",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = &options.nosync,
+		.val        = 0,
+		.descrip    = "non-synchronous transactions",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "sorted",
+		.shortName  = 'S',
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = &options.sorted,
+		.val        = 0,
+		.descrip    = "sort attributes",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = NULL,
+		.shortName  = 'o',
+		.argInfo    = POPT_ARG_STRING,
+		.arg        = NULL,
+		.val        = 'o',
+		.descrip    = "ldb_connect option",
+		.argDescrip = "OPTION"
+	},
+	{
+		.longName   = "controls",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_STRING,
+		.arg        = NULL,
+		.val        = 'c',
+		.descrip    = "controls",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "show-binary",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = &options.show_binary,
+		.val        = 0,
+		.descrip    = "display binary LDIF",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "paged",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = NULL,
+		.val        = 'P',
+		.descrip    = "use a paged search",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "show-deleted",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = NULL,
+		.val        = 'D',
+		.descrip    = "show deleted objects",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "show-recycled",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = NULL,
+		.val        = 'R',
+		.descrip    = "show recycled objects",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "show-deactivated-link",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = NULL,
+		.val        = 'd',
+		.descrip    = "show deactivated links",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "reveal",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = NULL,
+		.val        = 'r',
+		.descrip    = "reveal ldb internals",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "relax",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = NULL,
+		.val        = CMDLINE_RELAX,
+		.descrip    = "pass relax control",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "cross-ncs",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = NULL,
+		.val        = 'N',
+		.descrip    = "search across NC boundaries",
+		.argDescrip = NULL
+	},
+	{
+		.longName   = "extended-dn",
+		.shortName  = 0,
+		.argInfo    = POPT_ARG_NONE,
+		.arg        = NULL,
+		.val        = 'E',
+		.descrip    = "show extended DNs",
+		.argDescrip = NULL
+	},
 	{0}
 };
 
-- 
2.31.1


From dd4d6b01e957ec6e2c56f5d3ede23cc0aa43c1a4 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 17 Dec 2020 19:16:13 +0100
Subject: [PATCH 13/17] CVE-2020-25718 lib:ldb-samba: Improve
 calculate_popt_array_length()

Note that memcmp() doesn't work well with padding bytes. So avoid it!

(gdb) ptype/o struct poptOption
/* offset    |  size */  type = struct poptOption {
/*    0      |     8 */    const char *longName;
/*    8      |     1 */    char shortName;
/* XXX  3-byte hole  */
/*   12      |     4 */    unsigned int argInfo;
/*   16      |     8 */    void *arg;
/*   24      |     4 */    int val;
/* XXX  4-byte hole  */
/*   32      |     8 */    const char *descrip;
/*   40      |     8 */    const char *argDescrip;

                           /* total size (bytes):   48 */

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit c2c7c1f50a8acb3169e19ba4329aa78839b66def)
---
 ldb/tools/cmdline.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git ldb/tools/cmdline.c ldb/tools/cmdline.c
index affce47ac84..ff25fe05ec7 100644
--- ldb/tools/cmdline.c
+++ ldb/tools/cmdline.c
@@ -259,7 +259,7 @@ static struct poptOption builtin_popt_options[] = {
 		.descrip    = "show extended DNs",
 		.argDescrip = NULL
 	},
-	{0}
+	POPT_TABLEEND
 };
 
 void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f)
-- 
2.31.1


From 62fbcc6108d0ff4a20394912a58fb338ef9b3894 Mon Sep 17 00:00:00 2001
From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Date: Fri, 24 Jul 2020 12:41:29 +1200
Subject: [PATCH 14/17] CVE-2020-25718 ldb_controls: control_to_string avoids
 crash

Otherwise a malformed control with unexpected NULL data will segfault
ldb_control_to_string(), though this is not very likely to affect
anyone in practice as converting controls to strings is rarely
necessary. If it happens at all in Samba it is in Python code.

Found by Honggfuzz using fuzz_ldb_parse_control.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>

Autobuild-User(master): Douglas Bagnall <dbagnall@samba.org>
Autobuild-Date(master): Wed Jul 29 04:43:23 UTC 2020 on sn-devel-184

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit 2aace18f170644da9c293342a6df5e5b2ae8da25)
---
 ldb/common/ldb_controls.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git ldb/common/ldb_controls.c ldb/common/ldb_controls.c
index d67c0afd845..266aa90b224 100644
--- ldb/common/ldb_controls.c
+++ ldb/common/ldb_controls.c
@@ -286,6 +286,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr
 	if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) {
 		struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control);
 		char *cookie;
+		if (rep_control == NULL) {
+			return NULL;
+		}
 
 		cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len);
 		if (cookie == NULL) {
@@ -312,6 +315,10 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr
 
 		char *cookie;
 
+		if (rep_control == NULL) {
+			return NULL;
+		}
+
 		cookie = ldb_base64_encode(mem_ctx,
 					   (char *)rep_control->contextId,
 					   rep_control->ctxid_len);
@@ -334,6 +341,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr
 		struct ldb_sort_resp_control *rep_control = talloc_get_type(control->data,
 								struct ldb_sort_resp_control);
 
+		if (rep_control == NULL) {
+			return NULL;
+		}
 		res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s",
 					LDB_CONTROL_SORT_RESP_NAME,
 					control->critical,
@@ -347,6 +357,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr
 		struct ldb_asq_control *rep_control = talloc_get_type(control->data,
 								struct ldb_asq_control);
 
+		if (rep_control == NULL) {
+			return NULL;
+		}
 		res = talloc_asprintf(mem_ctx, "%s:%d:%d",
 					LDB_CONTROL_SORT_RESP_NAME,
 					control->critical,
@@ -360,6 +373,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr
 		struct ldb_dirsync_control *rep_control = talloc_get_type(control->data,
 								struct ldb_dirsync_control);
 
+		if (rep_control == NULL) {
+			return NULL;
+		}
 		cookie = ldb_base64_encode(mem_ctx, rep_control->cookie,
 				rep_control->cookie_len);
 		if (cookie == NULL) {
@@ -380,6 +396,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr
 		struct ldb_dirsync_control *rep_control = talloc_get_type(control->data,
 								struct ldb_dirsync_control);
 
+		if (rep_control == NULL) {
+			return NULL;
+		}
 		cookie = ldb_base64_encode(mem_ctx, rep_control->cookie,
 				rep_control->cookie_len);
 		if (cookie == NULL) {
@@ -399,6 +418,9 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr
 	if (strcmp(control->oid, LDB_CONTROL_VERIFY_NAME_OID) == 0) {
 		struct ldb_verify_name_control *rep_control = talloc_get_type(control->data, struct ldb_verify_name_control);
 
+		if (rep_control == NULL) {
+			return NULL;
+		}
 		if (rep_control->gc != NULL) {
 			res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s",
 						LDB_CONTROL_VERIFY_NAME_NAME,
-- 
2.31.1


From 0a5b2e1f858aac29b4a1d68695becbce72608ec7 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl@samba.org>
Date: Mon, 4 Jan 2021 13:55:01 +0100
Subject: [PATCH 15/17] CVE-2020-25718 ldb: Use hex_byte() in
 ldb_binary_decode()

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit b6a57c49c00a778f954aaf10db6ebe6dca8f5ae2)
---
 ldb/common/ldb_parse.c | 27 ++++-----------------------
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git ldb/common/ldb_parse.c ldb/common/ldb_parse.c
index 7e15206b168..f0045ad2093 100644
--- ldb/common/ldb_parse.c
+++ ldb/common/ldb_parse.c
@@ -53,26 +53,6 @@
  */
 #define LDB_MAX_PARSE_TREE_DEPTH 128
 
-static int ldb_parse_hex2char(const char *x)
-{
-	if (isxdigit(x[0]) && isxdigit(x[1])) {
-		const char h1 = x[0], h2 = x[1];
-		int c = 0;
-
-		if (h1 >= 'a') c = h1 - (int)'a' + 10;
-		else if (h1 >= 'A') c = h1 - (int)'A' + 10;
-		else if (h1 >= '0') c = h1 - (int)'0';
-		c = c << 4;
-		if (h2 >= 'a') c += h2 - (int)'a' + 10;
-		else if (h2 >= 'A') c += h2 - (int)'A' + 10;
-		else if (h2 >= '0') c += h2 - (int)'0';
-
-		return c;
-	}
-
-	return -1;
-}
-
 /*
 a filter is defined by:
                <filter> ::= '(' <filtercomp> ')'
@@ -101,10 +81,11 @@ struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str)
 
 	for (i=j=0;i<slen;i++) {
 		if (str[i] == '\\') {
-			int c;
+			uint8_t c;
+			bool ok;
 
-			c = ldb_parse_hex2char(&str[i+1]);
-			if (c == -1) {
+			ok = hex_byte(&str[i+1], &c);
+			if (!ok) {
 				talloc_free(ret.data);
 				memset(&ret, 0, sizeof(ret));
 				return ret;
-- 
2.31.1


From a380726adec33736ad8bf1f601287ce910c67761 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de>
Date: Mon, 19 Oct 2020 02:39:46 +0200
Subject: [PATCH 16/17] CVE-2020-25718 ldb_kv_index: fix empty initializer
 compile warning

Signed-off-by: Bjoern Jacke <bjacke@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

(cherry picked from commit c862ad64aea31d1d5ec66385bb50d9b97e609071)
---
 ldb/ldb_key_value/ldb_kv_index.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git ldb/ldb_key_value/ldb_kv_index.c ldb/ldb_key_value/ldb_kv_index.c
index 9be7c5adcbe..1cc042aa84f 100644
--- ldb/ldb_key_value/ldb_kv_index.c
+++ ldb/ldb_key_value/ldb_kv_index.c
@@ -2267,7 +2267,7 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv,
 	struct ldb_message *filtered_msg;
 	unsigned int i;
 	unsigned int num_keys = 0;
-	uint8_t previous_guid_key[LDB_KV_GUID_KEY_SIZE] = {};
+	uint8_t previous_guid_key[LDB_KV_GUID_KEY_SIZE] = {0};
 	struct ldb_val *keys = NULL;
 
 	/*
-- 
2.31.1


From 26412714929fc2bbb5030f253bd68ef27d483858 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Tue, 2 Nov 2021 15:19:31 +0100
Subject: [PATCH 17/17] CVE-2020-25718 ldb: version 2.2.3

Backport all C code changes from ldb-2.4.1
to be available for Samba 4.13.x

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14558

Signed-off-by: Stefan Metzmacher <metze@samba.org>
---
 ldb/ABI/ldb-2.2.3.sigs        | 283 ++++++++++++++++++++++++++++++
 ldb/ABI/pyldb-util-2.2.3.sigs |   3 +
 ldb/wscript                   |   3 +-
 3 files changed, 288 insertions(+), 1 deletion(-)
 create mode 100644 ldb/ABI/ldb-2.2.3.sigs
 create mode 100644 ldb/ABI/pyldb-util-2.2.3.sigs

diff --git ldb/ABI/ldb-2.2.3.sigs ldb/ABI/ldb-2.2.3.sigs
new file mode 100644
index 00000000000..5049dc64ce1
--- /dev/null
+++ ldb/ABI/ldb-2.2.3.sigs
@@ -0,0 +1,283 @@
+ldb_add: int (struct ldb_context *, const struct ldb_message *)
+ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *)
+ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...)
+ldb_attr_casefold: char *(TALLOC_CTX *, const char *)
+ldb_attr_dn: int (const char *)
+ldb_attr_in_list: int (const char * const *, const char *)
+ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *)
+ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *)
+ldb_base64_decode: int (char *)
+ldb_base64_encode: char *(TALLOC_CTX *, const char *, int)
+ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *)
+ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val)
+ldb_binary_encode_string: char *(TALLOC_CTX *, const char *)
+ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *)
+ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t)
+ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t)
+ldb_check_critical_controls: int (struct ldb_control **)
+ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *)
+ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *)
+ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **)
+ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *)
+ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *)
+ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...)
+ldb_debug_add: void (struct ldb_context *, const char *, ...)
+ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level)
+ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...)
+ldb_delete: int (struct ldb_context *, struct ldb_dn *)
+ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...)
+ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...)
+ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val)
+ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *)
+ldb_dn_check_special: bool (struct ldb_dn *, const char *)
+ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val)
+ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *)
+ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *)
+ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *)
+ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *)
+ldb_dn_get_casefold: const char *(struct ldb_dn *)
+ldb_dn_get_comp_num: int (struct ldb_dn *)
+ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int)
+ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int)
+ldb_dn_get_extended_comp_num: int (struct ldb_dn *)
+ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *)
+ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int)
+ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *)
+ldb_dn_get_linearized: const char *(struct ldb_dn *)
+ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *)
+ldb_dn_get_rdn_name: const char *(struct ldb_dn *)
+ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *)
+ldb_dn_has_extended: bool (struct ldb_dn *)
+ldb_dn_is_null: bool (struct ldb_dn *)
+ldb_dn_is_special: bool (struct ldb_dn *)
+ldb_dn_is_valid: bool (struct ldb_dn *)
+ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *)
+ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *)
+ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *)
+ldb_dn_minimise: bool (struct ldb_dn *)
+ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *)
+ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...)
+ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int)
+ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int)
+ldb_dn_remove_extended_components: void (struct ldb_dn *)
+ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *)
+ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val)
+ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *)
+ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *)
+ldb_dn_validate: bool (struct ldb_dn *)
+ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *)
+ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int)
+ldb_errstring: const char *(struct ldb_context *)
+ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **)
+ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *)
+ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *)
+ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_get_create_perms: unsigned int (struct ldb_context *)
+ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_get_event_context: struct tevent_context *(struct ldb_context *)
+ldb_get_flags: unsigned int (struct ldb_context *)
+ldb_get_opaque: void *(struct ldb_context *, const char *)
+ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *)
+ldb_global_init: int (void)
+ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *)
+ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *)
+ldb_handle_use_global_event_context: void (struct ldb_handle *)
+ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *)
+ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *)
+ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *)
+ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *)
+ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *)
+ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **)
+ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *)
+ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *)
+ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *)
+ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *)
+ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **)
+ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *)
+ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *)
+ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *)
+ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *)
+ldb_load_modules: int (struct ldb_context *, const char **)
+ldb_map_add: int (struct ldb_module *, struct ldb_request *)
+ldb_map_delete: int (struct ldb_module *, struct ldb_request *)
+ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *)
+ldb_map_modify: int (struct ldb_module *, struct ldb_request *)
+ldb_map_rename: int (struct ldb_module *, struct ldb_request *)
+ldb_map_search: int (struct ldb_module *, struct ldb_request *)
+ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *)
+ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope)
+ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *)
+ldb_match_msg_objectclass: int (const struct ldb_message *, const char *)
+ldb_mod_register_control: int (struct ldb_module *, const char *)
+ldb_modify: int (struct ldb_context *, const struct ldb_message *)
+ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *)
+ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **)
+ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int)
+ldb_module_flags: uint32_t (struct ldb_context *)
+ldb_module_get_ctx: struct ldb_context *(struct ldb_module *)
+ldb_module_get_name: const char *(struct ldb_module *)
+ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *)
+ldb_module_get_private: void *(struct ldb_module *)
+ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *)
+ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **)
+ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *)
+ldb_module_next: struct ldb_module *(struct ldb_module *)
+ldb_module_popt_options: struct poptOption **(struct ldb_context *)
+ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **)
+ldb_module_send_referral: int (struct ldb_request *, char *)
+ldb_module_set_next: void (struct ldb_module *, struct ldb_module *)
+ldb_module_set_private: void (struct ldb_module *, void *)
+ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type)
+ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *)
+ldb_modules_load: int (const char *, const char *)
+ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int)
+ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **)
+ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...)
+ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *)
+ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *)
+ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *)
+ldb_msg_add_string: int (struct ldb_message *, const char *, const char *)
+ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **)
+ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *)
+ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *)
+ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *)
+ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *)
+ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *)
+ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *)
+ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **)
+ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *)
+ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *)
+ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *)
+ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int)
+ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *)
+ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double)
+ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int)
+ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t)
+ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *)
+ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int)
+ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t)
+ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t)
+ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t)
+ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *)
+ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *)
+ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *)
+ldb_msg_new: struct ldb_message *(TALLOC_CTX *)
+ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **)
+ldb_msg_remove_attr: void (struct ldb_message *, const char *)
+ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *)
+ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *)
+ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *)
+ldb_msg_sort_elements: void (struct ldb_message *)
+ldb_next_del_trans: int (struct ldb_module *)
+ldb_next_end_trans: int (struct ldb_module *)
+ldb_next_init: int (struct ldb_module *)
+ldb_next_prepare_commit: int (struct ldb_module *)
+ldb_next_read_lock: int (struct ldb_module *)
+ldb_next_read_unlock: int (struct ldb_module *)
+ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *)
+ldb_next_request: int (struct ldb_module *, struct ldb_request *)
+ldb_next_start_trans: int (struct ldb_module *)
+ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_options_copy: const char **(TALLOC_CTX *, const char **)
+ldb_options_find: const char *(struct ldb_context *, const char **, const char *)
+ldb_options_get: const char **(struct ldb_context *)
+ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t)
+ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *)
+ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **)
+ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *)
+ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *)
+ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *)
+ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *)
+ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t)
+ldb_register_backend: int (const char *, ldb_connect_fn, bool)
+ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *)
+ldb_register_hook: int (ldb_hook_fn)
+ldb_register_module: int (const struct ldb_module_ops *)
+ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *)
+ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *)
+ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *)
+ldb_req_get_custom_flags: uint32_t (struct ldb_request *)
+ldb_req_is_untrusted: bool (struct ldb_request *)
+ldb_req_location: const char *(struct ldb_request *)
+ldb_req_mark_trusted: void (struct ldb_request *)
+ldb_req_mark_untrusted: void (struct ldb_request *)
+ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t)
+ldb_req_set_location: void (struct ldb_request *, const char *)
+ldb_request: int (struct ldb_context *, struct ldb_request *)
+ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *)
+ldb_request_done: int (struct ldb_request *, int)
+ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *)
+ldb_request_get_status: int (struct ldb_request *)
+ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *)
+ldb_request_set_state: void (struct ldb_request *, int)
+ldb_reset_err_string: void (struct ldb_context *)
+ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***)
+ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *)
+ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *)
+ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *)
+ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *)
+ldb_schema_attribute_remove: void (struct ldb_context *, const char *)
+ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int)
+ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *)
+ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *)
+ldb_schema_set_override_indexlist: void (struct ldb_context *, bool)
+ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...)
+ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *)
+ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *)
+ldb_set_create_perms: void (struct ldb_context *, unsigned int)
+ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *)
+ldb_set_debug_stderr: int (struct ldb_context *)
+ldb_set_default_dns: void (struct ldb_context *)
+ldb_set_errstring: void (struct ldb_context *, const char *)
+ldb_set_event_context: void (struct ldb_context *, struct tevent_context *)
+ldb_set_flags: void (struct ldb_context *, unsigned int)
+ldb_set_modules_dir: void (struct ldb_context *, const char *)
+ldb_set_opaque: int (struct ldb_context *, const char *, void *)
+ldb_set_require_private_event_context: void (struct ldb_context *)
+ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int)
+ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *)
+ldb_set_utf8_default: void (struct ldb_context *)
+ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t))
+ldb_setup_wellknown_attributes: int (struct ldb_context *)
+ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *)
+ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *)
+ldb_strerror: const char *(int)
+ldb_string_to_time: time_t (const char *)
+ldb_string_utc_to_time: time_t (const char *)
+ldb_timestring: char *(TALLOC_CTX *, time_t)
+ldb_timestring_utc: char *(TALLOC_CTX *, time_t)
+ldb_transaction_cancel: int (struct ldb_context *)
+ldb_transaction_cancel_noerr: int (struct ldb_context *)
+ldb_transaction_commit: int (struct ldb_context *)
+ldb_transaction_prepare_commit: int (struct ldb_context *)
+ldb_transaction_start: int (struct ldb_context *)
+ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *)
+ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int)
+ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *)
+ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *)
+ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *)
+ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *)
+ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *)
+ldb_val_string_cmp: int (const struct ldb_val *, const char *)
+ldb_val_to_time: int (const struct ldb_val *, time_t *)
+ldb_valid_attr_name: int (const char *)
+ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list)
+ldb_wait: int (struct ldb_handle *, enum ldb_wait_type)
diff --git ldb/ABI/pyldb-util-2.2.3.sigs ldb/ABI/pyldb-util-2.2.3.sigs
new file mode 100644
index 00000000000..164a806b2ff
--- /dev/null
+++ ldb/ABI/pyldb-util-2.2.3.sigs
@@ -0,0 +1,3 @@
+pyldb_Dn_FromDn: PyObject *(struct ldb_dn *)
+pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **)
+pyldb_check_type: bool (PyObject *, const char *)
diff --git ldb/wscript ldb/wscript
index b2bb923379f..57dfdd6fe6b 100644
--- ldb/wscript
+++ ldb/wscript
@@ -1,7 +1,8 @@
 #!/usr/bin/env python
 
 APPNAME = 'ldb'
-VERSION = '2.2.2'
+# For Samba 4.13.x
+VERSION = '2.2.3'
 
 import sys, os
 
-- 
2.31.1

