source: branches/samba-3.3.x/source/lib/ldb/common/ldb.c

Last change on this file was 263, checked in by Herwig Bauernfeind, 16 years ago

ldb init fix (by diver) in 3.3 branch

File size: 25.2 KB
Line 
1/*
2 ldb database library
3
4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Simo Sorce 2005-2006
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#include "includes.h"
36#include "ldb/include/includes.h"
37
38/*
39 initialise a ldb context
40 The mem_ctx is optional
41*/
42struct ldb_context *ldb_init(void *mem_ctx)
43{
44 struct ldb_context *ldb = talloc_zero(mem_ctx, struct ldb_context);
45 int ret;
46
47 ret = ldb_setup_wellknown_attributes(ldb);
48 if (ret != 0) {
49 talloc_free(ldb);
50 return NULL;
51 }
52
53 ldb_set_utf8_default(ldb);
54 ldb_set_create_perms(ldb, 0600);
55
56 return ldb;
57}
58
59static struct ldb_backend {
60 const char *name;
61 ldb_connect_fn connect_fn;
62 struct ldb_backend *prev, *next;
63} *ldb_backends = NULL;
64
65
66static ldb_connect_fn ldb_find_backend(const char *url)
67{
68 struct ldb_backend *backend;
69
70 for (backend = ldb_backends; backend; backend = backend->next) {
71 if (strncmp(backend->name, url, strlen(backend->name)) == 0) {
72 return backend->connect_fn;
73 }
74 }
75
76 return NULL;
77}
78
79/*
80 register a new ldb backend
81*/
82int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn)
83{
84 struct ldb_backend *backend = talloc(talloc_autofree_context(), struct ldb_backend);
85
86 if (ldb_find_backend(url_prefix)) {
87 return LDB_SUCCESS;
88 }
89
90 /* Maybe check for duplicity here later on? */
91
92 backend->name = talloc_strdup(backend, url_prefix);
93 backend->connect_fn = connectfn;
94 DLIST_ADD(ldb_backends, backend);
95
96 return LDB_SUCCESS;
97}
98
99/*
100 Return the ldb module form of a database. The URL can either be one of the following forms
101 ldb://path
102 ldapi://path
103
104 flags is made up of LDB_FLG_*
105
106 the options are passed uninterpreted to the backend, and are
107 backend specific.
108
109 This allows modules to get at only the backend module, for example where a module
110 may wish to direct certain requests at a particular backend.
111*/
112int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *options[],
113 struct ldb_module **backend_module)
114{
115 int ret;
116 char *backend;
117 ldb_connect_fn fn;
118
119// on OS2 we have a semicolon at the second character if w/o backend called
120#ifndef __OS2__
121 if (strchr(url, ':') != NULL) {
122#else
123 if (url[1] != ':' && strchr(url, ':') != NULL) {
124#endif
125 backend = talloc_strndup(ldb, url, strchr(url, ':')-url);
126 } else {
127 /* Default to tdb */
128 backend = talloc_strdup(ldb, "tdb");
129 }
130
131 fn = ldb_find_backend(backend);
132
133 if (fn == NULL) {
134 if (ldb_try_load_dso(ldb, backend) == 0) {
135 fn = ldb_find_backend(backend);
136 }
137 }
138
139 talloc_free(backend);
140
141 if (fn == NULL) {
142 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url);
143 return LDB_ERR_OTHER;
144 }
145
146 ret = fn(ldb, url, ldb->flags, options, backend_module);
147
148 if (ret != LDB_SUCCESS) {
149 ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url);
150 return ret;
151 }
152 return ret;
153}
154
155/*
156 try to autodetect a basedn if none specified. This fixes one of my
157 pet hates about ldapsearch, which is that you have to get a long,
158 complex basedn right to make any use of it.
159*/
160static const struct ldb_dn *ldb_set_default_basedn(struct ldb_context *ldb)
161{
162 TALLOC_CTX *tmp_ctx;
163 int ret;
164 static const char *attrs[] = { "defaultNamingContext", NULL };
165 struct ldb_result *res;
166 struct ldb_dn *basedn=NULL;
167
168 basedn = (struct ldb_dn *)ldb_get_opaque(ldb, "default_baseDN");
169 if (basedn) {
170 return basedn;
171 }
172
173 tmp_ctx = talloc_new(ldb);
174 ret = ldb_search(ldb, ldb_dn_new(tmp_ctx), LDB_SCOPE_BASE,
175 "(objectClass=*)", attrs, &res);
176 if (ret == LDB_SUCCESS) {
177 if (res->count == 1) {
178 basedn = ldb_msg_find_attr_as_dn(ldb, res->msgs[0], "defaultNamingContext");
179 ldb_set_opaque(ldb, "default_baseDN", basedn);
180 }
181 talloc_free(res);
182 }
183
184 talloc_free(tmp_ctx);
185 return basedn;
186}
187
188const struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb)
189{
190 return (const struct ldb_dn *)ldb_get_opaque(ldb, "default_baseDN");
191}
192
193/*
194 connect to a database. The URL can either be one of the following forms
195 ldb://path
196 ldapi://path
197
198 flags is made up of LDB_FLG_*
199
200 the options are passed uninterpreted to the backend, and are
201 backend specific
202*/
203int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[])
204{
205 int ret;
206
207 ldb->flags = flags;
208
209 ret = ldb_connect_backend(ldb, url, options, &ldb->modules);
210 if (ret != LDB_SUCCESS) {
211 return ret;
212 }
213
214 if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
215 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to load modules for %s: %s\n",
216 url, ldb_errstring(ldb));
217 return LDB_ERR_OTHER;
218 }
219
220 /* TODO: get timeout from options if available there */
221 ldb->default_timeout = 300; /* set default to 5 minutes */
222
223 /* set the default base dn */
224 ldb_set_default_basedn(ldb);
225
226 return LDB_SUCCESS;
227}
228
229void ldb_set_errstring(struct ldb_context *ldb, const char *err_string)
230{
231 if (ldb->err_string) {
232 talloc_free(ldb->err_string);
233 }
234 ldb->err_string = talloc_strdup(ldb, err_string);
235}
236
237void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...)
238{
239 va_list ap;
240
241 if (ldb->err_string) {
242 talloc_free(ldb->err_string);
243 }
244
245 va_start(ap, format);
246 ldb->err_string = talloc_vasprintf(ldb, format, ap);
247 va_end(ap);
248}
249
250void ldb_reset_err_string(struct ldb_context *ldb)
251{
252 if (ldb->err_string) {
253 talloc_free(ldb->err_string);
254 ldb->err_string = NULL;
255 }
256}
257
258#define FIRST_OP(ldb, op) do { \
259 module = ldb->modules; \
260 while (module && module->ops->op == NULL) module = module->next; \
261 if (module == NULL) { \
262 ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \
263 return LDB_ERR_OPERATIONS_ERROR; \
264 } \
265} while (0)
266
267/*
268 start a transaction
269*/
270static int ldb_transaction_start_internal(struct ldb_context *ldb)
271{
272 struct ldb_module *module;
273 int status;
274 FIRST_OP(ldb, start_transaction);
275
276 ldb_reset_err_string(ldb);
277
278 status = module->ops->start_transaction(module);
279 if (status != LDB_SUCCESS) {
280 if (ldb->err_string == NULL) {
281 /* no error string was setup by the backend */
282 ldb_asprintf_errstring(ldb,
283 "ldb transaction start: %s (%d)",
284 ldb_strerror(status),
285 status);
286 }
287 }
288 return status;
289}
290
291/*
292 commit a transaction
293*/
294static int ldb_transaction_commit_internal(struct ldb_context *ldb)
295{
296 struct ldb_module *module;
297 int status;
298 FIRST_OP(ldb, end_transaction);
299
300 ldb_reset_err_string(ldb);
301
302 status = module->ops->end_transaction(module);
303 if (status != LDB_SUCCESS) {
304 if (ldb->err_string == NULL) {
305 /* no error string was setup by the backend */
306 ldb_asprintf_errstring(ldb,
307 "ldb transaction commit: %s (%d)",
308 ldb_strerror(status),
309 status);
310 }
311 }
312 return status;
313}
314
315/*
316 cancel a transaction
317*/
318static int ldb_transaction_cancel_internal(struct ldb_context *ldb)
319{
320 struct ldb_module *module;
321 int status;
322 FIRST_OP(ldb, del_transaction);
323
324 status = module->ops->del_transaction(module);
325 if (status != LDB_SUCCESS) {
326 if (ldb->err_string == NULL) {
327 /* no error string was setup by the backend */
328 ldb_asprintf_errstring(ldb,
329 "ldb transaction cancel: %s (%d)",
330 ldb_strerror(status),
331 status);
332 }
333 }
334 return status;
335}
336
337int ldb_transaction_start(struct ldb_context *ldb)
338{
339 /* disable autotransactions */
340 ldb->transaction_active++;
341
342 return ldb_transaction_start_internal(ldb);
343}
344
345int ldb_transaction_commit(struct ldb_context *ldb)
346{
347 /* renable autotransactions (when we reach 0) */
348 if (ldb->transaction_active > 0)
349 ldb->transaction_active--;
350
351 return ldb_transaction_commit_internal(ldb);
352}
353
354int ldb_transaction_cancel(struct ldb_context *ldb)
355{
356 /* renable autotransactions (when we reach 0) */
357 if (ldb->transaction_active > 0)
358 ldb->transaction_active--;
359
360 return ldb_transaction_cancel_internal(ldb);
361}
362
363static int ldb_autotransaction_start(struct ldb_context *ldb)
364{
365 /* explicit transaction active, ignore autotransaction request */
366 if (ldb->transaction_active)
367 return LDB_SUCCESS;
368
369 return ldb_transaction_start_internal(ldb);
370}
371
372static int ldb_autotransaction_commit(struct ldb_context *ldb)
373{
374 /* explicit transaction active, ignore autotransaction request */
375 if (ldb->transaction_active)
376 return LDB_SUCCESS;
377
378 return ldb_transaction_commit_internal(ldb);
379}
380
381static int ldb_autotransaction_cancel(struct ldb_context *ldb)
382{
383 /* explicit transaction active, ignore autotransaction request */
384 if (ldb->transaction_active)
385 return LDB_SUCCESS;
386
387 return ldb_transaction_cancel_internal(ldb);
388}
389
390/* autostarts a transacion if none active */
391static int ldb_autotransaction_request(struct ldb_context *ldb, struct ldb_request *req)
392{
393 int ret;
394
395 ret = ldb_autotransaction_start(ldb);
396 if (ret != LDB_SUCCESS) {
397 return ret;
398 }
399
400 ret = ldb_request(ldb, req);
401 if (ret == LDB_SUCCESS) {
402 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
403 }
404
405 if (ret == LDB_SUCCESS) {
406 return ldb_autotransaction_commit(ldb);
407 }
408 ldb_autotransaction_cancel(ldb);
409
410 if (ldb->err_string == NULL) {
411 /* no error string was setup by the backend */
412 ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret);
413 }
414
415 return ret;
416}
417
418int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
419{
420 if (!handle) {
421 return LDB_SUCCESS;
422 }
423
424 return handle->module->ops->wait(handle, type);
425}
426
427/* set the specified timeout or, if timeout is 0 set the default timeout */
428/* timeout == -1 means no timeout */
429int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout)
430{
431 if (req == NULL) return LDB_ERR_OPERATIONS_ERROR;
432
433 if (timeout != 0) {
434 req->timeout = timeout;
435 } else {
436 req->timeout = ldb->default_timeout;
437 }
438 req->starttime = time(NULL);
439
440 return LDB_SUCCESS;
441}
442
443/* calculates the new timeout based on the previous starttime and timeout */
444int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq)
445{
446 time_t now;
447
448 if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR;
449
450 now = time(NULL);
451
452 if (oldreq == NULL)
453 return ldb_set_timeout(ldb, newreq, 0);
454
455 if ((now - oldreq->starttime) > oldreq->timeout) {
456 return LDB_ERR_TIME_LIMIT_EXCEEDED;
457 }
458 newreq->starttime = oldreq->starttime;
459 newreq->timeout = oldreq->timeout - (now - oldreq->starttime);
460
461 return LDB_SUCCESS;
462}
463
464
465/*
466 set the permissions for new files to be passed to open() in
467 backends that use local files
468 */
469void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms)
470{
471 ldb->create_perms = perms;
472}
473
474/*
475 start an ldb request
476 NOTE: the request must be a talloc context.
477 returns LDB_ERR_* on errors.
478*/
479int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
480{
481 struct ldb_module *module;
482 int ret;
483
484 ldb_reset_err_string(ldb);
485
486 /* call the first module in the chain */
487 switch (req->operation) {
488 case LDB_SEARCH:
489 FIRST_OP(ldb, search);
490 ret = module->ops->search(module, req);
491 break;
492 case LDB_ADD:
493 FIRST_OP(ldb, add);
494 ret = module->ops->add(module, req);
495 break;
496 case LDB_MODIFY:
497 FIRST_OP(ldb, modify);
498 ret = module->ops->modify(module, req);
499 break;
500 case LDB_DELETE:
501 FIRST_OP(ldb, del);
502 ret = module->ops->del(module, req);
503 break;
504 case LDB_RENAME:
505 FIRST_OP(ldb, rename);
506 ret = module->ops->rename(module, req);
507 break;
508 case LDB_SEQUENCE_NUMBER:
509 FIRST_OP(ldb, sequence_number);
510 ret = module->ops->sequence_number(module, req);
511 break;
512 default:
513 FIRST_OP(ldb, request);
514 ret = module->ops->request(module, req);
515 break;
516 }
517
518 return ret;
519}
520
521/*
522 search the database given a LDAP-like search expression
523
524 returns an LDB error code
525
526 Use talloc_free to free the ldb_message returned in 'res', if successful
527
528*/
529int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares)
530{
531 struct ldb_result *res;
532 int n;
533
534 if (!context) {
535 ldb_set_errstring(ldb, "NULL Context in callback");
536 return LDB_ERR_OPERATIONS_ERROR;
537 }
538
539 res = talloc_get_type(context, struct ldb_result);
540
541 if (!res || !ares) {
542 ldb_set_errstring(ldb, "NULL res or ares in callback");
543 goto error;
544 }
545
546 switch (ares->type) {
547 case LDB_REPLY_ENTRY:
548 res->msgs = talloc_realloc(res, res->msgs, struct ldb_message *, res->count + 2);
549 if (! res->msgs) {
550 goto error;
551 }
552
553 res->msgs[res->count + 1] = NULL;
554
555 res->msgs[res->count] = talloc_move(res->msgs, &ares->message);
556 res->count++;
557 break;
558 case LDB_REPLY_REFERRAL:
559 if (res->refs) {
560 for (n = 0; res->refs[n]; n++) /*noop*/ ;
561 } else {
562 n = 0;
563 }
564
565 res->refs = talloc_realloc(res, res->refs, char *, n + 2);
566 if (! res->refs) {
567 goto error;
568 }
569
570 res->refs[n] = talloc_move(res->refs, &ares->referral);
571 res->refs[n + 1] = NULL;
572 case LDB_REPLY_EXTENDED:
573 case LDB_REPLY_DONE:
574 /* TODO: we should really support controls on entries and referrals too! */
575 res->controls = talloc_move(res, &ares->controls);
576 break;
577 }
578 talloc_free(ares);
579 return LDB_SUCCESS;
580
581error:
582 talloc_free(ares);
583 return LDB_ERR_OPERATIONS_ERROR;
584}
585
586int ldb_build_search_req(struct ldb_request **ret_req,
587 struct ldb_context *ldb,
588 void *mem_ctx,
589 const struct ldb_dn *base,
590 enum ldb_scope scope,
591 const char *expression,
592 const char * const *attrs,
593 struct ldb_control **controls,
594 void *context,
595 ldb_request_callback_t callback)
596{
597 struct ldb_request *req;
598
599 *ret_req = NULL;
600
601 req = talloc(mem_ctx, struct ldb_request);
602 if (req == NULL) {
603 ldb_set_errstring(ldb, "Out of Memory");
604 return LDB_ERR_OPERATIONS_ERROR;
605 }
606
607 req->operation = LDB_SEARCH;
608 if (base == NULL) {
609 req->op.search.base = ldb_dn_new(req);
610 } else {
611 req->op.search.base = base;
612 }
613 req->op.search.scope = scope;
614
615 req->op.search.tree = ldb_parse_tree(req, expression);
616 if (req->op.search.tree == NULL) {
617 ldb_set_errstring(ldb, "Unable to parse search expression");
618 talloc_free(req);
619 return LDB_ERR_OPERATIONS_ERROR;
620 }
621
622 req->op.search.attrs = attrs;
623 req->controls = controls;
624 req->context = context;
625 req->callback = callback;
626
627 *ret_req = req;
628 return LDB_SUCCESS;
629}
630
631int ldb_build_add_req(struct ldb_request **ret_req,
632 struct ldb_context *ldb,
633 void *mem_ctx,
634 const struct ldb_message *message,
635 struct ldb_control **controls,
636 void *context,
637 ldb_request_callback_t callback)
638{
639 struct ldb_request *req;
640
641 *ret_req = NULL;
642
643 req = talloc(mem_ctx, struct ldb_request);
644 if (req == NULL) {
645 ldb_set_errstring(ldb, "Out of Memory");
646 return LDB_ERR_OPERATIONS_ERROR;
647 }
648
649 req->operation = LDB_ADD;
650 req->op.add.message = message;
651 req->controls = controls;
652 req->context = context;
653 req->callback = callback;
654
655 *ret_req = req;
656
657 return LDB_SUCCESS;
658}
659
660int ldb_build_mod_req(struct ldb_request **ret_req,
661 struct ldb_context *ldb,
662 void *mem_ctx,
663 const struct ldb_message *message,
664 struct ldb_control **controls,
665 void *context,
666 ldb_request_callback_t callback)
667{
668 struct ldb_request *req;
669
670 *ret_req = NULL;
671
672 req = talloc(mem_ctx, struct ldb_request);
673 if (req == NULL) {
674 ldb_set_errstring(ldb, "Out of Memory");
675 return LDB_ERR_OPERATIONS_ERROR;
676 }
677
678 req->operation = LDB_MODIFY;
679 req->op.mod.message = message;
680 req->controls = controls;
681 req->context = context;
682 req->callback = callback;
683
684 *ret_req = req;
685
686 return LDB_SUCCESS;
687}
688
689int ldb_build_del_req(struct ldb_request **ret_req,
690 struct ldb_context *ldb,
691 void *mem_ctx,
692 const struct ldb_dn *dn,
693 struct ldb_control **controls,
694 void *context,
695 ldb_request_callback_t callback)
696{
697 struct ldb_request *req;
698
699 *ret_req = NULL;
700
701 req = talloc(mem_ctx, struct ldb_request);
702 if (req == NULL) {
703 ldb_set_errstring(ldb, "Out of Memory");
704 return LDB_ERR_OPERATIONS_ERROR;
705 }
706
707 req->operation = LDB_DELETE;
708 req->op.del.dn = dn;
709 req->controls = controls;
710 req->context = context;
711 req->callback = callback;
712
713 *ret_req = req;
714
715 return LDB_SUCCESS;
716}
717
718int ldb_build_rename_req(struct ldb_request **ret_req,
719 struct ldb_context *ldb,
720 void *mem_ctx,
721 const struct ldb_dn *olddn,
722 const struct ldb_dn *newdn,
723 struct ldb_control **controls,
724 void *context,
725 ldb_request_callback_t callback)
726{
727 struct ldb_request *req;
728
729 *ret_req = NULL;
730
731 req = talloc(mem_ctx, struct ldb_request);
732 if (req == NULL) {
733 ldb_set_errstring(ldb, "Out of Memory");
734 return LDB_ERR_OPERATIONS_ERROR;
735 }
736
737 req->operation = LDB_RENAME;
738 req->op.rename.olddn = olddn;
739 req->op.rename.newdn = newdn;
740 req->controls = controls;
741 req->context = context;
742 req->callback = callback;
743
744 *ret_req = req;
745
746 return LDB_SUCCESS;
747}
748
749/*
750 note that ldb_search() will automatically replace a NULL 'base' value with the
751 defaultNamingContext from the rootDSE if available.
752*/
753int ldb_search(struct ldb_context *ldb,
754 const struct ldb_dn *base,
755 enum ldb_scope scope,
756 const char *expression,
757 const char * const *attrs,
758 struct ldb_result **_res)
759{
760 struct ldb_request *req;
761 int ret;
762 struct ldb_result *res;
763
764 *_res = NULL;
765
766 res = talloc_zero(ldb, struct ldb_result);
767 if (!res) {
768 return LDB_ERR_OPERATIONS_ERROR;
769 }
770
771 ret = ldb_build_search_req(&req, ldb, ldb,
772 base?base:ldb_get_default_basedn(ldb),
773 scope,
774 expression,
775 attrs,
776 NULL,
777 res,
778 ldb_search_default_callback);
779
780 if (ret != LDB_SUCCESS) goto done;
781
782 ldb_set_timeout(ldb, req, 0); /* use default timeout */
783
784 ret = ldb_request(ldb, req);
785
786 if (ret == LDB_SUCCESS) {
787 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
788 }
789
790 talloc_free(req);
791
792done:
793 if (ret != LDB_SUCCESS) {
794 talloc_free(res);
795 res = NULL;
796 }
797
798 *_res = res;
799 return ret;
800}
801
802/*
803 a useful search function where you can easily define the expression and that
804 takes a memory context where results are allocated
805*/
806
807int ldb_search_exp_fmt(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_result **result,
808 struct ldb_dn *base, enum ldb_scope scope, const char * const *attrs,
809 const char *exp_fmt, ...)
810{
811 struct ldb_result *res;
812 char *expression;
813 va_list ap;
814 int ret;
815
816 res = NULL;
817 *result = NULL;
818
819 va_start(ap, exp_fmt);
820 expression = talloc_vasprintf(mem_ctx, exp_fmt, ap);
821 va_end(ap);
822
823 if ( ! expression) {
824 return LDB_ERR_OPERATIONS_ERROR;
825 }
826
827 ret = ldb_search(ldb, base, scope, expression, attrs, &res);
828
829 if (ret == LDB_SUCCESS) {
830 talloc_steal(mem_ctx, res);
831 *result = res;
832 } else {
833 talloc_free(res);
834 }
835
836 talloc_free(expression);
837
838 return ret;
839}
840
841/*
842 add a record to the database. Will fail if a record with the given class and key
843 already exists
844*/
845int ldb_add(struct ldb_context *ldb,
846 const struct ldb_message *message)
847{
848 struct ldb_request *req;
849 int ret;
850
851 ret = ldb_msg_sanity_check(ldb, message);
852 if (ret != LDB_SUCCESS) {
853 return ret;
854 }
855
856 ret = ldb_build_add_req(&req, ldb, ldb,
857 message,
858 NULL,
859 NULL,
860 NULL);
861
862 if (ret != LDB_SUCCESS) return ret;
863
864 ldb_set_timeout(ldb, req, 0); /* use default timeout */
865
866 /* do request and autostart a transaction */
867 ret = ldb_autotransaction_request(ldb, req);
868
869 talloc_free(req);
870 return ret;
871}
872
873/*
874 modify the specified attributes of a record
875*/
876int ldb_modify(struct ldb_context *ldb,
877 const struct ldb_message *message)
878{
879 struct ldb_request *req;
880 int ret;
881
882 ret = ldb_msg_sanity_check(ldb, message);
883 if (ret != LDB_SUCCESS) {
884 return ret;
885 }
886
887 ret = ldb_build_mod_req(&req, ldb, ldb,
888 message,
889 NULL,
890 NULL,
891 NULL);
892
893 if (ret != LDB_SUCCESS) return ret;
894
895 ldb_set_timeout(ldb, req, 0); /* use default timeout */
896
897 /* do request and autostart a transaction */
898 ret = ldb_autotransaction_request(ldb, req);
899
900 talloc_free(req);
901 return ret;
902}
903
904
905/*
906 delete a record from the database
907*/
908int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
909{
910 struct ldb_request *req;
911 int ret;
912
913 ret = ldb_build_del_req(&req, ldb, ldb,
914 dn,
915 NULL,
916 NULL,
917 NULL);
918
919 if (ret != LDB_SUCCESS) return ret;
920
921 ldb_set_timeout(ldb, req, 0); /* use default timeout */
922
923 /* do request and autostart a transaction */
924 ret = ldb_autotransaction_request(ldb, req);
925
926 talloc_free(req);
927 return ret;
928}
929
930/*
931 rename a record in the database
932*/
933int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
934{
935 struct ldb_request *req;
936 int ret;
937
938 ret = ldb_build_rename_req(&req, ldb, ldb,
939 olddn,
940 newdn,
941 NULL,
942 NULL,
943 NULL);
944
945 if (ret != LDB_SUCCESS) return ret;
946
947 ldb_set_timeout(ldb, req, 0); /* use default timeout */
948
949 /* do request and autostart a transaction */
950 ret = ldb_autotransaction_request(ldb, req);
951
952 talloc_free(req);
953 return ret;
954}
955
956
957/*
958 return the global sequence number
959*/
960int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num)
961{
962 struct ldb_request *req;
963 int ret;
964
965 req = talloc(ldb, struct ldb_request);
966 if (req == NULL) {
967 ldb_set_errstring(ldb, "Out of Memory");
968 return LDB_ERR_OPERATIONS_ERROR;
969 }
970
971 req->operation = LDB_SEQUENCE_NUMBER;
972 req->controls = NULL;
973 req->context = NULL;
974 req->callback = NULL;
975 ldb_set_timeout(ldb, req, 0); /* use default timeout */
976
977 req->op.seq_num.type = type;
978 /* do request and autostart a transaction */
979 ret = ldb_request(ldb, req);
980
981 if (ret == LDB_SUCCESS) {
982 *seq_num = req->op.seq_num.seq_num;
983 }
984
985 talloc_free(req);
986 return ret;
987}
988
989
990
991/*
992 return extended error information
993*/
994const char *ldb_errstring(struct ldb_context *ldb)
995{
996 if (ldb->err_string) {
997 return ldb->err_string;
998 }
999
1000 return NULL;
1001}
1002
1003/*
1004 return a string explaining what a ldb error constant meancs
1005*/
1006const char *ldb_strerror(int ldb_err)
1007{
1008 switch (ldb_err) {
1009 case LDB_SUCCESS:
1010 return "Success";
1011 case LDB_ERR_OPERATIONS_ERROR:
1012 return "Operations error";
1013 case LDB_ERR_PROTOCOL_ERROR:
1014 return "Protocol error";
1015 case LDB_ERR_TIME_LIMIT_EXCEEDED:
1016 return "Time limit exceeded";
1017 case LDB_ERR_SIZE_LIMIT_EXCEEDED:
1018 return "Size limit exceeded";
1019 case LDB_ERR_COMPARE_FALSE:
1020 return "Compare false";
1021 case LDB_ERR_COMPARE_TRUE:
1022 return "Compare true";
1023 case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED:
1024 return "Auth method not supported";
1025 case LDB_ERR_STRONG_AUTH_REQUIRED:
1026 return "Strong auth required";
1027/* 9 RESERVED */
1028 case LDB_ERR_REFERRAL:
1029 return "Referral error";
1030 case LDB_ERR_ADMIN_LIMIT_EXCEEDED:
1031 return "Admin limit exceeded";
1032 case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION:
1033 return "Unsupported critical extension";
1034 case LDB_ERR_CONFIDENTIALITY_REQUIRED:
1035 return "Confidentiality required";
1036 case LDB_ERR_SASL_BIND_IN_PROGRESS:
1037 return "SASL bind in progress";
1038 case LDB_ERR_NO_SUCH_ATTRIBUTE:
1039 return "No such attribute";
1040 case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE:
1041 return "Undefined attribute type";
1042 case LDB_ERR_INAPPROPRIATE_MATCHING:
1043 return "Inappropriate matching";
1044 case LDB_ERR_CONSTRAINT_VIOLATION:
1045 return "Constraint violation";
1046 case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
1047 return "Attribute or value exists";
1048 case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
1049 return "Invalid attribute syntax";
1050/* 22-31 unused */
1051 case LDB_ERR_NO_SUCH_OBJECT:
1052 return "No such object";
1053 case LDB_ERR_ALIAS_PROBLEM:
1054 return "Alias problem";
1055 case LDB_ERR_INVALID_DN_SYNTAX:
1056 return "Invalid DN syntax";
1057/* 35 RESERVED */
1058 case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM:
1059 return "Alias dereferencing problem";
1060/* 37-47 unused */
1061 case LDB_ERR_INAPPROPRIATE_AUTHENTICATION:
1062 return "Inappropriate authentication";
1063 case LDB_ERR_INVALID_CREDENTIALS:
1064 return "Invalid credentials";
1065 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1066 return "insufficient access rights";
1067 case LDB_ERR_BUSY:
1068 return "Busy";
1069 case LDB_ERR_UNAVAILABLE:
1070 return "Unavailable";
1071 case LDB_ERR_UNWILLING_TO_PERFORM:
1072 return "Unwilling to perform";
1073 case LDB_ERR_LOOP_DETECT:
1074 return "Loop detect";
1075/* 55-63 unused */
1076 case LDB_ERR_NAMING_VIOLATION:
1077 return "Naming violation";
1078 case LDB_ERR_OBJECT_CLASS_VIOLATION:
1079 return "Object class violation";
1080 case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF:
1081 return "Not allowed on non-leaf";
1082 case LDB_ERR_NOT_ALLOWED_ON_RDN:
1083 return "Not allowed on RDN";
1084 case LDB_ERR_ENTRY_ALREADY_EXISTS:
1085 return "Entry already exists";
1086 case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED:
1087 return "Object class mods prohibited";
1088/* 70 RESERVED FOR CLDAP */
1089 case LDB_ERR_AFFECTS_MULTIPLE_DSAS:
1090 return "Affects multiple DSAs";
1091/* 72-79 unused */
1092 case LDB_ERR_OTHER:
1093 return "Other";
1094 }
1095
1096 return "Unknown error";
1097}
1098
1099/*
1100 set backend specific opaque parameters
1101*/
1102int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
1103{
1104 struct ldb_opaque *o;
1105
1106 /* allow updating an existing value */
1107 for (o=ldb->opaque;o;o=o->next) {
1108 if (strcmp(o->name, name) == 0) {
1109 o->value = value;
1110 return LDB_SUCCESS;
1111 }
1112 }
1113
1114 o = talloc(ldb, struct ldb_opaque);
1115 if (o == NULL) {
1116 ldb_oom(ldb);
1117 return LDB_ERR_OTHER;
1118 }
1119 o->next = ldb->opaque;
1120 o->name = name;
1121 o->value = value;
1122 ldb->opaque = o;
1123 return LDB_SUCCESS;
1124}
1125
1126/*
1127 get a previously set opaque value
1128*/
1129void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
1130{
1131 struct ldb_opaque *o;
1132 for (o=ldb->opaque;o;o=o->next) {
1133 if (strcmp(o->name, name) == 0) {
1134 return o->value;
1135 }
1136 }
1137 return NULL;
1138}
Note: See TracBrowser for help on using the repository browser.