source: trunk/server/source4/lib/ldb/common/ldb.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

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