r16172: Translate the ldb error codes into appropriate messages for the
[kai/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 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 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 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 = talloc_zero(ldb, struct ldb_result);
531         if (! *res) {
532                 return LDB_ERR_OPERATIONS_ERROR;
533         }
534
535         req = talloc(ldb, struct ldb_request);
536         if (req == NULL) {
537                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
538                 return LDB_ERR_OPERATIONS_ERROR;
539         }
540
541         req->operation = LDB_SEARCH;
542         req->op.search.base = base;
543         req->op.search.scope = scope;
544
545         req->op.search.tree = ldb_parse_tree(req, expression);
546         if (req->op.search.tree == NULL) {
547                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Unable to parse search expression"));
548                 talloc_free(req);
549                 return LDB_ERR_OPERATIONS_ERROR;
550         }
551
552         req->op.search.attrs = attrs;
553         req->controls = NULL;
554         req->async.context = res;
555         req->async.callback = ldb_search_callback;
556         ldb_set_timeout(ldb, req, 0); /* use default timeout */
557
558         ret = ldb_request(ldb, req);
559         
560         if (ret == LDB_SUCCESS) {
561                 ret = ldb_async_wait(req->async.handle, LDB_WAIT_ALL);
562         }
563         
564         if (ret != LDB_SUCCESS) {
565                 talloc_free(*res);
566                 *res = NULL;
567         }
568
569         talloc_free(req);
570         return ret;
571 }
572
573
574 /*
575   add a record to the database. Will fail if a record with the given class and key
576   already exists
577 */
578 int ldb_add(struct ldb_context *ldb, 
579             const struct ldb_message *message)
580 {
581         struct ldb_request *req;
582         int ret;
583
584         ret = ldb_msg_sanity_check(message);
585         if (ret != LDB_SUCCESS) return ret;
586
587         req = talloc(ldb, struct ldb_request);
588         if (req == NULL) {
589                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
590                 return LDB_ERR_OPERATIONS_ERROR;
591         }
592
593         req->operation = LDB_ADD;
594         req->op.add.message = message;
595         req->controls = NULL;
596         req->async.context = NULL;
597         req->async.callback = NULL;
598         ldb_set_timeout(ldb, req, 0); /* use default timeout */
599
600         /* do request and autostart a transaction */
601         ret = ldb_autotransaction_request(ldb, req);
602
603         talloc_free(req);
604         return ret;
605 }
606
607 /*
608   modify the specified attributes of a record
609 */
610 int ldb_modify(struct ldb_context *ldb, 
611                const struct ldb_message *message)
612 {
613         struct ldb_request *req;
614         int ret;
615
616         ret = ldb_msg_sanity_check(message);
617         if (ret != LDB_SUCCESS) return ret;
618
619         req = talloc(ldb, struct ldb_request);
620         if (req == NULL) {
621                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
622                 return LDB_ERR_OPERATIONS_ERROR;
623         }
624
625         req->operation = LDB_MODIFY;
626         req->op.add.message = message;
627         req->controls = NULL;
628         req->async.context = NULL;
629         req->async.callback = NULL;
630         ldb_set_timeout(ldb, req, 0); /* use default timeout */
631
632         /* do request and autostart a transaction */
633         ret = ldb_autotransaction_request(ldb, req);
634
635         talloc_free(req);
636         return ret;
637 }
638
639
640 /*
641   delete a record from the database
642 */
643 int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
644 {
645         struct ldb_request *req;
646         int ret;
647
648         req = talloc(ldb, struct ldb_request);
649         if (req == NULL) {
650                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
651                 return LDB_ERR_OPERATIONS_ERROR;
652         }
653
654         req->operation = LDB_DELETE;
655         req->op.del.dn = dn;
656         req->controls = NULL;
657         req->async.context = NULL;
658         req->async.callback = NULL;
659         ldb_set_timeout(ldb, req, 0); /* use default timeout */
660
661         /* do request and autostart a transaction */
662         ret = ldb_autotransaction_request(ldb, req);
663
664         talloc_free(req);
665         return ret;
666 }
667
668 /*
669   rename a record in the database
670 */
671 int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
672 {
673         struct ldb_request *req;
674         int ret;
675
676         req = talloc(ldb, struct ldb_request);
677         if (req == NULL) {
678                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
679                 return LDB_ERR_OPERATIONS_ERROR;
680         }
681
682         req->operation = LDB_RENAME;
683         req->op.rename.olddn = olddn;
684         req->op.rename.newdn = newdn;
685         req->controls = NULL;
686         req->async.context = NULL;
687         req->async.callback = NULL;
688         ldb_set_timeout(ldb, req, 0); /* use default timeout */
689
690         /* do request and autostart a transaction */
691         ret = ldb_autotransaction_request(ldb, req);
692
693         talloc_free(req);
694         return ret;
695 }
696
697
698 /*
699   rename a record in the database
700 */
701 int ldb_sequence_number(struct ldb_context *ldb, uint64_t *seq_num)
702 {
703         struct ldb_request *req;
704         int ret;
705
706         req = talloc(ldb, struct ldb_request);
707         if (req == NULL) {
708                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
709                 return LDB_ERR_OPERATIONS_ERROR;
710         }
711
712         req->operation = LDB_SEQUENCE_NUMBER;
713         req->controls = NULL;
714         req->async.context = NULL;
715         req->async.callback = NULL;
716         ldb_set_timeout(ldb, req, 0); /* use default timeout */
717
718         /* do request and autostart a transaction */
719         ret = ldb_request(ldb, req);
720         
721         if (ret == LDB_SUCCESS) {
722                 *seq_num = req->op.seq_num.seq_num;
723         }
724
725         talloc_free(req);
726         return ret;
727 }
728
729
730
731 /*
732   return extended error information 
733 */
734 const char *ldb_errstring(struct ldb_context *ldb)
735 {
736         if (ldb->err_string) {
737                 return ldb->err_string;
738         }
739
740         return NULL;
741 }
742
743 /*
744   return a string explaining what a ldb error constant meancs
745 */
746 const char *ldb_strerror(int ldb_err)
747 {
748         switch (ldb_err) {
749         case LDB_SUCCESS:
750                 return "Success";
751         case LDB_ERR_OPERATIONS_ERROR:
752                 return "Operations error";
753         case LDB_ERR_PROTOCOL_ERROR:
754                 return "Protocol error";
755         case LDB_ERR_TIME_LIMIT_EXCEEDED:
756                 return "Time limit exceeded";
757         case LDB_ERR_SIZE_LIMIT_EXCEEDED:
758                 return "Size limit exceeded";
759         case LDB_ERR_COMPARE_FALSE:
760                 return "Compare false";
761         case LDB_ERR_COMPARE_TRUE:
762                 return "Compare true";
763         case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED:
764                 return "Auth method not supported";
765         case LDB_ERR_STRONG_AUTH_REQUIRED:
766                 return "Strong auth required";
767 /* 9 RESERVED */
768         case LDB_ERR_REFERRAL:
769                 return "Referral error";
770         case LDB_ERR_ADMIN_LIMIT_EXCEEDED:
771                 return "Admin limit exceeded";
772         case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION:
773                 return "Unsupported critical extension";
774         case LDB_ERR_CONFIDENTIALITY_REQUIRED:
775                 return "Confidentiality required";
776         case LDB_ERR_SASL_BIND_IN_PROGRESS:
777                 return "SASL bind in progress";
778         case LDB_ERR_NO_SUCH_ATTRIBUTE:
779                 return "No such attribute";
780         case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE:
781                 return "Undefined attribute type";
782         case LDB_ERR_INAPPROPRIATE_MATCHING:
783                 return "Inappropriate matching";
784         case LDB_ERR_CONSTRAINT_VIOLATION:
785                 return "Constraint violation";
786         case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
787                 return "Attribute or value exists";
788         case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
789                 return "Invalid attribute syntax";
790 /* 22-31 unused */
791         case LDB_ERR_NO_SUCH_OBJECT:
792                 return "No such object";
793         case LDB_ERR_ALIAS_PROBLEM:
794                 return "Alias problem";
795         case LDB_ERR_INVALID_DN_SYNTAX:
796                 return "Invalid DN syntax";
797 /* 35 RESERVED */
798         case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM:
799                 return "Alias dereferencing problem";
800 /* 37-47 unused */
801         case LDB_ERR_INAPPROPRIATE_AUTHENTICATION:
802                 return "Inappropriate authentication";
803         case LDB_ERR_INVALID_CREDENTIALS:
804                 return "Invalid credentials";
805         case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
806                 return "insufficient access rights";
807         case LDB_ERR_BUSY:
808                 return "Busy";
809         case LDB_ERR_UNAVAILABLE:
810                 return "Unavailable";
811         case LDB_ERR_UNWILLING_TO_PERFORM:
812                 return "Unwilling to perform";
813         case LDB_ERR_LOOP_DETECT:
814                 return "Loop detect";
815 /* 55-63 unused */
816         case LDB_ERR_NAMING_VIOLATION:
817                 return "Naming violation";
818         case LDB_ERR_OBJECT_CLASS_VIOLATION:
819                 return "Object class violation";
820         case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF:
821                 return "Not allowed on non-leaf";
822         case LDB_ERR_NOT_ALLOWED_ON_RDN:
823                 return "Not allowed on RDN";
824         case LDB_ERR_ENTRY_ALREADY_EXISTS:
825                 return "Entry already exists";
826         case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED:
827                 return "Object class mods prohibited";
828 /* 70 RESERVED FOR CLDAP */
829         case LDB_ERR_AFFECTS_MULTIPLE_DSAS:
830                 return "Affects multiple DSAs";
831 /* 72-79 unused */
832         case LDB_ERR_OTHER:
833                 return "Other";
834         }
835
836         return "Unknown error";
837 }
838
839 /*
840   set backend specific opaque parameters
841 */
842 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
843 {
844         struct ldb_opaque *o;
845
846         /* allow updating an existing value */
847         for (o=ldb->opaque;o;o=o->next) {
848                 if (strcmp(o->name, name) == 0) {
849                         o->value = value;
850                         return LDB_SUCCESS;
851                 }
852         }
853
854         o = talloc(ldb, struct ldb_opaque);
855         if (o == NULL) {
856                 ldb_oom(ldb);
857                 return LDB_ERR_OTHER;
858         }
859         o->next = ldb->opaque;
860         o->name = name;
861         o->value = value;
862         ldb->opaque = o;
863         return LDB_SUCCESS;
864 }
865
866 /*
867   get a previously set opaque value
868 */
869 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
870 {
871         struct ldb_opaque *o;
872         for (o=ldb->opaque;o;o=o->next) {
873                 if (strcmp(o->name, name) == 0) {
874                         return o->value;
875                 }
876         }
877         return NULL;
878 }