From 1bc7443272b899e60f9ca710ccc8bc1e63ebb079 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Jan 2016 12:38:36 +0100 Subject: [PATCH 01/16] ldb: Fix some whitespace Signed-off-by: Volker Lendecke Reviewed-by: Guenther Deschner (cherry picked from commit 11c5513bb121fd43f566eacfe7b2af64f3cb3a83) --- lib/ldb/common/ldb_ldif.c | 58 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/lib/ldb/common/ldb_ldif.c b/lib/ldb/common/ldb_ldif.c index f9743dc..a8ad4aa 100644 --- a/lib/ldb/common/ldb_ldif.c +++ b/lib/ldb/common/ldb_ldif.c @@ -1,4 +1,4 @@ -/* +/* ldb database library Copyright (C) Andrew Tridgell 2004 @@ -6,7 +6,7 @@ ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released ** under the LGPL - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -39,7 +39,7 @@ #include "system/locale.h" /* - + */ static int ldb_read_data_file(TALLOC_CTX *mem_ctx, struct ldb_val *value) { @@ -236,7 +236,7 @@ static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *priva encode as base64 to a file */ static int base64_encode_f(struct ldb_context *ldb, - int (*fprintf_fn)(void *, const char *, ...), + int (*fprintf_fn)(void *, const char *, ...), void *private_data, const char *buf, int len, int start_pos) { @@ -273,9 +273,9 @@ static const struct { write to ldif, using a caller supplied write method, and only printing secrets if we are not in a trace */ static int ldb_ldif_write_trace(struct ldb_context *ldb, - int (*fprintf_fn)(void *, const char *, ...), + int (*fprintf_fn)(void *, const char *, ...), void *private_data, - const struct ldb_ldif *ldif, + const struct ldb_ldif *ldif, bool in_trace) { TALLOC_CTX *mem_ctx; @@ -324,20 +324,20 @@ static int ldb_ldif_write_trace(struct ldb_context *ldb, if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { case LDB_FLAG_MOD_ADD: - fprintf_fn(private_data, "add: %s\n", + fprintf_fn(private_data, "add: %s\n", msg->elements[i].name); break; case LDB_FLAG_MOD_DELETE: - fprintf_fn(private_data, "delete: %s\n", + fprintf_fn(private_data, "delete: %s\n", msg->elements[i].name); break; case LDB_FLAG_MOD_REPLACE: - fprintf_fn(private_data, "replace: %s\n", + fprintf_fn(private_data, "replace: %s\n", msg->elements[i].name); break; } } - + if (in_trace && secret_attributes && ldb_attr_in_list(secret_attributes, msg->elements[i].name)) { /* Deliberatly skip printing this password */ ret = fprintf_fn(private_data, "# %s::: REDACTED SECRET ATTRIBUTE\n", @@ -356,10 +356,10 @@ static int ldb_ldif_write_trace(struct ldb_context *ldb, use_b64_encode = !(ldb->flags & LDB_FLG_SHOW_BINARY) && ldb_should_b64_encode(ldb, &v); if (ret != LDB_SUCCESS || use_b64_encode) { - ret = fprintf_fn(private_data, "%s:: ", + ret = fprintf_fn(private_data, "%s:: ", msg->elements[i].name); CHECK_RET; - ret = base64_encode_f(ldb, fprintf_fn, private_data, + ret = base64_encode_f(ldb, fprintf_fn, private_data, (char *)v.data, v.length, strlen(msg->elements[i].name)+3); CHECK_RET; @@ -369,7 +369,7 @@ static int ldb_ldif_write_trace(struct ldb_context *ldb, ret = fprintf_fn(private_data, "%s: ", msg->elements[i].name); CHECK_RET; if (ldb->flags & LDB_FLG_SHOW_BINARY) { - ret = fprintf_fn(private_data, "%*.*s", + ret = fprintf_fn(private_data, "%*.*s", v.length, v.length, (char *)v.data); } else { ret = fold_string(fprintf_fn, private_data, @@ -403,7 +403,7 @@ static int ldb_ldif_write_trace(struct ldb_context *ldb, write to ldif, using a caller supplied write method */ int ldb_ldif_write(struct ldb_context *ldb, - int (*fprintf_fn)(void *, const char *, ...), + int (*fprintf_fn)(void *, const char *, ...), void *private_data, const struct ldb_ldif *ldif) { @@ -417,7 +417,7 @@ int ldb_ldif_write(struct ldb_context *ldb, caller frees */ -static char *next_chunk(struct ldb_context *ldb, +static char *next_chunk(struct ldb_context *ldb, int (*fgetc_fn)(void *), void *private_data) { size_t alloc_size=0, chunk_size = 0; @@ -442,15 +442,15 @@ static char *next_chunk(struct ldb_context *ldb, if (c == '\n') { in_comment = 0; } - continue; + continue; } - + /* handle continuation lines - see RFC2849 */ if (c == ' ' && chunk_size > 1 && chunk[chunk_size-1] == '\n') { chunk_size--; continue; } - + /* chunks are terminated by a double line-feed */ if (c == '\n' && chunk_size > 0 && chunk[chunk_size-1] == '\n') { chunk[chunk_size-1] = 0; @@ -785,7 +785,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, if (next_attr(ldif, &s, &attr, &value) != 0) { goto failed; } - + /* first line must be a dn */ if (ldb_attr_cmp(attr, "dn") != 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'", @@ -845,7 +845,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, } continue; } - + el = &msg->elements[msg->num_elements-1]; a = ldb_schema_attribute_by_name(ldb, attr); @@ -853,8 +853,8 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 && flags == el->flags) { /* its a continuation */ - el->values = - talloc_realloc(msg->elements, el->values, + el->values = + talloc_realloc(msg->elements, el->values, struct ldb_val, el->num_values+1); if (!el->values) { goto failed; @@ -874,8 +874,8 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, el->num_values++; } else { /* its a new attribute */ - msg->elements = talloc_realloc(msg, msg->elements, - struct ldb_message_element, + msg->elements = talloc_realloc(msg, msg->elements, + struct ldb_message_element, msg->num_elements+1); if (!msg->elements) { goto failed; @@ -934,7 +934,7 @@ static int fgetc_file(void *private_data) return c; } -struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb, +struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb, struct ldif_read_file_state *state) { return ldb_ldif_read(ldb, fgetc_file, state); @@ -1020,7 +1020,7 @@ static int ldif_printf_string(void *private_data, const char *fmt, ...) va_list ap; size_t oldlen = talloc_get_size(state->string); va_start(ap, fmt); - + state->string = talloc_vasprintf_append(state->string, fmt, ap); va_end(ap); if (!state->string) { @@ -1030,7 +1030,7 @@ static int ldif_printf_string(void *private_data, const char *fmt, ...) return talloc_get_size(state->string) - oldlen; } -char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, +char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_ldif *ldif) { struct ldif_write_string_state state; @@ -1044,7 +1044,7 @@ char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX * return state.string; } -char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, +char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_ldif *ldif) { struct ldif_write_string_state state; @@ -1062,7 +1062,7 @@ char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, convenient function to turn a ldb_message into a string. Useful for debugging */ -char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, +char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, enum ldb_changetype changetype, const struct ldb_message *msg) { -- 1.9.1 From c3f0e46e98b9b23c746ff90817b43af1da46c888 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Jan 2016 12:40:53 +0100 Subject: [PATCH 02/16] ldb: Avoid a "talloc_steal" There's only one caller of "next_chunk" that does a talloc_steal right after the call. Pass in a talloc context. Signed-off-by: Volker Lendecke Reviewed-by: Guenther Deschner (cherry picked from commit d56e42de64af84ad839749beaa22450f71bec58a) --- lib/ldb/common/ldb_ldif.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/ldb/common/ldb_ldif.c b/lib/ldb/common/ldb_ldif.c index a8ad4aa..07de517 100644 --- a/lib/ldb/common/ldb_ldif.c +++ b/lib/ldb/common/ldb_ldif.c @@ -417,7 +417,7 @@ int ldb_ldif_write(struct ldb_context *ldb, caller frees */ -static char *next_chunk(struct ldb_context *ldb, +static char *next_chunk(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void *), void *private_data) { size_t alloc_size=0, chunk_size = 0; @@ -429,7 +429,7 @@ static char *next_chunk(struct ldb_context *ldb, if (chunk_size+1 >= alloc_size) { char *c2; alloc_size += 1024; - c2 = talloc_realloc(ldb, chunk, char, alloc_size); + c2 = talloc_realloc(mem_ctx, chunk, char, alloc_size); if (!c2) { talloc_free(chunk); errno = ENOMEM; @@ -774,11 +774,10 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, msg->elements = NULL; msg->num_elements = 0; - chunk = next_chunk(ldb, fgetc_fn, private_data); + chunk = next_chunk(ldb, ldif, fgetc_fn, private_data); if (!chunk) { goto failed; } - talloc_steal(ldif, chunk); s = chunk; -- 1.9.1 From 840f76efbaf956c14b281f186d464537a1635077 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 14 Jan 2016 03:14:26 +0100 Subject: [PATCH 03/16] ldb:ABI: add missing pyldb-util.py3-1.1.25.sigs Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 8adf470af231718d334e282594079a67e4da9f05) --- lib/ldb/ABI/pyldb-util.py3-1.1.25.sigs | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 lib/ldb/ABI/pyldb-util.py3-1.1.25.sigs diff --git a/lib/ldb/ABI/pyldb-util.py3-1.1.25.sigs b/lib/ldb/ABI/pyldb-util.py3-1.1.25.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/lib/ldb/ABI/pyldb-util.py3-1.1.25.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) -- 1.9.1 From f2ea17c1e14a1d746f9dc9c79b3afb384ea8454a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 1 Feb 2016 11:00:14 +0100 Subject: [PATCH 04/16] s4:libcli/ldap: send AbandonRequests for cancelled requests This happens on a local timeout of an talloc_free() of the request. Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit cd77b0bba434139e13db5ec2096ca99b6b3f084d) --- source4/libcli/ldap/ldap_client.c | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 4b8f951..97a83ce 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -662,15 +662,50 @@ static void ldap_reconnect(struct ldap_connection *conn) } } +static void ldap_request_destructor_abandon(struct ldap_request *abandon) +{ + TALLOC_FREE(abandon); +} + /* destroy an open ldap request */ static int ldap_request_destructor(struct ldap_request *req) { if (req->state == LDAP_REQUEST_PENDING) { + struct ldap_message msg = { + .type = LDAP_TAG_AbandonRequest, + .r.AbandonRequest.messageid = req->messageid, + }; + struct ldap_request *abandon = NULL; + DLIST_REMOVE(req->conn->pending, req); + + abandon = ldap_request_send(req->conn, &msg); + if (abandon == NULL) { + ldap_error_handler(req->conn, NT_STATUS_NO_MEMORY); + return 0; + } + abandon->async.fn = ldap_request_destructor_abandon; + abandon->async.private_data = NULL; } + return 0; } +static void ldap_request_timeout_abandon(struct ldap_request *abandon) +{ + struct ldap_request *req = + talloc_get_type_abort(abandon->async.private_data, + struct ldap_request); + + if (req->state == LDAP_REQUEST_PENDING) { + DLIST_REMOVE(req->conn->pending, req); + } + req->state = LDAP_REQUEST_DONE; + if (req->async.fn) { + req->async.fn(req); + } +} + /* called on timeout of a ldap request */ @@ -683,7 +718,22 @@ static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer req->status = NT_STATUS_IO_TIMEOUT; if (req->state == LDAP_REQUEST_PENDING) { + struct ldap_message msg = { + .type = LDAP_TAG_AbandonRequest, + .r.AbandonRequest.messageid = req->messageid, + }; + struct ldap_request *abandon = NULL; + + abandon = ldap_request_send(req->conn, &msg); + if (abandon == NULL) { + ldap_error_handler(req->conn, NT_STATUS_NO_MEMORY); + return; + } + talloc_reparent(req->conn, req, abandon); + abandon->async.fn = ldap_request_timeout_abandon; + abandon->async.private_data = req; DLIST_REMOVE(req->conn->pending, req); + return; } req->state = LDAP_REQUEST_DONE; if (req->async.fn) { -- 1.9.1 From 7d56bd7fbb52c56651e2b1294a7f30675d0ff325 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Jan 2016 08:53:57 +0100 Subject: [PATCH 05/16] ldb-samba: fix the timeout setup in ildb_request_send() We need to use the startime as reference not the current time. We also allow timeout == -1 to indicate no timeout at all. Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit 5db9f865bca818da8d2334208f3141f7f5c7286d) --- lib/ldb-samba/ldb_ildap.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/ldb-samba/ldb_ildap.c b/lib/ldb-samba/ldb_ildap.c index 6ec363d..65f11db 100644 --- a/lib/ldb-samba/ldb_ildap.c +++ b/lib/ldb-samba/ldb_ildap.c @@ -418,11 +418,13 @@ static int ildb_request_send(struct ildb_context *ac, struct ldap_message *msg) return LDB_ERR_OPERATIONS_ERROR; } - talloc_free(req->time_event); - req->time_event = NULL; - if (ac->req->timeout) { - req->time_event = tevent_add_timer(ac->ildb->event_ctx, ac, - timeval_current_ofs(ac->req->timeout, 0), + TALLOC_FREE(req->time_event); + if (ac->req->timeout > 0) { + struct timeval tv = { + .tv_sec = ac->req->starttime + ac->req->timeout, + }; + + req->time_event = tevent_add_timer(ac->ildb->event_ctx, ac, tv, ildb_request_timeout, ac); } -- 1.9.1 From 67ab01228dd6515c9ae40f2ed6e2b20a9eac3f90 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Jan 2016 08:53:57 +0100 Subject: [PATCH 06/16] ldb: allow a timeout of -1 result in no timeout timer at all. This is required in order to have long running async searches, e.g. with LDB_CONTROL_NOTIFICATION_OID. Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit 2b1cd4a1147a8d5ba10ddcef4c2d258df2bd5dd4) --- lib/ldb/ldb_ldap/ldb_ldap.c | 18 +++++++++++------- lib/ldb/ldb_sqlite3/ldb_sqlite3.c | 11 +++++++---- lib/ldb/ldb_tdb/ldb_tdb.c | 14 +++++++++----- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/lib/ldb/ldb_ldap/ldb_ldap.c b/lib/ldb/ldb_ldap/ldb_ldap.c index 7e6ac90..29f8938 100644 --- a/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/lib/ldb/ldb_ldap/ldb_ldap.c @@ -252,8 +252,11 @@ static int lldb_search(struct lldb_context *lldb_ac) break; } - tv.tv_sec = req->timeout; + tv.tv_sec = 0; tv.tv_usec = 0; + if (req->timeout > 0) { + tv.tv_sec = req->timeout; + } ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, expression, @@ -836,12 +839,13 @@ static int lldb_handle_request(struct ldb_module *module, struct ldb_request *re return LDB_ERR_OPERATIONS_ERROR; } - - tv.tv_sec = req->starttime + req->timeout; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, lldb_timeout, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; + if (req->timeout > 0) { + tv.tv_sec = req->starttime + req->timeout; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, lldb_timeout, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } } return LDB_SUCCESS; diff --git a/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/lib/ldb/ldb_sqlite3/ldb_sqlite3.c index 223868a..60b39e8 100644 --- a/lib/ldb/ldb_sqlite3/ldb_sqlite3.c +++ b/lib/ldb/ldb_sqlite3/ldb_sqlite3.c @@ -1566,10 +1566,13 @@ static int lsql_handle_request(struct ldb_module *module, struct ldb_request *re return LDB_ERR_OPERATIONS_ERROR; } - tv.tv_sec = req->starttime + req->timeout; - ac->timeout_event = tevent_add_timer(ev, ac, tv, lsql_timeout, ac); - if (NULL == ac->timeout_event) { - return LDB_ERR_OPERATIONS_ERROR; + if (req->timeout > 0) { + tv.tv_sec = req->starttime + req->timeout; + tv.tv_usec = 0; + ac->timeout_event = tevent_add_timer(ev, ac, tv, lsql_timeout, ac); + if (NULL == ac->timeout_event) { + return LDB_ERR_OPERATIONS_ERROR; + } } return LDB_SUCCESS; diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c index bcb8f0f..8d1fd36 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1469,11 +1469,15 @@ static int ltdb_handle_request(struct ldb_module *module, return LDB_ERR_OPERATIONS_ERROR; } - tv.tv_sec = req->starttime + req->timeout; - ac->timeout_event = tevent_add_timer(ev, ac, tv, ltdb_timeout, ac); - if (NULL == ac->timeout_event) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; + if (req->timeout > 0) { + tv.tv_sec = req->starttime + req->timeout; + tv.tv_usec = 0; + ac->timeout_event = tevent_add_timer(ev, ac, tv, + ltdb_timeout, ac); + if (NULL == ac->timeout_event) { + talloc_free(ac); + return LDB_ERR_OPERATIONS_ERROR; + } } /* set a spy so that we do not try to use the request context -- 1.9.1 From 183f9ec6554c49b0adfe7e6766dcf498466fdc6b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 5 Jan 2016 17:59:32 +1300 Subject: [PATCH 07/16] pyldb: Free correct context when pyldb_Object_AsDn() fails Signed-off-by: Andrew Bartlett Reviewed-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit e7bdd30be54f3652cf060f4252f9eed3ea82078f) --- lib/ldb/pyldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c index 3daed96..8c3162a 100644 --- a/lib/ldb/pyldb.c +++ b/lib/ldb/pyldb.c @@ -1808,7 +1808,7 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar base = ldb_get_default_basedn(ldb_ctx); } else { if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) { - talloc_free(attrs); + talloc_free(mem_ctx); return NULL; } } -- 1.9.1 From a5b8b1a2dd4c7c152c2e73ca66714d0ddc6b948d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Jan 2016 00:05:09 +0100 Subject: [PATCH 08/16] pyldb: fix memory leak in py_ldb_search() Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit 2c2a2540f4076debdf2993781958b546c269aa49) --- lib/ldb/pyldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c index 8c3162a..dcd6cc5 100644 --- a/lib/ldb/pyldb.c +++ b/lib/ldb/pyldb.c @@ -1807,7 +1807,7 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar if (py_base == Py_None) { base = ldb_get_default_basedn(ldb_ctx); } else { - if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) { + if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) { talloc_free(mem_ctx); return NULL; } -- 1.9.1 From 23fcbc7fa4474a23c12c88b37d95003bbe253647 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Jan 2016 00:06:04 +0100 Subject: [PATCH 09/16] pyldb: fix help message for ldb.search() Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit e96fa7b10c5c6ee2cdd57c2aa553593c9372f87b) --- lib/ldb/pyldb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c index dcd6cc5..9d9d1e3 100644 --- a/lib/ldb/pyldb.c +++ b/lib/ldb/pyldb.c @@ -2003,7 +2003,7 @@ static PyMethodDef py_ldb_methods[] = { "S.rename(old_dn, new_dn, controls=None) -> None\n" "Rename an entry." }, { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS, - "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n" + "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n" "Search in a database.\n" "\n" ":param base: Optional base DN to search\n" @@ -2011,7 +2011,7 @@ static PyMethodDef py_ldb_methods[] = { ":param expression: Optional search expression\n" ":param attrs: Attributes to return (defaults to all)\n" ":param controls: Optional list of controls\n" - ":return: Iterator over Message objects\n" + ":return: ldb.Result object\n" }, { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS, NULL }, -- 1.9.1 From 113b2af1765265ff5b1a062b672c31f05c1bba37 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Jan 2016 00:06:45 +0100 Subject: [PATCH 10/16] pyldb: add ldb.search_iterator() This is able to handle async requests, e.g. with a notification control and processes results as they arrive instead of waiting for all results before returning. search_handle = ldb.search_iterator(...) for e in search_handle: if not isinstance(msg, ldb.Message): # referral continue name = e["name"][0] result = search_handle.result() Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit 77ca07801c81558d95b95e9120511cb2e00f3d03) --- lib/ldb/pyldb.c | 372 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 372 insertions(+) diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c index 9d9d1e3..eb0bf57 100644 --- a/lib/ldb/pyldb.c +++ b/lib/ldb/pyldb.c @@ -32,6 +32,27 @@ #include "ldb_private.h" #include "ldb_handlers.h" #include "pyldb.h" +#include "dlinklist.h" + +struct py_ldb_search_iterator_reply; + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + PyLdbObject *ldb; + struct { + struct ldb_request *req; + struct py_ldb_search_iterator_reply *next; + struct py_ldb_search_iterator_reply *result; + PyObject *exception; + } state; +} PyLdbSearchIteratorObject; + +struct py_ldb_search_iterator_reply { + struct py_ldb_search_iterator_reply *prev, *next; + PyLdbSearchIteratorObject *py_iter; + PyObject *obj; +}; void initldb(void); static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg); @@ -39,6 +60,7 @@ static PyObject *PyExc_LdbError; static PyTypeObject PyLdbControl; static PyTypeObject PyLdbResult; +static PyTypeObject PyLdbSearchIterator; static PyTypeObject PyLdbMessage; #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage) static PyTypeObject PyLdbModule; @@ -1869,6 +1891,200 @@ static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwar return py_ret; } +static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply) +{ + if (reply->py_iter != NULL) { + DLIST_REMOVE(reply->py_iter->state.next, reply); + if (reply->py_iter->state.result == reply) { + reply->py_iter->state.result = NULL; + } + reply->py_iter = NULL; + } + + if (reply->obj != NULL) { + Py_DECREF(reply->obj); + reply->obj = NULL; + } + + return 0; +} + +static int py_ldb_search_iterator_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context; + struct ldb_result result = { .msgs = NULL }; + struct py_ldb_search_iterator_reply *reply = NULL; + + if (ares == NULL) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->error != LDB_SUCCESS) { + int ret = ares->error; + TALLOC_FREE(ares); + return ldb_request_done(req, ret); + } + + reply = talloc_zero(py_iter->mem_ctx, + struct py_ldb_search_iterator_reply); + if (reply == NULL) { + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + reply->py_iter = py_iter; + talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor); + + switch (ares->type) { + case LDB_REPLY_ENTRY: + reply->obj = PyLdbMessage_FromMessage(ares->message); + if (reply->obj == NULL) { + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + DLIST_ADD_END(py_iter->state.next, reply); + TALLOC_FREE(ares); + return LDB_SUCCESS; + + case LDB_REPLY_REFERRAL: + reply->obj = PyStr_FromString(ares->referral); + if (reply->obj == NULL) { + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + DLIST_ADD_END(py_iter->state.next, reply); + TALLOC_FREE(ares); + return LDB_SUCCESS; + + case LDB_REPLY_DONE: + result = (struct ldb_result) { .controls = ares->controls }; + reply->obj = PyLdbResult_FromResult(&result); + if (reply->obj == NULL) { + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + py_iter->state.result = reply; + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_SUCCESS); + } + + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); +} + +static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_base = Py_None; + int scope = LDB_SCOPE_DEFAULT; + int timeout = 0; + char *expr = NULL; + PyObject *py_attrs = Py_None; + PyObject *py_controls = Py_None; + const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL }; + int ret; + const char **attrs; + struct ldb_context *ldb_ctx; + struct ldb_control **parsed_controls; + struct ldb_dn *base; + PyLdbSearchIteratorObject *py_iter; + + /* type "int" rather than "enum" for "scope" is intentional */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi", + discard_const_p(char *, kwnames), + &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout)) + return NULL; + + py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0); + if (py_iter == NULL) { + PyErr_NoMemory(); + return NULL; + } + py_iter->ldb = self; + Py_INCREF(self); + ZERO_STRUCT(py_iter->state); + py_iter->mem_ctx = talloc_new(NULL); + if (py_iter->mem_ctx == NULL) { + Py_DECREF(py_iter); + PyErr_NoMemory(); + return NULL; + } + + ldb_ctx = pyldb_Ldb_AsLdbContext(self); + + if (py_attrs == Py_None) { + attrs = NULL; + } else { + attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs"); + if (attrs == NULL) { + Py_DECREF(py_iter); + PyErr_NoMemory(); + return NULL; + } + } + + if (py_base == Py_None) { + base = ldb_get_default_basedn(ldb_ctx); + } else { + if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) { + Py_DECREF(py_iter); + PyErr_NoMemory(); + return NULL; + } + } + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = NULL; + + controls = PyList_AsStrList(py_iter->mem_ctx, + py_controls, "controls"); + if (controls == NULL) { + Py_DECREF(py_iter); + PyErr_NoMemory(); + return NULL; + } + + parsed_controls = ldb_parse_control_strings(ldb_ctx, + py_iter->mem_ctx, + controls); + if (controls[0] != NULL && parsed_controls == NULL) { + Py_DECREF(py_iter); + PyErr_NoMemory(); + return NULL; + } + talloc_free(controls); + } + + ret = ldb_build_search_req(&py_iter->state.req, + ldb_ctx, + py_iter->mem_ctx, + base, + scope, + expr, + attrs, + parsed_controls, + py_iter, + py_ldb_search_iterator_callback, + NULL); + if (ret != LDB_SUCCESS) { + Py_DECREF(py_iter); + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout); + + ret = ldb_request(ldb_ctx, py_iter->state.req); + if (ret != LDB_SUCCESS) { + Py_DECREF(py_iter); + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + return (PyObject *)py_iter; +} + static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args) { char *name; @@ -2013,6 +2229,18 @@ static PyMethodDef py_ldb_methods[] = { ":param controls: Optional list of controls\n" ":return: ldb.Result object\n" }, + { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS, + "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n" + "Search in a database.\n" + "\n" + ":param base: Optional base DN to search\n" + ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n" + ":param expression: Optional search expression\n" + ":param attrs: Attributes to return (defaults to all)\n" + ":param controls: Optional list of controls\n" + ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n" + ":return: ldb.SearchIterator object that provides results when they arrive\n" + }, { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS, NULL }, { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS, @@ -2235,6 +2463,147 @@ static PyTypeObject PyLdbResult = { .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, }; +static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self) +{ + Py_XDECREF(self->state.exception); + TALLOC_FREE(self->mem_ctx); + ZERO_STRUCT(self->state); + Py_DECREF(self->ldb); + Py_TYPE(self)->tp_free(self); +} + +static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self) +{ + PyObject *py_ret = NULL; + + if (self->state.req == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "ldb.SearchIterator request already finished"); + return NULL; + } + + /* + * TODO: do we want a non-blocking mode? + * In future we may add an optional 'nonblocking' + * argument to search_iterator(). + * + * For now we keep it simple and wait for at + * least one reply. + */ + + while (self->state.next == NULL) { + int ret; + + if (self->state.result != NULL) { + /* + * We (already) got a final result from the server. + * + * We stop the iteration and let + * py_ldb_search_iterator_result() will deliver + * the result details. + */ + TALLOC_FREE(self->state.req); + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + + ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE); + if (ret != LDB_SUCCESS) { + struct ldb_context *ldb_ctx; + TALLOC_FREE(self->state.req); + ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb); + /* + * We stop the iteration and let + * py_ldb_search_iterator_result() will deliver + * the exception. + */ + self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"), + ret, ldb_errstring(ldb_ctx)); + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + } + + py_ret = self->state.next->obj; + self->state.next->obj = NULL; + /* no TALLOC_FREE() as self->state.next is a list */ + talloc_free(self->state.next); + return py_ret; +} + +static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self) +{ + PyObject *py_ret = NULL; + + if (self->state.req != NULL) { + PyErr_SetString(PyExc_RuntimeError, + "ldb.SearchIterator request running"); + return NULL; + } + + if (self->state.next != NULL) { + PyErr_SetString(PyExc_RuntimeError, + "ldb.SearchIterator not fully consumed."); + return NULL; + } + + if (self->state.exception != NULL) { + PyErr_SetObject(PyExc_LdbError, self->state.exception); + self->state.exception = NULL; + return NULL; + } + + if (self->state.result == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "ldb.SearchIterator result already consumed"); + return NULL; + } + + py_ret = self->state.result->obj; + self->state.result->obj = NULL; + TALLOC_FREE(self->state.result); + return py_ret; +} + +static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self) +{ + if (self->state.req == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "ldb.SearchIterator request already finished"); + return NULL; + } + + Py_XDECREF(self->state.exception); + TALLOC_FREE(self->mem_ctx); + ZERO_STRUCT(self->state); + Py_RETURN_NONE; +} + +static PyMethodDef py_ldb_search_iterator_methods[] = { + { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS, + "S.result() -> ldb.Result (without msgs and referrals)\n" }, + { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS, + "S.abandon()\n" }, + { NULL } +}; + +static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self) +{ + return PyStr_FromString(""); +} + +static PyTypeObject PyLdbSearchIterator = { + .tp_name = "ldb.SearchIterator", + .tp_repr = (reprfunc)py_ldb_search_iterator_repr, + .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc, + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)py_ldb_search_iterator_next, + .tp_methods = py_ldb_search_iterator_methods, + .tp_basicsize = sizeof(PyLdbSearchIteratorObject), + .tp_doc = "LDB search_iterator.", + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; + static PyObject *py_ldb_module_repr(PyLdbModuleObject *self) { return PyStr_FromFormat("", @@ -3745,6 +4114,9 @@ static PyObject* module_init(void) if (PyType_Ready(&PyLdbResult) < 0) return NULL; + if (PyType_Ready(&PyLdbSearchIterator) < 0) + return NULL; + if (PyType_Ready(&PyLdbControl) < 0) return NULL; -- 1.9.1 From 165ebfe0a8f0c952e0cb23c57fae0a16982971b7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 1 Feb 2016 02:30:56 +0100 Subject: [PATCH 11/16] pyldb: add api tests for search_iterator() Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit 13e981d3d822876f6f6e741606dc5a772ab2cca5) --- lib/ldb/tests/python/api.py | 100 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py index af1ff03..98381fe 100755 --- a/lib/ldb/tests/python/api.py +++ b/lib/ldb/tests/python/api.py @@ -167,6 +167,106 @@ class SimpleLdb(TestCase): finally: l.delete(ldb.Dn(l, "dc=foo4")) + def test_search_iterator(self): + l = ldb.Ldb(filename()) + s = l.search_iterator() + s.abandon() + try: + for me in s: + self.fail() + self.fail() + except RuntimeError as re: + pass + try: + s.abandon() + self.fail() + except RuntimeError as re: + pass + try: + s.result() + self.fail() + except RuntimeError as re: + pass + + s = l.search_iterator() + count = 0 + for me in s: + self.assertTrue(isinstance(me, ldb.Message)) + count += 1 + r = s.result() + self.assertEqual(len(r), 0) + self.assertEqual(count, 0) + + m1 = ldb.Message() + m1.dn = ldb.Dn(l, "dc=foo4") + m1["bla"] = b"bla" + l.add(m1) + try: + s = l.search_iterator() + msgs = [] + for me in s: + self.assertTrue(isinstance(me, ldb.Message)) + count += 1 + msgs.append(me) + r = s.result() + self.assertEqual(len(r), 0) + self.assertEqual(len(msgs), 1) + self.assertEqual(msgs[0].dn, m1.dn) + + m2 = ldb.Message() + m2.dn = ldb.Dn(l, "dc=foo5") + m2["bla"] = b"bla" + l.add(m2) + + s = l.search_iterator() + msgs = [] + for me in s: + self.assertTrue(isinstance(me, ldb.Message)) + count += 1 + msgs.append(me) + r = s.result() + self.assertEqual(len(r), 0) + self.assertEqual(len(msgs), 2) + if msgs[0].dn == m1.dn: + self.assertEqual(msgs[0].dn, m1.dn) + self.assertEqual(msgs[1].dn, m2.dn) + else: + self.assertEqual(msgs[0].dn, m2.dn) + self.assertEqual(msgs[1].dn, m1.dn) + + s = l.search_iterator() + msgs = [] + for me in s: + self.assertTrue(isinstance(me, ldb.Message)) + count += 1 + msgs.append(me) + break + try: + s.result() + self.fail() + except RuntimeError as re: + pass + for me in s: + self.assertTrue(isinstance(me, ldb.Message)) + count += 1 + msgs.append(me) + break + for me in s: + self.fail() + + r = s.result() + self.assertEqual(len(r), 0) + self.assertEqual(len(msgs), 2) + if msgs[0].dn == m1.dn: + self.assertEqual(msgs[0].dn, m1.dn) + self.assertEqual(msgs[1].dn, m2.dn) + else: + self.assertEqual(msgs[0].dn, m2.dn) + self.assertEqual(msgs[1].dn, m1.dn) + finally: + l.delete(ldb.Dn(l, "dc=foo4")) + l.delete(ldb.Dn(l, "dc=foo5")) + def test_add_text(self): l = ldb.Ldb(filename()) m = ldb.Message() -- 1.9.1 From 39b44a92cafe2f92e536b0274d7465a3d743c19b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 14 Feb 2016 16:50:38 +0100 Subject: [PATCH 12/16] pyldb: eliminate warnings from python api test Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit 6c8ab59d068101caa40f9b15ed70a115b5612f47) --- lib/ldb/tests/python/api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/ldb/tests/python/api.py b/lib/ldb/tests/python/api.py index 98381fe..c2b3c89 100755 --- a/lib/ldb/tests/python/api.py +++ b/lib/ldb/tests/python/api.py @@ -670,13 +670,13 @@ class DnTests(TestCase): def test_add_child_str(self): x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe") self.assertTrue(x.add_child("bla=bloe")) - self.assertEquals("bla=bloe,dc=foo22,bar=bloe", x.__str__()) + self.assertEqual("bla=bloe,dc=foo22,bar=bloe", x.__str__()) def test_add_base_str(self): x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe") base = "bla=bloe" self.assertTrue(x.add_base(base)) - self.assertEquals("dc=foo23,bar=bloe,bla=bloe", x.__str__()) + self.assertEqual("dc=foo23,bar=bloe,bla=bloe", x.__str__()) def test_add(self): x = ldb.Dn(self.ldb, "dc=foo24") @@ -851,10 +851,10 @@ class LdbMsgTests(TestCase): "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')}).text", ]) else: - self.assertEquals( + self.assertEqual( repr(self.msg), "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})") - self.assertEquals( + self.assertEqual( repr(self.msg.text), "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])}).text") -- 1.9.1 From 99e176325521417be31527f3b4503278e6f3ac46 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 5 Feb 2016 13:55:31 +0100 Subject: [PATCH 13/16] ldb: add LDB_ATTR_FLAG_FORCE_BASE64_LDIF support This can be used to force ldb_write_ldif() to use base64 for a specific attribute. Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit f721f27da5f9ebb41639b70986ad1acb83206ed6) --- lib/ldb/common/ldb_ldif.c | 14 +++++++++++--- lib/ldb/include/ldb.h | 5 +++++ lib/ldb/pyldb.c | 5 +++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/ldb/common/ldb_ldif.c b/lib/ldb/common/ldb_ldif.c index 07de517..0aeda94b 100644 --- a/lib/ldb/common/ldb_ldif.c +++ b/lib/ldb/common/ldb_ldif.c @@ -348,13 +348,21 @@ static int ldb_ldif_write_trace(struct ldb_context *ldb, for (j=0;jelements[i].num_values;j++) { struct ldb_val v; - bool use_b64_encode; + bool use_b64_encode = false; + ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v); if (ret != LDB_SUCCESS) { v = msg->elements[i].values[j]; } - use_b64_encode = !(ldb->flags & LDB_FLG_SHOW_BINARY) - && ldb_should_b64_encode(ldb, &v); + + if (ldb->flags & LDB_FLG_SHOW_BINARY) { + use_b64_encode = false; + } else if (a->flags & LDB_ATTR_FLAG_FORCE_BASE64_LDIF) { + use_b64_encode = true; + } else { + use_b64_encode = ldb_should_b64_encode(ldb, &v); + } + if (ret != LDB_SUCCESS || use_b64_encode) { ret = fprintf_fn(private_data, "%s:: ", msg->elements[i].name); diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h index f48f753..dc0ce42 100644 --- a/lib/ldb/include/ldb.h +++ b/lib/ldb/include/ldb.h @@ -422,6 +422,11 @@ const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_c */ #define LDB_ATTR_FLAG_SINGLE_VALUE (1<<4) +/* + * The values should always be base64 encoded + */ +#define LDB_ATTR_FLAG_FORCE_BASE64_LDIF (1<<5) + /** LDAP attribute syntax for a DN diff --git a/lib/ldb/pyldb.c b/lib/ldb/pyldb.c index eb0bf57..bea837f 100644 --- a/lib/ldb/pyldb.c +++ b/lib/ldb/pyldb.c @@ -4147,6 +4147,11 @@ static PyObject* module_init(void) ADD_LDB_INT(FLAG_MOD_REPLACE); ADD_LDB_INT(FLAG_MOD_DELETE); + ADD_LDB_INT(ATTR_FLAG_HIDDEN); + ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX); + ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE); + ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF); + ADD_LDB_INT(SUCCESS); ADD_LDB_INT(ERR_OPERATIONS_ERROR); ADD_LDB_INT(ERR_PROTOCOL_ERROR); -- 1.9.1 From 4268fc662f821b6f247eb5b99aaf6a07a871aa2f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Jan 2016 09:36:56 +0100 Subject: [PATCH 14/16] ldb: add support for LDB_CONTROL_DIRSYNC_EX Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit ad2b5fae7f9b1437e6fcf73a0be3ca5d3ba0d5dc) --- lib/ldb/common/ldb_controls.c | 65 +++++++++++++++++++++++++++++++++++++++++++ lib/ldb/include/ldb.h | 2 ++ lib/ldb/tools/cmdline.c | 33 ++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/lib/ldb/common/ldb_controls.c b/lib/ldb/common/ldb_controls.c index 7346326..af056d0 100644 --- a/lib/ldb/common/ldb_controls.c +++ b/lib/ldb/common/ldb_controls.c @@ -367,6 +367,26 @@ char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *contr talloc_free(cookie); return res; } + if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_EX_OID) == 0) { + char *cookie; + struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, + struct ldb_dirsync_control); + + cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, + rep_control->cookie_len); + if (cookie == NULL) { + return NULL; + } + res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s", + LDB_CONTROL_DIRSYNC_EX_NAME, + control->critical, + rep_control->flags, + rep_control->max_attributes, + cookie); + + talloc_free(cookie); + return res; + } 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); @@ -525,6 +545,51 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO 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]; + int crit, max_attrs, ret; + uint32_t flags; + + cookie[0] = '\0'; + p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_EX_NAME)]); + ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie); + + if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) { + error_string = talloc_asprintf(mem_ctx, "invalid %s control syntax\n", + LDB_CONTROL_DIRSYNC_EX_NAME); + error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n"); + error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number, o = b64 binary blob"); + ldb_set_errstring(ldb, error_string); + talloc_free(error_string); + talloc_free(ctrl); + return NULL; + } + + /* w2k3 seems to ignore the parameter, + * but w2k sends a wrong cookie when this value is to small + * this would cause looping forever, while getting + * the same data and same cookie forever + */ + if (max_attrs == 0) max_attrs = 0x0FFFFFFF; + + ctrl->oid = LDB_CONTROL_DIRSYNC_EX_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_dirsync_control); + control->flags = flags; + control->max_attributes = max_attrs; + if (*cookie) { + control->cookie_len = ldb_base64_decode(cookie); + control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); + } else { + control->cookie = NULL; + control->cookie_len = 0; + } + ctrl->data = control; + + return ctrl; + } if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) { struct ldb_asq_control *control; diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h index dc0ce42..e715b92 100644 --- a/lib/ldb/include/ldb.h +++ b/lib/ldb/include/ldb.h @@ -657,6 +657,8 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); */ #define LDB_CONTROL_DIRSYNC_OID "1.2.840.113556.1.4.841" #define LDB_CONTROL_DIRSYNC_NAME "dirsync" +#define LDB_CONTROL_DIRSYNC_EX_OID "1.2.840.113556.1.4.2090" +#define LDB_CONTROL_DIRSYNC_EX_NAME "dirsync_ex" /** diff --git a/lib/ldb/tools/cmdline.c b/lib/ldb/tools/cmdline.c index a06445f..6d0a406 100644 --- a/lib/ldb/tools/cmdline.c +++ b/lib/ldb/tools/cmdline.c @@ -459,6 +459,39 @@ int handle_controls_reply(struct ldb_control **reply, struct ldb_control **reque continue; } + if (strcmp(LDB_CONTROL_DIRSYNC_EX_OID, reply[i]->oid) == 0) { + struct ldb_dirsync_control *rep_control, *req_control; + char *cookie; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control); + if (rep_control->cookie_len == 0) /* we are done */ + break; + + /* more processing required */ + /* let's fill in the request control with the new cookie */ + + for (j = 0; request[j]; j++) { + if (strcmp(LDB_CONTROL_DIRSYNC_EX_OID, request[j]->oid) == 0) + break; + } + /* if there's a reply control we must find a request + * control matching it */ + if (! request[j]) return -1; + + req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control); + + if (req_control->cookie) + talloc_free(req_control->cookie); + req_control->cookie = (char *)talloc_memdup( + req_control, rep_control->cookie, + rep_control->cookie_len); + req_control->cookie_len = rep_control->cookie_len; + + cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len); + printf("# DIRSYNC_EX cookie returned was:\n# %s\n", cookie); + + continue; + } /* no controls matched, throw a warning */ fprintf(stderr, "Unknown reply control oid: %s\n", reply[i]->oid); -- 1.9.1 From ec476387620005df7ad2a460c82631b281e167f2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 2 Feb 2016 10:04:20 +0100 Subject: [PATCH 15/16] ldb: version 1.1.26 * let a timeout of -1 indicate no timeout for a given request * fix memory leaks in pyldb ldb.search() * build fixes * improve pyldb ldb.search() help message * add pyldb ldb.search_iterator() api * add LDB_ATTR_FLAG_FORCE_BASE64_LDIF as optional argument to ldb_schema_attribute_add() * add client support for LDB_CONTROL_DIRSYNC_EX Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit fb705e19e8a8e727908c8913604c4cbffdb30c96) --- lib/ldb/ABI/ldb-1.1.26.sigs | 265 +++++++++++++++++++++++++++++++++ lib/ldb/ABI/pyldb-util-1.1.26.sigs | 2 + lib/ldb/ABI/pyldb-util.py3-1.1.26.sigs | 2 + lib/ldb/wscript | 2 +- 4 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 lib/ldb/ABI/ldb-1.1.26.sigs create mode 100644 lib/ldb/ABI/pyldb-util-1.1.26.sigs create mode 100644 lib/ldb/ABI/pyldb-util.py3-1.1.26.sigs diff --git a/lib/ldb/ABI/ldb-1.1.26.sigs b/lib/ldb/ABI/ldb-1.1.26.sigs new file mode 100644 index 0000000..3f33df9 --- /dev/null +++ b/lib/ldb/ABI/ldb-1.1.26.sigs @@ -0,0 +1,265 @@ +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_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_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_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +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_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_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_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_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_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +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_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +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_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_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +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 a/lib/ldb/ABI/pyldb-util-1.1.26.sigs b/lib/ldb/ABI/pyldb-util-1.1.26.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/lib/ldb/ABI/pyldb-util-1.1.26.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/lib/ldb/ABI/pyldb-util.py3-1.1.26.sigs b/lib/ldb/ABI/pyldb-util.py3-1.1.26.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/lib/ldb/ABI/pyldb-util.py3-1.1.26.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/lib/ldb/wscript b/lib/ldb/wscript index b7dd4aa..2398ff7 100755 --- a/lib/ldb/wscript +++ b/lib/ldb/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'ldb' -VERSION = '1.1.25' +VERSION = '1.1.26' blddir = 'bin' -- 1.9.1 From d0045ade38099c11cf38298ac8577a6865c3d50a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Jan 2016 09:37:13 +0100 Subject: [PATCH 16/16] s4:libcli/ldap: add support for LDB_CONTROL_DIRSYNC_EX_OID Signed-off-by: Stefan Metzmacher Reviewed-by: Garming Sam Reviewed-by: Andrew Bartlett (cherry picked from commit d104d6e04ff8ad8274db1a63f53a5c2b93e3e10b) --- source4/libcli/ldap/ldap_controls.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 448a263..14a80af 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -1256,6 +1256,7 @@ static const struct ldap_control_handler ldap_known_controls[] = { { LDB_CONTROL_SORT_RESP_OID, decode_server_sort_response, encode_server_sort_response }, { LDB_CONTROL_ASQ_OID, decode_asq_control, encode_asq_control }, { LDB_CONTROL_DIRSYNC_OID, decode_dirsync_request, encode_dirsync_request }, + { LDB_CONTROL_DIRSYNC_EX_OID, decode_dirsync_request, encode_dirsync_request }, { LDB_CONTROL_VLV_REQ_OID, decode_vlv_request, encode_vlv_request }, { LDB_CONTROL_VLV_RESP_OID, decode_vlv_response, encode_vlv_response }, { LDB_CONTROL_PERMISSIVE_MODIFY_OID, decode_flag_request, encode_flag_request }, -- 1.9.1