r13823: make async_wait part of the modules ops
[jra/samba/.git] / source4 / lib / ldb / common / ldb_modules.c
1
2 /* 
3    ldb database library
4
5    Copyright (C) Simo Sorce  2004
6
7      ** NOTE! The following LGPL license applies to the ldb
8      ** library. This does NOT imply that all of Samba is released
9      ** under the LGPL
10    
11    This library is free software; you can redistribute it and/or
12    modify it under the terms of the GNU Lesser General Public
13    License as published by the Free Software Foundation; either
14    version 2 of the License, or (at your option) any later version.
15
16    This library is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    Lesser General Public License for more details.
20
21    You should have received a copy of the GNU Lesser General Public
22    License along with this library; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 */
25
26 /*
27  *  Name: ldb
28  *
29  *  Component: ldb modules core
30  *
31  *  Description: core modules routines
32  *
33  *  Author: Simo Sorce
34  */
35
36 #include "includes.h"
37 #include "ldb/include/includes.h"
38
39 #define LDB_MODULE_PREFIX       "modules:"
40 #define LDB_MODULE_PREFIX_LEN   8
41
42 static char *talloc_strdup_no_spaces(struct ldb_context *ldb, const char *string)
43 {
44         int i, len;
45         char *trimmed;
46
47         trimmed = talloc_strdup(ldb, string);
48         if (!trimmed) {
49                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in talloc_strdup_trim_spaces()\n");
50                 return NULL;
51         }
52
53         len = strlen(trimmed);
54         for (i = 0; trimmed[i] != '\0'; i++) {
55                 switch (trimmed[i]) {
56                 case ' ':
57                 case '\t':
58                 case '\n':
59                         memmove(&trimmed[i], &trimmed[i + 1], len -i -1);
60                         break;
61                 }
62         }
63
64         return trimmed;
65 }
66
67
68 /* modules are called in inverse order on the stack.
69    Lets place them as an admin would think the right order is.
70    Modules order is important */
71 static char **ldb_modules_list_from_string(struct ldb_context *ldb, const char *string)
72 {
73         char **modules = NULL;
74         char *modstr, *p;
75         int i;
76
77         /* spaces not admitted */
78         modstr = talloc_strdup_no_spaces(ldb, string);
79         if ( ! modstr) {
80                 return NULL;
81         }
82
83         modules = talloc_realloc(ldb, modules, char *, 2);
84         if ( ! modules ) {
85                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
86                 talloc_free(modstr);
87                 return NULL;
88         }
89         talloc_steal(modules, modstr);
90
91         i = 0;
92         while ((p = strrchr(modstr, ',')) != NULL) {
93                 *p = '\0';
94                 p++;
95                 modules[i] = p;
96
97                 i++;
98                 modules = talloc_realloc(ldb, modules, char *, i + 2);
99                 if ( ! modules ) {
100                         ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
101                         return NULL;
102                 }
103
104         }
105         modules[i] = modstr;
106
107         modules[i + 1] = NULL;
108
109         return modules;
110 }
111
112 static struct ops_list_entry {
113         const struct ldb_module_ops *ops;
114         struct ops_list_entry *next;    
115 } *registered_modules = NULL;
116
117 static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
118 {
119         struct ops_list_entry *e;
120  
121         for (e = registered_modules; e; e = e->next) {
122                 if (strcmp(e->ops->name, name) == 0) 
123                         return e->ops;
124         }
125
126         return NULL;
127 }
128
129         
130 #ifndef STATIC_LIBLDB_MODULES
131 #define STATIC_LIBLDB_MODULES \
132         {       \
133                 ldb_schema_init,        \
134                 ldb_operational_init,   \
135                 ldb_rdn_name_init,      \
136                 ldb_objectclass_init,   \
137                 ldb_paged_results_init, \
138                 ldb_sort_init,          \
139                 NULL                    \
140         }
141 #endif
142
143 int ldb_global_init(void)
144 {
145         static int (*static_init_fns[])(void) = STATIC_LIBLDB_MODULES;
146
147         static int initialized = 0;
148         int ret = 0, i;
149
150         if (initialized) 
151                 return 0;
152
153         initialized = 1;
154         
155         for (i = 0; static_init_fns[i]; i++) {
156                 if (static_init_fns[i]() == -1)
157                         ret = -1;
158         }
159
160         return ret;
161 }
162
163 int ldb_register_module(const struct ldb_module_ops *ops)
164 {
165         struct ops_list_entry *entry = talloc(talloc_autofree_context(), struct ops_list_entry);
166
167         if (ldb_find_module_ops(ops->name) != NULL)
168                 return -1;
169
170         if (entry == NULL)
171                 return -1;
172
173         entry->ops = ops;
174         entry->next = registered_modules;
175         registered_modules = entry;
176
177         return 0;
178 }
179
180 int ldb_load_modules(struct ldb_context *ldb, const char *options[])
181 {
182         char **modules = NULL;
183         struct ldb_module *module;
184         int i;
185         /* find out which modules we are requested to activate */
186
187         /* check if we have a custom module list passd as ldb option */
188         if (options) {
189                 for (i = 0; options[i] != NULL; i++) {
190                         if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) {
191                                 modules = ldb_modules_list_from_string(ldb, &options[i][LDB_MODULE_PREFIX_LEN]);
192                         }
193                 }
194         }
195
196         /* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */
197         if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { 
198                 int ret;
199                 const char * const attrs[] = { "@LIST" , NULL};
200                 struct ldb_result *res = NULL;
201                 struct ldb_dn *mods;
202
203                 mods = ldb_dn_explode(ldb, "@MODULES");
204                 if (mods == NULL) {
205                         return -1;
206                 }
207
208                 ret = ldb_search(ldb, mods, LDB_SCOPE_BASE, "", attrs, &res);
209                 talloc_free(mods);
210                 if (ret == LDB_SUCCESS && (res->count == 0 || res->msgs[0]->num_elements == 0)) {
211                         ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db\n");
212                 } else {
213                         if (ret != LDB_SUCCESS) {
214                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb));
215                                 return -1;
216                         }
217                         if (res->count > 1) {
218                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", res->count);
219                                 talloc_free(res);
220                                 return -1;
221                         }
222
223                         modules = ldb_modules_list_from_string(ldb, 
224                                                                (const char *)res->msgs[0]->elements[0].values[0].data);
225
226                 }
227
228                 talloc_free(res);
229         }
230
231         if (modules == NULL) {
232                 ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database\n");
233                 return 0;
234         }
235
236         for (i = 0; modules[i] != NULL; i++) {
237                 struct ldb_module *current;
238                 const struct ldb_module_ops *ops;
239                                 
240                 ops = ldb_find_module_ops(modules[i]);
241                 if (ops == NULL) {
242                         ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n", 
243                                   modules[i]);
244                         continue;
245                 }
246
247                 current = talloc_zero(ldb, struct ldb_module);
248                 if (current == NULL) {
249                         return -1;
250                 }
251
252                 current->ldb = ldb;
253                 current->ops = ops;
254                 
255                 DLIST_ADD(ldb->modules, current);
256         }
257
258         module = ldb->modules;
259
260         while (module && module->ops->init_context == NULL) 
261                 module = module->next;
262
263         if (module && module->ops->init_context &&
264                 module->ops->init_context(module) != LDB_SUCCESS) {
265                 ldb_debug(ldb, LDB_DEBUG_FATAL, "module initialization failed\n");
266                 return -1;
267         }
268
269         talloc_free(modules);
270         return 0; 
271 }
272
273 /*
274   by using this we allow ldb modules to only implement the functions they care about,
275   which makes writing a module simpler, and makes it more likely to keep working
276   when ldb is extended
277 */
278 #define FIND_OP(module, op) do { \
279         module = module->next; \
280         while (module && module->ops->op == NULL) module = module->next; \
281         if (module == NULL) return LDB_ERR_OPERATIONS_ERROR; \
282 } while (0)
283
284
285 /*
286    helper functions to call the next module in chain
287 */
288 int ldb_next_request(struct ldb_module *module, struct ldb_request *request)
289 {
290         FIND_OP(module, request);
291         return module->ops->request(module, request);
292 }
293
294 int ldb_next_init(struct ldb_module *module)
295 {
296         /* init is different in that it is not an error if modules
297          * do not require initialization */
298
299         module = module->next;
300
301         while (module && module->ops->init_context == NULL) 
302                 module = module->next;
303
304         if (module == NULL) 
305                 return LDB_SUCCESS;
306
307         return module->ops->init_context(module);
308 }
309
310 int ldb_next_start_trans(struct ldb_module *module)
311 {
312         FIND_OP(module, start_transaction);
313         return module->ops->start_transaction(module);
314 }
315
316 int ldb_next_end_trans(struct ldb_module *module)
317 {
318         FIND_OP(module, end_transaction);
319         return module->ops->end_transaction(module);
320 }
321
322 int ldb_next_del_trans(struct ldb_module *module)
323 {
324         FIND_OP(module, del_transaction);
325         return module->ops->del_transaction(module);
326 }
327
328 int ldb_next_async_wait(struct ldb_module *module, struct ldb_async_handle *handle, enum ldb_async_wait_type type)
329 {
330         FIND_OP(module, async_wait);
331         return module->ops->async_wait(module, handle, type);
332 }