• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source3/lib/ldb/common/
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 3 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, see <http://www.gnu.org/licenses/>.
23*/
24
25/*
26 *  Name: ldb
27 *
28 *  Component: ldb modules core
29 *
30 *  Description: core modules routines
31 *
32 *  Author: Simo Sorce
33 */
34
35#include "includes.h"
36#include "ldb/include/includes.h"
37
38#if (_SAMBA_BUILD_ >= 4)
39#include "build.h"
40#include "dynconfig.h"
41#endif
42
43#define LDB_MODULE_PREFIX	"modules:"
44#define LDB_MODULE_PREFIX_LEN	8
45
46static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string)
47{
48	int i, len;
49	char *trimmed;
50
51	trimmed = talloc_strdup(mem_ctx, string);
52	if (!trimmed) {
53		return NULL;
54	}
55
56	len = strlen(trimmed);
57	for (i = 0; trimmed[i] != '\0'; i++) {
58		switch (trimmed[i]) {
59		case ' ':
60		case '\t':
61		case '\n':
62			memmove(&trimmed[i], &trimmed[i + 1], len -i -1);
63			break;
64		}
65	}
66
67	return trimmed;
68}
69
70
71/* modules are called in inverse order on the stack.
72   Lets place them as an admin would think the right order is.
73   Modules order is important */
74const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string)
75{
76	char **modules = NULL;
77	const char **m;
78	char *modstr, *p;
79	int i;
80
81	/* spaces not admitted */
82	modstr = ldb_modules_strdup_no_spaces(mem_ctx, string);
83	if ( ! modstr) {
84		ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()\n");
85		return NULL;
86	}
87
88	modules = talloc_realloc(mem_ctx, modules, char *, 2);
89	if ( ! modules ) {
90		ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
91		talloc_free(modstr);
92		return NULL;
93	}
94	talloc_steal(modules, modstr);
95
96	i = 0;
97	/* The str*r*chr walks backwards:  This is how we get the inverse order mentioned above */
98	while ((p = strrchr(modstr, ',')) != NULL) {
99		*p = '\0';
100		p++;
101		modules[i] = p;
102
103		i++;
104		modules = talloc_realloc(mem_ctx, modules, char *, i + 2);
105		if ( ! modules ) {
106			ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
107			return NULL;
108		}
109
110	}
111	modules[i] = modstr;
112
113	modules[i + 1] = NULL;
114
115	m = (const char **)modules;
116
117	return m;
118}
119
120static struct ops_list_entry {
121	const struct ldb_module_ops *ops;
122	struct ops_list_entry *next;
123} *registered_modules = NULL;
124
125static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
126{
127	struct ops_list_entry *e;
128
129	for (e = registered_modules; e; e = e->next) {
130 		if (strcmp(e->ops->name, name) == 0)
131			return e->ops;
132	}
133
134	return NULL;
135}
136
137#ifndef STATIC_ldb_MODULES
138
139#ifdef HAVE_LDB_LDAP
140#define LDAP_INIT ldb_ldap_init,
141#else
142#define LDAP_INIT
143#endif
144
145#ifdef HAVE_LDB_SQLITE3
146#define SQLITE3_INIT ldb_sqlite3_init,
147#else
148#define SQLITE3_INIT
149#endif
150
151#define STATIC_ldb_MODULES \
152	{	\
153		LDAP_INIT \
154		SQLITE3_INIT \
155		ldb_tdb_init, 	\
156		ldb_operational_init,	\
157		ldb_rdn_name_init,	\
158		ldb_objectclass_init,	\
159		ldb_paged_results_init,	\
160		ldb_sort_init,		\
161		ldb_asq_init,		\
162		NULL			\
163	}
164#endif
165
166int ldb_global_init(void)
167{
168	static int (*static_init_fns[])(void) = STATIC_ldb_MODULES;
169
170	static int initialized = 0;
171	int ret = 0, i;
172
173	if (initialized)
174		return 0;
175
176	initialized = 1;
177
178	for (i = 0; static_init_fns[i]; i++) {
179		if (static_init_fns[i]() == -1)
180			ret = -1;
181	}
182
183	return ret;
184}
185
186int ldb_register_module(const struct ldb_module_ops *ops)
187{
188	struct ops_list_entry *entry = talloc(talloc_autofree_context(), struct ops_list_entry);
189
190	if (ldb_find_module_ops(ops->name) != NULL)
191		return -1;
192
193	if (entry == NULL)
194		return -1;
195
196	entry->ops = ops;
197	entry->next = registered_modules;
198	registered_modules = entry;
199
200	return 0;
201}
202
203int ldb_try_load_dso(struct ldb_context *ldb, const char *name)
204{
205	char *path;
206	void *handle;
207	int (*init_fn) (void);
208	char *modulesdir;
209	int ret;
210
211#ifdef HAVE_DLOPEN
212	if (getenv("LD_LDB_MODULE_PATH") != NULL) {
213		modulesdir = talloc_strdup(ldb, getenv("LD_LDB_MODULE_PATH"));
214	} else {
215#ifdef _SAMBA_BUILD_
216		modulesdir = talloc_asprintf(ldb, "%s/ldb", get_dyn_LIBDIR());
217#else
218		modulesdir = talloc_strdup(ldb, MODULESDIR);
219#endif
220	}
221
222	path = talloc_asprintf(ldb, "%s/%s.%s", modulesdir, name, SHLIBEXT);
223
224	talloc_free(modulesdir);
225
226	ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path);
227
228	handle = dlopen(path, RTLD_NOW);
229	if (handle == NULL) {
230		ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s\n", name, path, dlerror());
231		return -1;
232	}
233
234	init_fn = (int (*)(void))dlsym(handle, "init_samba_module");
235
236	if (init_fn == NULL) {
237		ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol "
238			  "`init_samba_module' found in %s: %s\n", path,
239			  dlerror());
240		dlclose(handle);
241		return -1;
242	}
243
244	talloc_free(path);
245
246	ret = init_fn();
247	if (ret == -1) {
248		dlclose(handle);
249	}
250	return ret;
251#else
252	ldb_debug(ldb, LDB_DEBUG_TRACE, "no dlopen() - not trying to load %s module\n", name);
253	return -1;
254#endif
255}
256
257int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out)
258{
259	struct ldb_module *module;
260	int i;
261
262	module = backend;
263
264	for (i = 0; module_list[i] != NULL; i++) {
265		struct ldb_module *current;
266		const struct ldb_module_ops *ops;
267
268		ops = ldb_find_module_ops(module_list[i]);
269		if (ops == NULL) {
270			if (ldb_try_load_dso(ldb, module_list[i]) == 0) {
271				ops = ldb_find_module_ops(module_list[i]);
272			}
273		}
274
275		if (ops == NULL) {
276			ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n",
277				  module_list[i]);
278			continue;
279		}
280
281		current = talloc_zero(ldb, struct ldb_module);
282		if (current == NULL) {
283			return LDB_ERR_OPERATIONS_ERROR;
284		}
285		talloc_set_name(current, "ldb_module: %s", module_list[i]);
286
287		current->ldb = ldb;
288		current->ops = ops;
289
290		DLIST_ADD(module, current);
291	}
292	*out = module;
293	return LDB_SUCCESS;
294}
295
296int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module)
297{
298	while (module && module->ops->init_context == NULL)
299		module = module->next;
300
301	if (module && module->ops->init_context &&
302		module->ops->init_context(module) != LDB_SUCCESS) {
303		ldb_debug(ldb, LDB_DEBUG_FATAL, "module initialization failed\n");
304		return LDB_ERR_OPERATIONS_ERROR;
305	}
306
307	return LDB_SUCCESS;
308}
309
310int ldb_load_modules(struct ldb_context *ldb, const char *options[])
311{
312	const char **modules = NULL;
313	int i;
314	int ret;
315	TALLOC_CTX *mem_ctx = talloc_new(ldb);
316	if (!mem_ctx) {
317		return LDB_ERR_OPERATIONS_ERROR;
318	}
319
320	/* find out which modules we are requested to activate */
321
322	/* check if we have a custom module list passd as ldb option */
323	if (options) {
324		for (i = 0; options[i] != NULL; i++) {
325			if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) {
326				modules = ldb_modules_list_from_string(ldb, mem_ctx, &options[i][LDB_MODULE_PREFIX_LEN]);
327			}
328		}
329	}
330
331	/* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */
332	if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) {
333		const char * const attrs[] = { "@LIST" , NULL};
334		struct ldb_result *res = NULL;
335		struct ldb_dn *mods_dn;
336
337		mods_dn = ldb_dn_explode(mem_ctx, "@MODULES");
338		if (mods_dn == NULL) {
339			talloc_free(mem_ctx);
340			return -1;
341		}
342
343		ret = ldb_search(ldb, ldb, &res, mods_dn, LDB_SCOPE_BASE, attrs, "");
344		talloc_steal(mods_dn, res);
345		if (ret == LDB_SUCCESS && (res->count == 0 || res->msgs[0]->num_elements == 0)) {
346			ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db\n");
347		} else {
348			if (ret != LDB_SUCCESS) {
349				ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb));
350				talloc_free(mem_ctx);
351				return -1;
352			}
353			if (res->count > 1) {
354				ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", res->count);
355				talloc_free(mem_ctx);
356				return -1;
357			}
358
359			modules = ldb_modules_list_from_string(ldb, mem_ctx,
360							       (const char *)res->msgs[0]->elements[0].values[0].data);
361
362		}
363
364		talloc_free(mods_dn);
365	}
366
367	if (modules != NULL) {
368		ret = ldb_load_modules_list(ldb, modules, ldb->modules, &ldb->modules);
369		talloc_free(modules);
370		if (ret != LDB_SUCCESS) {
371			return ret;
372		}
373	} else {
374		ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database\n");
375	}
376
377	return ldb_init_module_chain(ldb, ldb->modules);
378}
379
380/*
381  by using this we allow ldb modules to only implement the functions they care about,
382  which makes writing a module simpler, and makes it more likely to keep working
383  when ldb is extended
384*/
385#define FIND_OP(module, op) do { \
386	struct ldb_context *ldb = module->ldb; \
387	module = module->next; \
388	while (module && module->ops->op == NULL) module = module->next; \
389	if (module == NULL) { \
390		ldb_asprintf_errstring(ldb, "Unable to find backend operation for " #op ); \
391		return LDB_ERR_OPERATIONS_ERROR;	\
392	}						\
393} while (0)
394
395
396/*
397   helper functions to call the next module in chain
398*/
399
400int ldb_next_request(struct ldb_module *module, struct ldb_request *request)
401{
402	switch (request->operation) {
403	case LDB_SEARCH:
404		FIND_OP(module, search);
405		return module->ops->search(module, request);
406	case LDB_ADD:
407		FIND_OP(module, add);
408		return module->ops->add(module, request);
409	case LDB_MODIFY:
410		FIND_OP(module, modify);
411		return module->ops->modify(module, request);
412	case LDB_DELETE:
413		FIND_OP(module, del);
414		return module->ops->del(module, request);
415	case LDB_RENAME:
416		FIND_OP(module, rename);
417		return module->ops->rename(module, request);
418	case LDB_SEQUENCE_NUMBER:
419		FIND_OP(module, sequence_number);
420		return module->ops->sequence_number(module, request);
421	default:
422		FIND_OP(module, request);
423		return module->ops->request(module, request);
424	}
425}
426
427int ldb_next_init(struct ldb_module *module)
428{
429	/* init is different in that it is not an error if modules
430	 * do not require initialization */
431
432	module = module->next;
433
434	while (module && module->ops->init_context == NULL)
435		module = module->next;
436
437	if (module == NULL)
438		return LDB_SUCCESS;
439
440	return module->ops->init_context(module);
441}
442
443int ldb_next_start_trans(struct ldb_module *module)
444{
445	FIND_OP(module, start_transaction);
446	return module->ops->start_transaction(module);
447}
448
449int ldb_next_end_trans(struct ldb_module *module)
450{
451	FIND_OP(module, end_transaction);
452	return module->ops->end_transaction(module);
453}
454
455int ldb_next_del_trans(struct ldb_module *module)
456{
457	FIND_OP(module, del_transaction);
458	return module->ops->del_transaction(module);
459}
460