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