r3897: add a locking infrastructure
[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/ldb.h"
38 #include "ldb/include/ldb_private.h"
39 #include "dlinklist.h"
40 #include <sys/types.h> 
41 #include <sys/stat.h> 
42 #include <unistd.h> 
43
44 #define LDB_MODULE_PREFIX       "modules"
45 #define LDB_MODULE_PREFIX_LEN   7
46 #define LDB_MODULE_SEP          ':'
47
48 int ldb_load_modules(struct ldb_context *ldb, const char *options[])
49 {
50         struct ldb_module *current;
51         char **modules;
52         char *p, *q;
53         int pn, i;
54
55         /* find out which modules we are requested to activate */
56         modules = NULL;
57         pn = 0;
58
59         if (options) {
60
61                 for (i = 0; options[i] != NULL; i++) {
62
63                         if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) {
64
65                                 p = q = ldb_strdup(ldb, &options[i][LDB_MODULE_PREFIX_LEN]);
66                                 if (*q != ':') {
67                                         ldb_free(ldb, q);
68                                         return -1;
69                                 }
70                                 do {
71                                         *p = '\0';
72                                         q = p + 1;
73                                         pn++;
74                                         modules = ldb_realloc_array(ldb, modules, sizeof(char *), pn);
75                                         if (!modules) {
76                                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in register_modules()\n");
77                                                 return -1;
78                                         }
79                                         modules[pn - 1] = q;
80                                 } while ((p = strchr(q, LDB_MODULE_SEP)));
81                         }
82                 }
83         }
84
85         if (!modules && strcmp("ldap", ldb->modules->ops->name)) { /* no modules in the options, look for @MODULES in the db (not for ldap) */
86                 int ret, j, k;
87                 const char * const attrs[] = { "@MODULE" , NULL};
88                 struct ldb_message **msg;
89
90                 ret = ldb_search(ldb, "", LDB_SCOPE_BASE, "dn=@MODULES", attrs, &msg);
91                 if (ret == 0) {
92                         ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db\n");
93                 } else {
94                         if (ret < 0) {
95                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb));
96                                 return -1;
97                         }
98                         if (ret > 1) {
99                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found, bailing out\n");
100                                 return -1;
101                         }
102
103                         for (j = 0; j < msg[0]->num_elements; j++) {
104                                 for (k = 0; k < msg[0]->elements[j].num_values; k++) {
105                                         pn++;
106                                         modules = ldb_realloc_array(ldb, modules, sizeof(char *), pn);
107                                         if (!modules) {
108                                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in register_modules()\n");
109                                                 return -1;
110                                         }
111                                         modules[pn - 1] = ldb_strndup(ldb, msg[0]->elements[j].values[k].data, msg[0]->elements[j].values[k].length);
112                                         if (!modules[pn - 1]) {
113                                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in register_modules()\n");
114                                                 return -1;
115                                         }
116                                 }
117                         }
118                 }
119                 ldb_search_free(ldb, msg);
120         }
121
122         if (modules) {
123
124                 for (i = 0; i < pn; i++) {
125
126                         if (strcmp(modules[i], "timestamps") == 0) {
127                                 current = timestamps_module_init(ldb, options);
128                                 if (!current) {
129                                         ldb_debug(ldb, LDB_DEBUG_FATAL, "function 'init_module' in %s fails\n", modules[i]);
130                                         return -1;
131                                 }
132                                 DLIST_ADD(ldb->modules, current);
133                                 continue;
134                         }
135 #if 0
136                         if (strcmp(modules[i], "schema") == 0) {
137                                 current = schema_module_init(ldb, options);
138                                 if (!current) {
139                                         ldb_debug(ldb, LDB_DEBUG_FATAL, "function 'init_module' in %s fails\n", modules[i]);
140                                         return -1;
141                                 }
142                                 DLIST_ADD(ldb->modules, current);
143                                 continue;
144                         }
145 #endif
146 #ifdef HAVE_DLOPEN_DISABLED
147                 {
148                         void *handle;
149                         ldb_module_init_function init;
150                         struct stat st;
151                         const char *errstr;
152
153                         if (stat(modules[i], &st) < 0) {
154                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Required module [%s] not found, bailing out!\n", modules[i]);
155                                 return -1;
156                         }
157
158                         handle = dlopen(modules[i], RTLD_LAZY);
159
160                         if (!handle) {
161                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Error loading module %s [%s]\n", modules[i], dlerror());
162                                 return -1;
163                         }
164
165                         init = (ldb_module_init_function)dlsym(handle, "init_module");
166
167                         errstr = dlerror();
168                         if (errstr) {
169                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Error trying to resolve symbol 'init_module' in %s [%s]\n", modules[i], errstr);
170                                 return -1;
171                         }
172
173                         current = init(ldb, options);
174                         if (!current) {
175                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "function 'init_module' in %s fails\n", modules[i]);
176                                 return -1;
177                         }
178                         DLIST_ADD(ldb->modules, current);
179                 }
180 #else
181                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Required module [%s] not found, bailing out!\n", modules[i]);
182                 return -1;
183 #endif
184                 }
185         }
186
187         return 0; 
188 }
189
190 /*
191    helper functions to call the next module in chain
192 */
193 int ldb_next_close(struct ldb_module *module)
194 {
195         if (!module->next) {
196                 return -1;
197         }
198         return module->next->ops->close(module->next);
199 }
200
201 int ldb_next_search(struct ldb_module *module, 
202                const char *base,
203                enum ldb_scope scope,
204                const char *expression,
205                const char * const *attrs, struct ldb_message ***res)
206 {
207         if (!module->next) {
208                 return -1;
209         }
210         return module->next->ops->search(module->next, base, scope, expression, attrs, res);
211 }
212
213 int ldb_next_search_free(struct ldb_module *module, struct ldb_message **msg)
214 {
215         if (!module->next) {
216                 return -1;
217         }
218         return module->next->ops->search_free(module->next, msg);
219 }
220
221 int ldb_next_add_record(struct ldb_module *module, const struct ldb_message *message)
222 {
223         if (!module->next) {
224                 return -1;
225         }
226         return module->next->ops->add_record(module->next, message);
227 }
228
229 int ldb_next_modify_record(struct ldb_module *module, const struct ldb_message *message)
230 {
231         if (!module->next) {
232                 return -1;
233         }
234         return module->next->ops->modify_record(module->next, message);
235 }
236
237 int ldb_next_delete_record(struct ldb_module *module, const char *dn)
238 {
239         if (!module->next) {
240                 return -1;
241         }
242         return module->next->ops->delete_record(module->next, dn);
243 }
244
245 int ldb_next_rename_record(struct ldb_module *module, const char *olddn, const char *newdn)
246 {
247         if (!module->next) {
248                 return -1;
249         }
250         return module->next->ops->rename_record(module->next, olddn, newdn);
251 }
252
253 int ldb_next_named_lock(struct ldb_module *module, const char *lockname)
254 {
255         if (!module->next) {
256                 return -1;
257         }
258         return module->next->ops->named_lock(module->next, lockname);
259 }
260
261 int ldb_next_named_unlock(struct ldb_module *module, const char *lockname)
262 {
263         if (!module->next) {
264                 return -1;
265         }
266         return module->next->ops->named_unlock(module->next, lockname);
267 }
268
269 const char *ldb_next_errstring(struct ldb_module *module)
270 {
271         if (!module->next) {
272                 return NULL;
273         }
274         return module->next->ops->errstring(module->next);
275 }
276
277 void ldb_next_cache_free(struct ldb_module *module)
278 {
279         if (!module->next) {
280                 return;
281         }
282         module->next->ops->cache_free(module->next);
283 }