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