4 Copyright (C) Andrew Tridgell 2004
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Component: ldb core API
30 * Description: core API routines interfacing to ldb backends
32 * Author: Andrew Tridgell
36 #include "ldb/include/includes.h"
39 initialise a ldb context
40 The mem_ctx is optional
42 struct ldb_context *ldb_init(void *mem_ctx)
44 struct ldb_context *ldb = talloc_zero(mem_ctx, struct ldb_context);
47 ret = ldb_setup_wellknown_attributes(ldb);
53 ldb_set_utf8_default(ldb);
58 static struct ldb_backend {
60 ldb_connect_fn connect_fn;
61 struct ldb_backend *prev, *next;
62 } *ldb_backends = NULL;
64 register a new ldb backend
66 int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn)
68 struct ldb_backend *backend = talloc(talloc_autofree_context(), struct ldb_backend);
70 /* Maybe check for duplicity here later on? */
72 backend->name = talloc_strdup(backend, url_prefix);
73 backend->connect_fn = connectfn;
74 DLIST_ADD(ldb_backends, backend);
79 static ldb_connect_fn ldb_find_backend(const char *url)
81 struct ldb_backend *backend;
83 for (backend = ldb_backends; backend; backend = backend->next) {
84 if (strncmp(backend->name, url, strlen(backend->name)) == 0) {
85 return backend->connect_fn;
93 connect to a database. The URL can either be one of the following forms
97 flags is made up of LDB_FLG_*
99 the options are passed uninterpreted to the backend, and are
102 int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[])
108 if (strchr(url, ':') != NULL) {
109 backend = talloc_strndup(ldb, url, strchr(url, ':')-url);
112 backend = talloc_strdup(ldb, "tdb");
115 fn = ldb_find_backend(backend);
118 if (ldb_try_load_dso(ldb, backend) == 0) {
119 fn = ldb_find_backend(backend);
123 talloc_free(backend);
126 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url);
127 return LDB_ERR_OTHER;
130 ret = fn(ldb, url, flags, options);
132 if (ret != LDB_SUCCESS) {
133 ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url);
137 if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
138 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to load modules for '%s'\n", url);
139 return LDB_ERR_OTHER;
145 void ldb_set_errstring(struct ldb_context *ldb, char *err_string)
147 if (ldb->err_string) {
148 talloc_free(ldb->err_string);
150 ldb->err_string = talloc_steal(ldb, err_string);
153 void ldb_reset_err_string(struct ldb_context *ldb)
155 if (ldb->err_string) {
156 talloc_free(ldb->err_string);
157 ldb->err_string = NULL;
161 #define FIRST_OP(ldb, op) do { \
162 module = ldb->modules; \
163 while (module && module->ops->op == NULL) module = module->next; \
164 if (module == NULL) return LDB_ERR_OPERATIONS_ERROR; \
170 int ldb_transaction_start(struct ldb_context *ldb)
172 struct ldb_module *module;
174 FIRST_OP(ldb, start_transaction);
176 ldb->transaction_active++;
178 ldb_reset_err_string(ldb);
180 status = module->ops->start_transaction(module);
181 if (status != LDB_SUCCESS) {
182 if (ldb->err_string == NULL) {
183 /* no error string was setup by the backend */
184 ldb_set_errstring(ldb,
185 talloc_asprintf(ldb, "ldb transaction start error %d", status));
194 int ldb_transaction_commit(struct ldb_context *ldb)
196 struct ldb_module *module;
198 FIRST_OP(ldb, end_transaction);
200 if (ldb->transaction_active > 0) {
201 ldb->transaction_active--;
203 return LDB_ERR_OPERATIONS_ERROR;
206 ldb_reset_err_string(ldb);
208 status = module->ops->end_transaction(module);
209 if (status != LDB_SUCCESS) {
210 if (ldb->err_string == NULL) {
211 /* no error string was setup by the backend */
212 ldb_set_errstring(ldb,
213 talloc_asprintf(ldb, "ldb transaction commit error %d", status));
222 int ldb_transaction_cancel(struct ldb_context *ldb)
224 struct ldb_module *module;
226 FIRST_OP(ldb, del_transaction);
228 if (ldb->transaction_active > 0) {
229 ldb->transaction_active--;
231 return LDB_ERR_OPERATIONS_ERROR;
234 status = module->ops->del_transaction(module);
235 if (status != LDB_SUCCESS) {
236 if (ldb->err_string == NULL) {
237 /* no error string was setup by the backend */
238 ldb_set_errstring(ldb,
239 talloc_asprintf(ldb, "ldb transaction cancel error %d", status));
245 int ldb_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_type type)
247 return handle->module->ops->async_wait(handle, type);
251 check for an error return from an op
252 if an op fails, but has not setup an error string, then setup one now
254 static int ldb_op_finish(struct ldb_context *ldb, int status)
256 if (status == LDB_SUCCESS) {
257 return ldb_transaction_commit(ldb);
259 if (ldb->err_string == NULL) {
260 /* no error string was setup by the backend */
261 ldb_set_errstring(ldb,
262 talloc_asprintf(ldb, "ldb error %d", status));
264 ldb_transaction_cancel(ldb);
270 autostarts a transacion if none active and the operation is not a search
271 NOTE: the request must be a talloc context.
272 returns LDB_ERR_* on errors.
274 int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
276 int status, started_transaction=0;
278 ldb_reset_err_string(ldb);
280 if (req->operation == LDB_REQ_SEARCH) {
281 req->op.search.res = NULL;
284 /* start a transaction if needed */
285 if ((!ldb->transaction_active) &&
286 (req->operation == LDB_REQ_ADD ||
287 req->operation == LDB_REQ_MODIFY ||
288 req->operation == LDB_REQ_DELETE ||
289 req->operation == LDB_REQ_RENAME)) {
290 status = ldb_transaction_start(ldb);
291 if (status != LDB_SUCCESS) {
295 started_transaction = 1;
298 /* call the first module in the chain */
299 status = ldb->modules->ops->request(ldb->modules, req);
301 if (started_transaction) {
302 return ldb_op_finish(ldb, status);
309 search the database given a LDAP-like search expression
311 return the number of records found, or -1 on error
313 Use talloc_free to free the ldb_message returned in 'res'
316 int ldb_search(struct ldb_context *ldb,
317 const struct ldb_dn *base,
318 enum ldb_scope scope,
319 const char *expression,
320 const char * const *attrs,
321 struct ldb_result **res)
323 struct ldb_request *req;
328 req = talloc(ldb, struct ldb_request);
330 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
331 return LDB_ERR_OPERATIONS_ERROR;
334 req->operation = LDB_REQ_SEARCH;
335 req->op.search.base = base;
336 req->op.search.scope = scope;
338 req->op.search.tree = ldb_parse_tree(req, expression);
339 if (req->op.search.tree == NULL) {
340 ldb_set_errstring(ldb, talloc_strdup(ldb, "Unable to parse search expression"));
342 return LDB_ERR_OPERATIONS_ERROR;
345 req->op.search.attrs = attrs;
346 req->controls = NULL;
348 ret = ldb_request(ldb, req);
350 (*res) = talloc_steal(ldb, req->op.search.res);
357 add a record to the database. Will fail if a record with the given class and key
360 int ldb_add(struct ldb_context *ldb,
361 const struct ldb_message *message)
363 struct ldb_request *req;
366 ret = ldb_msg_sanity_check(message);
367 if (ret != LDB_SUCCESS) return ret;
369 req = talloc(ldb, struct ldb_request);
371 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
372 return LDB_ERR_OPERATIONS_ERROR;
375 req->operation = LDB_REQ_ADD;
376 req->op.add.message = message;
377 req->controls = NULL;
379 ret = ldb_request(ldb, req);
386 modify the specified attributes of a record
388 int ldb_modify(struct ldb_context *ldb,
389 const struct ldb_message *message)
391 struct ldb_request *req;
394 ret = ldb_msg_sanity_check(message);
395 if (ret != LDB_SUCCESS) return ret;
397 req = talloc(ldb, struct ldb_request);
399 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
400 return LDB_ERR_OPERATIONS_ERROR;
403 req->operation = LDB_REQ_MODIFY;
404 req->op.add.message = message;
405 req->controls = NULL;
407 ret = ldb_request(ldb, req);
415 delete a record from the database
417 int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
419 struct ldb_request *req;
422 req = talloc(ldb, struct ldb_request);
424 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
425 return LDB_ERR_OPERATIONS_ERROR;
428 req->operation = LDB_REQ_DELETE;
430 req->controls = NULL;
432 ret = ldb_request(ldb, req);
439 rename a record in the database
441 int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
443 struct ldb_request *req;
446 req = talloc(ldb, struct ldb_request);
448 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
449 return LDB_ERR_OPERATIONS_ERROR;
452 req->operation = LDB_REQ_RENAME;
453 req->op.rename.olddn = olddn;
454 req->op.rename.newdn = newdn;
455 req->controls = NULL;
457 ret = ldb_request(ldb, req);
466 return extended error information
468 const char *ldb_errstring(struct ldb_context *ldb)
470 if (ldb->err_string) {
471 return ldb->err_string;
478 return a string explaining what a ldb error constant meancs
480 const char *ldb_strerror(int ldb_err)
485 case LDB_ERR_OPERATIONS_ERROR:
486 return "Operations error";
487 case LDB_ERR_PROTOCOL_ERROR:
488 return "Protocol error";
489 case LDB_ERR_TIME_LIMIT_EXCEEDED:
490 return "Time limit exceeded";
491 case LDB_ERR_SIZE_LIMIT_EXCEEDED:
492 return "Size limit exceeded";
493 case LDB_ERR_COMPARE_FALSE:
494 return "Compare false";
495 case LDB_ERR_COMPARE_TRUE:
496 return "Compare true";
497 case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED:
498 return "Auth method not supported";
499 case LDB_ERR_STRONG_AUTH_REQUIRED:
500 return "Strong auth required";
502 case LDB_ERR_REFERRAL:
503 return "Referral error";
504 case LDB_ERR_ADMIN_LIMIT_EXCEEDED:
505 return "Admin limit exceeded";
506 case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION:
507 return "Unsupported critical extension";
508 case LDB_ERR_CONFIDENTIALITY_REQUIRED:
509 return "Confidentiality required";
510 case LDB_ERR_SASL_BIND_IN_PROGRESS:
511 return "SASL bind in progress";
512 case LDB_ERR_NO_SUCH_ATTRIBUTE:
513 return "No such attribute";
514 case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE:
515 return "Undefined attribute type";
516 case LDB_ERR_INAPPROPRIATE_MATCHING:
517 return "Inappropriate matching";
518 case LDB_ERR_CONSTRAINT_VIOLATION:
519 return "Constraint violation";
520 case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS:
521 return "Attribute or value exists";
522 case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
523 return "Invalid attribute syntax";
525 case LDB_ERR_NO_SUCH_OBJECT:
526 return "No such object";
527 case LDB_ERR_ALIAS_PROBLEM:
528 return "Alias problem";
529 case LDB_ERR_INVALID_DN_SYNTAX:
530 return "Invalid DN syntax";
532 case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM:
533 return "Alias dereferencing problem";
535 case LDB_ERR_INAPPROPRIATE_AUTHENTICATION:
536 return "Inappropriate authentication";
537 case LDB_ERR_INVALID_CREDENTIALS:
538 return "Invalid credentials";
539 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
540 return "insufficient access rights";
543 case LDB_ERR_UNAVAILABLE:
544 return "Unavailable";
545 case LDB_ERR_UNWILLING_TO_PERFORM:
546 return "Unwilling to perform";
547 case LDB_ERR_LOOP_DETECT:
548 return "Loop detect";
550 case LDB_ERR_NAMING_VIOLATION:
551 return "Naming violation";
552 case LDB_ERR_OBJECT_CLASS_VIOLATION:
553 return "Object class violation";
554 case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF:
555 return "Not allowed on non-leaf";
556 case LDB_ERR_NOT_ALLOWED_ON_RDN:
557 return "Not allowed on RDN";
558 case LDB_ERR_ENTRY_ALREADY_EXISTS:
559 return "Entry already exists";
560 case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED:
561 return "Object class mods prohibited";
562 /* 70 RESERVED FOR CLDAP */
563 case LDB_ERR_AFFECTS_MULTIPLE_DSAS:
564 return "Affects multiple DSAs";
570 return "Unknown error";
574 set backend specific opaque parameters
576 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
578 struct ldb_opaque *o;
580 /* allow updating an existing value */
581 for (o=ldb->opaque;o;o=o->next) {
582 if (strcmp(o->name, name) == 0) {
588 o = talloc(ldb, struct ldb_opaque);
591 return LDB_ERR_OTHER;
593 o->next = ldb->opaque;
601 get a previously set opaque value
603 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
605 struct ldb_opaque *o;
606 for (o=ldb->opaque;o;o=o->next) {
607 if (strcmp(o->name, name) == 0) {