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;
479 set backend specific opaque parameters
481 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
483 struct ldb_opaque *o;
485 /* allow updating an existing value */
486 for (o=ldb->opaque;o;o=o->next) {
487 if (strcmp(o->name, name) == 0) {
493 o = talloc(ldb, struct ldb_opaque);
496 return LDB_ERR_OTHER;
498 o->next = ldb->opaque;
506 get a previously set opaque value
508 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
510 struct ldb_opaque *o;
511 for (o=ldb->opaque;o;o=o->next) {
512 if (strcmp(o->name, name) == 0) {