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

Last change on this file was 454, checked in by Silvan Scherrer, 15 years ago

Samba Server 3.5: merged changes from 3.3

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