4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Simo Sorce 2005-2008
7 ** NOTE! The following LGPL license applies to the ldb
8 ** library. This does NOT imply that all of Samba is released
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Lesser General Public
13 License as published by the Free Software Foundation; either
14 version 3 of the License, or (at your option) any later version.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 * Component: ldb core API
30 * Description: core API routines interfacing to ldb backends
32 * Author: Andrew Tridgell
35 #define TEVENT_DEPRECATED 1
36 #include "ldb_private.h"
39 static int ldb_context_destructor(void *ptr)
41 struct ldb_context *ldb = talloc_get_type(ptr, struct ldb_context);
43 if (ldb->transaction_active) {
44 ldb_debug(ldb, LDB_DEBUG_FATAL,
45 "A transaction is still active in ldb context [%p] on %s",
46 ldb, (const char *)ldb_get_opaque(ldb, "ldb_url"));
53 this is used to catch debug messages from events
55 static void ldb_tevent_debug(void *context, enum tevent_debug_level level,
56 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
58 static void ldb_tevent_debug(void *context, enum tevent_debug_level level,
59 const char *fmt, va_list ap)
61 struct ldb_context *ldb = talloc_get_type(context, struct ldb_context);
62 enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL;
66 case TEVENT_DEBUG_FATAL:
67 ldb_level = LDB_DEBUG_FATAL;
69 case TEVENT_DEBUG_ERROR:
70 ldb_level = LDB_DEBUG_ERROR;
72 case TEVENT_DEBUG_WARNING:
73 ldb_level = LDB_DEBUG_WARNING;
75 case TEVENT_DEBUG_TRACE:
76 ldb_level = LDB_DEBUG_TRACE;
80 vasprintf(&s, fmt, ap);
82 ldb_debug(ldb, ldb_level, "tevent: %s", s);
87 initialise a ldb context
88 The mem_ctx is required
89 The event_ctx is required
91 struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx)
93 struct ldb_context *ldb;
95 const char *modules_path = getenv("LDB_MODULES_PATH");
97 if (modules_path == NULL) {
98 modules_path = LDB_MODULESDIR;
101 ret = ldb_modules_load(modules_path, LDB_VERSION);
102 if (ret != LDB_SUCCESS) {
106 ldb = talloc_zero(mem_ctx, struct ldb_context);
111 /* A new event context so that callers who don't want ldb
112 * operating on thier global event context can work without
113 * having to provide their own private one explicitly */
114 if (ev_ctx == NULL) {
115 ev_ctx = tevent_context_init(ldb);
116 tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb);
117 tevent_loop_allow_nesting(ev_ctx);
120 ret = ldb_setup_wellknown_attributes(ldb);
121 if (ret != LDB_SUCCESS) {
126 ldb_set_utf8_default(ldb);
127 ldb_set_create_perms(ldb, 0666);
128 ldb_set_modules_dir(ldb, LDB_MODULESDIR);
129 ldb_set_event_context(ldb, ev_ctx);
131 /* TODO: get timeout from options if available there */
132 ldb->default_timeout = 300; /* set default to 5 minutes */
134 talloc_set_destructor((TALLOC_CTX *)ldb, ldb_context_destructor);
140 try to autodetect a basedn if none specified. This fixes one of my
141 pet hates about ldapsearch, which is that you have to get a long,
142 complex basedn right to make any use of it.
144 void ldb_set_default_dns(struct ldb_context *ldb)
148 struct ldb_result *res;
149 struct ldb_dn *tmp_dn=NULL;
150 static const char *attrs[] = {
151 "rootDomainNamingContext",
152 "configurationNamingContext",
153 "schemaNamingContext",
154 "defaultNamingContext",
158 tmp_ctx = talloc_new(ldb);
159 ret = ldb_search(ldb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, ldb, NULL),
160 LDB_SCOPE_BASE, attrs, "(objectClass=*)");
161 if (ret != LDB_SUCCESS) {
162 talloc_free(tmp_ctx);
166 if (res->count != 1) {
167 talloc_free(tmp_ctx);
171 if (!ldb_get_opaque(ldb, "rootDomainNamingContext")) {
172 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
173 "rootDomainNamingContext");
174 ldb_set_opaque(ldb, "rootDomainNamingContext", tmp_dn);
177 if (!ldb_get_opaque(ldb, "configurationNamingContext")) {
178 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
179 "configurationNamingContext");
180 ldb_set_opaque(ldb, "configurationNamingContext", tmp_dn);
183 if (!ldb_get_opaque(ldb, "schemaNamingContext")) {
184 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
185 "schemaNamingContext");
186 ldb_set_opaque(ldb, "schemaNamingContext", tmp_dn);
189 if (!ldb_get_opaque(ldb, "defaultNamingContext")) {
190 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
191 "defaultNamingContext");
192 ldb_set_opaque(ldb, "defaultNamingContext", tmp_dn);
195 talloc_free(tmp_ctx);
198 struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb)
200 void *opaque = ldb_get_opaque(ldb, "rootDomainNamingContext");
201 return talloc_get_type(opaque, struct ldb_dn);
204 struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb)
206 void *opaque = ldb_get_opaque(ldb, "configurationNamingContext");
207 return talloc_get_type(opaque, struct ldb_dn);
210 struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb)
212 void *opaque = ldb_get_opaque(ldb, "schemaNamingContext");
213 return talloc_get_type(opaque, struct ldb_dn);
216 struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb)
218 void *opaque = ldb_get_opaque(ldb, "defaultNamingContext");
219 return talloc_get_type(opaque, struct ldb_dn);
223 connect to a database. The URL can either be one of the following forms
227 flags is made up of LDB_FLG_*
229 the options are passed uninterpreted to the backend, and are
232 int ldb_connect(struct ldb_context *ldb, const char *url,
233 unsigned int flags, const char *options[])
237 /* We seem to need to do this here, or else some utilities don't
238 * get ldb backends */
242 url2 = talloc_strdup(ldb, url);
245 return LDB_ERR_OPERATIONS_ERROR;
247 ret = ldb_set_opaque(ldb, "ldb_url", url2);
248 if (ret != LDB_SUCCESS) {
252 ret = ldb_module_connect_backend(ldb, url, options, &ldb->modules);
253 if (ret != LDB_SUCCESS) {
257 if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
258 ldb_debug(ldb, LDB_DEBUG_FATAL,
259 "Unable to load modules for %s: %s",
260 url, ldb_errstring(ldb));
261 return LDB_ERR_OTHER;
264 /* set the default base dn */
265 ldb_set_default_dns(ldb);
270 void ldb_set_errstring(struct ldb_context *ldb, const char *err_string)
272 ldb_asprintf_errstring(ldb, "%s", err_string);
275 void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...)
279 if (ldb->err_string) {
280 talloc_free(ldb->err_string);
283 va_start(ap, format);
284 ldb->err_string = talloc_vasprintf(ldb, format, ap);
287 if (ldb->flags & LDB_FLG_ENABLE_TRACING) {
288 ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_asprintf/set_errstring: %s",
293 void ldb_reset_err_string(struct ldb_context *ldb)
295 if (ldb->err_string) {
296 talloc_free(ldb->err_string);
297 ldb->err_string = NULL;
304 set an ldb error based on file:line
306 int ldb_error_at(struct ldb_context *ldb, int ecode,
307 const char *reason, const char *file, int line)
309 if (reason == NULL) {
310 reason = ldb_strerror(ecode);
312 ldb_asprintf_errstring(ldb, "%s at %s:%d", reason, file, line);
317 #define FIRST_OP_NOERR(ldb, op) do { \
318 module = ldb->modules; \
319 while (module && module->ops->op == NULL) module = module->next; \
320 if ((ldb->flags & LDB_FLG_ENABLE_TRACING) && module) { \
321 ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_trace_request: (%s)->" #op, \
322 module->ops->name); \
326 #define FIRST_OP(ldb, op) do { \
327 FIRST_OP_NOERR(ldb, op); \
328 if (module == NULL) { \
329 ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \
330 return LDB_ERR_OPERATIONS_ERROR; \
338 int ldb_transaction_start(struct ldb_context *ldb)
340 struct ldb_module *module;
343 ldb_debug(ldb, LDB_DEBUG_TRACE,
344 "start ldb transaction (nesting: %d)",
345 ldb->transaction_active);
347 /* explicit transaction active, count nested requests */
348 if (ldb->transaction_active) {
349 ldb->transaction_active++;
353 /* start a new transaction */
354 ldb->transaction_active++;
355 ldb->prepare_commit_done = false;
357 FIRST_OP(ldb, start_transaction);
359 ldb_reset_err_string(ldb);
361 status = module->ops->start_transaction(module);
362 if (status != LDB_SUCCESS) {
363 if (ldb->err_string == NULL) {
364 /* no error string was setup by the backend */
365 ldb_asprintf_errstring(ldb,
366 "ldb transaction start: %s (%d)",
367 ldb_strerror(status),
371 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
372 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s",
373 ldb_errstring(module->ldb));
379 prepare for transaction commit (first phase of two phase commit)
381 int ldb_transaction_prepare_commit(struct ldb_context *ldb)
383 struct ldb_module *module;
386 if (ldb->prepare_commit_done) {
390 /* commit only when all nested transactions are complete */
391 if (ldb->transaction_active > 1) {
395 ldb->prepare_commit_done = true;
397 if (ldb->transaction_active < 0) {
398 ldb_debug(ldb, LDB_DEBUG_FATAL,
399 "prepare commit called but no ldb transactions are active!");
400 ldb->transaction_active = 0;
401 return LDB_ERR_OPERATIONS_ERROR;
404 /* call prepare transaction if available */
405 FIRST_OP_NOERR(ldb, prepare_commit);
406 if (module == NULL) {
410 status = module->ops->prepare_commit(module);
411 if (status != LDB_SUCCESS) {
412 /* if a module fails the prepare then we need
413 to call the end transaction for everyone */
414 FIRST_OP(ldb, del_transaction);
415 module->ops->del_transaction(module);
416 if (ldb->err_string == NULL) {
417 /* no error string was setup by the backend */
418 ldb_asprintf_errstring(ldb,
419 "ldb transaction prepare commit: %s (%d)",
420 ldb_strerror(status),
423 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
424 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "prepare commit transaction error: %s",
425 ldb_errstring(module->ldb));
436 int ldb_transaction_commit(struct ldb_context *ldb)
438 struct ldb_module *module;
441 status = ldb_transaction_prepare_commit(ldb);
442 if (status != LDB_SUCCESS) {
446 ldb->transaction_active--;
448 ldb_debug(ldb, LDB_DEBUG_TRACE,
449 "commit ldb transaction (nesting: %d)",
450 ldb->transaction_active);
452 /* commit only when all nested transactions are complete */
453 if (ldb->transaction_active > 0) {
457 if (ldb->transaction_active < 0) {
458 ldb_debug(ldb, LDB_DEBUG_FATAL,
459 "commit called but no ldb transactions are active!");
460 ldb->transaction_active = 0;
461 return LDB_ERR_OPERATIONS_ERROR;
464 ldb_reset_err_string(ldb);
466 FIRST_OP(ldb, end_transaction);
467 status = module->ops->end_transaction(module);
468 if (status != LDB_SUCCESS) {
469 if (ldb->err_string == NULL) {
470 /* no error string was setup by the backend */
471 ldb_asprintf_errstring(ldb,
472 "ldb transaction commit: %s (%d)",
473 ldb_strerror(status),
476 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
477 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "commit ldb transaction error: %s",
478 ldb_errstring(module->ldb));
480 /* cancel the transaction */
481 FIRST_OP(ldb, del_transaction);
482 module->ops->del_transaction(module);
491 int ldb_transaction_cancel(struct ldb_context *ldb)
493 struct ldb_module *module;
496 ldb->transaction_active--;
498 ldb_debug(ldb, LDB_DEBUG_TRACE,
499 "cancel ldb transaction (nesting: %d)",
500 ldb->transaction_active);
502 /* really cancel only if all nested transactions are complete */
503 if (ldb->transaction_active > 0) {
507 if (ldb->transaction_active < 0) {
508 ldb_debug(ldb, LDB_DEBUG_FATAL,
509 "cancel called but no ldb transactions are active!");
510 ldb->transaction_active = 0;
511 return LDB_ERR_OPERATIONS_ERROR;
514 FIRST_OP(ldb, del_transaction);
516 status = module->ops->del_transaction(module);
517 if (status != LDB_SUCCESS) {
518 if (ldb->err_string == NULL) {
519 /* no error string was setup by the backend */
520 ldb_asprintf_errstring(ldb,
521 "ldb transaction cancel: %s (%d)",
522 ldb_strerror(status),
525 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
526 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "cancel ldb transaction error: %s",
527 ldb_errstring(module->ldb));
534 cancel a transaction with no error if no transaction is pending
535 used when we fork() to clear any parent transactions
537 int ldb_transaction_cancel_noerr(struct ldb_context *ldb)
539 if (ldb->transaction_active > 0) {
540 return ldb_transaction_cancel(ldb);
546 /* autostarts a transaction if none active */
547 static int ldb_autotransaction_request(struct ldb_context *ldb,
548 struct ldb_request *req)
552 ret = ldb_transaction_start(ldb);
553 if (ret != LDB_SUCCESS) {
557 ret = ldb_request(ldb, req);
558 if (ret == LDB_SUCCESS) {
559 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
562 if (ret == LDB_SUCCESS) {
563 return ldb_transaction_commit(ldb);
565 ldb_transaction_cancel(ldb);
567 if (ldb->err_string == NULL) {
568 /* no error string was setup by the backend */
569 ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret);
575 int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
577 struct tevent_context *ev;
581 return LDB_ERR_UNAVAILABLE;
584 if (handle->state == LDB_ASYNC_DONE) {
585 return handle->status;
588 ev = ldb_get_event_context(handle->ldb);
590 return LDB_ERR_OPERATIONS_ERROR;
595 ret = tevent_loop_once(ev);
597 return LDB_ERR_OPERATIONS_ERROR;
599 if (handle->status != LDB_SUCCESS) {
600 return handle->status;
605 while (handle->state != LDB_ASYNC_DONE) {
606 ret = tevent_loop_once(ev);
608 return LDB_ERR_OPERATIONS_ERROR;
610 if (handle->status != LDB_SUCCESS) {
611 return handle->status;
614 if (handle->status != LDB_SUCCESS) {
615 return handle->status;
623 /* set the specified timeout or, if timeout is 0 set the default timeout */
624 int ldb_set_timeout(struct ldb_context *ldb,
625 struct ldb_request *req,
628 if (req == NULL) return LDB_ERR_OPERATIONS_ERROR;
631 req->timeout = timeout;
633 req->timeout = ldb->default_timeout;
635 req->starttime = time(NULL);
640 /* calculates the new timeout based on the previous starttime and timeout */
641 int ldb_set_timeout_from_prev_req(struct ldb_context *ldb,
642 struct ldb_request *oldreq,
643 struct ldb_request *newreq)
645 if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR;
647 if (oldreq == NULL) {
648 return ldb_set_timeout(ldb, newreq, 0);
651 newreq->starttime = oldreq->starttime;
652 newreq->timeout = oldreq->timeout;
659 set the permissions for new files to be passed to open() in
660 backends that use local files
662 void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms)
664 ldb->create_perms = perms;
667 unsigned int ldb_get_create_perms(struct ldb_context *ldb)
669 return ldb->create_perms;
672 void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev)
677 struct tevent_context * ldb_get_event_context(struct ldb_context *ldb)
682 void ldb_request_set_state(struct ldb_request *req, int state)
684 req->handle->state = state;
687 int ldb_request_get_status(struct ldb_request *req)
689 return req->handle->status;
696 static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req)
698 TALLOC_CTX *tmp_ctx = talloc_new(req);
701 switch (req->operation) {
703 ldb_debug_add(ldb, "ldb_trace_request: SEARCH\n");
704 ldb_debug_add(ldb, " dn: %s\n",
705 ldb_dn_is_null(req->op.search.base)?"<rootDSE>":
706 ldb_dn_get_linearized(req->op.search.base));
707 ldb_debug_add(ldb, " scope: %s\n",
708 req->op.search.scope==LDB_SCOPE_BASE?"base":
709 req->op.search.scope==LDB_SCOPE_ONELEVEL?"one":
710 req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN");
711 ldb_debug_add(ldb, " expr: %s\n",
712 ldb_filter_from_tree(tmp_ctx, req->op.search.tree));
713 if (req->op.search.attrs == NULL) {
714 ldb_debug_add(ldb, " attr: <ALL>\n");
716 for (i=0; req->op.search.attrs[i]; i++) {
717 ldb_debug_add(ldb, " attr: %s\n", req->op.search.attrs[i]);
722 ldb_debug_add(ldb, "ldb_trace_request: DELETE\n");
723 ldb_debug_add(ldb, " dn: %s\n",
724 ldb_dn_get_linearized(req->op.del.dn));
727 ldb_debug_add(ldb, "ldb_trace_request: RENAME\n");
728 ldb_debug_add(ldb, " olddn: %s\n",
729 ldb_dn_get_linearized(req->op.rename.olddn));
730 ldb_debug_add(ldb, " newdn: %s\n",
731 ldb_dn_get_linearized(req->op.rename.newdn));
734 ldb_debug_add(ldb, "ldb_trace_request: EXTENDED\n");
735 ldb_debug_add(ldb, " oid: %s\n", req->op.extended.oid);
736 ldb_debug_add(ldb, " data: %s\n", req->op.extended.data?"yes":"no");
739 ldb_debug_add(ldb, "ldb_trace_request: ADD\n");
740 ldb_debug_add(req->handle->ldb, "%s\n",
741 ldb_ldif_message_string(req->handle->ldb, tmp_ctx,
743 req->op.add.message));
746 ldb_debug_add(ldb, "ldb_trace_request: MODIFY\n");
747 ldb_debug_add(req->handle->ldb, "%s\n",
748 ldb_ldif_message_string(req->handle->ldb, tmp_ctx,
750 req->op.mod.message));
752 case LDB_REQ_REGISTER_CONTROL:
753 ldb_debug_add(ldb, "ldb_trace_request: REGISTER_CONTROL\n");
754 ldb_debug_add(req->handle->ldb, "%s\n",
755 req->op.reg_control.oid);
757 case LDB_REQ_REGISTER_PARTITION:
758 ldb_debug_add(ldb, "ldb_trace_request: REGISTER_PARTITION\n");
759 ldb_debug_add(req->handle->ldb, "%s\n",
760 ldb_dn_get_linearized(req->op.reg_partition.dn));
763 ldb_debug_add(ldb, "ldb_trace_request: UNKNOWN(%u)\n",
768 if (req->controls == NULL) {
769 ldb_debug_add(ldb, " control: <NONE>\n");
771 for (i=0; req->controls && req->controls[i]; i++) {
772 if (req->controls[i]->oid) {
773 ldb_debug_add(ldb, " control: %s crit:%u data:%s\n",
774 req->controls[i]->oid,
775 req->controls[i]->critical,
776 req->controls[i]->data?"yes":"no");
781 ldb_debug_end(ldb, LDB_DEBUG_TRACE);
783 talloc_free(tmp_ctx);
787 check that the element flags don't have any internal bits set
789 static int ldb_msg_check_element_flags(struct ldb_context *ldb,
790 const struct ldb_message *message)
793 for (i=0; i<message->num_elements; i++) {
794 if (message->elements[i].flags & LDB_FLAG_INTERNAL_MASK) {
795 ldb_asprintf_errstring(ldb, "Invalid element flags 0x%08x on element %s in %s\n",
796 message->elements[i].flags, message->elements[i].name,
797 ldb_dn_get_linearized(message->dn));
798 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
807 NOTE: the request must be a talloc context.
808 returns LDB_ERR_* on errors.
810 int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
812 struct ldb_module *module;
815 if (req->callback == NULL) {
816 ldb_set_errstring(ldb, "Requests MUST define callbacks");
817 return LDB_ERR_UNWILLING_TO_PERFORM;
820 ldb_reset_err_string(ldb);
822 if (ldb->flags & LDB_FLG_ENABLE_TRACING) {
823 ldb_trace_request(ldb, req);
826 /* call the first module in the chain */
827 switch (req->operation) {
829 /* due to "ldb_build_search_req" base DN always != NULL */
830 if (!ldb_dn_validate(req->op.search.base)) {
831 ldb_asprintf_errstring(ldb, "ldb_search: invalid basedn '%s'",
832 ldb_dn_get_linearized(req->op.search.base));
833 return LDB_ERR_INVALID_DN_SYNTAX;
835 FIRST_OP(ldb, search);
836 ret = module->ops->search(module, req);
839 if (!ldb_dn_validate(req->op.add.message->dn)) {
840 ldb_asprintf_errstring(ldb, "ldb_add: invalid dn '%s'",
841 ldb_dn_get_linearized(req->op.add.message->dn));
842 return LDB_ERR_INVALID_DN_SYNTAX;
845 * we have to normalize here, as so many places
846 * in modules and backends assume we don't have two
847 * elements with the same name
849 ret = ldb_msg_normalize(ldb, req, req->op.add.message,
850 discard_const(&req->op.add.message));
851 if (ret != LDB_SUCCESS) {
856 ret = ldb_msg_check_element_flags(ldb, req->op.add.message);
857 if (ret != LDB_SUCCESS) {
859 * "ldb_msg_check_element_flags" generates an error
864 ret = module->ops->add(module, req);
867 if (!ldb_dn_validate(req->op.mod.message->dn)) {
868 ldb_asprintf_errstring(ldb, "ldb_modify: invalid dn '%s'",
869 ldb_dn_get_linearized(req->op.mod.message->dn));
870 return LDB_ERR_INVALID_DN_SYNTAX;
872 FIRST_OP(ldb, modify);
873 ret = ldb_msg_check_element_flags(ldb, req->op.mod.message);
874 if (ret != LDB_SUCCESS) {
876 * "ldb_msg_check_element_flags" generates an error
881 ret = module->ops->modify(module, req);
884 if (!ldb_dn_validate(req->op.del.dn)) {
885 ldb_asprintf_errstring(ldb, "ldb_delete: invalid dn '%s'",
886 ldb_dn_get_linearized(req->op.del.dn));
887 return LDB_ERR_INVALID_DN_SYNTAX;
890 ret = module->ops->del(module, req);
893 if (!ldb_dn_validate(req->op.rename.olddn)) {
894 ldb_asprintf_errstring(ldb, "ldb_rename: invalid olddn '%s'",
895 ldb_dn_get_linearized(req->op.rename.olddn));
896 return LDB_ERR_INVALID_DN_SYNTAX;
898 if (!ldb_dn_validate(req->op.rename.newdn)) {
899 ldb_asprintf_errstring(ldb, "ldb_rename: invalid newdn '%s'",
900 ldb_dn_get_linearized(req->op.rename.newdn));
901 return LDB_ERR_INVALID_DN_SYNTAX;
903 FIRST_OP(ldb, rename);
904 ret = module->ops->rename(module, req);
907 FIRST_OP(ldb, extended);
908 ret = module->ops->extended(module, req);
911 FIRST_OP(ldb, request);
912 ret = module->ops->request(module, req);
916 if ((ret != LDB_SUCCESS) && (ldb->err_string == NULL)) {
917 /* if no error string was setup by the backend */
918 ldb_asprintf_errstring(ldb, "ldb_request: %s (%d)",
919 ldb_strerror(ret), ret);
925 int ldb_request_done(struct ldb_request *req, int status)
927 req->handle->state = LDB_ASYNC_DONE;
928 req->handle->status = status;
933 search the database given a LDAP-like search expression
935 returns an LDB error code
937 Use talloc_free to free the ldb_message returned in 'res', if successful
940 int ldb_search_default_callback(struct ldb_request *req,
941 struct ldb_reply *ares)
943 struct ldb_result *res;
946 res = talloc_get_type(req->context, struct ldb_result);
949 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
951 if (ares->error != LDB_SUCCESS) {
952 return ldb_request_done(req, ares->error);
955 switch (ares->type) {
956 case LDB_REPLY_ENTRY:
957 res->msgs = talloc_realloc(res, res->msgs,
958 struct ldb_message *, res->count + 2);
960 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
963 res->msgs[res->count + 1] = NULL;
965 res->msgs[res->count] = talloc_move(res->msgs, &ares->message);
969 case LDB_REPLY_REFERRAL:
971 for (n = 0; res->refs[n]; n++) /*noop*/ ;
976 res->refs = talloc_realloc(res, res->refs, char *, n + 2);
978 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
981 res->refs[n] = talloc_move(res->refs, &ares->referral);
982 res->refs[n + 1] = NULL;
986 /* TODO: we should really support controls on entries
987 * and referrals too! */
988 res->controls = talloc_move(res, &ares->controls);
990 /* this is the last message, and means the request is done */
991 /* we have to signal and eventual ldb_wait() waiting that the
992 * async request operation was completed */
994 return ldb_request_done(req, LDB_SUCCESS);
1002 int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares)
1004 struct ldb_result *res;
1008 res = talloc_get_type(req->context, struct ldb_result);
1011 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1014 if (ares->error != LDB_SUCCESS) {
1017 return ldb_request_done(req, ret);
1020 switch (ares->type) {
1021 case LDB_REPLY_REFERRAL:
1023 for (n = 0; res->refs[n]; n++) /*noop*/ ;
1028 res->refs = talloc_realloc(res, res->refs, char *, n + 2);
1030 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1033 res->refs[n] = talloc_move(res->refs, &ares->referral);
1034 res->refs[n + 1] = NULL;
1037 case LDB_REPLY_DONE:
1039 return ldb_request_done(req, LDB_SUCCESS);
1042 ldb_set_errstring(req->handle->ldb, "Invalid reply type!");
1043 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1047 return ldb_request_done(req, LDB_SUCCESS);
1050 int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares)
1055 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1058 if (ares->error != LDB_SUCCESS) {
1061 return ldb_request_done(req, ret);
1064 if (ares->type != LDB_REPLY_DONE) {
1066 ldb_set_errstring(req->handle->ldb, "Invalid reply type!");
1067 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1071 return ldb_request_done(req, LDB_SUCCESS);
1074 int ldb_build_search_req_ex(struct ldb_request **ret_req,
1075 struct ldb_context *ldb,
1076 TALLOC_CTX *mem_ctx,
1077 struct ldb_dn *base,
1078 enum ldb_scope scope,
1079 struct ldb_parse_tree *tree,
1080 const char * const *attrs,
1081 struct ldb_control **controls,
1083 ldb_request_callback_t callback,
1084 struct ldb_request *parent)
1086 struct ldb_request *req;
1090 req = talloc(mem_ctx, struct ldb_request);
1093 return LDB_ERR_OPERATIONS_ERROR;
1096 req->operation = LDB_SEARCH;
1098 req->op.search.base = ldb_dn_new(req, ldb, NULL);
1100 req->op.search.base = base;
1102 req->op.search.scope = scope;
1104 req->op.search.tree = tree;
1105 if (req->op.search.tree == NULL) {
1106 ldb_set_errstring(ldb, "'tree' can't be NULL");
1108 return LDB_ERR_OPERATIONS_ERROR;
1111 req->op.search.attrs = attrs;
1112 req->controls = controls;
1113 req->context = context;
1114 req->callback = callback;
1116 ldb_set_timeout_from_prev_req(ldb, parent, req);
1118 req->handle = ldb_handle_new(req, ldb);
1119 if (req->handle == NULL) {
1121 return LDB_ERR_OPERATIONS_ERROR;
1125 req->handle->nesting++;
1126 req->handle->parent = parent;
1127 req->handle->flags = parent->handle->flags;
1128 req->handle->custom_flags = parent->handle->custom_flags;
1135 int ldb_build_search_req(struct ldb_request **ret_req,
1136 struct ldb_context *ldb,
1137 TALLOC_CTX *mem_ctx,
1138 struct ldb_dn *base,
1139 enum ldb_scope scope,
1140 const char *expression,
1141 const char * const *attrs,
1142 struct ldb_control **controls,
1144 ldb_request_callback_t callback,
1145 struct ldb_request *parent)
1147 struct ldb_parse_tree *tree;
1150 tree = ldb_parse_tree(mem_ctx, expression);
1152 ldb_set_errstring(ldb, "Unable to parse search expression");
1153 return LDB_ERR_OPERATIONS_ERROR;
1156 ret = ldb_build_search_req_ex(ret_req, ldb, mem_ctx, base,
1157 scope, tree, attrs, controls,
1158 context, callback, parent);
1159 if (ret == LDB_SUCCESS) {
1160 talloc_steal(*ret_req, tree);
1165 int ldb_build_add_req(struct ldb_request **ret_req,
1166 struct ldb_context *ldb,
1167 TALLOC_CTX *mem_ctx,
1168 const struct ldb_message *message,
1169 struct ldb_control **controls,
1171 ldb_request_callback_t callback,
1172 struct ldb_request *parent)
1174 struct ldb_request *req;
1178 req = talloc(mem_ctx, struct ldb_request);
1180 ldb_set_errstring(ldb, "Out of Memory");
1181 return LDB_ERR_OPERATIONS_ERROR;
1184 req->operation = LDB_ADD;
1185 req->op.add.message = message;
1186 req->controls = controls;
1187 req->context = context;
1188 req->callback = callback;
1190 ldb_set_timeout_from_prev_req(ldb, parent, req);
1192 req->handle = ldb_handle_new(req, ldb);
1193 if (req->handle == NULL) {
1195 return LDB_ERR_OPERATIONS_ERROR;
1199 req->handle->nesting++;
1200 req->handle->parent = parent;
1201 req->handle->flags = parent->handle->flags;
1202 req->handle->custom_flags = parent->handle->custom_flags;
1210 int ldb_build_mod_req(struct ldb_request **ret_req,
1211 struct ldb_context *ldb,
1212 TALLOC_CTX *mem_ctx,
1213 const struct ldb_message *message,
1214 struct ldb_control **controls,
1216 ldb_request_callback_t callback,
1217 struct ldb_request *parent)
1219 struct ldb_request *req;
1223 req = talloc(mem_ctx, struct ldb_request);
1225 ldb_set_errstring(ldb, "Out of Memory");
1226 return LDB_ERR_OPERATIONS_ERROR;
1229 req->operation = LDB_MODIFY;
1230 req->op.mod.message = message;
1231 req->controls = controls;
1232 req->context = context;
1233 req->callback = callback;
1235 ldb_set_timeout_from_prev_req(ldb, parent, req);
1237 req->handle = ldb_handle_new(req, ldb);
1238 if (req->handle == NULL) {
1240 return LDB_ERR_OPERATIONS_ERROR;
1244 req->handle->nesting++;
1245 req->handle->parent = parent;
1246 req->handle->flags = parent->handle->flags;
1247 req->handle->custom_flags = parent->handle->custom_flags;
1255 int ldb_build_del_req(struct ldb_request **ret_req,
1256 struct ldb_context *ldb,
1257 TALLOC_CTX *mem_ctx,
1259 struct ldb_control **controls,
1261 ldb_request_callback_t callback,
1262 struct ldb_request *parent)
1264 struct ldb_request *req;
1268 req = talloc(mem_ctx, struct ldb_request);
1270 ldb_set_errstring(ldb, "Out of Memory");
1271 return LDB_ERR_OPERATIONS_ERROR;
1274 req->operation = LDB_DELETE;
1275 req->op.del.dn = dn;
1276 req->controls = controls;
1277 req->context = context;
1278 req->callback = callback;
1280 ldb_set_timeout_from_prev_req(ldb, parent, req);
1282 req->handle = ldb_handle_new(req, ldb);
1283 if (req->handle == NULL) {
1285 return LDB_ERR_OPERATIONS_ERROR;
1289 req->handle->nesting++;
1290 req->handle->parent = parent;
1291 req->handle->flags = parent->handle->flags;
1292 req->handle->custom_flags = parent->handle->custom_flags;
1300 int ldb_build_rename_req(struct ldb_request **ret_req,
1301 struct ldb_context *ldb,
1302 TALLOC_CTX *mem_ctx,
1303 struct ldb_dn *olddn,
1304 struct ldb_dn *newdn,
1305 struct ldb_control **controls,
1307 ldb_request_callback_t callback,
1308 struct ldb_request *parent)
1310 struct ldb_request *req;
1314 req = talloc(mem_ctx, struct ldb_request);
1316 ldb_set_errstring(ldb, "Out of Memory");
1317 return LDB_ERR_OPERATIONS_ERROR;
1320 req->operation = LDB_RENAME;
1321 req->op.rename.olddn = olddn;
1322 req->op.rename.newdn = newdn;
1323 req->controls = controls;
1324 req->context = context;
1325 req->callback = callback;
1327 ldb_set_timeout_from_prev_req(ldb, parent, req);
1329 req->handle = ldb_handle_new(req, ldb);
1330 if (req->handle == NULL) {
1332 return LDB_ERR_OPERATIONS_ERROR;
1336 req->handle->nesting++;
1337 req->handle->parent = parent;
1338 req->handle->flags = parent->handle->flags;
1339 req->handle->custom_flags = parent->handle->custom_flags;
1347 int ldb_extended_default_callback(struct ldb_request *req,
1348 struct ldb_reply *ares)
1350 struct ldb_result *res;
1352 res = talloc_get_type(req->context, struct ldb_result);
1355 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1357 if (ares->error != LDB_SUCCESS) {
1358 return ldb_request_done(req, ares->error);
1361 if (ares->type == LDB_REPLY_DONE) {
1363 /* TODO: we should really support controls on entries and referrals too! */
1364 res->extended = talloc_move(res, &ares->response);
1365 res->controls = talloc_move(res, &ares->controls);
1368 return ldb_request_done(req, LDB_SUCCESS);
1372 ldb_set_errstring(req->handle->ldb, "Invalid reply type!");
1373 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1376 int ldb_build_extended_req(struct ldb_request **ret_req,
1377 struct ldb_context *ldb,
1378 TALLOC_CTX *mem_ctx,
1381 struct ldb_control **controls,
1383 ldb_request_callback_t callback,
1384 struct ldb_request *parent)
1386 struct ldb_request *req;
1390 req = talloc(mem_ctx, struct ldb_request);
1392 ldb_set_errstring(ldb, "Out of Memory");
1393 return LDB_ERR_OPERATIONS_ERROR;
1396 req->operation = LDB_EXTENDED;
1397 req->op.extended.oid = oid;
1398 req->op.extended.data = data;
1399 req->controls = controls;
1400 req->context = context;
1401 req->callback = callback;
1403 ldb_set_timeout_from_prev_req(ldb, parent, req);
1405 req->handle = ldb_handle_new(req, ldb);
1406 if (req->handle == NULL) {
1408 return LDB_ERR_OPERATIONS_ERROR;
1412 req->handle->nesting++;
1413 req->handle->parent = parent;
1414 req->handle->flags = parent->handle->flags;
1415 req->handle->custom_flags = parent->handle->custom_flags;
1423 int ldb_extended(struct ldb_context *ldb,
1426 struct ldb_result **_res)
1428 struct ldb_request *req;
1430 struct ldb_result *res;
1435 res = talloc_zero(ldb, struct ldb_result);
1437 return LDB_ERR_OPERATIONS_ERROR;
1440 ret = ldb_build_extended_req(&req, ldb, ldb,
1442 res, ldb_extended_default_callback,
1444 ldb_req_set_location(req, "ldb_extended");
1446 if (ret != LDB_SUCCESS) goto done;
1448 ldb_set_timeout(ldb, req, 0); /* use default timeout */
1450 ret = ldb_request(ldb, req);
1452 if (ret == LDB_SUCCESS) {
1453 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1457 if (ret != LDB_SUCCESS) {
1469 note that ldb_search() will automatically replace a NULL 'base' value
1470 with the defaultNamingContext from the rootDSE if available.
1472 int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
1473 struct ldb_result **result, struct ldb_dn *base,
1474 enum ldb_scope scope, const char * const *attrs,
1475 const char *exp_fmt, ...)
1477 struct ldb_request *req;
1478 struct ldb_result *res;
1487 res = talloc_zero(mem_ctx, struct ldb_result);
1489 return LDB_ERR_OPERATIONS_ERROR;
1493 va_start(ap, exp_fmt);
1494 expression = talloc_vasprintf(mem_ctx, exp_fmt, ap);
1499 return LDB_ERR_OPERATIONS_ERROR;
1503 ret = ldb_build_search_req(&req, ldb, mem_ctx,
1504 base?base:ldb_get_default_basedn(ldb),
1510 ldb_search_default_callback,
1512 ldb_req_set_location(req, "ldb_search");
1514 if (ret != LDB_SUCCESS) goto done;
1516 ret = ldb_request(ldb, req);
1518 if (ret == LDB_SUCCESS) {
1519 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1523 if (ret != LDB_SUCCESS) {
1528 talloc_free(expression);
1536 add a record to the database. Will fail if a record with the given class
1537 and key already exists
1539 int ldb_add(struct ldb_context *ldb,
1540 const struct ldb_message *message)
1542 struct ldb_request *req;
1545 ret = ldb_msg_sanity_check(ldb, message);
1546 if (ret != LDB_SUCCESS) {
1550 ret = ldb_build_add_req(&req, ldb, ldb,
1554 ldb_op_default_callback,
1556 ldb_req_set_location(req, "ldb_add");
1558 if (ret != LDB_SUCCESS) return ret;
1560 /* do request and autostart a transaction */
1561 ret = ldb_autotransaction_request(ldb, req);
1568 modify the specified attributes of a record
1570 int ldb_modify(struct ldb_context *ldb,
1571 const struct ldb_message *message)
1573 struct ldb_request *req;
1576 ret = ldb_msg_sanity_check(ldb, message);
1577 if (ret != LDB_SUCCESS) {
1581 ret = ldb_build_mod_req(&req, ldb, ldb,
1585 ldb_op_default_callback,
1587 ldb_req_set_location(req, "ldb_modify");
1589 if (ret != LDB_SUCCESS) return ret;
1591 /* do request and autostart a transaction */
1592 ret = ldb_autotransaction_request(ldb, req);
1600 delete a record from the database
1602 int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn)
1604 struct ldb_request *req;
1607 ret = ldb_build_del_req(&req, ldb, ldb,
1611 ldb_op_default_callback,
1613 ldb_req_set_location(req, "ldb_delete");
1615 if (ret != LDB_SUCCESS) return ret;
1617 /* do request and autostart a transaction */
1618 ret = ldb_autotransaction_request(ldb, req);
1625 rename a record in the database
1627 int ldb_rename(struct ldb_context *ldb,
1628 struct ldb_dn *olddn, struct ldb_dn *newdn)
1630 struct ldb_request *req;
1633 ret = ldb_build_rename_req(&req, ldb, ldb,
1638 ldb_op_default_callback,
1640 ldb_req_set_location(req, "ldb_rename");
1642 if (ret != LDB_SUCCESS) return ret;
1644 /* do request and autostart a transaction */
1645 ret = ldb_autotransaction_request(ldb, req);
1653 return the global sequence number
1655 int ldb_sequence_number(struct ldb_context *ldb,
1656 enum ldb_sequence_type type, uint64_t *seq_num)
1658 struct ldb_seqnum_request *seq;
1659 struct ldb_seqnum_result *seqr;
1660 struct ldb_result *res;
1661 TALLOC_CTX *tmp_ctx;
1666 tmp_ctx = talloc_zero(ldb, struct ldb_request);
1667 if (tmp_ctx == NULL) {
1668 ldb_set_errstring(ldb, "Out of Memory");
1669 return LDB_ERR_OPERATIONS_ERROR;
1671 seq = talloc_zero(tmp_ctx, struct ldb_seqnum_request);
1673 ldb_set_errstring(ldb, "Out of Memory");
1674 ret = LDB_ERR_OPERATIONS_ERROR;
1679 ret = ldb_extended(ldb, LDB_EXTENDED_SEQUENCE_NUMBER, seq, &res);
1680 if (ret != LDB_SUCCESS) {
1683 talloc_steal(tmp_ctx, res);
1685 if (strcmp(LDB_EXTENDED_SEQUENCE_NUMBER, res->extended->oid) != 0) {
1686 ldb_set_errstring(ldb, "Invalid OID in reply");
1687 ret = LDB_ERR_OPERATIONS_ERROR;
1690 seqr = talloc_get_type(res->extended->data,
1691 struct ldb_seqnum_result);
1692 *seq_num = seqr->seq_num;
1695 talloc_free(tmp_ctx);
1700 return extended error information
1702 const char *ldb_errstring(struct ldb_context *ldb)
1704 if (ldb->err_string) {
1705 return ldb->err_string;
1712 return a string explaining what a ldb error constant meancs
1714 const char *ldb_strerror(int ldb_err)
1719 case LDB_ERR_OPERATIONS_ERROR:
1720 return "Operations error";
1721 case LDB_ERR_PROTOCOL_ERROR:
1722 return "Protocol error";
1723 case LDB_ERR_TIME_LIMIT_EXCEEDED:
1724 return "Time limit exceeded";
1725 case LDB_ERR_SIZE_LIMIT_EXCEEDED:
1726 return "Size limit exceeded";
1727 case LDB_ERR_COMPARE_FALSE:
1728 return "Compare false";
1729 case LDB_ERR_COMPARE_TRUE:
1730 return "Compare true";
1731 case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED:
1732 return "Auth method not supported";
1733 case LDB_ERR_STRONG_AUTH_REQUIRED:
1734 return "Strong auth required";
1736 case LDB_ERR_REFERRAL:
1737 return "Referral error";
1738 case LDB_ERR_ADMIN_LIMIT_EXCEEDED:
1739 return "Admin limit exceeded";
1740 case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION:
1741 return "Unsupported critical extension";
1742 case LDB_ERR_CONFIDENTIALITY_REQUIRED:
1743 return "Confidentiality required";
1744 case LDB_ERR_SASL_BIND_IN_PROGRESS:
1745 return "SASL bind in progress";
1746 case LDB_ERR_NO_SUCH_ATTRIBUTE:
1747 return "No such attribute";
1748 case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE:
1749 return "Undefined attribute type";
1750 case LDB_ERR_INAPPROPRIATE_MATCHING:
1751 return "Inappropriate matching";
1752 case LDB_ERR_CONSTRAINT_VIOLATION:
1753 return "Constraint violation";
1754 case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
1755 return "Attribute or value exists";
1756 case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
1757 return "Invalid attribute syntax";
1759 case LDB_ERR_NO_SUCH_OBJECT:
1760 return "No such object";
1761 case LDB_ERR_ALIAS_PROBLEM:
1762 return "Alias problem";
1763 case LDB_ERR_INVALID_DN_SYNTAX:
1764 return "Invalid DN syntax";
1766 case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM:
1767 return "Alias dereferencing problem";
1769 case LDB_ERR_INAPPROPRIATE_AUTHENTICATION:
1770 return "Inappropriate authentication";
1771 case LDB_ERR_INVALID_CREDENTIALS:
1772 return "Invalid credentials";
1773 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1774 return "insufficient access rights";
1777 case LDB_ERR_UNAVAILABLE:
1778 return "Unavailable";
1779 case LDB_ERR_UNWILLING_TO_PERFORM:
1780 return "Unwilling to perform";
1781 case LDB_ERR_LOOP_DETECT:
1782 return "Loop detect";
1784 case LDB_ERR_NAMING_VIOLATION:
1785 return "Naming violation";
1786 case LDB_ERR_OBJECT_CLASS_VIOLATION:
1787 return "Object class violation";
1788 case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF:
1789 return "Not allowed on non-leaf";
1790 case LDB_ERR_NOT_ALLOWED_ON_RDN:
1791 return "Not allowed on RDN";
1792 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1793 return "Entry already exists";
1794 case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED:
1795 return "Object class mods prohibited";
1796 /* 70 RESERVED FOR CLDAP */
1797 case LDB_ERR_AFFECTS_MULTIPLE_DSAS:
1798 return "Affects multiple DSAs";
1804 return "Unknown error";
1808 set backend specific opaque parameters
1810 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
1812 struct ldb_opaque *o;
1814 /* allow updating an existing value */
1815 for (o=ldb->opaque;o;o=o->next) {
1816 if (strcmp(o->name, name) == 0) {
1822 o = talloc(ldb, struct ldb_opaque);
1825 return LDB_ERR_OTHER;
1827 o->next = ldb->opaque;
1835 get a previously set opaque value
1837 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
1839 struct ldb_opaque *o;
1840 for (o=ldb->opaque;o;o=o->next) {
1841 if (strcmp(o->name, name) == 0) {
1848 int ldb_global_init(void)
1850 /* Provided for compatibility with some older versions of ldb */
1854 /* return the ldb flags */
1855 unsigned int ldb_get_flags(struct ldb_context *ldb)
1860 /* set the ldb flags */
1861 void ldb_set_flags(struct ldb_context *ldb, unsigned flags)
1868 set the location in a ldb request. Used for debugging
1870 void ldb_req_set_location(struct ldb_request *req, const char *location)
1872 if (req && req->handle) {
1873 req->handle->location = location;
1878 return the location set with dsdb_req_set_location
1880 const char *ldb_req_location(struct ldb_request *req)
1882 return req->handle->location;
1886 mark a request as untrusted. This tells the rootdse module to remove
1887 unregistered controls
1889 void ldb_req_mark_untrusted(struct ldb_request *req)
1891 req->handle->flags |= LDB_HANDLE_FLAG_UNTRUSTED;
1895 mark a request as trusted.
1897 void ldb_req_mark_trusted(struct ldb_request *req)
1899 req->handle->flags &= ~LDB_HANDLE_FLAG_UNTRUSTED;
1903 set custom flags. Those flags are set by applications using ldb,
1904 they are application dependent and the same bit can have different
1905 meaning in different application.
1907 void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags)
1909 if (req != NULL && req->handle != NULL) {
1910 req->handle->custom_flags = flags;
1916 get custom flags. Those flags are set by applications using ldb,
1917 they are application dependent and the same bit can have different
1918 meaning in different application.
1920 uint32_t ldb_req_get_custom_flags(struct ldb_request *req)
1922 if (req != NULL && req->handle != NULL) {
1923 return req->handle->custom_flags;
1927 * 0 is not something any better or worse than
1928 * anything else as req or the handle is NULL
1935 return true is a request is untrusted
1937 bool ldb_req_is_untrusted(struct ldb_request *req)
1939 return (req->handle->flags & LDB_HANDLE_FLAG_UNTRUSTED) != 0;