r14592: Add support for loading shared modules to LDB.
[kai/samba.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         char *backend;
106         ldb_connect_fn fn;
107
108         if (strchr(url, ':') != NULL) {
109                 backend = talloc_strndup(ldb, url, strchr(url, ':')-url);
110         } else {
111                 /* Default to tdb */
112                 backend = talloc_strdup(ldb, "tdb");
113         }
114
115         fn = ldb_find_backend(backend);
116
117         if (fn == NULL) {
118                 if (ldb_try_load_dso(ldb, backend) == 0) {
119                         fn = ldb_find_backend(backend);
120                 }
121         }
122
123         talloc_free(backend);
124
125         if (fn == NULL) {
126                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url);
127                 return LDB_ERR_OTHER;
128         }
129
130         ret = fn(ldb, url, flags, options);
131
132         if (ret != LDB_SUCCESS) {
133                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url);
134                 return ret;
135         }
136
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;
140         }
141
142         return LDB_SUCCESS;
143 }
144
145 void ldb_set_errstring(struct ldb_context *ldb, char *err_string)
146 {
147         if (ldb->err_string) {
148                 talloc_free(ldb->err_string);
149         }
150         ldb->err_string = talloc_steal(ldb, err_string);
151 }
152
153 void ldb_reset_err_string(struct ldb_context *ldb)
154 {
155         if (ldb->err_string) {
156                 talloc_free(ldb->err_string);
157                 ldb->err_string = NULL;
158         }
159 }
160
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; \
165 } while (0)
166
167 /*
168   start a transaction
169 */
170 int ldb_transaction_start(struct ldb_context *ldb)
171 {
172         struct ldb_module *module;
173         int status;
174         FIRST_OP(ldb, start_transaction);
175         
176         ldb->transaction_active++;
177
178         ldb_reset_err_string(ldb);
179
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));
186                 }
187         }
188         return status;
189 }
190
191 /*
192   commit a transaction
193 */
194 int ldb_transaction_commit(struct ldb_context *ldb)
195 {
196         struct ldb_module *module;
197         int status;
198         FIRST_OP(ldb, end_transaction);
199
200         if (ldb->transaction_active > 0) {
201                 ldb->transaction_active--;
202         } else {
203                 return LDB_ERR_OPERATIONS_ERROR;
204         }
205
206         ldb_reset_err_string(ldb);
207
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));
214                 }
215         }
216         return status;
217 }
218
219 /*
220   cancel a transaction
221 */
222 int ldb_transaction_cancel(struct ldb_context *ldb)
223 {
224         struct ldb_module *module;
225         int status;
226         FIRST_OP(ldb, del_transaction);
227
228         if (ldb->transaction_active > 0) {
229                 ldb->transaction_active--;
230         } else {
231                 return LDB_ERR_OPERATIONS_ERROR;
232         }
233
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));
240                 }
241         }
242         return status;
243 }
244
245 int ldb_async_wait(struct ldb_async_handle *handle, enum ldb_async_wait_type type)
246 {
247         return handle->module->ops->async_wait(handle, type);
248 }
249
250 /*
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
253 */
254 static int ldb_op_finish(struct ldb_context *ldb, int status)
255 {
256         if (status == LDB_SUCCESS) {
257                 return ldb_transaction_commit(ldb);
258         }
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));
263         }
264         ldb_transaction_cancel(ldb);
265         return status;
266 }
267
268 /*
269   start an ldb request
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.
273 */
274 int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
275 {
276         int status, started_transaction=0;
277
278         ldb_reset_err_string(ldb);
279
280         if (req->operation == LDB_REQ_SEARCH) {
281                 req->op.search.res = NULL;
282         }
283
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) {
292                         talloc_free(req);
293                         return status;
294                 }
295                 started_transaction = 1;
296         }
297
298         /* call the first module in the chain */
299         status = ldb->modules->ops->request(ldb->modules, req);
300
301         if (started_transaction) {
302                 return ldb_op_finish(ldb, status);
303         }
304
305         return status;
306 }
307
308 /*
309   search the database given a LDAP-like search expression
310
311   return the number of records found, or -1 on error
312
313   Use talloc_free to free the ldb_message returned in 'res'
314
315 */
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)
322 {
323         struct ldb_request *req;
324         int ret;
325
326         (*res) = NULL;
327
328         req = talloc(ldb, struct ldb_request);
329         if (req == NULL) {
330                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
331                 return LDB_ERR_OPERATIONS_ERROR;
332         }
333
334         req->operation = LDB_REQ_SEARCH;
335         req->op.search.base = base;
336         req->op.search.scope = scope;
337
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"));
341                 talloc_free(req);
342                 return LDB_ERR_OPERATIONS_ERROR;
343         }
344
345         req->op.search.attrs = attrs;
346         req->controls = NULL;
347
348         ret = ldb_request(ldb, req);
349
350         (*res) = talloc_steal(ldb, req->op.search.res);
351
352         talloc_free(req);
353         return ret;
354 }
355
356 /*
357   add a record to the database. Will fail if a record with the given class and key
358   already exists
359 */
360 int ldb_add(struct ldb_context *ldb, 
361             const struct ldb_message *message)
362 {
363         struct ldb_request *req;
364         int ret;
365
366         ret = ldb_msg_sanity_check(message);
367         if (ret != LDB_SUCCESS) return ret;
368
369         req = talloc(ldb, struct ldb_request);
370         if (req == NULL) {
371                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
372                 return LDB_ERR_OPERATIONS_ERROR;
373         }
374
375         req->operation = LDB_REQ_ADD;
376         req->op.add.message = message;
377         req->controls = NULL;
378
379         ret = ldb_request(ldb, req);
380
381         talloc_free(req);
382         return ret;
383 }
384
385 /*
386   modify the specified attributes of a record
387 */
388 int ldb_modify(struct ldb_context *ldb, 
389                const struct ldb_message *message)
390 {
391         struct ldb_request *req;
392         int ret;
393
394         ret = ldb_msg_sanity_check(message);
395         if (ret != LDB_SUCCESS) return ret;
396
397         req = talloc(ldb, struct ldb_request);
398         if (req == NULL) {
399                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
400                 return LDB_ERR_OPERATIONS_ERROR;
401         }
402
403         req->operation = LDB_REQ_MODIFY;
404         req->op.add.message = message;
405         req->controls = NULL;
406
407         ret = ldb_request(ldb, req);
408
409         talloc_free(req);
410         return ret;
411 }
412
413
414 /*
415   delete a record from the database
416 */
417 int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
418 {
419         struct ldb_request *req;
420         int ret;
421
422         req = talloc(ldb, struct ldb_request);
423         if (req == NULL) {
424                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
425                 return LDB_ERR_OPERATIONS_ERROR;
426         }
427
428         req->operation = LDB_REQ_DELETE;
429         req->op.del.dn = dn;
430         req->controls = NULL;
431
432         ret = ldb_request(ldb, req);
433
434         talloc_free(req);
435         return ret;
436 }
437
438 /*
439   rename a record in the database
440 */
441 int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
442 {
443         struct ldb_request *req;
444         int ret;
445
446         req = talloc(ldb, struct ldb_request);
447         if (req == NULL) {
448                 ldb_set_errstring(ldb, talloc_strdup(ldb, "Out of memory!"));
449                 return LDB_ERR_OPERATIONS_ERROR;
450         }
451
452         req->operation = LDB_REQ_RENAME;
453         req->op.rename.olddn = olddn;
454         req->op.rename.newdn = newdn;
455         req->controls = NULL;
456
457         ret = ldb_request(ldb, req);
458
459         talloc_free(req);
460         return ret;
461 }
462
463
464
465 /*
466   return extended error information 
467 */
468 const char *ldb_errstring(struct ldb_context *ldb)
469 {
470         if (ldb->err_string) {
471                 return ldb->err_string;
472         }
473
474         return NULL;
475 }
476
477
478 /*
479   set backend specific opaque parameters
480 */
481 int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
482 {
483         struct ldb_opaque *o;
484
485         /* allow updating an existing value */
486         for (o=ldb->opaque;o;o=o->next) {
487                 if (strcmp(o->name, name) == 0) {
488                         o->value = value;
489                         return LDB_SUCCESS;
490                 }
491         }
492
493         o = talloc(ldb, struct ldb_opaque);
494         if (o == NULL) {
495                 ldb_oom(ldb);
496                 return LDB_ERR_OTHER;
497         }
498         o->next = ldb->opaque;
499         o->name = name;
500         o->value = value;
501         ldb->opaque = o;
502         return LDB_SUCCESS;
503 }
504
505 /*
506   get a previously set opaque value
507 */
508 void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
509 {
510         struct ldb_opaque *o;
511         for (o=ldb->opaque;o;o=o->next) {
512                 if (strcmp(o->name, name) == 0) {
513                         return o->value;
514                 }
515         }
516         return NULL;
517 }