f3ca4df9b4c619a462bdb8bf4b2bde3665f987d4
[kai/samba-autobuild/.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 #ifdef HAVE_DLOPEN_DISABLED
45 #include <dlfcn.h>
46 #endif
47
48 #define LDB_MODULE_PREFIX       "modules:"
49 #define LDB_MODULE_PREFIX_LEN   8
50
51 static char *talloc_strdup_no_spaces(struct ldb_context *ldb, const char *string)
52 {
53         int i, len;
54         char *trimmed;
55
56         trimmed = talloc_strdup(ldb, string);
57         if (!trimmed) {
58                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in talloc_strdup_trim_spaces()\n");
59                 return NULL;
60         }
61
62         len = strlen(trimmed);
63         for (i = 0; trimmed[i] != '\0'; i++) {
64                 switch (trimmed[i]) {
65                 case ' ':
66                 case '\t':
67                 case '\n':
68                         memmove(&trimmed[i], &trimmed[i + 1], len -i -1);
69                         break;
70                 }
71         }
72
73         return trimmed;
74 }
75
76
77 /* modules are called in inverse order on the stack.
78    Lets place them as an admin would think the right order is.
79    Modules order is imprtant */
80 static char **ldb_modules_list_from_string(struct ldb_context *ldb, const char *string)
81 {
82         char **modules = NULL;
83         char *modstr, *p;
84         int i;
85
86         /* spaces not admitted */
87         modstr = talloc_strdup_no_spaces(ldb, string);
88         if ( ! modstr) {
89                 return NULL;
90         }
91
92         modules = talloc_realloc(ldb, modules, char *, 2);
93         if ( ! modules ) {
94                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
95                 talloc_free(modstr);
96                 return NULL;
97         }
98         talloc_steal(modules, modstr);
99
100         i = 0;
101         while ((p = strrchr(modstr, ',')) != NULL) {
102                 *p = '\0';
103                 p++;
104                 modules[i] = p;
105
106                 i++;
107                 modules = talloc_realloc(ldb, modules, char *, i + 2);
108                 if ( ! modules ) {
109                         ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
110                         return NULL;
111                 }
112
113         }
114         modules[i] = modstr;
115
116         modules[i + 1] = NULL;
117
118         return modules;
119 }
120
121 int ldb_load_modules(struct ldb_context *ldb, const char *options[])
122 {
123         char **modules = NULL;
124         int i;
125         struct {
126                 const char *name;
127                 ldb_module_init_t init;
128         } well_known_modules[] = {
129                 { "schema", schema_module_init },
130                 { "operational", operational_module_init },
131                 { "rdn_name", rdn_name_module_init },
132 #ifdef _SAMBA_BUILD_
133                 { "objectguid", objectguid_module_init },
134                 { "samldb", samldb_module_init },
135                 { "samba3sam", ldb_samba3sam_module_init },
136                 { "proxy", proxy_module_init },
137 #endif
138                 { NULL, NULL }
139         };
140
141         /* find out which modules we are requested to activate */
142
143         /* check if we have a custom module list passd as ldb option */
144         if (options) {
145                 for (i = 0; options[i] != NULL; i++) {
146                         if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) {
147                                 modules = ldb_modules_list_from_string(ldb, &options[i][LDB_MODULE_PREFIX_LEN]);
148                         }
149                 }
150         }
151
152         /* if not overloaded by options and the backend is not ldap try to load the modules list form ldb */
153         if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { 
154                 int ret;
155                 const char * const attrs[] = { "@LIST" , NULL};
156                 struct ldb_message **msg = NULL;
157                 struct ldb_dn *mods;
158
159                 mods = ldb_dn_explode(ldb, "@MODULES");
160                 if (mods == NULL) {
161                         return -1;
162                 }
163
164                 ret = ldb_search(ldb, mods, LDB_SCOPE_BASE, "", attrs, &msg);
165                 talloc_free(mods);
166                 if (ret == 0 || (ret == 1 && msg[0]->num_elements == 0)) {
167                         ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db\n");
168                 } else {
169                         if (ret < 0) {
170                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb));
171                                 return -1;
172                         }
173                         if (ret > 1) {
174                                 ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", ret);
175                                 talloc_free(msg);
176                                 return -1;
177                         }
178
179                         modules = ldb_modules_list_from_string(ldb, 
180                                                                (const char *)msg[0]->elements[0].values[0].data);
181
182                 }
183
184                 talloc_free(msg);
185         }
186
187         if (modules == NULL) {
188                 ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database\n");
189                 return 0;
190         }
191
192         for (i = 0; modules[i] != NULL; i++) {
193                 struct ldb_module *current;
194                 int m;
195                 for (m=0;well_known_modules[m].name;m++) {
196                         if (strcmp(modules[i], well_known_modules[m].name) == 0) {
197                                 current = well_known_modules[m].init(ldb, options);
198                                 if (current == NULL) {
199                                         ldb_debug(ldb, LDB_DEBUG_FATAL, "function 'init_module' in %s fails\n", modules[i]);
200                                         return -1;
201                                 }
202                                 DLIST_ADD(ldb->modules, current);
203                                 break;
204                         }
205                 }
206                 if (well_known_modules[m].name == NULL) {
207                         ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n", 
208                                   modules[i]);
209                 }
210         }
211
212         talloc_free(modules);
213         return 0; 
214 }
215
216 /*
217   by using this we allow ldb modules to only implement the functions they care about,
218   which makes writing a module simpler, and makes it more likely to keep working
219   when ldb is extended
220 */
221 #define FIND_OP(module, op) do { \
222         module = module->next; \
223         while (module && module->ops->op == NULL) module = module->next; \
224         if (module == NULL) return -1; \
225 } while (0)
226
227
228 /*
229    helper functions to call the next module in chain
230 */
231 int ldb_next_search_bytree(struct ldb_module *module, 
232                            const struct ldb_dn *base,
233                            enum ldb_scope scope,
234                            struct ldb_parse_tree *tree,
235                            const char * const *attrs, struct ldb_message ***res)
236 {
237         FIND_OP(module, search_bytree);
238         return module->ops->search_bytree(module, base, scope, tree, attrs, res);
239 }
240
241 int ldb_next_search(struct ldb_module *module, 
242                     const struct ldb_dn *base,
243                     enum ldb_scope scope,
244                     const char *expression,
245                     const char * const *attrs, struct ldb_message ***res)
246 {
247         struct ldb_parse_tree *tree;
248         int ret;
249         FIND_OP(module, search_bytree);
250         tree = ldb_parse_tree(module, expression);
251         if (tree == NULL) {
252                 ldb_set_errstring(module, talloc_strdup(module, "Unable to parse search expression"));
253                 return -1;
254         }
255         ret = module->ops->search_bytree(module, base, scope, tree, attrs, res);
256         talloc_free(tree);
257         return ret;
258 }
259
260
261 int ldb_next_add_record(struct ldb_module *module, const struct ldb_message *message)
262 {
263         FIND_OP(module, add_record);
264         return module->ops->add_record(module, message);
265 }
266
267 int ldb_next_modify_record(struct ldb_module *module, const struct ldb_message *message)
268 {
269         FIND_OP(module, modify_record);
270         return module->ops->modify_record(module, message);
271 }
272
273 int ldb_next_delete_record(struct ldb_module *module, const struct ldb_dn *dn)
274 {
275         FIND_OP(module, delete_record);
276         return module->ops->delete_record(module, dn);
277 }
278
279 int ldb_next_rename_record(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
280 {
281         FIND_OP(module, rename_record);
282         return module->ops->rename_record(module, olddn, newdn);
283 }
284
285 int ldb_next_start_trans(struct ldb_module *module)
286 {
287         FIND_OP(module, start_transaction);
288         return module->ops->start_transaction(module);
289 }
290
291 int ldb_next_end_trans(struct ldb_module *module)
292 {
293         FIND_OP(module, end_transaction);
294         return module->ops->end_transaction(module);
295 }
296
297 int ldb_next_del_trans(struct ldb_module *module)
298 {
299         FIND_OP(module, del_transaction);
300         return module->ops->del_transaction(module);
301 }
302
303 void ldb_set_errstring(struct ldb_module *module, char *err_string)
304 {
305         if (module->ldb->err_string) {
306                 talloc_free(module->ldb->err_string);
307         }
308
309         module->ldb->err_string = err_string;
310 }
311