6ba5fbbc2081af94e419a476fc19c8208dde399f
[ira/wip.git] / source / 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 #ifdef _SAMBA_BUILD_
40 #include "build.h"
41 #endif
42
43 #define LDB_MODULE_PREFIX       "modules:"
44 #define LDB_MODULE_PREFIX_LEN   8
45
46 static char *talloc_strdup_no_spaces(struct ldb_context *ldb, const char *string)
47 {
48         int i, len;
49         char *trimmed;
50
51         trimmed = talloc_strdup(ldb, string);
52         if (!trimmed) {
53                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in talloc_strdup_trim_spaces()\n");
54                 return NULL;
55         }
56
57         len = strlen(trimmed);
58         for (i = 0; trimmed[i] != '\0'; i++) {
59                 switch (trimmed[i]) {
60                 case ' ':
61                 case '\t':
62                 case '\n':
63                         memmove(&trimmed[i], &trimmed[i + 1], len -i -1);
64                         break;
65                 }
66         }
67
68         return trimmed;
69 }
70
71
72 /* modules are called in inverse order on the stack.
73    Lets place them as an admin would think the right order is.
74    Modules order is important */
75 static char **ldb_modules_list_from_string(struct ldb_context *ldb, const char *string)
76 {
77         char **modules = NULL;
78         char *modstr, *p;
79         int i;
80
81         /* spaces not admitted */
82         modstr = talloc_strdup_no_spaces(ldb, string);
83         if ( ! modstr) {
84                 return NULL;
85         }
86
87         modules = talloc_realloc(ldb, modules, char *, 2);
88         if ( ! modules ) {
89                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
90                 talloc_free(modstr);
91                 return NULL;
92         }
93         talloc_steal(modules, modstr);
94
95         i = 0;
96         while ((p = strrchr(modstr, ',')) != NULL) {
97                 *p = '\0';
98                 p++;
99                 modules[i] = p;
100
101                 i++;
102                 modules = talloc_realloc(ldb, modules, char *, i + 2);
103                 if ( ! modules ) {
104                         ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
105                         return NULL;
106                 }
107
108         }
109         modules[i] = modstr;
110
111         modules[i + 1] = NULL;
112
113         return modules;
114 }
115
116 static struct ops_list_entry {
117         const struct ldb_module_ops *ops;
118         struct ops_list_entry *next;    
119 } *registered_modules = NULL;
120
121 static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
122 {
123         struct ops_list_entry *e;
124  
125         for (e = registered_modules; e; e = e->next) {
126                 if (strcmp(e->ops->name, name) == 0) 
127                         return e->ops;
128         }
129
130         return NULL;
131 }
132
133 #ifdef HAVE_LDAP
134 #define LDAP_INIT ldb_ldap_init,
135 #else
136 #define LDAP_INIT
137 #endif
138
139 #ifdef HAVE_SQLITE3
140 #define SQLITE3_INIT ldb_sqlite3_init,
141 #else
142 #define SQLITE3_INIT
143 #endif
144
145 #ifndef STATIC_ldb_MODULES
146 #define STATIC_ldb_MODULES \
147         {       \
148                 LDAP_INIT \
149                 SQLITE3_INIT \
150                 ldb_tdb_init,   \
151                 ldb_schema_init,        \
152                 ldb_operational_init,   \
153                 ldb_rdn_name_init,      \
154                 ldb_objectclass_init,   \
155                 ldb_paged_results_init, \
156                 ldb_sort_init,          \
157                 NULL                    \
158         }
159 #endif
160
161 int ldb_global_init(void)
162 {
163         static int (*static_init_fns[])(void) = STATIC_ldb_MODULES;
164
165         static int initialized = 0;
166         int ret = 0, i;
167
168         if (initialized) 
169                 return 0;
170
171         initialized = 1;
172         
173         for (i = 0; static_init_fns[i]; i++) {
174                 if (static_init_fns[i]() == -1)
175                         ret = -1;
176         }
177
178         return ret;
179 }
180
181 int ldb_register_module(const struct ldb_module_ops *ops)
182 {
183         struct ops_list_entry *entry = talloc(talloc_autofree_context(), struct ops_list_entry);
184
185         if (ldb_find_module_ops(ops->name) != NULL)
186                 return -1;
187
188         if (entry == NULL)
189                 return -1;
190
191         entry->ops = ops;
192         entry->next = registered_modules;
193         registered_modules = entry;
194
195         return 0;
196 }
197
198 int ldb_try_load_dso(struct ldb_context *ldb, const char *name)
199 {
200         char *path;
201         void *handle;
202         int (*init_fn) (void);
203
204 #ifdef HAVE_DLOPEN
205         path = talloc_asprintf(ldb, "%s/%s.%s", MODULESDIR, name, SHLIBEXT);
206
207         ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path);
208
209         handle = dlopen(path, 0);
210         if (handle == NULL) {
211                 ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s\n", name, path, dlerror());
212                 return -1;
213         }
214
215         init_fn = dlsym(handle, "init_module");
216
217         if (init_fn == NULL) {
218                 ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `init_module' found in %s: %s\n", path, dlerror());
219                 return -1;
220         }
221
222         talloc_free(path);
223
224         return init_fn();
225 #else
226         ldb_debug(ldb, LDB_DEBUG_TRACE, "no dlopen() - not trying to load %s module\n", name);
227         return -1;
228 #endif
229 }
230
231 int ldb_load_modules(struct ldb_context *ldb, const char *options[])
232 {
233         char **modules = NULL;
234         struct ldb_module *module;
235         int i;
236         /* find out which modules we are requested to activate */
237
238         /* check if we have a custom module list passd as ldb option */
239         if (options) {
240                 for (i = 0; options[i] != NULL; i++) {
241                         if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) {
242                                 modules = ldb_modules_list_from_string(ldb, &options[i][LDB_MODULE_PREFIX_LEN]);
243                         }
244                 }
245         }
246
247         /* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */
248         if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { 
249                 int ret;
250                 const char * const attrs[] = { "@LIST" , NULL};
251                 struct ldb_result *res = NULL;
252                 struct ldb_dn *mods;
253
254                 mods = ldb_dn_explode(ldb, "@MODULES");
255                 if (mods == NULL) {
256                         return -1;
257                 }
258
259                 ret = ldb_search(ldb, mods, LDB_SCOPE_BASE, "", attrs, &res);
260                 talloc_free(mods);
261                 if (ret == LDB_SUCCESS && (res->count == 0 || res->msgs[0]->num_elements == 0)) {
262                         ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db\n");
263                 } else {
264                         if (ret != LDB_SUCCESS) {
265                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb));
266                                 return -1;
267                         }
268                         if (res->count > 1) {
269                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", res->count);
270                                 talloc_free(res);
271                                 return -1;
272                         }
273
274                         modules = ldb_modules_list_from_string(ldb, 
275                                                                (const char *)res->msgs[0]->elements[0].values[0].data);
276
277                 }
278
279                 talloc_free(res);
280         }
281
282         if (modules != NULL) {
283                 for (i = 0; modules[i] != NULL; i++) {
284                         struct ldb_module *current;
285                         const struct ldb_module_ops *ops;
286                                 
287                         ops = ldb_find_module_ops(modules[i]);
288                         if (ops == NULL) {
289                                 if (ldb_try_load_dso(ldb, modules[i]) == 0) {
290                                         ops = ldb_find_module_ops(modules[i]);
291                                 }
292                         }
293                         
294                         if (ops == NULL) {
295                                 ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n", 
296                                           modules[i]);
297                                 continue;
298                         }
299
300                         current = talloc_zero(ldb, struct ldb_module);
301                         if (current == NULL) {
302                                 return -1;
303                         }
304
305                         current->ldb = ldb;
306                         current->ops = ops;
307                 
308                         DLIST_ADD(ldb->modules, current);
309                 }
310
311                 talloc_free(modules);
312         } else {
313                 ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database\n");
314         }
315
316         module = ldb->modules;
317
318         while (module && module->ops->init_context == NULL) 
319                 module = module->next;
320
321         if (module && module->ops->init_context &&
322                 module->ops->init_context(module) != LDB_SUCCESS) {
323                 ldb_debug(ldb, LDB_DEBUG_FATAL, "module initialization failed\n");
324                 return -1;
325         }
326
327         return 0; 
328 }
329
330 /*
331   by using this we allow ldb modules to only implement the functions they care about,
332   which makes writing a module simpler, and makes it more likely to keep working
333   when ldb is extended
334 */
335 #define FIND_OP(module, op) do { \
336         module = module->next; \
337         while (module && module->ops->op == NULL) module = module->next; \
338         if (module == NULL) return LDB_ERR_OPERATIONS_ERROR; \
339 } while (0)
340
341
342 /*
343    helper functions to call the next module in chain
344 */
345 int ldb_next_request(struct ldb_module *module, struct ldb_request *request)
346 {
347         FIND_OP(module, request);
348         return module->ops->request(module, request);
349 }
350
351 int ldb_next_init(struct ldb_module *module)
352 {
353         /* init is different in that it is not an error if modules
354          * do not require initialization */
355
356         module = module->next;
357
358         while (module && module->ops->init_context == NULL) 
359                 module = module->next;
360
361         if (module == NULL) 
362                 return LDB_SUCCESS;
363
364         return module->ops->init_context(module);
365 }
366
367 int ldb_next_start_trans(struct ldb_module *module)
368 {
369         FIND_OP(module, start_transaction);
370         return module->ops->start_transaction(module);
371 }
372
373 int ldb_next_end_trans(struct ldb_module *module)
374 {
375         FIND_OP(module, end_transaction);
376         return module->ops->end_transaction(module);
377 }
378
379 int ldb_next_del_trans(struct ldb_module *module)
380 {
381         FIND_OP(module, del_transaction);
382         return module->ops->del_transaction(module);
383 }