⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldb.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    ldb database library   Copyright (C) Andrew Tridgell  2004   Copyright (C) Simo Sorce  2005-2006     ** NOTE! The following LGPL license applies to the ldb     ** library. This does NOT imply that all of Samba is released     ** under the LGPL      This library is free software; you can redistribute it and/or   modify it under the terms of the GNU Lesser General Public   License as published by the Free Software Foundation; either   version 3 of the License, or (at your option) any later version.   This library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Lesser General Public License for more details.   You should have received a copy of the GNU Lesser General Public   License along with this library; if not, see <http://www.gnu.org/licenses/>.*//* *  Name: ldb * *  Component: ldb core API * *  Description: core API routines interfacing to ldb backends * *  Author: Andrew Tridgell */#include "ldb_includes.h"/*    initialise a ldb context   The mem_ctx is optional*/struct ldb_context *ldb_init(void *mem_ctx){	struct ldb_context *ldb = talloc_zero(mem_ctx, struct ldb_context);	int ret;	ret = ldb_setup_wellknown_attributes(ldb);	if (ret != 0) {		talloc_free(ldb);		return NULL;	}	ldb_set_utf8_default(ldb);	ldb_set_create_perms(ldb, 0666);	ldb_set_modules_dir(ldb, LDB_MODULESDIR);	return ldb;}static struct backends_list_entry {	struct ldb_backend_ops *ops;	struct backends_list_entry *prev, *next;} *ldb_backends = NULL;#ifndef STATIC_LIBLDB_BACKENDS #ifdef HAVE_LDB_LDAP#define LDAP_INIT &ldb_ldap_backend_ops, \				  &ldb_ldapi_backend_ops, \				  &ldb_ldaps_backend_ops,#else#define LDAP_INIT#endif#ifdef HAVE_LDB_SQLITE3#define SQLITE3_INIT &ldb_sqlite3_backend_ops,#else#define SQLITE3_INIT#endif#define STATIC_LIBLDB_BACKENDS \	LDAP_INIT \	SQLITE3_INIT \	&ldb_tdb_backend_ops, 	\	NULL#endifconst static struct ldb_backend_ops *builtin_backends[] = {	STATIC_LIBLDB_BACKENDS};static ldb_connect_fn ldb_find_backend(const char *url){	struct backends_list_entry *backend;	int i;	for (i = 0; builtin_backends[i]; i++) {		if (strncmp(builtin_backends[i]->name, url, strlen(builtin_backends[i]->name)) == 0)			return builtin_backends[i]->connect_fn;	}	for (backend = ldb_backends; backend; backend = backend->next) {		if (strncmp(backend->ops->name, url, strlen(backend->ops->name)) == 0) {			return backend->ops->connect_fn;		}	}	return NULL;}/* register a new ldb backend*/int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn){	struct ldb_backend_ops *backend = talloc(talloc_autofree_context(), struct ldb_backend_ops);	struct backends_list_entry *entry = talloc(talloc_autofree_context(), struct backends_list_entry);	if (ldb_find_backend(url_prefix)) {		return LDB_SUCCESS;	}	/* Maybe check for duplicity here later on? */	backend->name = talloc_strdup(backend, url_prefix);	backend->connect_fn = connectfn;	entry->ops = backend;	DLIST_ADD(ldb_backends, entry);	return LDB_SUCCESS;}/*    Return the ldb module form of a database. The URL can either be one of the following forms   ldb://path   ldapi://path   flags is made up of LDB_FLG_*   the options are passed uninterpreted to the backend, and are   backend specific.  This allows modules to get at only the backend module, for example where a module   may wish to direct certain requests at a particular backend.*/int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *options[],			struct ldb_module **backend_module){	int ret;	char *backend;	ldb_connect_fn fn;	if (strchr(url, ':') != NULL) {		backend = talloc_strndup(ldb, url, strchr(url, ':')-url);	} else {		/* Default to tdb */		backend = talloc_strdup(ldb, "tdb");	}	fn = ldb_find_backend(backend);	if (fn == NULL) {		int (*init_fn) (void);		init_fn = ldb_dso_load_symbol(ldb, backend,					      "init_module");		if (init_fn != NULL && init_fn() == 0) {			fn = ldb_find_backend(backend);		}	}	if (fn == NULL) {		struct ldb_backend_ops *ops;		char *symbol_name = talloc_asprintf(ldb, "ldb_%s_backend_ops", backend);		if (symbol_name == NULL) {			return LDB_ERR_OPERATIONS_ERROR;		}		ops = ldb_dso_load_symbol(ldb, backend, symbol_name);		if (ops != NULL) {			fn = ops->connect_fn;		}		talloc_free(symbol_name);	}	talloc_free(backend);	if (fn == NULL) {		ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url);		return LDB_ERR_OTHER;	}	ret = fn(ldb, url, ldb->flags, options, backend_module);	if (ret != LDB_SUCCESS) {		ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url);		return ret;	}	return ret;}/*  try to autodetect a basedn if none specified. This fixes one of my  pet hates about ldapsearch, which is that you have to get a long,  complex basedn right to make any use of it.*/void ldb_set_default_dns(struct ldb_context *ldb){	TALLOC_CTX *tmp_ctx;	int ret;	struct ldb_result *res;	struct ldb_dn *tmp_dn=NULL;	static const char *attrs[] = {		"rootDomainNamingContext",		"configurationNamingContext",		"schemaNamingContext",		"defaultNamingContext",		NULL	};	tmp_ctx = talloc_new(ldb);	ret = ldb_search(ldb, ldb_dn_new(tmp_ctx, ldb, NULL), LDB_SCOPE_BASE, 			 "(objectClass=*)", attrs, &res);	if (ret == LDB_SUCCESS) {		if (res->count == 1) {			if (!ldb_get_opaque(ldb, "rootDomainNamingContext")) {				tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], "rootDomainNamingContext");				ldb_set_opaque(ldb, "rootDomainNamingContext", tmp_dn);			}			if (!ldb_get_opaque(ldb, "configurationNamingContext")) {				tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], "configurationNamingContext");				ldb_set_opaque(ldb, "configurationNamingContext", tmp_dn);			}			if (!ldb_get_opaque(ldb, "schemaNamingContext")) {				tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], "schemaNamingContext");				ldb_set_opaque(ldb, "schemaNamingContext", tmp_dn);			}			if (!ldb_get_opaque(ldb, "defaultNamingContext")) {				tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], "defaultNamingContext");				ldb_set_opaque(ldb, "defaultNamingContext", tmp_dn);			}		}		talloc_free(res);	}	talloc_free(tmp_ctx);}struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb){	return talloc_get_type(ldb_get_opaque(ldb, "rootDomainNamingContext"), struct ldb_dn);}struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb){	return talloc_get_type(ldb_get_opaque(ldb, "configurationNamingContext"), struct ldb_dn);}struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb){	return talloc_get_type(ldb_get_opaque(ldb, "schemaNamingContext"), struct ldb_dn);}struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb){	return talloc_get_type(ldb_get_opaque(ldb, "defaultNamingContext"), struct ldb_dn);}/*  connect to a database. The URL can either be one of the following forms   ldb://path   ldapi://path   flags is made up of LDB_FLG_*   the options are passed uninterpreted to the backend, and are   backend specific*/int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]){	int ret;	const char *url2;	/* We seem to need to do this here, or else some utilities don't get ldb backends */	ldb->flags = flags;	url2 = talloc_strdup(ldb, url);	if (!url2) {		ldb_oom(ldb);		return LDB_ERR_OPERATIONS_ERROR;	}	ret = ldb_set_opaque(ldb, "ldb_url", talloc_strdup(ldb, url2));	if (ret != LDB_SUCCESS) {		return ret;	}	ret = ldb_connect_backend(ldb, url, options, &ldb->modules);	if (ret != LDB_SUCCESS) {		return ret;	}	if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {		ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to load modules for %s: %s\n",			  url, ldb_errstring(ldb));		return LDB_ERR_OTHER;	}	/* TODO: get timeout from options if available there */	ldb->default_timeout = 300; /* set default to 5 minutes */	/* set the default base dn */	ldb_set_default_dns(ldb);	return LDB_SUCCESS;}void ldb_set_errstring(struct ldb_context *ldb, const char *err_string){	if (ldb->err_string) {		talloc_free(ldb->err_string);	}	ldb->err_string = talloc_strdup(ldb, err_string);}void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...){	va_list ap;	char *old_string = NULL;	if (ldb->err_string) {		old_string = ldb->err_string;	}	va_start(ap, format);	ldb->err_string = talloc_vasprintf(ldb, format, ap);	va_end(ap);	talloc_free(old_string);}void ldb_reset_err_string(struct ldb_context *ldb){	if (ldb->err_string) {		talloc_free(ldb->err_string);		ldb->err_string = NULL;	}}#define FIRST_OP(ldb, op) do { \	module = ldb->modules;					\	while (module && module->ops->op == NULL) module = module->next; \	if (module == NULL) {						\		ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \		return LDB_ERR_OPERATIONS_ERROR;			\	} \} while (0)/*  start a transaction*/static int ldb_transaction_start_internal(struct ldb_context *ldb){	struct ldb_module *module;	int status;	FIRST_OP(ldb, start_transaction);	ldb_reset_err_string(ldb);	status = module->ops->start_transaction(module);	if (status != LDB_SUCCESS) {		if (ldb->err_string == NULL) {			/* no error string was setup by the backend */			ldb_asprintf_errstring(ldb,						"ldb transaction start: %s (%d)", 						ldb_strerror(status), 						status);		}	}	return status;}/*  commit a transaction*/static int ldb_transaction_commit_internal(struct ldb_context *ldb){	struct ldb_module *module;	int status;	FIRST_OP(ldb, end_transaction);	ldb_reset_err_string(ldb);	status = module->ops->end_transaction(module);	if (status != LDB_SUCCESS) {		if (ldb->err_string == NULL) {			/* no error string was setup by the backend */			ldb_asprintf_errstring(ldb, 						"ldb transaction commit: %s (%d)", 						ldb_strerror(status), 						status);		}	}	return status;}/*  cancel a transaction*/static int ldb_transaction_cancel_internal(struct ldb_context *ldb){	struct ldb_module *module;	int status;	FIRST_OP(ldb, del_transaction);	status = module->ops->del_transaction(module);	if (status != LDB_SUCCESS) {		if (ldb->err_string == NULL) {			/* no error string was setup by the backend */			ldb_asprintf_errstring(ldb, 						"ldb transaction cancel: %s (%d)", 						ldb_strerror(status), 						status);		}	}	return status;}int ldb_transaction_start(struct ldb_context *ldb){	/* disable autotransactions */	ldb->transaction_active++;	return ldb_transaction_start_internal(ldb);}int ldb_transaction_commit(struct ldb_context *ldb){	/* renable autotransactions (when we reach 0) */	if (ldb->transaction_active > 0)		ldb->transaction_active--;	return ldb_transaction_commit_internal(ldb);}int ldb_transaction_cancel(struct ldb_context *ldb){	/* renable autotransactions (when we reach 0) */	if (ldb->transaction_active > 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -