r13998: From now on ldb_request() will require an alloced request
[bbaumbach/samba-autobuild/.git] / source4 / lib / ldb / common / ldb.c
1 /* 
2    ldb database library
3
4    Copyright (C) Andrew Tridgell  2004
5
6      ** NOTE! The following LGPL license applies to the ldb
7      ** library. This does NOT imply that all of Samba is released
8      ** under the LGPL
9    
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.
14
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.
19
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
23 */
24
25 /*
26  *  Name: ldb
27  *
28  *  Component: ldb core API
29  *
30  *  Description: core API routines interfacing to ldb backends
31  *
32  *  Author: Andrew Tridgell
33  */
34
35 #include "includes.h"
36 #include "ldb/include/includes.h"
37
38 /* 
39    initialise a ldb context
40    The mem_ctx is optional
41 */
42 struct ldb_context *ldb_init(void *mem_ctx)
43 {
44         struct ldb_context *ldb = talloc_zero(mem_ctx, struct ldb_context);
45         int ret;
46
47         ret = ldb_setup_wellknown_attributes(ldb);
48         if (ret != 0) {
49                 talloc_free(ldb);
50                 return NULL;
51         }
52
53         ldb_set_utf8_default(ldb);
54
55         return ldb;
56 }
57
58 static struct ldb_backend {
59         const char *name;
60         ldb_connect_fn connect_fn;
61         struct ldb_backend *prev, *next;
62 } *ldb_backends = NULL;
63 /*
64  register a new ldb backend
65 */
66 int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn)
67 {
68         struct ldb_backend *backend = talloc(talloc_autofree_context(), struct ldb_backend);
69
70         /* Maybe check for duplicity here later on? */
71
72         backend->name = talloc_strdup(backend, url_prefix);
73         backend->connect_fn = connectfn;
74         DLIST_ADD(ldb_backends, backend);
75
76         return LDB_SUCCESS;
77 }
78
79 static ldb_connect_fn ldb_find_backend(const char *url)
80 {
81         struct ldb_backend *backend;
82
83         for (backend = ldb_backends; backend; backend = backend->next) {
84                 if (strncmp(backend->name, url, strlen(backend->name)) == 0) {
85                         return backend->connect_fn;
86                 }
87         }
88
89         return NULL;
90 }
91
92 /* 
93  connect to a database. The URL can either be one of the following forms
94    ldb://path
95    ldapi://path
96
97    flags is made up of LDB_FLG_*
98
99    the options are passed uninterpreted to the backend, and are
100    backend specific
101 */
102 int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[])
103 {
104         int ret;
105         ldb_connect_fn fn;
106
107         if (strchr(url, ':') != NULL) {
108                 fn = ldb_find_backend(url);
109         } else {
110                 /* Default to tdb */
111                 fn = ldb_find_backend("tdb:");
112         }
113
114         if (fn == NULL) {
115                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url);
116                 return LDB_ERR_OTHER;
117         }
118
119         ret = fn(ldb, url, flags, options);
120
121         if (ret != LDB_SUCCESS) {
122                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url);
123                 return ret;
124         }
125
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;
129         }
130
131         return LDB_SUCCESS;
132 }
133
134 void ldb_set_errstring(struct ldb_context *ldb, char *err_string)
135 {
136         if (ldb->err_string) {
137                 talloc_free(ldb->err_string);
138         }
139         ldb->err_string = talloc_steal(ldb, err_string);
140 }
141
142 void ldb_reset_err_string(struct ldb_context *ldb)
143 {
144         if (ldb->err_string) {
145                 talloc_free(ldb->err_string);
146                 ldb->err_string = NULL;
147         }
148 }
149
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; \
154 } while (0)
155
156 /*
157   start a transaction
158 */
159 int ldb_transaction_start(struct ldb_context *ldb)
160 {
161         struct ldb_module *module;
162         int status;
163         FIRST_OP(ldb, start_transaction);
164         
165         ldb->transaction_active++;
166
167         ldb_reset_err_string(ldb);
168
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));
175                 }
176         }
177         return status;
178 }
179
180 /*
181   commit a transaction
182 */
183 int ldb_transaction_commit(struct ldb_context *ldb)
184 {
185         struct ldb_module *module;
186         int status;
187         FIRST_OP(ldb, end_transaction);
188
189         if (ldb->transaction_active > 0) {
190                 ldb->transaction_active--;
191         } else {
192                 return LDB_ERR_OPERATIONS_ERROR;
193         }
194
195         ldb_reset_err_string(ldb);
196
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));
203                 }
204         }
205         return status;
206 }
207
208 /*
209   cancel a transaction
210 */
211 int ldb_transaction_cancel(struct ldb_context *ldb)
212 {
213         struct ldb_module *module;
214         int status;
215         FIRST_OP(ldb, del_transaction);
216
217         if (ldb->transaction_active > 0) {
218                 ldb->transaction_active--;
219         } else {
220                 return LDB_ERR_OPERATIONS_ERROR;
221         }
222
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));
229                 }
230         }
231         return status;
232 }
233
234 int ldb_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_type type)
235 {
236         return handle->module->ops->async_wait(handle, type);
237 }
238
239 /*
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
242 */
243 static int ldb_op_finish(struct ldb_context *ldb, int status)
244 {
245         if (status == LDB_SUCCESS) {
246                 return ldb_transaction_commit(ldb);
247         }
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));
252         }
253         ldb_transaction_cancel(ldb);
254         return status;
255 }
256
257 /*
258   start an ldb request
259   autostarts a transacion if none active and the operation is not a search
260   NOTE: the request must be a talloc context.
261   returns LDB_ERR_* on errors.
262 */
263 int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
264 {
265         int status, started_transaction=0;
266
267         ldb_reset_err_string(ldb);
268
269         if (req->operation == LDB_REQ_SEARCH) {
270                 req->op.search.res = NULL;
271         }
272
273         /* start a transaction if needed */
274         if ((!ldb->transaction_active) &&
275             (req->operation == LDB_REQ_ADD ||
276              req->operation == LDB_REQ_MODIFY ||
277              req->operation == LDB_REQ_DELETE ||
278              req->operation == LDB_REQ_RENAME)) {
279                 status = ldb_transaction_start(ldb);
280                 if (status != LDB_SUCCESS) {
281                         talloc_free(req);
282                         return status;
283                 }
284                 started_transaction = 1;
285         }
286
287         /* call the first module in the chain */
288         status = ldb->modules->ops->request(ldb->modules, req);
289
290         if (started_transaction) {
291                 return ldb_op_finish(ldb, status);
292         }
293
294         return status;
295 }
296
297 /*
298   search the database given a LDAP-like search expression
299
300   return the number of records found, or -1 on error
301
302   Use talloc_free to free the ldb_message returned in 'res'
303
304 */
305 int ldb_search(struct ldb_context *ldb, 
306                const struct ldb_dn *base,
307                enum ldb_scope scope,
308                const char *expression,
309                const char * const *attrs, 
310                struct ldb_result **res)
311 {
312         struct ldb_request *req;
313         int ret;
314
315         (*res) = NULL;
316
317         req = talloc(ldb, struct ldb_request);
318         if (req == NULL) {
319                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
320                 return LDB_ERR_OPERATIONS_ERROR;
321         }
322
323         req->operation = LDB_REQ_SEARCH;
324         req->op.search.base = base;
325         req->op.search.scope = scope;
326
327         req->op.search.tree = ldb_parse_tree(req, expression);
328         if (req->op.search.tree == NULL) {
329                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Unable to parse search expression"));
330                 talloc_free(req);
331                 return LDB_ERR_OPERATIONS_ERROR;
332         }
333
334         req->op.search.attrs = attrs;
335         req->controls = NULL;
336
337         ret = ldb_request(ldb, req);
338
339         (*res) = talloc_steal(ldb, req->op.search.res);
340
341         talloc_free(req);
342         return ret;
343 }
344
345 /*
346   add a record to the database. Will fail if a record with the given class and key
347   already exists
348 */
349 int ldb_add(struct ldb_context *ldb, 
350             const struct ldb_message *message)
351 {
352         struct ldb_request *req;
353         int ret;
354
355         ret = ldb_msg_sanity_check(message);
356         if (ret != LDB_SUCCESS) return ret;
357
358         req = talloc(ldb, struct ldb_request);
359         if (req == NULL) {
360                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
361                 return LDB_ERR_OPERATIONS_ERROR;
362         }
363
364         req->operation = LDB_REQ_ADD;
365         req->op.add.message = message;
366         req->controls = NULL;
367
368         ret = ldb_request(ldb, req);
369
370         talloc_free(req);
371         return ret;
372 }
373
374 /*
375   modify the specified attributes of a record
376 */
377 int ldb_modify(struct ldb_context *ldb, 
378                const struct ldb_message *message)
379 {
380         struct ldb_request *req;
381         int ret;
382
383         ret = ldb_msg_sanity_check(message);
384         if (ret != LDB_SUCCESS) return ret;
385
386         req = talloc(ldb, struct ldb_request);
387         if (req == NULL) {
388                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
389                 return LDB_ERR_OPERATIONS_ERROR;
390         }
391
392         req->operation = LDB_REQ_MODIFY;
393         req->op.add.message = message;
394         req->controls = NULL;
395
396         ret = ldb_request(ldb, req);
397
398         talloc_free(req);
399         return ret;
400 }
401
402
403 /*
404   delete a record from the database
405 */
406 int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
407 {
408         struct ldb_request *req;
409         int ret;
410
411         req = talloc(ldb, struct ldb_request);
412         if (req == NULL) {
413                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
414                 return LDB_ERR_OPERATIONS_ERROR;
415         }
416
417         req->operation = LDB_REQ_DELETE;
418         req->op.del.dn = dn;
419         req->controls = NULL;
420
421         ret = ldb_request(ldb, req);
422
423         talloc_free(req);
424         return ret;
425 }
426
427 /*
428   rename a record in the database
429 */
430 int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
431 {
432         struct ldb_request *req;
433         int ret;
434
435         req = talloc(ldb, struct ldb_request);
436         if (req == NULL) {
437                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
438                 return LDB_ERR_OPERATIONS_ERROR;
439         }
440
441         req->operation = LDB_REQ_RENAME;
442         req->op.rename.olddn = olddn;
443         req->op.rename.newdn = newdn;
444         req->controls = NULL;
445
446         ret = ldb_request(ldb, req);
447
448         talloc_free(req);
449         return ret;
450 }
451
452
453
454 /*
455   return extended error information 
456 */
457 const char *ldb_errstring(struct ldb_context *ldb)
458 {
459         if (ldb->err_string) {
460                 return ldb->err_string;
461         }
462
463         return NULL;
464 }
465
466
467 /*
468   set backend specific opaque parameters
469 */
470 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
471 {
472         struct ldb_opaque *o;
473
474         /* allow updating an existing value */
475         for (o=ldb->opaque;o;o=o->next) {
476                 if (strcmp(o->name, name) == 0) {
477                         o->value = value;
478                         return LDB_SUCCESS;
479                 }
480         }
481
482         o = talloc(ldb, struct ldb_opaque);
483         if (o == NULL) {
484                 ldb_oom(ldb);
485                 return LDB_ERR_OTHER;
486         }
487         o->next = ldb->opaque;
488         o->name = name;
489         o->value = value;
490         ldb->opaque = o;
491         return LDB_SUCCESS;
492 }
493
494 /*
495   get a previously set opaque value
496 */
497 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
498 {
499         struct ldb_opaque *o;
500         for (o=ldb->opaque;o;o=o->next) {
501                 if (strcmp(o->name, name) == 0) {
502                         return o->value;
503                 }
504         }
505         return NULL;
506 }