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_error(handle->ldb, LDB_ERR_UNAVAILABLE, NULL);
584 if (handle->state == LDB_ASYNC_DONE) {
585 if ((handle->status != LDB_SUCCESS) &&
586 (handle->ldb->err_string == NULL)) {
587 /* if no error string was setup by the backend */
588 ldb_asprintf_errstring(handle->ldb, "ldb_wait: %s (%d)",
589 ldb_strerror(handle->status),
592 return handle->status;
595 ev = ldb_get_event_context(handle->ldb);
597 return ldb_oom(handle->ldb);
602 ret = tevent_loop_once(ev);
604 return ldb_operr(handle->ldb);
606 if (handle->status != LDB_SUCCESS) {
607 if (handle->ldb->err_string == NULL) {
609 * if no error string was setup by the backend
611 ldb_asprintf_errstring(handle->ldb,
613 ldb_strerror(handle->status),
616 return handle->status;
621 while (handle->state != LDB_ASYNC_DONE) {
622 ret = tevent_loop_once(ev);
624 return ldb_operr(handle->ldb);
626 if (handle->status != LDB_SUCCESS) {
627 if (handle->ldb->err_string == NULL) {
629 * if no error string was setup by the
632 ldb_asprintf_errstring(handle->ldb,
634 ldb_strerror(handle->status),
637 return handle->status;
640 if (handle->status != LDB_SUCCESS) {
641 if (handle->ldb->err_string == NULL) {
643 * if no error string was setup by the backend
645 ldb_asprintf_errstring(handle->ldb,
647 ldb_strerror(handle->status),
650 return handle->status;
658 /* set the specified timeout or, if timeout is 0 set the default timeout */
659 int ldb_set_timeout(struct ldb_context *ldb,
660 struct ldb_request *req,
663 if (req == NULL) return LDB_ERR_OPERATIONS_ERROR;
666 req->timeout = timeout;
668 req->timeout = ldb->default_timeout;
670 req->starttime = time(NULL);
675 /* calculates the new timeout based on the previous starttime and timeout */
676 int ldb_set_timeout_from_prev_req(struct ldb_context *ldb,
677 struct ldb_request *oldreq,
678 struct ldb_request *newreq)
680 if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR;
682 if (oldreq == NULL) {
683 return ldb_set_timeout(ldb, newreq, 0);
686 newreq->starttime = oldreq->starttime;
687 newreq->timeout = oldreq->timeout;
694 set the permissions for new files to be passed to open() in
695 backends that use local files
697 void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms)
699 ldb->create_perms = perms;
702 unsigned int ldb_get_create_perms(struct ldb_context *ldb)
704 return ldb->create_perms;
707 void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev)
712 struct tevent_context * ldb_get_event_context(struct ldb_context *ldb)
717 void ldb_request_set_state(struct ldb_request *req, int state)
719 req->handle->state = state;
722 int ldb_request_get_status(struct ldb_request *req)
724 return req->handle->status;
731 static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req)
733 TALLOC_CTX *tmp_ctx = talloc_new(req);
736 switch (req->operation) {
738 ldb_debug_add(ldb, "ldb_trace_request: SEARCH\n");
739 ldb_debug_add(ldb, " dn: %s\n",
740 ldb_dn_is_null(req->op.search.base)?"<rootDSE>":
741 ldb_dn_get_linearized(req->op.search.base));
742 ldb_debug_add(ldb, " scope: %s\n",
743 req->op.search.scope==LDB_SCOPE_BASE?"base":
744 req->op.search.scope==LDB_SCOPE_ONELEVEL?"one":
745 req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN");
746 ldb_debug_add(ldb, " expr: %s\n",
747 ldb_filter_from_tree(tmp_ctx, req->op.search.tree));
748 if (req->op.search.attrs == NULL) {
749 ldb_debug_add(ldb, " attr: <ALL>\n");
751 for (i=0; req->op.search.attrs[i]; i++) {
752 ldb_debug_add(ldb, " attr: %s\n", req->op.search.attrs[i]);
757 ldb_debug_add(ldb, "ldb_trace_request: DELETE\n");
758 ldb_debug_add(ldb, " dn: %s\n",
759 ldb_dn_get_linearized(req->op.del.dn));
762 ldb_debug_add(ldb, "ldb_trace_request: RENAME\n");
763 ldb_debug_add(ldb, " olddn: %s\n",
764 ldb_dn_get_linearized(req->op.rename.olddn));
765 ldb_debug_add(ldb, " newdn: %s\n",
766 ldb_dn_get_linearized(req->op.rename.newdn));
769 ldb_debug_add(ldb, "ldb_trace_request: EXTENDED\n");
770 ldb_debug_add(ldb, " oid: %s\n", req->op.extended.oid);
771 ldb_debug_add(ldb, " data: %s\n", req->op.extended.data?"yes":"no");
774 ldb_debug_add(ldb, "ldb_trace_request: ADD\n");
775 ldb_debug_add(req->handle->ldb, "%s\n",
776 ldb_ldif_message_string(req->handle->ldb, tmp_ctx,
778 req->op.add.message));
781 ldb_debug_add(ldb, "ldb_trace_request: MODIFY\n");
782 ldb_debug_add(req->handle->ldb, "%s\n",
783 ldb_ldif_message_string(req->handle->ldb, tmp_ctx,
785 req->op.mod.message));
787 case LDB_REQ_REGISTER_CONTROL:
788 ldb_debug_add(ldb, "ldb_trace_request: REGISTER_CONTROL\n");
789 ldb_debug_add(req->handle->ldb, "%s\n",
790 req->op.reg_control.oid);
792 case LDB_REQ_REGISTER_PARTITION:
793 ldb_debug_add(ldb, "ldb_trace_request: REGISTER_PARTITION\n");
794 ldb_debug_add(req->handle->ldb, "%s\n",
795 ldb_dn_get_linearized(req->op.reg_partition.dn));
798 ldb_debug_add(ldb, "ldb_trace_request: UNKNOWN(%u)\n",
803 if (req->controls == NULL) {
804 ldb_debug_add(ldb, " control: <NONE>\n");
806 for (i=0; req->controls && req->controls[i]; i++) {
807 if (req->controls[i]->oid) {
808 ldb_debug_add(ldb, " control: %s crit:%u data:%s\n",
809 req->controls[i]->oid,
810 req->controls[i]->critical,
811 req->controls[i]->data?"yes":"no");
816 ldb_debug_end(ldb, LDB_DEBUG_TRACE);
818 talloc_free(tmp_ctx);
822 check that the element flags don't have any internal bits set
824 static int ldb_msg_check_element_flags(struct ldb_context *ldb,
825 const struct ldb_message *message)
828 for (i=0; i<message->num_elements; i++) {
829 if (message->elements[i].flags & LDB_FLAG_INTERNAL_MASK) {
830 ldb_asprintf_errstring(ldb, "Invalid element flags 0x%08x on element %s in %s\n",
831 message->elements[i].flags, message->elements[i].name,
832 ldb_dn_get_linearized(message->dn));
833 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
842 NOTE: the request must be a talloc context.
843 returns LDB_ERR_* on errors.
845 int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
847 struct ldb_module *module;
850 if (req->callback == NULL) {
851 ldb_set_errstring(ldb, "Requests MUST define callbacks");
852 return LDB_ERR_UNWILLING_TO_PERFORM;
855 ldb_reset_err_string(ldb);
857 if (ldb->flags & LDB_FLG_ENABLE_TRACING) {
858 ldb_trace_request(ldb, req);
861 /* call the first module in the chain */
862 switch (req->operation) {
864 /* due to "ldb_build_search_req" base DN always != NULL */
865 if (!ldb_dn_validate(req->op.search.base)) {
866 ldb_asprintf_errstring(ldb, "ldb_search: invalid basedn '%s'",
867 ldb_dn_get_linearized(req->op.search.base));
868 return LDB_ERR_INVALID_DN_SYNTAX;
870 FIRST_OP(ldb, search);
871 ret = module->ops->search(module, req);
874 if (!ldb_dn_validate(req->op.add.message->dn)) {
875 ldb_asprintf_errstring(ldb, "ldb_add: invalid dn '%s'",
876 ldb_dn_get_linearized(req->op.add.message->dn));
877 return LDB_ERR_INVALID_DN_SYNTAX;
880 * we have to normalize here, as so many places
881 * in modules and backends assume we don't have two
882 * elements with the same name
884 ret = ldb_msg_normalize(ldb, req, req->op.add.message,
885 discard_const(&req->op.add.message));
886 if (ret != LDB_SUCCESS) {
891 ret = ldb_msg_check_element_flags(ldb, req->op.add.message);
892 if (ret != LDB_SUCCESS) {
894 * "ldb_msg_check_element_flags" generates an error
899 ret = module->ops->add(module, req);
902 if (!ldb_dn_validate(req->op.mod.message->dn)) {
903 ldb_asprintf_errstring(ldb, "ldb_modify: invalid dn '%s'",
904 ldb_dn_get_linearized(req->op.mod.message->dn));
905 return LDB_ERR_INVALID_DN_SYNTAX;
907 FIRST_OP(ldb, modify);
908 ret = ldb_msg_check_element_flags(ldb, req->op.mod.message);
909 if (ret != LDB_SUCCESS) {
911 * "ldb_msg_check_element_flags" generates an error
916 ret = module->ops->modify(module, req);
919 if (!ldb_dn_validate(req->op.del.dn)) {
920 ldb_asprintf_errstring(ldb, "ldb_delete: invalid dn '%s'",
921 ldb_dn_get_linearized(req->op.del.dn));
922 return LDB_ERR_INVALID_DN_SYNTAX;
925 ret = module->ops->del(module, req);
928 if (!ldb_dn_validate(req->op.rename.olddn)) {
929 ldb_asprintf_errstring(ldb, "ldb_rename: invalid olddn '%s'",
930 ldb_dn_get_linearized(req->op.rename.olddn));
931 return LDB_ERR_INVALID_DN_SYNTAX;
933 if (!ldb_dn_validate(req->op.rename.newdn)) {
934 ldb_asprintf_errstring(ldb, "ldb_rename: invalid newdn '%s'",
935 ldb_dn_get_linearized(req->op.rename.newdn));
936 return LDB_ERR_INVALID_DN_SYNTAX;
938 FIRST_OP(ldb, rename);
939 ret = module->ops->rename(module, req);
942 FIRST_OP(ldb, extended);
943 ret = module->ops->extended(module, req);
946 FIRST_OP(ldb, request);
947 ret = module->ops->request(module, req);
951 if ((ret != LDB_SUCCESS) && (ldb->err_string == NULL)) {
952 /* if no error string was setup by the backend */
953 ldb_asprintf_errstring(ldb, "ldb_request: %s (%d)",
954 ldb_strerror(ret), ret);
960 int ldb_request_done(struct ldb_request *req, int status)
962 req->handle->state = LDB_ASYNC_DONE;
963 req->handle->status = status;
968 search the database given a LDAP-like search expression
970 returns an LDB error code
972 Use talloc_free to free the ldb_message returned in 'res', if successful
975 int ldb_search_default_callback(struct ldb_request *req,
976 struct ldb_reply *ares)
978 struct ldb_result *res;
981 res = talloc_get_type(req->context, struct ldb_result);
984 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
986 if (ares->error != LDB_SUCCESS) {
987 return ldb_request_done(req, ares->error);
990 switch (ares->type) {
991 case LDB_REPLY_ENTRY:
992 res->msgs = talloc_realloc(res, res->msgs,
993 struct ldb_message *, res->count + 2);
995 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
998 res->msgs[res->count + 1] = NULL;
1000 res->msgs[res->count] = talloc_move(res->msgs, &ares->message);
1004 case LDB_REPLY_REFERRAL:
1006 for (n = 0; res->refs[n]; n++) /*noop*/ ;
1011 res->refs = talloc_realloc(res, res->refs, char *, n + 2);
1013 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1016 res->refs[n] = talloc_move(res->refs, &ares->referral);
1017 res->refs[n + 1] = NULL;
1020 case LDB_REPLY_DONE:
1021 /* TODO: we should really support controls on entries
1022 * and referrals too! */
1023 res->controls = talloc_move(res, &ares->controls);
1025 /* this is the last message, and means the request is done */
1026 /* we have to signal and eventual ldb_wait() waiting that the
1027 * async request operation was completed */
1029 return ldb_request_done(req, LDB_SUCCESS);
1037 int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares)
1039 struct ldb_result *res;
1043 res = talloc_get_type(req->context, struct ldb_result);
1046 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1049 if (ares->error != LDB_SUCCESS) {
1052 return ldb_request_done(req, ret);
1055 switch (ares->type) {
1056 case LDB_REPLY_REFERRAL:
1058 for (n = 0; res->refs[n]; n++) /*noop*/ ;
1063 res->refs = talloc_realloc(res, res->refs, char *, n + 2);
1065 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1068 res->refs[n] = talloc_move(res->refs, &ares->referral);
1069 res->refs[n + 1] = NULL;
1072 case LDB_REPLY_DONE:
1074 return ldb_request_done(req, LDB_SUCCESS);
1077 ldb_set_errstring(req->handle->ldb, "Invalid reply type!");
1078 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1082 return ldb_request_done(req, LDB_SUCCESS);
1085 int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares)
1090 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1093 if (ares->error != LDB_SUCCESS) {
1096 return ldb_request_done(req, ret);
1099 if (ares->type != LDB_REPLY_DONE) {
1101 ldb_set_errstring(req->handle->ldb, "Invalid reply type!");
1102 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1106 return ldb_request_done(req, LDB_SUCCESS);
1109 int ldb_build_search_req_ex(struct ldb_request **ret_req,
1110 struct ldb_context *ldb,
1111 TALLOC_CTX *mem_ctx,
1112 struct ldb_dn *base,
1113 enum ldb_scope scope,
1114 struct ldb_parse_tree *tree,
1115 const char * const *attrs,
1116 struct ldb_control **controls,
1118 ldb_request_callback_t callback,
1119 struct ldb_request *parent)
1121 struct ldb_request *req;
1125 req = talloc(mem_ctx, struct ldb_request);
1128 return LDB_ERR_OPERATIONS_ERROR;
1131 req->operation = LDB_SEARCH;
1133 req->op.search.base = ldb_dn_new(req, ldb, NULL);
1135 req->op.search.base = base;
1137 req->op.search.scope = scope;
1139 req->op.search.tree = tree;
1140 if (req->op.search.tree == NULL) {
1141 ldb_set_errstring(ldb, "'tree' can't be NULL");
1143 return LDB_ERR_OPERATIONS_ERROR;
1146 req->op.search.attrs = attrs;
1147 req->controls = controls;
1148 req->context = context;
1149 req->callback = callback;
1151 ldb_set_timeout_from_prev_req(ldb, parent, req);
1153 req->handle = ldb_handle_new(req, ldb);
1154 if (req->handle == NULL) {
1156 return LDB_ERR_OPERATIONS_ERROR;
1160 req->handle->nesting++;
1161 req->handle->parent = parent;
1162 req->handle->flags = parent->handle->flags;
1163 req->handle->custom_flags = parent->handle->custom_flags;
1170 int ldb_build_search_req(struct ldb_request **ret_req,
1171 struct ldb_context *ldb,
1172 TALLOC_CTX *mem_ctx,
1173 struct ldb_dn *base,
1174 enum ldb_scope scope,
1175 const char *expression,
1176 const char * const *attrs,
1177 struct ldb_control **controls,
1179 ldb_request_callback_t callback,
1180 struct ldb_request *parent)
1182 struct ldb_parse_tree *tree;
1185 tree = ldb_parse_tree(mem_ctx, expression);
1187 ldb_set_errstring(ldb, "Unable to parse search expression");
1188 return LDB_ERR_OPERATIONS_ERROR;
1191 ret = ldb_build_search_req_ex(ret_req, ldb, mem_ctx, base,
1192 scope, tree, attrs, controls,
1193 context, callback, parent);
1194 if (ret == LDB_SUCCESS) {
1195 talloc_steal(*ret_req, tree);
1200 int ldb_build_add_req(struct ldb_request **ret_req,
1201 struct ldb_context *ldb,
1202 TALLOC_CTX *mem_ctx,
1203 const struct ldb_message *message,
1204 struct ldb_control **controls,
1206 ldb_request_callback_t callback,
1207 struct ldb_request *parent)
1209 struct ldb_request *req;
1213 req = talloc(mem_ctx, struct ldb_request);
1215 ldb_set_errstring(ldb, "Out of Memory");
1216 return LDB_ERR_OPERATIONS_ERROR;
1219 req->operation = LDB_ADD;
1220 req->op.add.message = message;
1221 req->controls = controls;
1222 req->context = context;
1223 req->callback = callback;
1225 ldb_set_timeout_from_prev_req(ldb, parent, req);
1227 req->handle = ldb_handle_new(req, ldb);
1228 if (req->handle == NULL) {
1230 return LDB_ERR_OPERATIONS_ERROR;
1234 req->handle->nesting++;
1235 req->handle->parent = parent;
1236 req->handle->flags = parent->handle->flags;
1237 req->handle->custom_flags = parent->handle->custom_flags;
1245 int ldb_build_mod_req(struct ldb_request **ret_req,
1246 struct ldb_context *ldb,
1247 TALLOC_CTX *mem_ctx,
1248 const struct ldb_message *message,
1249 struct ldb_control **controls,
1251 ldb_request_callback_t callback,
1252 struct ldb_request *parent)
1254 struct ldb_request *req;
1258 req = talloc(mem_ctx, struct ldb_request);
1260 ldb_set_errstring(ldb, "Out of Memory");
1261 return LDB_ERR_OPERATIONS_ERROR;
1264 req->operation = LDB_MODIFY;
1265 req->op.mod.message = message;
1266 req->controls = controls;
1267 req->context = context;
1268 req->callback = callback;
1270 ldb_set_timeout_from_prev_req(ldb, parent, req);
1272 req->handle = ldb_handle_new(req, ldb);
1273 if (req->handle == NULL) {
1275 return LDB_ERR_OPERATIONS_ERROR;
1279 req->handle->nesting++;
1280 req->handle->parent = parent;
1281 req->handle->flags = parent->handle->flags;
1282 req->handle->custom_flags = parent->handle->custom_flags;
1290 int ldb_build_del_req(struct ldb_request **ret_req,
1291 struct ldb_context *ldb,
1292 TALLOC_CTX *mem_ctx,
1294 struct ldb_control **controls,
1296 ldb_request_callback_t callback,
1297 struct ldb_request *parent)
1299 struct ldb_request *req;
1303 req = talloc(mem_ctx, struct ldb_request);
1305 ldb_set_errstring(ldb, "Out of Memory");
1306 return LDB_ERR_OPERATIONS_ERROR;
1309 req->operation = LDB_DELETE;
1310 req->op.del.dn = dn;
1311 req->controls = controls;
1312 req->context = context;
1313 req->callback = callback;
1315 ldb_set_timeout_from_prev_req(ldb, parent, req);
1317 req->handle = ldb_handle_new(req, ldb);
1318 if (req->handle == NULL) {
1320 return LDB_ERR_OPERATIONS_ERROR;
1324 req->handle->nesting++;
1325 req->handle->parent = parent;
1326 req->handle->flags = parent->handle->flags;
1327 req->handle->custom_flags = parent->handle->custom_flags;
1335 int ldb_build_rename_req(struct ldb_request **ret_req,
1336 struct ldb_context *ldb,
1337 TALLOC_CTX *mem_ctx,
1338 struct ldb_dn *olddn,
1339 struct ldb_dn *newdn,
1340 struct ldb_control **controls,
1342 ldb_request_callback_t callback,
1343 struct ldb_request *parent)
1345 struct ldb_request *req;
1349 req = talloc(mem_ctx, struct ldb_request);
1351 ldb_set_errstring(ldb, "Out of Memory");
1352 return LDB_ERR_OPERATIONS_ERROR;
1355 req->operation = LDB_RENAME;
1356 req->op.rename.olddn = olddn;
1357 req->op.rename.newdn = newdn;
1358 req->controls = controls;
1359 req->context = context;
1360 req->callback = callback;
1362 ldb_set_timeout_from_prev_req(ldb, parent, req);
1364 req->handle = ldb_handle_new(req, ldb);
1365 if (req->handle == NULL) {
1367 return LDB_ERR_OPERATIONS_ERROR;
1371 req->handle->nesting++;
1372 req->handle->parent = parent;
1373 req->handle->flags = parent->handle->flags;
1374 req->handle->custom_flags = parent->handle->custom_flags;
1382 int ldb_extended_default_callback(struct ldb_request *req,
1383 struct ldb_reply *ares)
1385 struct ldb_result *res;
1387 res = talloc_get_type(req->context, struct ldb_result);
1390 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1392 if (ares->error != LDB_SUCCESS) {
1393 return ldb_request_done(req, ares->error);
1396 if (ares->type == LDB_REPLY_DONE) {
1398 /* TODO: we should really support controls on entries and referrals too! */
1399 res->extended = talloc_move(res, &ares->response);
1400 res->controls = talloc_move(res, &ares->controls);
1403 return ldb_request_done(req, LDB_SUCCESS);
1407 ldb_set_errstring(req->handle->ldb, "Invalid reply type!");
1408 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1411 int ldb_build_extended_req(struct ldb_request **ret_req,
1412 struct ldb_context *ldb,
1413 TALLOC_CTX *mem_ctx,
1416 struct ldb_control **controls,
1418 ldb_request_callback_t callback,
1419 struct ldb_request *parent)
1421 struct ldb_request *req;
1425 req = talloc(mem_ctx, struct ldb_request);
1427 ldb_set_errstring(ldb, "Out of Memory");
1428 return LDB_ERR_OPERATIONS_ERROR;
1431 req->operation = LDB_EXTENDED;
1432 req->op.extended.oid = oid;
1433 req->op.extended.data = data;
1434 req->controls = controls;
1435 req->context = context;
1436 req->callback = callback;
1438 ldb_set_timeout_from_prev_req(ldb, parent, req);
1440 req->handle = ldb_handle_new(req, ldb);
1441 if (req->handle == NULL) {
1443 return LDB_ERR_OPERATIONS_ERROR;
1447 req->handle->nesting++;
1448 req->handle->parent = parent;
1449 req->handle->flags = parent->handle->flags;
1450 req->handle->custom_flags = parent->handle->custom_flags;
1458 int ldb_extended(struct ldb_context *ldb,
1461 struct ldb_result **_res)
1463 struct ldb_request *req;
1465 struct ldb_result *res;
1470 res = talloc_zero(ldb, struct ldb_result);
1472 return LDB_ERR_OPERATIONS_ERROR;
1475 ret = ldb_build_extended_req(&req, ldb, ldb,
1477 res, ldb_extended_default_callback,
1479 ldb_req_set_location(req, "ldb_extended");
1481 if (ret != LDB_SUCCESS) goto done;
1483 ldb_set_timeout(ldb, req, 0); /* use default timeout */
1485 ret = ldb_request(ldb, req);
1487 if (ret == LDB_SUCCESS) {
1488 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1492 if (ret != LDB_SUCCESS) {
1504 note that ldb_search() will automatically replace a NULL 'base' value
1505 with the defaultNamingContext from the rootDSE if available.
1507 int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
1508 struct ldb_result **result, struct ldb_dn *base,
1509 enum ldb_scope scope, const char * const *attrs,
1510 const char *exp_fmt, ...)
1512 struct ldb_request *req;
1513 struct ldb_result *res;
1522 res = talloc_zero(mem_ctx, struct ldb_result);
1524 return LDB_ERR_OPERATIONS_ERROR;
1528 va_start(ap, exp_fmt);
1529 expression = talloc_vasprintf(mem_ctx, exp_fmt, ap);
1534 return LDB_ERR_OPERATIONS_ERROR;
1538 ret = ldb_build_search_req(&req, ldb, mem_ctx,
1539 base?base:ldb_get_default_basedn(ldb),
1545 ldb_search_default_callback,
1547 ldb_req_set_location(req, "ldb_search");
1549 if (ret != LDB_SUCCESS) goto done;
1551 ret = ldb_request(ldb, req);
1553 if (ret == LDB_SUCCESS) {
1554 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1558 if (ret != LDB_SUCCESS) {
1563 talloc_free(expression);
1571 add a record to the database. Will fail if a record with the given class
1572 and key already exists
1574 int ldb_add(struct ldb_context *ldb,
1575 const struct ldb_message *message)
1577 struct ldb_request *req;
1580 ret = ldb_msg_sanity_check(ldb, message);
1581 if (ret != LDB_SUCCESS) {
1585 ret = ldb_build_add_req(&req, ldb, ldb,
1589 ldb_op_default_callback,
1591 ldb_req_set_location(req, "ldb_add");
1593 if (ret != LDB_SUCCESS) return ret;
1595 /* do request and autostart a transaction */
1596 ret = ldb_autotransaction_request(ldb, req);
1603 modify the specified attributes of a record
1605 int ldb_modify(struct ldb_context *ldb,
1606 const struct ldb_message *message)
1608 struct ldb_request *req;
1611 ret = ldb_msg_sanity_check(ldb, message);
1612 if (ret != LDB_SUCCESS) {
1616 ret = ldb_build_mod_req(&req, ldb, ldb,
1620 ldb_op_default_callback,
1622 ldb_req_set_location(req, "ldb_modify");
1624 if (ret != LDB_SUCCESS) return ret;
1626 /* do request and autostart a transaction */
1627 ret = ldb_autotransaction_request(ldb, req);
1635 delete a record from the database
1637 int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn)
1639 struct ldb_request *req;
1642 ret = ldb_build_del_req(&req, ldb, ldb,
1646 ldb_op_default_callback,
1648 ldb_req_set_location(req, "ldb_delete");
1650 if (ret != LDB_SUCCESS) return ret;
1652 /* do request and autostart a transaction */
1653 ret = ldb_autotransaction_request(ldb, req);
1660 rename a record in the database
1662 int ldb_rename(struct ldb_context *ldb,
1663 struct ldb_dn *olddn, struct ldb_dn *newdn)
1665 struct ldb_request *req;
1668 ret = ldb_build_rename_req(&req, ldb, ldb,
1673 ldb_op_default_callback,
1675 ldb_req_set_location(req, "ldb_rename");
1677 if (ret != LDB_SUCCESS) return ret;
1679 /* do request and autostart a transaction */
1680 ret = ldb_autotransaction_request(ldb, req);
1688 return the global sequence number
1690 int ldb_sequence_number(struct ldb_context *ldb,
1691 enum ldb_sequence_type type, uint64_t *seq_num)
1693 struct ldb_seqnum_request *seq;
1694 struct ldb_seqnum_result *seqr;
1695 struct ldb_result *res;
1696 TALLOC_CTX *tmp_ctx;
1701 tmp_ctx = talloc_zero(ldb, struct ldb_request);
1702 if (tmp_ctx == NULL) {
1703 ldb_set_errstring(ldb, "Out of Memory");
1704 return LDB_ERR_OPERATIONS_ERROR;
1706 seq = talloc_zero(tmp_ctx, struct ldb_seqnum_request);
1708 ldb_set_errstring(ldb, "Out of Memory");
1709 ret = LDB_ERR_OPERATIONS_ERROR;
1714 ret = ldb_extended(ldb, LDB_EXTENDED_SEQUENCE_NUMBER, seq, &res);
1715 if (ret != LDB_SUCCESS) {
1718 talloc_steal(tmp_ctx, res);
1720 if (strcmp(LDB_EXTENDED_SEQUENCE_NUMBER, res->extended->oid) != 0) {
1721 ldb_set_errstring(ldb, "Invalid OID in reply");
1722 ret = LDB_ERR_OPERATIONS_ERROR;
1725 seqr = talloc_get_type(res->extended->data,
1726 struct ldb_seqnum_result);
1727 *seq_num = seqr->seq_num;
1730 talloc_free(tmp_ctx);
1735 return extended error information
1737 const char *ldb_errstring(struct ldb_context *ldb)
1739 if (ldb->err_string) {
1740 return ldb->err_string;
1747 return a string explaining what a ldb error constant meancs
1749 const char *ldb_strerror(int ldb_err)
1754 case LDB_ERR_OPERATIONS_ERROR:
1755 return "Operations error";
1756 case LDB_ERR_PROTOCOL_ERROR:
1757 return "Protocol error";
1758 case LDB_ERR_TIME_LIMIT_EXCEEDED:
1759 return "Time limit exceeded";
1760 case LDB_ERR_SIZE_LIMIT_EXCEEDED:
1761 return "Size limit exceeded";
1762 case LDB_ERR_COMPARE_FALSE:
1763 return "Compare false";
1764 case LDB_ERR_COMPARE_TRUE:
1765 return "Compare true";
1766 case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED:
1767 return "Auth method not supported";
1768 case LDB_ERR_STRONG_AUTH_REQUIRED:
1769 return "Strong auth required";
1771 case LDB_ERR_REFERRAL:
1772 return "Referral error";
1773 case LDB_ERR_ADMIN_LIMIT_EXCEEDED:
1774 return "Admin limit exceeded";
1775 case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION:
1776 return "Unsupported critical extension";
1777 case LDB_ERR_CONFIDENTIALITY_REQUIRED:
1778 return "Confidentiality required";
1779 case LDB_ERR_SASL_BIND_IN_PROGRESS:
1780 return "SASL bind in progress";
1781 case LDB_ERR_NO_SUCH_ATTRIBUTE:
1782 return "No such attribute";
1783 case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE:
1784 return "Undefined attribute type";
1785 case LDB_ERR_INAPPROPRIATE_MATCHING:
1786 return "Inappropriate matching";
1787 case LDB_ERR_CONSTRAINT_VIOLATION:
1788 return "Constraint violation";
1789 case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
1790 return "Attribute or value exists";
1791 case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
1792 return "Invalid attribute syntax";
1794 case LDB_ERR_NO_SUCH_OBJECT:
1795 return "No such object";
1796 case LDB_ERR_ALIAS_PROBLEM:
1797 return "Alias problem";
1798 case LDB_ERR_INVALID_DN_SYNTAX:
1799 return "Invalid DN syntax";
1801 case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM:
1802 return "Alias dereferencing problem";
1804 case LDB_ERR_INAPPROPRIATE_AUTHENTICATION:
1805 return "Inappropriate authentication";
1806 case LDB_ERR_INVALID_CREDENTIALS:
1807 return "Invalid credentials";
1808 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1809 return "insufficient access rights";
1812 case LDB_ERR_UNAVAILABLE:
1813 return "Unavailable";
1814 case LDB_ERR_UNWILLING_TO_PERFORM:
1815 return "Unwilling to perform";
1816 case LDB_ERR_LOOP_DETECT:
1817 return "Loop detect";
1819 case LDB_ERR_NAMING_VIOLATION:
1820 return "Naming violation";
1821 case LDB_ERR_OBJECT_CLASS_VIOLATION:
1822 return "Object class violation";
1823 case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF:
1824 return "Not allowed on non-leaf";
1825 case LDB_ERR_NOT_ALLOWED_ON_RDN:
1826 return "Not allowed on RDN";
1827 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1828 return "Entry already exists";
1829 case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED:
1830 return "Object class mods prohibited";
1831 /* 70 RESERVED FOR CLDAP */
1832 case LDB_ERR_AFFECTS_MULTIPLE_DSAS:
1833 return "Affects multiple DSAs";
1839 return "Unknown error";
1843 set backend specific opaque parameters
1845 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
1847 struct ldb_opaque *o;
1849 /* allow updating an existing value */
1850 for (o=ldb->opaque;o;o=o->next) {
1851 if (strcmp(o->name, name) == 0) {
1857 o = talloc(ldb, struct ldb_opaque);
1860 return LDB_ERR_OTHER;
1862 o->next = ldb->opaque;
1870 get a previously set opaque value
1872 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
1874 struct ldb_opaque *o;
1875 for (o=ldb->opaque;o;o=o->next) {
1876 if (strcmp(o->name, name) == 0) {
1883 int ldb_global_init(void)
1885 /* Provided for compatibility with some older versions of ldb */
1889 /* return the ldb flags */
1890 unsigned int ldb_get_flags(struct ldb_context *ldb)
1895 /* set the ldb flags */
1896 void ldb_set_flags(struct ldb_context *ldb, unsigned flags)
1903 set the location in a ldb request. Used for debugging
1905 void ldb_req_set_location(struct ldb_request *req, const char *location)
1907 if (req && req->handle) {
1908 req->handle->location = location;
1913 return the location set with dsdb_req_set_location
1915 const char *ldb_req_location(struct ldb_request *req)
1917 return req->handle->location;
1921 mark a request as untrusted. This tells the rootdse module to remove
1922 unregistered controls
1924 void ldb_req_mark_untrusted(struct ldb_request *req)
1926 req->handle->flags |= LDB_HANDLE_FLAG_UNTRUSTED;
1930 mark a request as trusted.
1932 void ldb_req_mark_trusted(struct ldb_request *req)
1934 req->handle->flags &= ~LDB_HANDLE_FLAG_UNTRUSTED;
1938 set custom flags. Those flags are set by applications using ldb,
1939 they are application dependent and the same bit can have different
1940 meaning in different application.
1942 void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags)
1944 if (req != NULL && req->handle != NULL) {
1945 req->handle->custom_flags = flags;
1951 get custom flags. Those flags are set by applications using ldb,
1952 they are application dependent and the same bit can have different
1953 meaning in different application.
1955 uint32_t ldb_req_get_custom_flags(struct ldb_request *req)
1957 if (req != NULL && req->handle != NULL) {
1958 return req->handle->custom_flags;
1962 * 0 is not something any better or worse than
1963 * anything else as req or the handle is NULL
1970 return true is a request is untrusted
1972 bool ldb_req_is_untrusted(struct ldb_request *req)
1974 return (req->handle->flags & LDB_HANDLE_FLAG_UNTRUSTED) != 0;