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[])
107 if (strchr(url, ':') != NULL) {
108 fn = ldb_find_backend(url);
111 fn = ldb_find_backend("tdb:");
115 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url);
116 return LDB_ERR_OTHER;
119 ret = fn(ldb, url, flags, options);
121 if (ret != LDB_SUCCESS) {
122 ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url);
126 if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
127 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to load modules for '%s'\n", url);
128 return LDB_ERR_OTHER;
134 void ldb_set_errstring(struct ldb_context *ldb, char *err_string)
136 if (ldb->err_string) {
137 talloc_free(ldb->err_string);
139 ldb->err_string = talloc_steal(ldb, err_string);
142 void ldb_reset_err_string(struct ldb_context *ldb)
144 if (ldb->err_string) {
145 talloc_free(ldb->err_string);
146 ldb->err_string = NULL;
150 #define FIRST_OP(ldb, op) do { \
151 module = ldb->modules; \
152 while (module && module->ops->op == NULL) module = module->next; \
153 if (module == NULL) return LDB_ERR_OPERATIONS_ERROR; \
159 int ldb_transaction_start(struct ldb_context *ldb)
161 struct ldb_module *module;
163 FIRST_OP(ldb, start_transaction);
165 ldb->transaction_active++;
167 ldb_reset_err_string(ldb);
169 status = module->ops->start_transaction(module);
170 if (status != LDB_SUCCESS) {
171 if (ldb->err_string == NULL) {
172 /* no error string was setup by the backend */
173 ldb_set_errstring(ldb,
174 talloc_asprintf(ldb, "ldb transaction start error %d", status));
183 int ldb_transaction_commit(struct ldb_context *ldb)
185 struct ldb_module *module;
187 FIRST_OP(ldb, end_transaction);
189 if (ldb->transaction_active > 0) {
190 ldb->transaction_active--;
192 return LDB_ERR_OPERATIONS_ERROR;
195 ldb_reset_err_string(ldb);
197 status = module->ops->end_transaction(module);
198 if (status != LDB_SUCCESS) {
199 if (ldb->err_string == NULL) {
200 /* no error string was setup by the backend */
201 ldb_set_errstring(ldb,
202 talloc_asprintf(ldb, "ldb transaction commit error %d", status));
211 int ldb_transaction_cancel(struct ldb_context *ldb)
213 struct ldb_module *module;
215 FIRST_OP(ldb, del_transaction);
217 if (ldb->transaction_active > 0) {
218 ldb->transaction_active--;
220 return LDB_ERR_OPERATIONS_ERROR;
223 status = module->ops->del_transaction(module);
224 if (status != LDB_SUCCESS) {
225 if (ldb->err_string == NULL) {
226 /* no error string was setup by the backend */
227 ldb_set_errstring(ldb,
228 talloc_asprintf(ldb, "ldb transaction cancel error %d", status));
234 int ldb_async_wait(struct ldb_context *ldb, struct ldb_async_handle *handle, enum ldb_async_wait_type type)
236 return handle->module->ops->async_wait(handle, type);
240 check for an error return from an op
241 if an op fails, but has not setup an error string, then setup one now
243 static int ldb_op_finish(struct ldb_context *ldb, int status)
245 if (status == LDB_SUCCESS) {
246 return ldb_transaction_commit(ldb);
248 if (ldb->err_string == NULL) {
249 /* no error string was setup by the backend */
250 ldb_set_errstring(ldb,
251 talloc_asprintf(ldb, "ldb error %d", status));
253 ldb_transaction_cancel(ldb);
259 autostarts a transacion if none active and the operation is not a search
260 returns LDB_ERR_* on errors.
262 int ldb_request(struct ldb_context *ldb, struct ldb_request *request)
264 int status, started_transaction=0;
265 struct ldb_request *r;
267 ldb_reset_err_string(ldb);
269 /* to allow ldb modules to assume they can use the request ptr
270 as a talloc context for the request, we have to copy the
272 r = talloc(ldb, struct ldb_request);
275 return LDB_ERR_OPERATIONS_ERROR;
280 if (r->operation == LDB_REQ_SEARCH) {
281 r->op.search.res = NULL;
284 /* start a transaction if needed */
285 if ((!ldb->transaction_active) &&
286 (request->operation == LDB_REQ_ADD ||
287 request->operation == LDB_REQ_MODIFY ||
288 request->operation == LDB_REQ_DELETE ||
289 request->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, r);
301 /* the search call is the only one that returns something
302 other than a status code. We steal the results into
303 the context of the ldb before freeing the request */
304 if (status == LDB_SUCCESS && request->operation == LDB_REQ_SEARCH) {
305 request->op.search.res = talloc_steal(ldb, r->op.search.res);
307 if (status == LDB_SUCCESS && request->operation == LDB_ASYNC_SEARCH) {
308 request->async.handle = r->async.handle;
312 if (started_transaction) {
313 return ldb_op_finish(ldb, status);
320 search the database given a LDAP-like search expression
322 return the number of records found, or -1 on error
324 Use talloc_free to free the ldb_message returned in 'res'
327 int ldb_search(struct ldb_context *ldb,
328 const struct ldb_dn *base,
329 enum ldb_scope scope,
330 const char *expression,
331 const char * const *attrs,
332 struct ldb_result **res)
334 struct ldb_request request;
335 struct ldb_parse_tree *tree;
340 tree = ldb_parse_tree(ldb, expression);
342 ldb_set_errstring(ldb, talloc_strdup(ldb, "Unable to parse search expression"));
346 request.operation = LDB_REQ_SEARCH;
347 request.op.search.base = base;
348 request.op.search.scope = scope;
349 request.op.search.tree = tree;
350 request.op.search.attrs = attrs;
351 request.controls = NULL;
353 ret = ldb_request(ldb, &request);
355 (*res) = request.op.search.res;
363 add a record to the database. Will fail if a record with the given class and key
366 int ldb_add(struct ldb_context *ldb,
367 const struct ldb_message *message)
369 struct ldb_request request;
372 status = ldb_msg_sanity_check(message);
373 if (status != LDB_SUCCESS) return status;
375 request.operation = LDB_REQ_ADD;
376 request.op.add.message = message;
377 request.controls = NULL;
379 return ldb_request(ldb, &request);
383 modify the specified attributes of a record
385 int ldb_modify(struct ldb_context *ldb,
386 const struct ldb_message *message)
388 struct ldb_request request;
391 status = ldb_msg_sanity_check(message);
392 if (status != LDB_SUCCESS) return status;
394 request.operation = LDB_REQ_MODIFY;
395 request.op.mod.message = message;
396 request.controls = NULL;
398 return ldb_request(ldb, &request);
403 delete a record from the database
405 int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
407 struct ldb_request request;
409 request.operation = LDB_REQ_DELETE;
410 request.op.del.dn = dn;
411 request.controls = NULL;
413 return ldb_request(ldb, &request);
417 rename a record in the database
419 int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
421 struct ldb_request request;
423 request.operation = LDB_REQ_RENAME;
424 request.op.rename.olddn = olddn;
425 request.op.rename.newdn = newdn;
426 request.controls = NULL;
428 return ldb_request(ldb, &request);
434 return extended error information
436 const char *ldb_errstring(struct ldb_context *ldb)
438 if (ldb->err_string) {
439 return ldb->err_string;
447 set backend specific opaque parameters
449 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
451 struct ldb_opaque *o;
453 /* allow updating an existing value */
454 for (o=ldb->opaque;o;o=o->next) {
455 if (strcmp(o->name, name) == 0) {
461 o = talloc(ldb, struct ldb_opaque);
464 return LDB_ERR_OTHER;
466 o->next = ldb->opaque;
474 get a previously set opaque value
476 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
478 struct ldb_opaque *o;
479 for (o=ldb->opaque;o;o=o->next) {
480 if (strcmp(o->name, name) == 0) {