source: vendor/current/lib/ldb/common/ldb.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 47.0 KB
Line 
1/*
2 ldb database library
3
4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Simo Sorce 2005-2008
6
7 ** NOTE! The following LGPL license applies to the ldb
8 ** library. This does NOT imply that all of Samba is released
9 ** under the LGPL
10
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.
15
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.
20
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/>.
23*/
24
25/*
26 * Name: ldb
27 *
28 * Component: ldb core API
29 *
30 * Description: core API routines interfacing to ldb backends
31 *
32 * Author: Andrew Tridgell
33 */
34
35#define TEVENT_DEPRECATED 1
36#include "ldb_private.h"
37#include "ldb.h"
38
39static int ldb_context_destructor(void *ptr)
40{
41 struct ldb_context *ldb = talloc_get_type(ptr, struct ldb_context);
42
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"));
47 }
48
49 return 0;
50}
51
52/*
53 this is used to catch debug messages from events
54*/
55static void ldb_tevent_debug(void *context, enum tevent_debug_level level,
56 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
57
58static void ldb_tevent_debug(void *context, enum tevent_debug_level level,
59 const char *fmt, va_list ap)
60{
61 struct ldb_context *ldb = talloc_get_type(context, struct ldb_context);
62 enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL;
63
64 switch (level) {
65 case TEVENT_DEBUG_FATAL:
66 ldb_level = LDB_DEBUG_FATAL;
67 break;
68 case TEVENT_DEBUG_ERROR:
69 ldb_level = LDB_DEBUG_ERROR;
70 break;
71 case TEVENT_DEBUG_WARNING:
72 ldb_level = LDB_DEBUG_WARNING;
73 break;
74 case TEVENT_DEBUG_TRACE:
75 ldb_level = LDB_DEBUG_TRACE;
76 break;
77 };
78
79 /* There isn't a tevent: prefix here because to add it means
80 * actually printing the string, and most of the time we don't
81 * want to show it */
82 ldb_vdebug(ldb, ldb_level, fmt, ap);
83}
84
85/*
86 initialise a ldb context
87 The mem_ctx is required
88 The event_ctx is required
89*/
90struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx)
91{
92 struct ldb_context *ldb;
93 int ret;
94 const char *modules_path = getenv("LDB_MODULES_PATH");
95
96 if (modules_path == NULL) {
97 modules_path = LDB_MODULESDIR;
98 }
99
100 ret = ldb_modules_load(modules_path, LDB_VERSION);
101 if (ret != LDB_SUCCESS) {
102 return NULL;
103 }
104
105 ldb = talloc_zero(mem_ctx, struct ldb_context);
106 if (ldb == NULL) {
107 return NULL;
108 }
109
110 /* A new event context so that callers who don't want ldb
111 * operating on thier global event context can work without
112 * having to provide their own private one explicitly */
113 if (ev_ctx == NULL) {
114 ev_ctx = tevent_context_init(ldb);
115 if (ev_ctx == NULL) {
116 talloc_free(ldb);
117 return NULL;
118 }
119 tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb);
120 tevent_loop_allow_nesting(ev_ctx);
121 }
122
123 ret = ldb_setup_wellknown_attributes(ldb);
124 if (ret != LDB_SUCCESS) {
125 talloc_free(ldb);
126 return NULL;
127 }
128
129 ldb_set_utf8_default(ldb);
130 ldb_set_create_perms(ldb, 0666);
131 ldb_set_modules_dir(ldb, LDB_MODULESDIR);
132 ldb_set_event_context(ldb, ev_ctx);
133 ret = ldb_register_extended_match_rules(ldb);
134 if (ret != LDB_SUCCESS) {
135 talloc_free(ldb);
136 return NULL;
137 }
138
139 /* TODO: get timeout from options if available there */
140 ldb->default_timeout = 300; /* set default to 5 minutes */
141
142 talloc_set_destructor((TALLOC_CTX *)ldb, ldb_context_destructor);
143
144 return ldb;
145}
146
147/*
148 try to autodetect a basedn if none specified. This fixes one of my
149 pet hates about ldapsearch, which is that you have to get a long,
150 complex basedn right to make any use of it.
151*/
152void ldb_set_default_dns(struct ldb_context *ldb)
153{
154 TALLOC_CTX *tmp_ctx;
155 int ret;
156 struct ldb_result *res;
157 struct ldb_dn *tmp_dn=NULL;
158 static const char *attrs[] = {
159 "rootDomainNamingContext",
160 "configurationNamingContext",
161 "schemaNamingContext",
162 "defaultNamingContext",
163 NULL
164 };
165
166 tmp_ctx = talloc_new(ldb);
167 ret = ldb_search(ldb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, ldb, NULL),
168 LDB_SCOPE_BASE, attrs, "(objectClass=*)");
169 if (ret != LDB_SUCCESS) {
170 talloc_free(tmp_ctx);
171 return;
172 }
173
174 if (res->count != 1) {
175 talloc_free(tmp_ctx);
176 return;
177 }
178
179 if (!ldb_get_opaque(ldb, "rootDomainNamingContext")) {
180 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
181 "rootDomainNamingContext");
182 ldb_set_opaque(ldb, "rootDomainNamingContext", tmp_dn);
183 }
184
185 if (!ldb_get_opaque(ldb, "configurationNamingContext")) {
186 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
187 "configurationNamingContext");
188 ldb_set_opaque(ldb, "configurationNamingContext", tmp_dn);
189 }
190
191 if (!ldb_get_opaque(ldb, "schemaNamingContext")) {
192 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
193 "schemaNamingContext");
194 ldb_set_opaque(ldb, "schemaNamingContext", tmp_dn);
195 }
196
197 if (!ldb_get_opaque(ldb, "defaultNamingContext")) {
198 tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0],
199 "defaultNamingContext");
200 ldb_set_opaque(ldb, "defaultNamingContext", tmp_dn);
201 }
202
203 talloc_free(tmp_ctx);
204}
205
206struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb)
207{
208 void *opaque = ldb_get_opaque(ldb, "rootDomainNamingContext");
209 return talloc_get_type(opaque, struct ldb_dn);
210}
211
212struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb)
213{
214 void *opaque = ldb_get_opaque(ldb, "configurationNamingContext");
215 return talloc_get_type(opaque, struct ldb_dn);
216}
217
218struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb)
219{
220 void *opaque = ldb_get_opaque(ldb, "schemaNamingContext");
221 return talloc_get_type(opaque, struct ldb_dn);
222}
223
224struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb)
225{
226 void *opaque = ldb_get_opaque(ldb, "defaultNamingContext");
227 return talloc_get_type(opaque, struct ldb_dn);
228}
229
230/*
231 connect to a database. The URL can either be one of the following forms
232 ldb://path
233 ldapi://path
234
235 flags is made up of LDB_FLG_*
236
237 the options are passed uninterpreted to the backend, and are
238 backend specific
239*/
240int ldb_connect(struct ldb_context *ldb, const char *url,
241 unsigned int flags, const char *options[])
242{
243 int ret;
244 char *url2;
245 /* We seem to need to do this here, or else some utilities don't
246 * get ldb backends */
247
248 ldb->flags = flags;
249
250 url2 = talloc_strdup(ldb, url);
251 if (!url2) {
252 ldb_oom(ldb);
253 return LDB_ERR_OPERATIONS_ERROR;
254 }
255 ret = ldb_set_opaque(ldb, "ldb_url", url2);
256 if (ret != LDB_SUCCESS) {
257 return ret;
258 }
259
260 ret = ldb_module_connect_backend(ldb, url, options, &ldb->modules);
261 if (ret != LDB_SUCCESS) {
262 return ret;
263 }
264
265 ret = ldb_load_modules(ldb, options);
266 if (ret != LDB_SUCCESS) {
267 ldb_debug(ldb, LDB_DEBUG_FATAL,
268 "Unable to load modules for %s: %s",
269 url, ldb_errstring(ldb));
270 return ret;
271 }
272
273 /* set the default base dn */
274 ldb_set_default_dns(ldb);
275
276 return LDB_SUCCESS;
277}
278
279void ldb_set_errstring(struct ldb_context *ldb, const char *err_string)
280{
281 ldb_asprintf_errstring(ldb, "%s", err_string);
282}
283
284void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...)
285{
286 va_list ap;
287
288 if (ldb->err_string) {
289 talloc_free(ldb->err_string);
290 }
291
292 va_start(ap, format);
293 ldb->err_string = talloc_vasprintf(ldb, format, ap);
294 va_end(ap);
295
296 if (ldb->flags & LDB_FLG_ENABLE_TRACING) {
297 ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_asprintf/set_errstring: %s",
298 ldb->err_string);
299 }
300}
301
302void ldb_reset_err_string(struct ldb_context *ldb)
303{
304 if (ldb->err_string) {
305 talloc_free(ldb->err_string);
306 ldb->err_string = NULL;
307 }
308}
309
310
311
312/*
313 set an ldb error based on file:line
314*/
315int ldb_error_at(struct ldb_context *ldb, int ecode,
316 const char *reason, const char *file, int line)
317{
318 if (reason == NULL) {
319 reason = ldb_strerror(ecode);
320 }
321 ldb_asprintf_errstring(ldb, "%s at %s:%d", reason, file, line);
322 return ecode;
323}
324
325
326#define FIRST_OP_NOERR(ldb, op) do { \
327 module = ldb->modules; \
328 while (module && module->ops->op == NULL) module = module->next; \
329 if ((ldb->flags & LDB_FLG_ENABLE_TRACING) && module) { \
330 ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_trace_request: (%s)->" #op, \
331 module->ops->name); \
332 } \
333} while (0)
334
335#define FIRST_OP(ldb, op) do { \
336 FIRST_OP_NOERR(ldb, op); \
337 if (module == NULL) { \
338 ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \
339 return LDB_ERR_OPERATIONS_ERROR; \
340 } \
341} while (0)
342
343
344/*
345 start a transaction
346*/
347int ldb_transaction_start(struct ldb_context *ldb)
348{
349 struct ldb_module *module;
350 int status;
351
352 ldb_debug(ldb, LDB_DEBUG_TRACE,
353 "start ldb transaction (nesting: %d)",
354 ldb->transaction_active);
355
356 /* explicit transaction active, count nested requests */
357 if (ldb->transaction_active) {
358 ldb->transaction_active++;
359 return LDB_SUCCESS;
360 }
361
362 /* start a new transaction */
363 ldb->transaction_active++;
364 ldb->prepare_commit_done = false;
365
366 FIRST_OP(ldb, start_transaction);
367
368 ldb_reset_err_string(ldb);
369
370 status = module->ops->start_transaction(module);
371 if (status != LDB_SUCCESS) {
372 if (ldb->err_string == NULL) {
373 /* no error string was setup by the backend */
374 ldb_asprintf_errstring(ldb,
375 "ldb transaction start: %s (%d)",
376 ldb_strerror(status),
377 status);
378 }
379 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
380 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s",
381 ldb_errstring(module->ldb));
382 }
383 } else {
384 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
385 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "start ldb transaction success");
386 }
387 }
388 return status;
389}
390
391/*
392 prepare for transaction commit (first phase of two phase commit)
393*/
394int ldb_transaction_prepare_commit(struct ldb_context *ldb)
395{
396 struct ldb_module *module;
397 int status;
398
399 if (ldb->prepare_commit_done) {
400 return LDB_SUCCESS;
401 }
402
403 /* commit only when all nested transactions are complete */
404 if (ldb->transaction_active > 1) {
405 return LDB_SUCCESS;
406 }
407
408 ldb->prepare_commit_done = true;
409
410 if (ldb->transaction_active < 0) {
411 ldb_debug(ldb, LDB_DEBUG_FATAL,
412 "prepare commit called but no ldb transactions are active!");
413 ldb->transaction_active = 0;
414 return LDB_ERR_OPERATIONS_ERROR;
415 }
416
417 /* call prepare transaction if available */
418 FIRST_OP_NOERR(ldb, prepare_commit);
419 if (module == NULL) {
420 return LDB_SUCCESS;
421 }
422
423 status = module->ops->prepare_commit(module);
424 if (status != LDB_SUCCESS) {
425 ldb->transaction_active--;
426 /* if a module fails the prepare then we need
427 to call the end transaction for everyone */
428 FIRST_OP(ldb, del_transaction);
429 module->ops->del_transaction(module);
430 if (ldb->err_string == NULL) {
431 /* no error string was setup by the backend */
432 ldb_asprintf_errstring(ldb,
433 "ldb transaction prepare commit: %s (%d)",
434 ldb_strerror(status),
435 status);
436 }
437 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
438 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "prepare commit transaction error: %s",
439 ldb_errstring(module->ldb));
440 }
441 }
442
443 return status;
444}
445
446
447/*
448 commit a transaction
449*/
450int ldb_transaction_commit(struct ldb_context *ldb)
451{
452 struct ldb_module *module;
453 int status;
454
455 status = ldb_transaction_prepare_commit(ldb);
456 if (status != LDB_SUCCESS) {
457 return status;
458 }
459
460 ldb->transaction_active--;
461
462 ldb_debug(ldb, LDB_DEBUG_TRACE,
463 "commit ldb transaction (nesting: %d)",
464 ldb->transaction_active);
465
466 /* commit only when all nested transactions are complete */
467 if (ldb->transaction_active > 0) {
468 return LDB_SUCCESS;
469 }
470
471 if (ldb->transaction_active < 0) {
472 ldb_debug(ldb, LDB_DEBUG_FATAL,
473 "commit called but no ldb transactions are active!");
474 ldb->transaction_active = 0;
475 return LDB_ERR_OPERATIONS_ERROR;
476 }
477
478 ldb_reset_err_string(ldb);
479
480 FIRST_OP(ldb, end_transaction);
481 status = module->ops->end_transaction(module);
482 if (status != LDB_SUCCESS) {
483 if (ldb->err_string == NULL) {
484 /* no error string was setup by the backend */
485 ldb_asprintf_errstring(ldb,
486 "ldb transaction commit: %s (%d)",
487 ldb_strerror(status),
488 status);
489 }
490 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
491 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "commit ldb transaction error: %s",
492 ldb_errstring(module->ldb));
493 }
494 /* cancel the transaction */
495 FIRST_OP(ldb, del_transaction);
496 module->ops->del_transaction(module);
497 }
498 return status;
499}
500
501
502/*
503 cancel a transaction
504*/
505int ldb_transaction_cancel(struct ldb_context *ldb)
506{
507 struct ldb_module *module;
508 int status;
509
510 ldb->transaction_active--;
511
512 ldb_debug(ldb, LDB_DEBUG_TRACE,
513 "cancel ldb transaction (nesting: %d)",
514 ldb->transaction_active);
515
516 /* really cancel only if all nested transactions are complete */
517 if (ldb->transaction_active > 0) {
518 return LDB_SUCCESS;
519 }
520
521 if (ldb->transaction_active < 0) {
522 ldb_debug(ldb, LDB_DEBUG_FATAL,
523 "cancel called but no ldb transactions are active!");
524 ldb->transaction_active = 0;
525 return LDB_ERR_OPERATIONS_ERROR;
526 }
527
528 FIRST_OP(ldb, del_transaction);
529
530 status = module->ops->del_transaction(module);
531 if (status != LDB_SUCCESS) {
532 if (ldb->err_string == NULL) {
533 /* no error string was setup by the backend */
534 ldb_asprintf_errstring(ldb,
535 "ldb transaction cancel: %s (%d)",
536 ldb_strerror(status),
537 status);
538 }
539 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) {
540 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "cancel ldb transaction error: %s",
541 ldb_errstring(module->ldb));
542 }
543 }
544 return status;
545}
546
547/*
548 cancel a transaction with no error if no transaction is pending
549 used when we fork() to clear any parent transactions
550*/
551int ldb_transaction_cancel_noerr(struct ldb_context *ldb)
552{
553 if (ldb->transaction_active > 0) {
554 return ldb_transaction_cancel(ldb);
555 }
556 return LDB_SUCCESS;
557}
558
559
560/* autostarts a transaction if none active */
561static int ldb_autotransaction_request(struct ldb_context *ldb,
562 struct ldb_request *req)
563{
564 int ret;
565
566 ret = ldb_transaction_start(ldb);
567 if (ret != LDB_SUCCESS) {
568 return ret;
569 }
570
571 ret = ldb_request(ldb, req);
572 if (ret == LDB_SUCCESS) {
573 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
574 }
575
576 if (ret == LDB_SUCCESS) {
577 return ldb_transaction_commit(ldb);
578 }
579 ldb_transaction_cancel(ldb);
580
581 return ret;
582}
583
584int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
585{
586 struct tevent_context *ev;
587 int ret;
588
589 if (handle == NULL) {
590 return LDB_ERR_UNAVAILABLE;
591 }
592
593 if (handle->state == LDB_ASYNC_DONE) {
594 if ((handle->status != LDB_SUCCESS) &&
595 (handle->ldb->err_string == NULL)) {
596 /* if no error string was setup by the backend */
597 ldb_asprintf_errstring(handle->ldb, "ldb_wait: %s (%d)",
598 ldb_strerror(handle->status),
599 handle->status);
600 }
601 return handle->status;
602 }
603
604 ev = ldb_get_event_context(handle->ldb);
605 if (NULL == ev) {
606 return ldb_oom(handle->ldb);
607 }
608
609 switch (type) {
610 case LDB_WAIT_NONE:
611 ret = tevent_loop_once(ev);
612 if (ret != 0) {
613 return ldb_operr(handle->ldb);
614 }
615 if (handle->status != LDB_SUCCESS) {
616 if (handle->ldb->err_string == NULL) {
617 /*
618 * if no error string was setup by the backend
619 */
620 ldb_asprintf_errstring(handle->ldb,
621 "ldb_wait: %s (%d)",
622 ldb_strerror(handle->status),
623 handle->status);
624 }
625 return handle->status;
626 }
627 break;
628
629 case LDB_WAIT_ALL:
630 while (handle->state != LDB_ASYNC_DONE) {
631 ret = tevent_loop_once(ev);
632 if (ret != 0) {
633 return ldb_operr(handle->ldb);
634 }
635 if (handle->status != LDB_SUCCESS) {
636 if (handle->ldb->err_string == NULL) {
637 /*
638 * if no error string was setup by the
639 * backend
640 */
641 ldb_asprintf_errstring(handle->ldb,
642 "ldb_wait: %s (%d)",
643 ldb_strerror(handle->status),
644 handle->status);
645 }
646 return handle->status;
647 }
648 }
649 if (handle->status != LDB_SUCCESS) {
650 if (handle->ldb->err_string == NULL) {
651 /*
652 * if no error string was setup by the backend
653 */
654 ldb_asprintf_errstring(handle->ldb,
655 "ldb_wait: %s (%d)",
656 ldb_strerror(handle->status),
657 handle->status);
658 }
659 return handle->status;
660 }
661 break;
662 }
663
664 return LDB_SUCCESS;
665}
666
667/* set the specified timeout or, if timeout is 0 set the default timeout */
668int ldb_set_timeout(struct ldb_context *ldb,
669 struct ldb_request *req,
670 int timeout)
671{
672 if (req == NULL) return LDB_ERR_OPERATIONS_ERROR;
673
674 if (timeout != 0) {
675 req->timeout = timeout;
676 } else {
677 req->timeout = ldb->default_timeout;
678 }
679 req->starttime = time(NULL);
680
681 return LDB_SUCCESS;
682}
683
684/* calculates the new timeout based on the previous starttime and timeout */
685int ldb_set_timeout_from_prev_req(struct ldb_context *ldb,
686 struct ldb_request *oldreq,
687 struct ldb_request *newreq)
688{
689 if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR;
690
691 if (oldreq == NULL) {
692 return ldb_set_timeout(ldb, newreq, 0);
693 }
694
695 newreq->starttime = oldreq->starttime;
696 newreq->timeout = oldreq->timeout;
697
698 return LDB_SUCCESS;
699}
700
701
702/*
703 set the permissions for new files to be passed to open() in
704 backends that use local files
705 */
706void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms)
707{
708 ldb->create_perms = perms;
709}
710
711unsigned int ldb_get_create_perms(struct ldb_context *ldb)
712{
713 return ldb->create_perms;
714}
715
716void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev)
717{
718 ldb->ev_ctx = ev;
719}
720
721struct tevent_context * ldb_get_event_context(struct ldb_context *ldb)
722{
723 return ldb->ev_ctx;
724}
725
726void ldb_request_set_state(struct ldb_request *req, int state)
727{
728 req->handle->state = state;
729}
730
731int ldb_request_get_status(struct ldb_request *req)
732{
733 return req->handle->status;
734}
735
736
737/*
738 trace a ldb request
739*/
740static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req)
741{
742 TALLOC_CTX *tmp_ctx = talloc_new(req);
743 unsigned int i;
744 struct ldb_ldif ldif;
745
746 switch (req->operation) {
747 case LDB_SEARCH:
748 ldb_debug_add(ldb, "ldb_trace_request: SEARCH\n");
749 ldb_debug_add(ldb, " dn: %s\n",
750 ldb_dn_is_null(req->op.search.base)?"<rootDSE>":
751 ldb_dn_get_linearized(req->op.search.base));
752 ldb_debug_add(ldb, " scope: %s\n",
753 req->op.search.scope==LDB_SCOPE_BASE?"base":
754 req->op.search.scope==LDB_SCOPE_ONELEVEL?"one":
755 req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN");
756 ldb_debug_add(ldb, " expr: %s\n",
757 ldb_filter_from_tree(tmp_ctx, req->op.search.tree));
758 if (req->op.search.attrs == NULL) {
759 ldb_debug_add(ldb, " attr: <ALL>\n");
760 } else {
761 for (i=0; req->op.search.attrs[i]; i++) {
762 ldb_debug_add(ldb, " attr: %s\n", req->op.search.attrs[i]);
763 }
764 }
765 break;
766 case LDB_DELETE:
767 ldb_debug_add(ldb, "ldb_trace_request: DELETE\n");
768 ldb_debug_add(ldb, " dn: %s\n",
769 ldb_dn_get_linearized(req->op.del.dn));
770 break;
771 case LDB_RENAME:
772 ldb_debug_add(ldb, "ldb_trace_request: RENAME\n");
773 ldb_debug_add(ldb, " olddn: %s\n",
774 ldb_dn_get_linearized(req->op.rename.olddn));
775 ldb_debug_add(ldb, " newdn: %s\n",
776 ldb_dn_get_linearized(req->op.rename.newdn));
777 break;
778 case LDB_EXTENDED:
779 ldb_debug_add(ldb, "ldb_trace_request: EXTENDED\n");
780 ldb_debug_add(ldb, " oid: %s\n", req->op.extended.oid);
781 ldb_debug_add(ldb, " data: %s\n", req->op.extended.data?"yes":"no");
782 break;
783 case LDB_ADD:
784 ldif.changetype = LDB_CHANGETYPE_ADD;
785 ldif.msg = discard_const_p(struct ldb_message, req->op.add.message);
786
787 ldb_debug_add(ldb, "ldb_trace_request: ADD\n");
788
789 /*
790 * The choice to call
791 * ldb_ldif_write_redacted_trace_string() is CRITICAL
792 * for security. It ensures that we do not output
793 * passwords into debug logs
794 */
795
796 ldb_debug_add(req->handle->ldb, "%s\n",
797 ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif));
798 break;
799 case LDB_MODIFY:
800 ldif.changetype = LDB_CHANGETYPE_MODIFY;
801 ldif.msg = discard_const_p(struct ldb_message, req->op.mod.message);
802
803 ldb_debug_add(ldb, "ldb_trace_request: MODIFY\n");
804
805 /*
806 * The choice to call
807 * ldb_ldif_write_redacted_trace_string() is CRITICAL
808 * for security. It ensures that we do not output
809 * passwords into debug logs
810 */
811
812 ldb_debug_add(req->handle->ldb, "%s\n",
813 ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif));
814 break;
815 case LDB_REQ_REGISTER_CONTROL:
816 ldb_debug_add(ldb, "ldb_trace_request: REGISTER_CONTROL\n");
817 ldb_debug_add(req->handle->ldb, "%s\n",
818 req->op.reg_control.oid);
819 break;
820 case LDB_REQ_REGISTER_PARTITION:
821 ldb_debug_add(ldb, "ldb_trace_request: REGISTER_PARTITION\n");
822 ldb_debug_add(req->handle->ldb, "%s\n",
823 ldb_dn_get_linearized(req->op.reg_partition.dn));
824 break;
825 default:
826 ldb_debug_add(ldb, "ldb_trace_request: UNKNOWN(%u)\n",
827 req->operation);
828 break;
829 }
830
831 if (req->controls == NULL) {
832 ldb_debug_add(ldb, " control: <NONE>\n");
833 } else {
834 for (i=0; req->controls && req->controls[i]; i++) {
835 if (req->controls[i]->oid) {
836 ldb_debug_add(ldb, " control: %s crit:%u data:%s\n",
837 req->controls[i]->oid,
838 req->controls[i]->critical,
839 req->controls[i]->data?"yes":"no");
840 }
841 }
842 }
843
844 ldb_debug_end(ldb, LDB_DEBUG_TRACE);
845
846 talloc_free(tmp_ctx);
847}
848
849/*
850 check that the element flags don't have any internal bits set
851 */
852static int ldb_msg_check_element_flags(struct ldb_context *ldb,
853 const struct ldb_message *message)
854{
855 unsigned i;
856 for (i=0; i<message->num_elements; i++) {
857 if (message->elements[i].flags & LDB_FLAG_INTERNAL_MASK) {
858 ldb_asprintf_errstring(ldb, "Invalid element flags 0x%08x on element %s in %s\n",
859 message->elements[i].flags, message->elements[i].name,
860 ldb_dn_get_linearized(message->dn));
861 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
862 }
863 }
864 return LDB_SUCCESS;
865}
866
867
868/*
869 start an ldb request
870 NOTE: the request must be a talloc context.
871 returns LDB_ERR_* on errors.
872*/
873int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
874{
875 struct ldb_module *module;
876 int ret;
877
878 if (req->callback == NULL) {
879 ldb_set_errstring(ldb, "Requests MUST define callbacks");
880 return LDB_ERR_UNWILLING_TO_PERFORM;
881 }
882
883 ldb_reset_err_string(ldb);
884
885 if (ldb->flags & LDB_FLG_ENABLE_TRACING) {
886 ldb_trace_request(ldb, req);
887 }
888
889 /* call the first module in the chain */
890 switch (req->operation) {
891 case LDB_SEARCH:
892 /* due to "ldb_build_search_req" base DN always != NULL */
893 if (!ldb_dn_validate(req->op.search.base)) {
894 ldb_asprintf_errstring(ldb, "ldb_search: invalid basedn '%s'",
895 ldb_dn_get_linearized(req->op.search.base));
896 return LDB_ERR_INVALID_DN_SYNTAX;
897 }
898 FIRST_OP(ldb, search);
899 ret = module->ops->search(module, req);
900 break;
901 case LDB_ADD:
902 if (!ldb_dn_validate(req->op.add.message->dn)) {
903 ldb_asprintf_errstring(ldb, "ldb_add: invalid dn '%s'",
904 ldb_dn_get_linearized(req->op.add.message->dn));
905 return LDB_ERR_INVALID_DN_SYNTAX;
906 }
907 /*
908 * we have to normalize here, as so many places
909 * in modules and backends assume we don't have two
910 * elements with the same name
911 */
912 ret = ldb_msg_normalize(ldb, req, req->op.add.message,
913 discard_const(&req->op.add.message));
914 if (ret != LDB_SUCCESS) {
915 ldb_oom(ldb);
916 return ret;
917 }
918 FIRST_OP(ldb, add);
919 ret = ldb_msg_check_element_flags(ldb, req->op.add.message);
920 if (ret != LDB_SUCCESS) {
921 /*
922 * "ldb_msg_check_element_flags" generates an error
923 * string
924 */
925 return ret;
926 }
927 ret = module->ops->add(module, req);
928 break;
929 case LDB_MODIFY:
930 if (!ldb_dn_validate(req->op.mod.message->dn)) {
931 ldb_asprintf_errstring(ldb, "ldb_modify: invalid dn '%s'",
932 ldb_dn_get_linearized(req->op.mod.message->dn));
933 return LDB_ERR_INVALID_DN_SYNTAX;
934 }
935 FIRST_OP(ldb, modify);
936 ret = ldb_msg_check_element_flags(ldb, req->op.mod.message);
937 if (ret != LDB_SUCCESS) {
938 /*
939 * "ldb_msg_check_element_flags" generates an error
940 * string
941 */
942 return ret;
943 }
944 ret = module->ops->modify(module, req);
945 break;
946 case LDB_DELETE:
947 if (!ldb_dn_validate(req->op.del.dn)) {
948 ldb_asprintf_errstring(ldb, "ldb_delete: invalid dn '%s'",
949 ldb_dn_get_linearized(req->op.del.dn));
950 return LDB_ERR_INVALID_DN_SYNTAX;
951 }
952 FIRST_OP(ldb, del);
953 ret = module->ops->del(module, req);
954 break;
955 case LDB_RENAME:
956 if (!ldb_dn_validate(req->op.rename.olddn)) {
957 ldb_asprintf_errstring(ldb, "ldb_rename: invalid olddn '%s'",
958 ldb_dn_get_linearized(req->op.rename.olddn));
959 return LDB_ERR_INVALID_DN_SYNTAX;
960 }
961 if (!ldb_dn_validate(req->op.rename.newdn)) {
962 ldb_asprintf_errstring(ldb, "ldb_rename: invalid newdn '%s'",
963 ldb_dn_get_linearized(req->op.rename.newdn));
964 return LDB_ERR_INVALID_DN_SYNTAX;
965 }
966 FIRST_OP(ldb, rename);
967 ret = module->ops->rename(module, req);
968 break;
969 case LDB_EXTENDED:
970 FIRST_OP(ldb, extended);
971 ret = module->ops->extended(module, req);
972 break;
973 default:
974 FIRST_OP(ldb, request);
975 ret = module->ops->request(module, req);
976 break;
977 }
978
979 if ((ret != LDB_SUCCESS) && (ldb->err_string == NULL)) {
980 /* if no error string was setup by the backend */
981 ldb_asprintf_errstring(ldb, "ldb_request: %s (%d)",
982 ldb_strerror(ret), ret);
983 }
984
985 return ret;
986}
987
988int ldb_request_done(struct ldb_request *req, int status)
989{
990 req->handle->state = LDB_ASYNC_DONE;
991 req->handle->status = status;
992 return status;
993}
994
995/*
996 search the database given a LDAP-like search expression
997
998 returns an LDB error code
999
1000 Use talloc_free to free the ldb_message returned in 'res', if successful
1001
1002*/
1003int ldb_search_default_callback(struct ldb_request *req,
1004 struct ldb_reply *ares)
1005{
1006 struct ldb_result *res;
1007 unsigned int n;
1008
1009 res = talloc_get_type(req->context, struct ldb_result);
1010
1011 if (!ares) {
1012 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1013 }
1014 if (ares->error != LDB_SUCCESS) {
1015 return ldb_request_done(req, ares->error);
1016 }
1017
1018 switch (ares->type) {
1019 case LDB_REPLY_ENTRY:
1020 res->msgs = talloc_realloc(res, res->msgs,
1021 struct ldb_message *, res->count + 2);
1022 if (! res->msgs) {
1023 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1024 }
1025
1026 res->msgs[res->count + 1] = NULL;
1027
1028 res->msgs[res->count] = talloc_move(res->msgs, &ares->message);
1029 res->count++;
1030 break;
1031
1032 case LDB_REPLY_REFERRAL:
1033 if (res->refs) {
1034 for (n = 0; res->refs[n]; n++) /*noop*/ ;
1035 } else {
1036 n = 0;
1037 }
1038
1039 res->refs = talloc_realloc(res, res->refs, char *, n + 2);
1040 if (! res->refs) {
1041 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1042 }
1043
1044 res->refs[n] = talloc_move(res->refs, &ares->referral);
1045 res->refs[n + 1] = NULL;
1046 break;
1047
1048 case LDB_REPLY_DONE:
1049 /* TODO: we should really support controls on entries
1050 * and referrals too! */
1051 res->controls = talloc_move(res, &ares->controls);
1052
1053 /* this is the last message, and means the request is done */
1054 /* we have to signal and eventual ldb_wait() waiting that the
1055 * async request operation was completed */
1056 talloc_free(ares);
1057 return ldb_request_done(req, LDB_SUCCESS);
1058 }
1059
1060 talloc_free(ares);
1061
1062 return LDB_SUCCESS;
1063}
1064
1065int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares)
1066{
1067 struct ldb_result *res;
1068 unsigned int n;
1069 int ret;
1070
1071 res = talloc_get_type(req->context, struct ldb_result);
1072
1073 if (!ares) {
1074 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1075 }
1076
1077 if (ares->error != LDB_SUCCESS) {
1078 ret = ares->error;
1079 talloc_free(ares);
1080 return ldb_request_done(req, ret);
1081 }
1082
1083 switch (ares->type) {
1084 case LDB_REPLY_REFERRAL:
1085 if (res->refs) {
1086 for (n = 0; res->refs[n]; n++) /*noop*/ ;
1087 } else {
1088 n = 0;
1089 }
1090
1091 res->refs = talloc_realloc(res, res->refs, char *, n + 2);
1092 if (! res->refs) {
1093 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1094 }
1095
1096 res->refs[n] = talloc_move(res->refs, &ares->referral);
1097 res->refs[n + 1] = NULL;
1098 break;
1099
1100 case LDB_REPLY_DONE:
1101 talloc_free(ares);
1102 return ldb_request_done(req, LDB_SUCCESS);
1103 default:
1104 talloc_free(ares);
1105 ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type);
1106 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1107 }
1108
1109 talloc_free(ares);
1110 return ldb_request_done(req, LDB_SUCCESS);
1111}
1112
1113int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares)
1114{
1115 int ret;
1116
1117 if (!ares) {
1118 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1119 }
1120
1121 if (ares->error != LDB_SUCCESS) {
1122 ret = ares->error;
1123 talloc_free(ares);
1124 return ldb_request_done(req, ret);
1125 }
1126
1127 if (ares->type != LDB_REPLY_DONE) {
1128 talloc_free(ares);
1129 ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type);
1130 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1131 }
1132
1133 talloc_free(ares);
1134 return ldb_request_done(req, LDB_SUCCESS);
1135}
1136
1137int ldb_build_search_req_ex(struct ldb_request **ret_req,
1138 struct ldb_context *ldb,
1139 TALLOC_CTX *mem_ctx,
1140 struct ldb_dn *base,
1141 enum ldb_scope scope,
1142 struct ldb_parse_tree *tree,
1143 const char * const *attrs,
1144 struct ldb_control **controls,
1145 void *context,
1146 ldb_request_callback_t callback,
1147 struct ldb_request *parent)
1148{
1149 struct ldb_request *req;
1150
1151 *ret_req = NULL;
1152
1153 req = talloc(mem_ctx, struct ldb_request);
1154 if (req == NULL) {
1155 ldb_oom(ldb);
1156 return LDB_ERR_OPERATIONS_ERROR;
1157 }
1158
1159 req->operation = LDB_SEARCH;
1160 if (base == NULL) {
1161 req->op.search.base = ldb_dn_new(req, ldb, NULL);
1162 } else {
1163 req->op.search.base = base;
1164 }
1165 req->op.search.scope = scope;
1166
1167 req->op.search.tree = tree;
1168 if (req->op.search.tree == NULL) {
1169 ldb_set_errstring(ldb, "'tree' can't be NULL");
1170 talloc_free(req);
1171 return LDB_ERR_OPERATIONS_ERROR;
1172 }
1173
1174 req->op.search.attrs = attrs;
1175 req->controls = controls;
1176 req->context = context;
1177 req->callback = callback;
1178
1179 ldb_set_timeout_from_prev_req(ldb, parent, req);
1180
1181 req->handle = ldb_handle_new(req, ldb);
1182 if (req->handle == NULL) {
1183 ldb_oom(ldb);
1184 return LDB_ERR_OPERATIONS_ERROR;
1185 }
1186
1187 if (parent) {
1188 req->handle->nesting++;
1189 req->handle->parent = parent;
1190 req->handle->flags = parent->handle->flags;
1191 req->handle->custom_flags = parent->handle->custom_flags;
1192 }
1193
1194 *ret_req = req;
1195 return LDB_SUCCESS;
1196}
1197
1198int ldb_build_search_req(struct ldb_request **ret_req,
1199 struct ldb_context *ldb,
1200 TALLOC_CTX *mem_ctx,
1201 struct ldb_dn *base,
1202 enum ldb_scope scope,
1203 const char *expression,
1204 const char * const *attrs,
1205 struct ldb_control **controls,
1206 void *context,
1207 ldb_request_callback_t callback,
1208 struct ldb_request *parent)
1209{
1210 struct ldb_parse_tree *tree;
1211 int ret;
1212
1213 tree = ldb_parse_tree(mem_ctx, expression);
1214 if (tree == NULL) {
1215 ldb_set_errstring(ldb, "Unable to parse search expression");
1216 return LDB_ERR_OPERATIONS_ERROR;
1217 }
1218
1219 ret = ldb_build_search_req_ex(ret_req, ldb, mem_ctx, base,
1220 scope, tree, attrs, controls,
1221 context, callback, parent);
1222 if (ret == LDB_SUCCESS) {
1223 talloc_steal(*ret_req, tree);
1224 }
1225 return ret;
1226}
1227
1228int ldb_build_add_req(struct ldb_request **ret_req,
1229 struct ldb_context *ldb,
1230 TALLOC_CTX *mem_ctx,
1231 const struct ldb_message *message,
1232 struct ldb_control **controls,
1233 void *context,
1234 ldb_request_callback_t callback,
1235 struct ldb_request *parent)
1236{
1237 struct ldb_request *req;
1238
1239 *ret_req = NULL;
1240
1241 req = talloc(mem_ctx, struct ldb_request);
1242 if (req == NULL) {
1243 ldb_set_errstring(ldb, "Out of Memory");
1244 return LDB_ERR_OPERATIONS_ERROR;
1245 }
1246
1247 req->operation = LDB_ADD;
1248 req->op.add.message = message;
1249 req->controls = controls;
1250 req->context = context;
1251 req->callback = callback;
1252
1253 ldb_set_timeout_from_prev_req(ldb, parent, req);
1254
1255 req->handle = ldb_handle_new(req, ldb);
1256 if (req->handle == NULL) {
1257 ldb_oom(ldb);
1258 return LDB_ERR_OPERATIONS_ERROR;
1259 }
1260
1261 if (parent) {
1262 req->handle->nesting++;
1263 req->handle->parent = parent;
1264 req->handle->flags = parent->handle->flags;
1265 req->handle->custom_flags = parent->handle->custom_flags;
1266 }
1267
1268 *ret_req = req;
1269
1270 return LDB_SUCCESS;
1271}
1272
1273int ldb_build_mod_req(struct ldb_request **ret_req,
1274 struct ldb_context *ldb,
1275 TALLOC_CTX *mem_ctx,
1276 const struct ldb_message *message,
1277 struct ldb_control **controls,
1278 void *context,
1279 ldb_request_callback_t callback,
1280 struct ldb_request *parent)
1281{
1282 struct ldb_request *req;
1283
1284 *ret_req = NULL;
1285
1286 req = talloc(mem_ctx, struct ldb_request);
1287 if (req == NULL) {
1288 ldb_set_errstring(ldb, "Out of Memory");
1289 return LDB_ERR_OPERATIONS_ERROR;
1290 }
1291
1292 req->operation = LDB_MODIFY;
1293 req->op.mod.message = message;
1294 req->controls = controls;
1295 req->context = context;
1296 req->callback = callback;
1297
1298 ldb_set_timeout_from_prev_req(ldb, parent, req);
1299
1300 req->handle = ldb_handle_new(req, ldb);
1301 if (req->handle == NULL) {
1302 ldb_oom(ldb);
1303 return LDB_ERR_OPERATIONS_ERROR;
1304 }
1305
1306 if (parent) {
1307 req->handle->nesting++;
1308 req->handle->parent = parent;
1309 req->handle->flags = parent->handle->flags;
1310 req->handle->custom_flags = parent->handle->custom_flags;
1311 }
1312
1313 *ret_req = req;
1314
1315 return LDB_SUCCESS;
1316}
1317
1318int ldb_build_del_req(struct ldb_request **ret_req,
1319 struct ldb_context *ldb,
1320 TALLOC_CTX *mem_ctx,
1321 struct ldb_dn *dn,
1322 struct ldb_control **controls,
1323 void *context,
1324 ldb_request_callback_t callback,
1325 struct ldb_request *parent)
1326{
1327 struct ldb_request *req;
1328
1329 *ret_req = NULL;
1330
1331 req = talloc(mem_ctx, struct ldb_request);
1332 if (req == NULL) {
1333 ldb_set_errstring(ldb, "Out of Memory");
1334 return LDB_ERR_OPERATIONS_ERROR;
1335 }
1336
1337 req->operation = LDB_DELETE;
1338 req->op.del.dn = dn;
1339 req->controls = controls;
1340 req->context = context;
1341 req->callback = callback;
1342
1343 ldb_set_timeout_from_prev_req(ldb, parent, req);
1344
1345 req->handle = ldb_handle_new(req, ldb);
1346 if (req->handle == NULL) {
1347 ldb_oom(ldb);
1348 return LDB_ERR_OPERATIONS_ERROR;
1349 }
1350
1351 if (parent) {
1352 req->handle->nesting++;
1353 req->handle->parent = parent;
1354 req->handle->flags = parent->handle->flags;
1355 req->handle->custom_flags = parent->handle->custom_flags;
1356 }
1357
1358 *ret_req = req;
1359
1360 return LDB_SUCCESS;
1361}
1362
1363int ldb_build_rename_req(struct ldb_request **ret_req,
1364 struct ldb_context *ldb,
1365 TALLOC_CTX *mem_ctx,
1366 struct ldb_dn *olddn,
1367 struct ldb_dn *newdn,
1368 struct ldb_control **controls,
1369 void *context,
1370 ldb_request_callback_t callback,
1371 struct ldb_request *parent)
1372{
1373 struct ldb_request *req;
1374
1375 *ret_req = NULL;
1376
1377 req = talloc(mem_ctx, struct ldb_request);
1378 if (req == NULL) {
1379 ldb_set_errstring(ldb, "Out of Memory");
1380 return LDB_ERR_OPERATIONS_ERROR;
1381 }
1382
1383 req->operation = LDB_RENAME;
1384 req->op.rename.olddn = olddn;
1385 req->op.rename.newdn = newdn;
1386 req->controls = controls;
1387 req->context = context;
1388 req->callback = callback;
1389
1390 ldb_set_timeout_from_prev_req(ldb, parent, req);
1391
1392 req->handle = ldb_handle_new(req, ldb);
1393 if (req->handle == NULL) {
1394 ldb_oom(ldb);
1395 return LDB_ERR_OPERATIONS_ERROR;
1396 }
1397
1398 if (parent) {
1399 req->handle->nesting++;
1400 req->handle->parent = parent;
1401 req->handle->flags = parent->handle->flags;
1402 req->handle->custom_flags = parent->handle->custom_flags;
1403 }
1404
1405 *ret_req = req;
1406
1407 return LDB_SUCCESS;
1408}
1409
1410int ldb_extended_default_callback(struct ldb_request *req,
1411 struct ldb_reply *ares)
1412{
1413 struct ldb_result *res;
1414
1415 res = talloc_get_type(req->context, struct ldb_result);
1416
1417 if (!ares) {
1418 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1419 }
1420 if (ares->error != LDB_SUCCESS) {
1421 return ldb_request_done(req, ares->error);
1422 }
1423
1424 if (ares->type == LDB_REPLY_DONE) {
1425
1426 /* TODO: we should really support controls on entries and referrals too! */
1427 res->extended = talloc_move(res, &ares->response);
1428 res->controls = talloc_move(res, &ares->controls);
1429
1430 talloc_free(ares);
1431 return ldb_request_done(req, LDB_SUCCESS);
1432 }
1433
1434 talloc_free(ares);
1435 ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type);
1436 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1437}
1438
1439int ldb_build_extended_req(struct ldb_request **ret_req,
1440 struct ldb_context *ldb,
1441 TALLOC_CTX *mem_ctx,
1442 const char *oid,
1443 void *data,
1444 struct ldb_control **controls,
1445 void *context,
1446 ldb_request_callback_t callback,
1447 struct ldb_request *parent)
1448{
1449 struct ldb_request *req;
1450
1451 *ret_req = NULL;
1452
1453 req = talloc(mem_ctx, struct ldb_request);
1454 if (req == NULL) {
1455 ldb_set_errstring(ldb, "Out of Memory");
1456 return LDB_ERR_OPERATIONS_ERROR;
1457 }
1458
1459 req->operation = LDB_EXTENDED;
1460 req->op.extended.oid = oid;
1461 req->op.extended.data = data;
1462 req->controls = controls;
1463 req->context = context;
1464 req->callback = callback;
1465
1466 ldb_set_timeout_from_prev_req(ldb, parent, req);
1467
1468 req->handle = ldb_handle_new(req, ldb);
1469 if (req->handle == NULL) {
1470 ldb_oom(ldb);
1471 return LDB_ERR_OPERATIONS_ERROR;
1472 }
1473
1474 if (parent) {
1475 req->handle->nesting++;
1476 req->handle->parent = parent;
1477 req->handle->flags = parent->handle->flags;
1478 req->handle->custom_flags = parent->handle->custom_flags;
1479 }
1480
1481 *ret_req = req;
1482
1483 return LDB_SUCCESS;
1484}
1485
1486int ldb_extended(struct ldb_context *ldb,
1487 const char *oid,
1488 void *data,
1489 struct ldb_result **_res)
1490{
1491 struct ldb_request *req;
1492 int ret;
1493 struct ldb_result *res;
1494
1495 *_res = NULL;
1496 req = NULL;
1497
1498 res = talloc_zero(ldb, struct ldb_result);
1499 if (!res) {
1500 return LDB_ERR_OPERATIONS_ERROR;
1501 }
1502
1503 ret = ldb_build_extended_req(&req, ldb, ldb,
1504 oid, data, NULL,
1505 res, ldb_extended_default_callback,
1506 NULL);
1507 ldb_req_set_location(req, "ldb_extended");
1508
1509 if (ret != LDB_SUCCESS) goto done;
1510
1511 ldb_set_timeout(ldb, req, 0); /* use default timeout */
1512
1513 ret = ldb_request(ldb, req);
1514
1515 if (ret == LDB_SUCCESS) {
1516 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1517 }
1518
1519done:
1520 if (ret != LDB_SUCCESS) {
1521 talloc_free(res);
1522 res = NULL;
1523 }
1524
1525 talloc_free(req);
1526
1527 *_res = res;
1528 return ret;
1529}
1530
1531/*
1532 note that ldb_search() will automatically replace a NULL 'base' value
1533 with the defaultNamingContext from the rootDSE if available.
1534*/
1535int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
1536 struct ldb_result **result, struct ldb_dn *base,
1537 enum ldb_scope scope, const char * const *attrs,
1538 const char *exp_fmt, ...)
1539{
1540 struct ldb_request *req;
1541 struct ldb_result *res;
1542 char *expression;
1543 va_list ap;
1544 int ret;
1545
1546 expression = NULL;
1547 *result = NULL;
1548 req = NULL;
1549
1550 res = talloc_zero(mem_ctx, struct ldb_result);
1551 if (!res) {
1552 return LDB_ERR_OPERATIONS_ERROR;
1553 }
1554
1555 if (exp_fmt) {
1556 va_start(ap, exp_fmt);
1557 expression = talloc_vasprintf(mem_ctx, exp_fmt, ap);
1558 va_end(ap);
1559
1560 if (!expression) {
1561 talloc_free(res);
1562 return LDB_ERR_OPERATIONS_ERROR;
1563 }
1564 }
1565
1566 ret = ldb_build_search_req(&req, ldb, mem_ctx,
1567 base?base:ldb_get_default_basedn(ldb),
1568 scope,
1569 expression,
1570 attrs,
1571 NULL,
1572 res,
1573 ldb_search_default_callback,
1574 NULL);
1575 ldb_req_set_location(req, "ldb_search");
1576
1577 if (ret != LDB_SUCCESS) goto done;
1578
1579 ret = ldb_request(ldb, req);
1580
1581 if (ret == LDB_SUCCESS) {
1582 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1583 }
1584
1585done:
1586 if (ret != LDB_SUCCESS) {
1587 talloc_free(res);
1588 res = NULL;
1589 }
1590
1591 talloc_free(expression);
1592 talloc_free(req);
1593
1594 *result = res;
1595 return ret;
1596}
1597
1598/*
1599 add a record to the database. Will fail if a record with the given class
1600 and key already exists
1601*/
1602int ldb_add(struct ldb_context *ldb,
1603 const struct ldb_message *message)
1604{
1605 struct ldb_request *req;
1606 int ret;
1607
1608 ret = ldb_msg_sanity_check(ldb, message);
1609 if (ret != LDB_SUCCESS) {
1610 return ret;
1611 }
1612
1613 ret = ldb_build_add_req(&req, ldb, ldb,
1614 message,
1615 NULL,
1616 NULL,
1617 ldb_op_default_callback,
1618 NULL);
1619 ldb_req_set_location(req, "ldb_add");
1620
1621 if (ret != LDB_SUCCESS) return ret;
1622
1623 /* do request and autostart a transaction */
1624 ret = ldb_autotransaction_request(ldb, req);
1625
1626 talloc_free(req);
1627 return ret;
1628}
1629
1630/*
1631 modify the specified attributes of a record
1632*/
1633int ldb_modify(struct ldb_context *ldb,
1634 const struct ldb_message *message)
1635{
1636 struct ldb_request *req;
1637 int ret;
1638
1639 ret = ldb_msg_sanity_check(ldb, message);
1640 if (ret != LDB_SUCCESS) {
1641 return ret;
1642 }
1643
1644 ret = ldb_build_mod_req(&req, ldb, ldb,
1645 message,
1646 NULL,
1647 NULL,
1648 ldb_op_default_callback,
1649 NULL);
1650 ldb_req_set_location(req, "ldb_modify");
1651
1652 if (ret != LDB_SUCCESS) return ret;
1653
1654 /* do request and autostart a transaction */
1655 ret = ldb_autotransaction_request(ldb, req);
1656
1657 talloc_free(req);
1658 return ret;
1659}
1660
1661
1662/*
1663 delete a record from the database
1664*/
1665int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn)
1666{
1667 struct ldb_request *req;
1668 int ret;
1669
1670 ret = ldb_build_del_req(&req, ldb, ldb,
1671 dn,
1672 NULL,
1673 NULL,
1674 ldb_op_default_callback,
1675 NULL);
1676 ldb_req_set_location(req, "ldb_delete");
1677
1678 if (ret != LDB_SUCCESS) return ret;
1679
1680 /* do request and autostart a transaction */
1681 ret = ldb_autotransaction_request(ldb, req);
1682
1683 talloc_free(req);
1684 return ret;
1685}
1686
1687/*
1688 rename a record in the database
1689*/
1690int ldb_rename(struct ldb_context *ldb,
1691 struct ldb_dn *olddn, struct ldb_dn *newdn)
1692{
1693 struct ldb_request *req;
1694 int ret;
1695
1696 ret = ldb_build_rename_req(&req, ldb, ldb,
1697 olddn,
1698 newdn,
1699 NULL,
1700 NULL,
1701 ldb_op_default_callback,
1702 NULL);
1703 ldb_req_set_location(req, "ldb_rename");
1704
1705 if (ret != LDB_SUCCESS) return ret;
1706
1707 /* do request and autostart a transaction */
1708 ret = ldb_autotransaction_request(ldb, req);
1709
1710 talloc_free(req);
1711 return ret;
1712}
1713
1714
1715/*
1716 return the global sequence number
1717*/
1718int ldb_sequence_number(struct ldb_context *ldb,
1719 enum ldb_sequence_type type, uint64_t *seq_num)
1720{
1721 struct ldb_seqnum_request *seq;
1722 struct ldb_seqnum_result *seqr;
1723 struct ldb_result *res;
1724 TALLOC_CTX *tmp_ctx;
1725 int ret;
1726
1727 *seq_num = 0;
1728
1729 tmp_ctx = talloc_zero(ldb, struct ldb_request);
1730 if (tmp_ctx == NULL) {
1731 ldb_set_errstring(ldb, "Out of Memory");
1732 return LDB_ERR_OPERATIONS_ERROR;
1733 }
1734 seq = talloc_zero(tmp_ctx, struct ldb_seqnum_request);
1735 if (seq == NULL) {
1736 ldb_set_errstring(ldb, "Out of Memory");
1737 ret = LDB_ERR_OPERATIONS_ERROR;
1738 goto done;
1739 }
1740 seq->type = type;
1741
1742 ret = ldb_extended(ldb, LDB_EXTENDED_SEQUENCE_NUMBER, seq, &res);
1743 if (ret != LDB_SUCCESS) {
1744 goto done;
1745 }
1746 talloc_steal(tmp_ctx, res);
1747
1748 if (strcmp(LDB_EXTENDED_SEQUENCE_NUMBER, res->extended->oid) != 0) {
1749 ldb_set_errstring(ldb, "Invalid OID in reply");
1750 ret = LDB_ERR_OPERATIONS_ERROR;
1751 goto done;
1752 }
1753 seqr = talloc_get_type(res->extended->data,
1754 struct ldb_seqnum_result);
1755 *seq_num = seqr->seq_num;
1756
1757done:
1758 talloc_free(tmp_ctx);
1759 return ret;
1760}
1761
1762/*
1763 return extended error information
1764*/
1765const char *ldb_errstring(struct ldb_context *ldb)
1766{
1767 if (ldb->err_string) {
1768 return ldb->err_string;
1769 }
1770
1771 return NULL;
1772}
1773
1774/*
1775 return a string explaining what a ldb error constant meancs
1776*/
1777const char *ldb_strerror(int ldb_err)
1778{
1779 switch (ldb_err) {
1780 case LDB_SUCCESS:
1781 return "Success";
1782 case LDB_ERR_OPERATIONS_ERROR:
1783 return "Operations error";
1784 case LDB_ERR_PROTOCOL_ERROR:
1785 return "Protocol error";
1786 case LDB_ERR_TIME_LIMIT_EXCEEDED:
1787 return "Time limit exceeded";
1788 case LDB_ERR_SIZE_LIMIT_EXCEEDED:
1789 return "Size limit exceeded";
1790 case LDB_ERR_COMPARE_FALSE:
1791 return "Compare false";
1792 case LDB_ERR_COMPARE_TRUE:
1793 return "Compare true";
1794 case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED:
1795 return "Auth method not supported";
1796 case LDB_ERR_STRONG_AUTH_REQUIRED:
1797 return "Strong auth required";
1798/* 9 RESERVED */
1799 case LDB_ERR_REFERRAL:
1800 return "Referral error";
1801 case LDB_ERR_ADMIN_LIMIT_EXCEEDED:
1802 return "Admin limit exceeded";
1803 case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION:
1804 return "Unsupported critical extension";
1805 case LDB_ERR_CONFIDENTIALITY_REQUIRED:
1806 return "Confidentiality required";
1807 case LDB_ERR_SASL_BIND_IN_PROGRESS:
1808 return "SASL bind in progress";
1809 case LDB_ERR_NO_SUCH_ATTRIBUTE:
1810 return "No such attribute";
1811 case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE:
1812 return "Undefined attribute type";
1813 case LDB_ERR_INAPPROPRIATE_MATCHING:
1814 return "Inappropriate matching";
1815 case LDB_ERR_CONSTRAINT_VIOLATION:
1816 return "Constraint violation";
1817 case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
1818 return "Attribute or value exists";
1819 case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
1820 return "Invalid attribute syntax";
1821/* 22-31 unused */
1822 case LDB_ERR_NO_SUCH_OBJECT:
1823 return "No such object";
1824 case LDB_ERR_ALIAS_PROBLEM:
1825 return "Alias problem";
1826 case LDB_ERR_INVALID_DN_SYNTAX:
1827 return "Invalid DN syntax";
1828/* 35 RESERVED */
1829 case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM:
1830 return "Alias dereferencing problem";
1831/* 37-47 unused */
1832 case LDB_ERR_INAPPROPRIATE_AUTHENTICATION:
1833 return "Inappropriate authentication";
1834 case LDB_ERR_INVALID_CREDENTIALS:
1835 return "Invalid credentials";
1836 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1837 return "insufficient access rights";
1838 case LDB_ERR_BUSY:
1839 return "Busy";
1840 case LDB_ERR_UNAVAILABLE:
1841 return "Unavailable";
1842 case LDB_ERR_UNWILLING_TO_PERFORM:
1843 return "Unwilling to perform";
1844 case LDB_ERR_LOOP_DETECT:
1845 return "Loop detect";
1846/* 55-63 unused */
1847 case LDB_ERR_NAMING_VIOLATION:
1848 return "Naming violation";
1849 case LDB_ERR_OBJECT_CLASS_VIOLATION:
1850 return "Object class violation";
1851 case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF:
1852 return "Not allowed on non-leaf";
1853 case LDB_ERR_NOT_ALLOWED_ON_RDN:
1854 return "Not allowed on RDN";
1855 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1856 return "Entry already exists";
1857 case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED:
1858 return "Object class mods prohibited";
1859/* 70 RESERVED FOR CLDAP */
1860 case LDB_ERR_AFFECTS_MULTIPLE_DSAS:
1861 return "Affects multiple DSAs";
1862/* 72-79 unused */
1863 case LDB_ERR_OTHER:
1864 return "Other";
1865 }
1866
1867 return "Unknown error";
1868}
1869
1870/*
1871 set backend specific opaque parameters
1872*/
1873int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
1874{
1875 struct ldb_opaque *o;
1876
1877 /* allow updating an existing value */
1878 for (o=ldb->opaque;o;o=o->next) {
1879 if (strcmp(o->name, name) == 0) {
1880 o->value = value;
1881 return LDB_SUCCESS;
1882 }
1883 }
1884
1885 o = talloc(ldb, struct ldb_opaque);
1886 if (o == NULL) {
1887 ldb_oom(ldb);
1888 return LDB_ERR_OTHER;
1889 }
1890 o->next = ldb->opaque;
1891 o->name = name;
1892 o->value = value;
1893 ldb->opaque = o;
1894 return LDB_SUCCESS;
1895}
1896
1897/*
1898 get a previously set opaque value
1899*/
1900void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
1901{
1902 struct ldb_opaque *o;
1903 for (o=ldb->opaque;o;o=o->next) {
1904 if (strcmp(o->name, name) == 0) {
1905 return o->value;
1906 }
1907 }
1908 return NULL;
1909}
1910
1911int ldb_global_init(void)
1912{
1913 /* Provided for compatibility with some older versions of ldb */
1914 return 0;
1915}
1916
1917/* return the ldb flags */
1918unsigned int ldb_get_flags(struct ldb_context *ldb)
1919{
1920 return ldb->flags;
1921}
1922
1923/* set the ldb flags */
1924void ldb_set_flags(struct ldb_context *ldb, unsigned flags)
1925{
1926 ldb->flags = flags;
1927}
1928
1929
1930/*
1931 set the location in a ldb request. Used for debugging
1932 */
1933void ldb_req_set_location(struct ldb_request *req, const char *location)
1934{
1935 if (req && req->handle) {
1936 req->handle->location = location;
1937 }
1938}
1939
1940/*
1941 return the location set with dsdb_req_set_location
1942 */
1943const char *ldb_req_location(struct ldb_request *req)
1944{
1945 return req->handle->location;
1946}
1947
1948/**
1949 mark a request as untrusted. This tells the rootdse module to remove
1950 unregistered controls
1951 */
1952void ldb_req_mark_untrusted(struct ldb_request *req)
1953{
1954 req->handle->flags |= LDB_HANDLE_FLAG_UNTRUSTED;
1955}
1956
1957/**
1958 mark a request as trusted.
1959 */
1960void ldb_req_mark_trusted(struct ldb_request *req)
1961{
1962 req->handle->flags &= ~LDB_HANDLE_FLAG_UNTRUSTED;
1963}
1964
1965/**
1966 set custom flags. Those flags are set by applications using ldb,
1967 they are application dependent and the same bit can have different
1968 meaning in different application.
1969 */
1970void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags)
1971{
1972 if (req != NULL && req->handle != NULL) {
1973 req->handle->custom_flags = flags;
1974 }
1975}
1976
1977
1978/**
1979 get custom flags. Those flags are set by applications using ldb,
1980 they are application dependent and the same bit can have different
1981 meaning in different application.
1982 */
1983uint32_t ldb_req_get_custom_flags(struct ldb_request *req)
1984{
1985 if (req != NULL && req->handle != NULL) {
1986 return req->handle->custom_flags;
1987 }
1988
1989 /*
1990 * 0 is not something any better or worse than
1991 * anything else as req or the handle is NULL
1992 */
1993 return 0;
1994}
1995
1996
1997/**
1998 * return true if a request is untrusted
1999 */
2000bool ldb_req_is_untrusted(struct ldb_request *req)
2001{
2002 return (req->handle->flags & LDB_HANDLE_FLAG_UNTRUSTED) != 0;
2003}
Note: See TracBrowser for help on using the repository browser.