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);
59 connect to a database. The URL can either be one of the following forms
63 flags is made up of LDB_FLG_*
65 the options are passed uninterpreted to the backend, and are
68 int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[])
72 if (strncmp(url, "tdb:", 4) == 0 ||
73 strchr(url, ':') == NULL) {
74 ret = ltdb_connect(ldb, url, flags, options);
78 else if (strncmp(url, "ldap", 4) == 0) {
79 ret = ildb_connect(ldb, url, flags, options);
82 else if (strncmp(url, "ldap", 4) == 0) {
83 ret = lldb_connect(ldb, url, flags, options);
87 else if (strncmp(url, "sqlite:", 7) == 0) {
88 ret = lsqlite3_connect(ldb, url, flags, options);
92 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url);
96 if (ret != LDB_SUCCESS) {
97 ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url);
101 if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
102 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to load modules for '%s'\n", url);
103 return LDB_ERR_OTHER;
109 void ldb_set_errstring(struct ldb_context *ldb, char *err_string)
111 if (ldb->err_string) {
112 talloc_free(ldb->err_string);
114 ldb->err_string = talloc_steal(ldb, err_string);
117 void ldb_reset_err_string(struct ldb_context *ldb)
119 if (ldb->err_string) {
120 talloc_free(ldb->err_string);
121 ldb->err_string = NULL;
125 #define FIRST_OP(ldb, op) do { \
126 module = ldb->modules; \
127 while (module && module->ops->op == NULL) module = module->next; \
128 if (module == NULL) return -1; \
132 second stage init all modules loaded
134 int ldb_second_stage_init(struct ldb_context *ldb)
136 struct ldb_module *module;
138 FIRST_OP(ldb, second_stage_init);
140 return module->ops->second_stage_init(module);
147 int ldb_transaction_start(struct ldb_context *ldb)
149 struct ldb_module *module;
151 FIRST_OP(ldb, start_transaction);
153 ldb->transaction_active++;
155 ldb_reset_err_string(ldb);
157 status = module->ops->start_transaction(module);
158 if (status != LDB_SUCCESS) {
159 if (ldb->err_string == NULL) {
160 /* no error string was setup by the backend */
161 ldb_set_errstring(ldb,
162 talloc_asprintf(ldb, "ldb transaction start error %d", status));
171 int ldb_transaction_commit(struct ldb_context *ldb)
173 struct ldb_module *module;
175 FIRST_OP(ldb, end_transaction);
177 if (ldb->transaction_active > 0) {
178 ldb->transaction_active--;
180 return LDB_ERR_OPERATIONS_ERROR;
183 ldb_reset_err_string(ldb);
185 status = module->ops->end_transaction(module);
186 if (status != LDB_SUCCESS) {
187 if (ldb->err_string == NULL) {
188 /* no error string was setup by the backend */
189 ldb_set_errstring(ldb,
190 talloc_asprintf(ldb, "ldb transaction commit error %d", status));
199 int ldb_transaction_cancel(struct ldb_context *ldb)
201 struct ldb_module *module;
203 FIRST_OP(ldb, del_transaction);
205 if (ldb->transaction_active > 0) {
206 ldb->transaction_active--;
208 return LDB_ERR_OPERATIONS_ERROR;
211 status = module->ops->del_transaction(module);
212 if (status != LDB_SUCCESS) {
213 if (ldb->err_string == NULL) {
214 /* no error string was setup by the backend */
215 ldb_set_errstring(ldb,
216 talloc_asprintf(ldb, "ldb transaction cancel error %d", status));
222 int ldb_async_wait(struct ldb_context *ldb, struct ldb_async_handle *handle, enum ldb_async_wait_type type)
224 if (ldb->async_wait != NULL)
225 return ldb->async_wait(handle, type);
227 return LDB_ERR_OPERATIONS_ERROR;
231 check for an error return from an op
232 if an op fails, but has not setup an error string, then setup one now
234 static int ldb_op_finish(struct ldb_context *ldb, int status)
236 if (status == LDB_SUCCESS) {
237 return ldb_transaction_commit(ldb);
239 if (ldb->err_string == NULL) {
240 /* no error string was setup by the backend */
241 ldb_set_errstring(ldb,
242 talloc_asprintf(ldb, "ldb error %d", status));
244 ldb_transaction_cancel(ldb);
250 autostarts a transacion if none active and the operation is not a search
251 returns LDB_ERR_* on errors.
253 int ldb_request(struct ldb_context *ldb, struct ldb_request *request)
255 int status, started_transaction=0;
256 struct ldb_request *r;
258 ldb_reset_err_string(ldb);
260 /* to allow ldb modules to assume they can use the request ptr
261 as a talloc context for the request, we have to copy the
263 r = talloc(ldb, struct ldb_request);
266 return LDB_ERR_OPERATIONS_ERROR;
271 if (r->operation == LDB_REQ_SEARCH) {
272 r->op.search.res = NULL;
275 /* start a transaction if needed */
276 if ((!ldb->transaction_active) &&
277 (request->operation == LDB_REQ_ADD ||
278 request->operation == LDB_REQ_MODIFY ||
279 request->operation == LDB_REQ_DELETE ||
280 request->operation == LDB_REQ_RENAME)) {
281 status = ldb_transaction_start(ldb);
282 if (status != LDB_SUCCESS) {
286 started_transaction = 1;
289 /* call the first module in the chain */
290 status = ldb->modules->ops->request(ldb->modules, r);
292 /* the search call is the only one that returns something
293 other than a status code. We steal the results into
294 the context of the ldb before freeing the request */
295 if (request->operation == LDB_REQ_SEARCH) {
296 request->op.search.res = talloc_steal(ldb, r->op.search.res);
298 if (request->operation == LDB_ASYNC_SEARCH) {
299 request->async.handle = r->async.handle;
303 if (started_transaction) {
304 return ldb_op_finish(ldb, status);
311 search the database given a LDAP-like search expression
313 return the number of records found, or -1 on error
315 Use talloc_free to free the ldb_message returned in 'res'
318 int ldb_search(struct ldb_context *ldb,
319 const struct ldb_dn *base,
320 enum ldb_scope scope,
321 const char *expression,
322 const char * const *attrs,
323 struct ldb_result **res)
325 struct ldb_request request;
326 struct ldb_parse_tree *tree;
331 tree = ldb_parse_tree(ldb, expression);
333 ldb_set_errstring(ldb, talloc_strdup(ldb, "Unable to parse search expression"));
337 request.operation = LDB_REQ_SEARCH;
338 request.op.search.base = base;
339 request.op.search.scope = scope;
340 request.op.search.tree = tree;
341 request.op.search.attrs = attrs;
342 request.controls = NULL;
344 ret = ldb_request(ldb, &request);
346 (*res) = request.op.search.res;
354 add a record to the database. Will fail if a record with the given class and key
357 int ldb_add(struct ldb_context *ldb,
358 const struct ldb_message *message)
360 struct ldb_request request;
363 status = ldb_msg_sanity_check(message);
364 if (status != LDB_SUCCESS) return status;
366 request.operation = LDB_REQ_ADD;
367 request.op.add.message = message;
368 request.controls = NULL;
370 return ldb_request(ldb, &request);
374 modify the specified attributes of a record
376 int ldb_modify(struct ldb_context *ldb,
377 const struct ldb_message *message)
379 struct ldb_request request;
382 status = ldb_msg_sanity_check(message);
383 if (status != LDB_SUCCESS) return status;
385 request.operation = LDB_REQ_MODIFY;
386 request.op.mod.message = message;
387 request.controls = NULL;
389 return ldb_request(ldb, &request);
394 delete a record from the database
396 int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
398 struct ldb_request request;
400 request.operation = LDB_REQ_DELETE;
401 request.op.del.dn = dn;
402 request.controls = NULL;
404 return ldb_request(ldb, &request);
408 rename a record in the database
410 int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
412 struct ldb_request request;
414 request.operation = LDB_REQ_RENAME;
415 request.op.rename.olddn = olddn;
416 request.op.rename.newdn = newdn;
417 request.controls = NULL;
419 return ldb_request(ldb, &request);
425 return extended error information
427 const char *ldb_errstring(struct ldb_context *ldb)
429 if (ldb->err_string) {
430 return ldb->err_string;
438 set backend specific opaque parameters
440 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
442 struct ldb_opaque *o;
444 /* allow updating an existing value */
445 for (o=ldb->opaque;o;o=o->next) {
446 if (strcmp(o->name, name) == 0) {
452 o = talloc(ldb, struct ldb_opaque);
455 return LDB_ERR_OTHER;
457 o->next = ldb->opaque;
465 get a previously set opaque value
467 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
469 struct ldb_opaque *o;
470 for (o=ldb->opaque;o;o=o->next) {
471 if (strcmp(o->name, name) == 0) {