r16825: Make ldb_sainity_check() set an error string. This makes it much
[kamenim/samba.git] / source4 / lib / ldb / common / ldb.c
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 2 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, write to the Free Software
23    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 */
25
26 /*
27  *  Name: ldb
28  *
29  *  Component: ldb core API
30  *
31  *  Description: core API routines interfacing to ldb backends
32  *
33  *  Author: Andrew Tridgell
34  */
35
36 #include "includes.h"
37 #include "ldb/include/includes.h"
38
39 /* 
40    initialise a ldb context
41    The mem_ctx is optional
42 */
43 struct ldb_context *ldb_init(void *mem_ctx)
44 {
45         struct ldb_context *ldb = talloc_zero(mem_ctx, struct ldb_context);
46         int ret;
47
48         ret = ldb_setup_wellknown_attributes(ldb);
49         if (ret != 0) {
50                 talloc_free(ldb);
51                 return NULL;
52         }
53
54         ldb_set_utf8_default(ldb);
55
56         return ldb;
57 }
58
59 static 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  register a new ldb backend
66 */
67 int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn)
68 {
69         struct ldb_backend *backend = talloc(talloc_autofree_context(), struct ldb_backend);
70
71         /* Maybe check for duplicity here later on? */
72
73         backend->name = talloc_strdup(backend, url_prefix);
74         backend->connect_fn = connectfn;
75         DLIST_ADD(ldb_backends, backend);
76
77         return LDB_SUCCESS;
78 }
79
80 static ldb_connect_fn ldb_find_backend(const char *url)
81 {
82         struct ldb_backend *backend;
83
84         for (backend = ldb_backends; backend; backend = backend->next) {
85                 if (strncmp(backend->name, url, strlen(backend->name)) == 0) {
86                         return backend->connect_fn;
87                 }
88         }
89
90         return NULL;
91 }
92
93 /* 
94    Return the ldb module form of a database. The URL can either be one of the following forms
95    ldb://path
96    ldapi://path
97
98    flags is made up of LDB_FLG_*
99
100    the options are passed uninterpreted to the backend, and are
101    backend specific.
102
103   This allows modules to get at only the backend module, for example where a module 
104   may wish to direct certain requests at a particular backend.
105 */
106 int ldb_connect_backend(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[],
107                         struct ldb_module **backend_module)
108 {
109         int ret;
110         char *backend;
111         ldb_connect_fn fn;
112
113         if (strchr(url, ':') != NULL) {
114                 backend = talloc_strndup(ldb, url, strchr(url, ':')-url);
115         } else {
116                 /* Default to tdb */
117                 backend = talloc_strdup(ldb, "tdb");
118         }
119
120         fn = ldb_find_backend(backend);
121
122         if (fn == NULL) {
123                 if (ldb_try_load_dso(ldb, backend) == 0) {
124                         fn = ldb_find_backend(backend);
125                 }
126         }
127
128         talloc_free(backend);
129
130         if (fn == NULL) {
131                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url);
132                 return LDB_ERR_OTHER;
133         }
134
135         ret = fn(ldb, url, flags, options, backend_module);
136
137         if (ret != LDB_SUCCESS) {
138                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url);
139                 return ret;
140         }
141         return ret;
142 }
143
144
145 /* 
146  connect to a database. The URL can either be one of the following forms
147    ldb://path
148    ldapi://path
149
150    flags is made up of LDB_FLG_*
151
152    the options are passed uninterpreted to the backend, and are
153    backend specific
154 */
155 int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[])
156 {
157         int ret;
158
159         ret = ldb_connect_backend(ldb, url, flags, options, &ldb->modules);
160         if (ret != LDB_SUCCESS) {
161                 return ret;
162         }
163
164         if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
165                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to load modules for '%s'\n", url);
166                 return LDB_ERR_OTHER;
167         }
168
169         /* TODO: get timeout from options if available there */
170         ldb->default_timeout = 300; /* set default to 5 minutes */
171
172         return LDB_SUCCESS;
173 }
174
175 void ldb_set_errstring(struct ldb_context *ldb, char *err_string)
176 {
177         if (ldb->err_string) {
178                 talloc_free(ldb->err_string);
179         }
180         ldb->err_string = talloc_steal(ldb, err_string);
181 }
182
183 void ldb_reset_err_string(struct ldb_context *ldb)
184 {
185         if (ldb->err_string) {
186                 talloc_free(ldb->err_string);
187                 ldb->err_string = NULL;
188         }
189 }
190
191 #define FIRST_OP(ldb, op) do { \
192         module = ldb->modules;                                  \
193         while (module && module->ops->op == NULL) module = module->next; \
194         if (module == NULL) {                                           \
195                 ldb_set_errstring(ldb, \
196                                   talloc_asprintf(ldb, "unable to find module or backend to handle operation: " #op)); \
197                 return LDB_ERR_OPERATIONS_ERROR;                        \
198         } \
199 } while (0)
200
201 /*
202   start a transaction
203 */
204 static int ldb_transaction_start_internal(struct ldb_context *ldb)
205 {
206         struct ldb_module *module;
207         int status;
208         FIRST_OP(ldb, start_transaction);
209
210         ldb_reset_err_string(ldb);
211
212         status = module->ops->start_transaction(module);
213         if (status != LDB_SUCCESS) {
214                 if (ldb->err_string == NULL) {
215                         /* no error string was setup by the backend */
216                         ldb_set_errstring(ldb, 
217                                           talloc_asprintf(ldb, "ldb transaction start: %s (%d)", 
218                                                           ldb_strerror(status), 
219                                                           status));
220                 }
221         }
222         return status;
223 }
224
225 /*
226   commit a transaction
227 */
228 static int ldb_transaction_commit_internal(struct ldb_context *ldb)
229 {
230         struct ldb_module *module;
231         int status;
232         FIRST_OP(ldb, end_transaction);
233
234         ldb_reset_err_string(ldb);
235
236         status = module->ops->end_transaction(module);
237         if (status != LDB_SUCCESS) {
238                 if (ldb->err_string == NULL) {
239                         /* no error string was setup by the backend */
240                         ldb_set_errstring(ldb, 
241                                           talloc_asprintf(ldb, "ldb transaction commit: %s (%d)", 
242                                                           ldb_strerror(status), 
243                                                           status));
244                 }
245         }
246         return status;
247 }
248
249 /*
250   cancel a transaction
251 */
252 static int ldb_transaction_cancel_internal(struct ldb_context *ldb)
253 {
254         struct ldb_module *module;
255         int status;
256         FIRST_OP(ldb, del_transaction);
257
258         status = module->ops->del_transaction(module);
259         if (status != LDB_SUCCESS) {
260                 if (ldb->err_string == NULL) {
261                         /* no error string was setup by the backend */
262                         ldb_set_errstring(ldb, 
263                                           talloc_asprintf(ldb, "ldb transaction cancel: %s (%d)", 
264                                                           ldb_strerror(status), 
265                                                           status));
266                 }
267         }
268         return status;
269 }
270
271 int ldb_transaction_start(struct ldb_context *ldb)
272 {
273         /* disable autotransactions */
274         ldb->transaction_active++;
275
276         return ldb_transaction_start_internal(ldb);
277 }
278
279 int ldb_transaction_commit(struct ldb_context *ldb)
280 {
281         /* renable autotransactions (when we reach 0) */
282         if (ldb->transaction_active > 0)
283                 ldb->transaction_active--;
284
285         return ldb_transaction_commit_internal(ldb);
286 }
287
288 int ldb_transaction_cancel(struct ldb_context *ldb)
289 {
290         /* renable autotransactions (when we reach 0) */
291         if (ldb->transaction_active > 0)
292                 ldb->transaction_active--;
293
294         return ldb_transaction_cancel_internal(ldb);
295 }
296
297 static int ldb_autotransaction_start(struct ldb_context *ldb)
298 {
299         /* explicit transaction active, ignore autotransaction request */
300         if (ldb->transaction_active)
301                 return LDB_SUCCESS;
302
303         return ldb_transaction_start_internal(ldb);
304 }
305
306 static int ldb_autotransaction_commit(struct ldb_context *ldb)
307 {
308         /* explicit transaction active, ignore autotransaction request */
309         if (ldb->transaction_active)
310                 return LDB_SUCCESS;
311
312         return ldb_transaction_commit_internal(ldb);
313 }
314
315 static int ldb_autotransaction_cancel(struct ldb_context *ldb)
316 {
317         /* explicit transaction active, ignore autotransaction request */
318         if (ldb->transaction_active)
319                 return LDB_SUCCESS;
320
321         return ldb_transaction_cancel_internal(ldb);
322 }
323
324 /* autostarts a transacion if none active */
325 static int ldb_autotransaction_request(struct ldb_context *ldb, struct ldb_request *req)
326 {
327         int ret;
328
329         ret = ldb_autotransaction_start(ldb);
330         if (ret != LDB_SUCCESS) {
331                 return ret;
332         }
333
334         ret = ldb_request(ldb, req);
335         if (ret == LDB_SUCCESS) {
336                 ret = ldb_async_wait(req->async.handle, LDB_WAIT_ALL);
337         }
338
339         if (ret == LDB_SUCCESS) {
340                 return ldb_autotransaction_commit(ldb);
341         }
342         ldb_autotransaction_cancel(ldb);
343
344         if (ldb->err_string == NULL) {
345                 /* no error string was setup by the backend */
346                 ldb_set_errstring(ldb, 
347                                   talloc_asprintf(ldb, "%s (%d)", 
348                                                   ldb_strerror(ret), ret));
349         }
350
351         return ret;
352 }
353
354 int ldb_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_type type)
355 {
356         if (!handle) {
357                 return LDB_SUCCESS;
358         }
359
360         return handle->module->ops->async_wait(handle, type);
361 }
362
363 /* set the specified timeout or, if timeout is 0 set the default timeout */
364 /* timeout == -1 means no timeout */
365 int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout)
366 {
367         if (req == NULL) return LDB_ERR_OPERATIONS_ERROR;
368         
369         if (timeout != 0) {
370                 req->async.timeout = timeout;
371         } else {
372                 req->async.timeout = ldb->default_timeout;
373         }
374         req->async.starttime = time(NULL);
375
376         return LDB_SUCCESS;
377 }
378
379 /* calculates the new timeout based on the previous starttime and timeout */
380 int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq)
381 {
382         time_t now;
383
384         if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR;
385
386         now = time(NULL);
387
388         if (oldreq == NULL)
389                 return ldb_set_timeout(ldb, newreq, 0);
390
391         if ((now - oldreq->async.starttime) > oldreq->async.timeout) {
392                 return LDB_ERR_TIME_LIMIT_EXCEEDED;
393         }
394         newreq->async.starttime = oldreq->async.starttime;
395         newreq->async.timeout = oldreq->async.timeout - (now - oldreq->async.starttime);
396
397         return LDB_SUCCESS;
398 }
399
400 /*
401   start an ldb request
402   NOTE: the request must be a talloc context.
403   returns LDB_ERR_* on errors.
404 */
405 int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
406 {
407         struct ldb_module *module;
408         int ret;
409
410         ldb_reset_err_string(ldb);
411
412         /* call the first module in the chain */
413         switch (req->operation) {
414         case LDB_SEARCH:
415                 FIRST_OP(ldb, search);
416                 ret = module->ops->search(module, req);
417                 break;
418         case LDB_ADD:
419                 FIRST_OP(ldb, add);
420                 ret = module->ops->add(module, req);
421                 break;
422         case LDB_MODIFY:
423                 FIRST_OP(ldb, modify);
424                 ret = module->ops->modify(module, req);
425                 break;
426         case LDB_DELETE:
427                 FIRST_OP(ldb, del);
428                 ret = module->ops->del(module, req);
429                 break;
430         case LDB_RENAME:
431                 FIRST_OP(ldb, rename);
432                 ret = module->ops->rename(module, req);
433                 break;
434         case LDB_SEQUENCE_NUMBER:
435                 FIRST_OP(ldb, sequence_number);
436                 ret = module->ops->sequence_number(module, req);
437                 break;
438         default:
439                 FIRST_OP(ldb, request);
440                 ret = module->ops->request(module, req);
441                 break;
442         }
443
444         return ret;
445 }
446
447 /*
448   search the database given a LDAP-like search expression
449
450   returns an LDB error code
451
452   Use talloc_free to free the ldb_message returned in 'res', if successful
453
454 */
455 static int ldb_search_callback(struct ldb_context *ldb, void *context, struct ldb_async_result *ares)
456 {
457         struct ldb_result *res;
458         int n;
459         
460         if (!context) {
461                 ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context in callback"));
462                 return LDB_ERR_OPERATIONS_ERROR;
463         }       
464
465         res = *((struct ldb_result **)context);
466
467         if (!res || !ares) {
468                 goto error;
469         }
470
471         if (ares->type == LDB_REPLY_ENTRY) {
472                 res->msgs = talloc_realloc(res, res->msgs, struct ldb_message *, res->count + 2);
473                 if (! res->msgs) {
474                         goto error;
475                 }
476
477                 res->msgs[res->count + 1] = NULL;
478
479                 res->msgs[res->count] = talloc_steal(res->msgs, ares->message);
480                 if (! res->msgs[res->count]) {
481                         goto error;
482                 }
483
484                 res->count++;
485         }
486
487         if (ares->type == LDB_REPLY_REFERRAL) {
488                 if (res->refs) {
489                         for (n = 0; res->refs[n]; n++) /*noop*/ ;
490                 } else {
491                         n = 0;
492                 }
493
494                 res->refs = talloc_realloc(res, res->refs, char *, n + 2);
495                 if (! res->refs) {
496                         goto error;
497                 }
498
499                 res->refs[n] = talloc_steal(res->refs, ares->referral);
500                 res->refs[n + 1] = NULL;
501         }
502
503         if (ares->controls) {
504                 res->controls = talloc_steal(res, ares->controls);
505                 if (! res->controls) {
506                         goto error;
507                 }
508         }
509
510         talloc_free(ares);
511         return LDB_SUCCESS;
512
513 error:
514         talloc_free(ares);
515         talloc_free(res);
516         *((struct ldb_result **)context) = NULL;
517         return LDB_ERR_OPERATIONS_ERROR;
518 }
519
520 int ldb_search(struct ldb_context *ldb, 
521                const struct ldb_dn *base,
522                enum ldb_scope scope,
523                const char *expression,
524                const char * const *attrs, 
525                struct ldb_result **res)
526 {
527         struct ldb_request *req;
528         int ret;
529
530         *res = NULL;
531         
532         req = talloc(ldb, struct ldb_request);
533         if (req == NULL) {
534                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
535                 return LDB_ERR_OPERATIONS_ERROR;
536         }
537
538         req->operation = LDB_SEARCH;
539         req->op.search.base = base;
540         req->op.search.scope = scope;
541
542         req->op.search.tree = ldb_parse_tree(req, expression);
543         if (req->op.search.tree == NULL) {
544                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Unable to parse search expression"));
545                 talloc_free(req);
546                 return LDB_ERR_OPERATIONS_ERROR;
547         }
548
549         *res = talloc_zero(ldb, struct ldb_result);
550         if (! *res) {
551                 talloc_free(req);
552                 return LDB_ERR_OPERATIONS_ERROR;
553         }
554
555         req->op.search.attrs = attrs;
556         req->controls = NULL;
557         req->async.context = res;
558         req->async.callback = ldb_search_callback;
559         ldb_set_timeout(ldb, req, 0); /* use default timeout */
560
561         ret = ldb_request(ldb, req);
562         
563         if (ret == LDB_SUCCESS) {
564                 ret = ldb_async_wait(req->async.handle, LDB_WAIT_ALL);
565         }
566         
567         if (ret != LDB_SUCCESS) {
568                 talloc_free(*res);
569                 *res = NULL;
570         }
571
572         talloc_free(req);
573         return ret;
574 }
575
576
577 /*
578   add a record to the database. Will fail if a record with the given class and key
579   already exists
580 */
581 int ldb_add(struct ldb_context *ldb, 
582             const struct ldb_message *message)
583 {
584         struct ldb_request *req;
585         int ret;
586
587         ret = ldb_msg_sanity_check(ldb, message);
588         if (ret != LDB_SUCCESS) {
589                 return ret;
590         }
591                 
592         req = talloc(ldb, struct ldb_request);
593         if (req == NULL) {
594                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
595                 return LDB_ERR_OPERATIONS_ERROR;
596         }
597
598         req->operation = LDB_ADD;
599         req->op.add.message = message;
600         req->controls = NULL;
601         req->async.context = NULL;
602         req->async.callback = NULL;
603         ldb_set_timeout(ldb, req, 0); /* use default timeout */
604
605         /* do request and autostart a transaction */
606         ret = ldb_autotransaction_request(ldb, req);
607
608         talloc_free(req);
609         return ret;
610 }
611
612 /*
613   modify the specified attributes of a record
614 */
615 int ldb_modify(struct ldb_context *ldb, 
616                const struct ldb_message *message)
617 {
618         struct ldb_request *req;
619         int ret;
620
621         ret = ldb_msg_sanity_check(ldb, message);
622         if (ret != LDB_SUCCESS) return ret;
623
624         req = talloc(ldb, struct ldb_request);
625         if (req == NULL) {
626                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
627                 return LDB_ERR_OPERATIONS_ERROR;
628         }
629
630         req->operation = LDB_MODIFY;
631         req->op.add.message = message;
632         req->controls = NULL;
633         req->async.context = NULL;
634         req->async.callback = NULL;
635         ldb_set_timeout(ldb, req, 0); /* use default timeout */
636
637         /* do request and autostart a transaction */
638         ret = ldb_autotransaction_request(ldb, req);
639
640         talloc_free(req);
641         return ret;
642 }
643
644
645 /*
646   delete a record from the database
647 */
648 int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
649 {
650         struct ldb_request *req;
651         int ret;
652
653         req = talloc(ldb, struct ldb_request);
654         if (req == NULL) {
655                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
656                 return LDB_ERR_OPERATIONS_ERROR;
657         }
658
659         req->operation = LDB_DELETE;
660         req->op.del.dn = dn;
661         req->controls = NULL;
662         req->async.context = NULL;
663         req->async.callback = NULL;
664         ldb_set_timeout(ldb, req, 0); /* use default timeout */
665
666         /* do request and autostart a transaction */
667         ret = ldb_autotransaction_request(ldb, req);
668
669         talloc_free(req);
670         return ret;
671 }
672
673 /*
674   rename a record in the database
675 */
676 int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
677 {
678         struct ldb_request *req;
679         int ret;
680
681         req = talloc(ldb, struct ldb_request);
682         if (req == NULL) {
683                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
684                 return LDB_ERR_OPERATIONS_ERROR;
685         }
686
687         req->operation = LDB_RENAME;
688         req->op.rename.olddn = olddn;
689         req->op.rename.newdn = newdn;
690         req->controls = NULL;
691         req->async.context = NULL;
692         req->async.callback = NULL;
693         ldb_set_timeout(ldb, req, 0); /* use default timeout */
694
695         /* do request and autostart a transaction */
696         ret = ldb_autotransaction_request(ldb, req);
697
698         talloc_free(req);
699         return ret;
700 }
701
702
703 /*
704   rename a record in the database
705 */
706 int ldb_sequence_number(struct ldb_context *ldb, uint64_t *seq_num)
707 {
708         struct ldb_request *req;
709         int ret;
710
711         req = talloc(ldb, struct ldb_request);
712         if (req == NULL) {
713                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
714                 return LDB_ERR_OPERATIONS_ERROR;
715         }
716
717         req->operation = LDB_SEQUENCE_NUMBER;
718         req->controls = NULL;
719         req->async.context = NULL;
720         req->async.callback = NULL;
721         ldb_set_timeout(ldb, req, 0); /* use default timeout */
722
723         /* do request and autostart a transaction */
724         ret = ldb_request(ldb, req);
725         
726         if (ret == LDB_SUCCESS) {
727                 *seq_num = req->op.seq_num.seq_num;
728         }
729
730         talloc_free(req);
731         return ret;
732 }
733
734
735
736 /*
737   return extended error information 
738 */
739 const char *ldb_errstring(struct ldb_context *ldb)
740 {
741         if (ldb->err_string) {
742                 return ldb->err_string;
743         }
744
745         return NULL;
746 }
747
748 /*
749   return a string explaining what a ldb error constant meancs
750 */
751 const char *ldb_strerror(int ldb_err)
752 {
753         switch (ldb_err) {
754         case LDB_SUCCESS:
755                 return "Success";
756         case LDB_ERR_OPERATIONS_ERROR:
757                 return "Operations error";
758         case LDB_ERR_PROTOCOL_ERROR:
759                 return "Protocol error";
760         case LDB_ERR_TIME_LIMIT_EXCEEDED:
761                 return "Time limit exceeded";
762         case LDB_ERR_SIZE_LIMIT_EXCEEDED:
763                 return "Size limit exceeded";
764         case LDB_ERR_COMPARE_FALSE:
765                 return "Compare false";
766         case LDB_ERR_COMPARE_TRUE:
767                 return "Compare true";
768         case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED:
769                 return "Auth method not supported";
770         case LDB_ERR_STRONG_AUTH_REQUIRED:
771                 return "Strong auth required";
772 /* 9 RESERVED */
773         case LDB_ERR_REFERRAL:
774                 return "Referral error";
775         case LDB_ERR_ADMIN_LIMIT_EXCEEDED:
776                 return "Admin limit exceeded";
777         case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION:
778                 return "Unsupported critical extension";
779         case LDB_ERR_CONFIDENTIALITY_REQUIRED:
780                 return "Confidentiality required";
781         case LDB_ERR_SASL_BIND_IN_PROGRESS:
782                 return "SASL bind in progress";
783         case LDB_ERR_NO_SUCH_ATTRIBUTE:
784                 return "No such attribute";
785         case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE:
786                 return "Undefined attribute type";
787         case LDB_ERR_INAPPROPRIATE_MATCHING:
788                 return "Inappropriate matching";
789         case LDB_ERR_CONSTRAINT_VIOLATION:
790                 return "Constraint violation";
791         case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
792                 return "Attribute or value exists";
793         case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
794                 return "Invalid attribute syntax";
795 /* 22-31 unused */
796         case LDB_ERR_NO_SUCH_OBJECT:
797                 return "No such object";
798         case LDB_ERR_ALIAS_PROBLEM:
799                 return "Alias problem";
800         case LDB_ERR_INVALID_DN_SYNTAX:
801                 return "Invalid DN syntax";
802 /* 35 RESERVED */
803         case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM:
804                 return "Alias dereferencing problem";
805 /* 37-47 unused */
806         case LDB_ERR_INAPPROPRIATE_AUTHENTICATION:
807                 return "Inappropriate authentication";
808         case LDB_ERR_INVALID_CREDENTIALS:
809                 return "Invalid credentials";
810         case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
811                 return "insufficient access rights";
812         case LDB_ERR_BUSY:
813                 return "Busy";
814         case LDB_ERR_UNAVAILABLE:
815                 return "Unavailable";
816         case LDB_ERR_UNWILLING_TO_PERFORM:
817                 return "Unwilling to perform";
818         case LDB_ERR_LOOP_DETECT:
819                 return "Loop detect";
820 /* 55-63 unused */
821         case LDB_ERR_NAMING_VIOLATION:
822                 return "Naming violation";
823         case LDB_ERR_OBJECT_CLASS_VIOLATION:
824                 return "Object class violation";
825         case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF:
826                 return "Not allowed on non-leaf";
827         case LDB_ERR_NOT_ALLOWED_ON_RDN:
828                 return "Not allowed on RDN";
829         case LDB_ERR_ENTRY_ALREADY_EXISTS:
830                 return "Entry already exists";
831         case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED:
832                 return "Object class mods prohibited";
833 /* 70 RESERVED FOR CLDAP */
834         case LDB_ERR_AFFECTS_MULTIPLE_DSAS:
835                 return "Affects multiple DSAs";
836 /* 72-79 unused */
837         case LDB_ERR_OTHER:
838                 return "Other";
839         }
840
841         return "Unknown error";
842 }
843
844 /*
845   set backend specific opaque parameters
846 */
847 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
848 {
849         struct ldb_opaque *o;
850
851         /* allow updating an existing value */
852         for (o=ldb->opaque;o;o=o->next) {
853                 if (strcmp(o->name, name) == 0) {
854                         o->value = value;
855                         return LDB_SUCCESS;
856                 }
857         }
858
859         o = talloc(ldb, struct ldb_opaque);
860         if (o == NULL) {
861                 ldb_oom(ldb);
862                 return LDB_ERR_OTHER;
863         }
864         o->next = ldb->opaque;
865         o->name = name;
866         o->value = value;
867         ldb->opaque = o;
868         return LDB_SUCCESS;
869 }
870
871 /*
872   get a previously set opaque value
873 */
874 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
875 {
876         struct ldb_opaque *o;
877         for (o=ldb->opaque;o;o=o->next) {
878                 if (strcmp(o->name, name) == 0) {
879                         return o->value;
880                 }
881         }
882         return NULL;
883 }