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

📄 ldb_map.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
/*   ldb database mapping module   Copyright (C) Jelmer Vernooij 2005   Copyright (C) Martin Kuehl <mkhl@samba.org> 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 ldb_map module * *  Description: Map portions of data into a different format on a *  remote partition. * *  Author: Jelmer Vernooij, Martin Kuehl */#include "ldb_includes.h"#include "ldb_map.h"#include "ldb_map_private.h"#ifndef _PUBLIC_#define _PUBLIC_#endif/* Description of the provided ldb requests: - special attribute 'isMapped' - search:     - if parse tree can be split         - search remote records w/ remote attrs and parse tree     - otherwise         - enumerate all remote records     - for each remote result         - map remote result to local message         - search local result         - is present             - merge local into remote result             - run callback on merged result         - otherwise             - run callback on remote result - add:     - split message into local and remote part     - if local message is not empty         - add isMapped to local message         - add local message     - add remote message - modify:     - split message into local and remote part     - if local message is not empty         - add isMapped to local message         - search for local record         - if present             - modify local record         - otherwise             - add local message     - modify remote record - delete:     - search for local record     - if present         - delete local record     - delete remote record - rename:     - search for local record     - if present         - rename local record         - modify local isMapped     - rename remote record*//* Private data structures * ======================= *//* Global private data *//* Extract mappings from private data. */const struct ldb_map_context *map_get_context(struct ldb_module *module){	const struct map_private *data = talloc_get_type(module->private_data, struct map_private);	return data->context;}/* Create a generic request context. */static struct map_context *map_init_context(struct ldb_handle *h, struct ldb_request *req){	struct map_context *ac;	ac = talloc_zero(h, struct map_context);	if (ac == NULL) {		map_oom(h->module);		return NULL;	}	ac->module = h->module;	ac->orig_req = req;	return ac;}/* Create a search request context. */struct map_search_context *map_init_search_context(struct map_context *ac, struct ldb_reply *ares){	struct map_search_context *sc;	sc = talloc_zero(ac, struct map_search_context);	if (sc == NULL) {		map_oom(ac->module);		return NULL;	}	sc->ac = ac;	sc->local_res = NULL;	sc->remote_res = ares;	return sc;}/* Create a request context and handle. */struct ldb_handle *map_init_handle(struct ldb_request *req, struct ldb_module *module){	struct map_context *ac;	struct ldb_handle *h;	h = talloc_zero(req, struct ldb_handle);	if (h == NULL) {		map_oom(module);		return NULL;	}	h->module = module;	ac = map_init_context(h, req);	if (ac == NULL) {		talloc_free(h);		return NULL;	}	h->private_data = (void *)ac;	h->state = LDB_ASYNC_INIT;	h->status = LDB_SUCCESS;	return h;}/* Dealing with DNs for different partitions * ========================================= *//* Check whether any data should be stored in the local partition. */bool map_check_local_db(struct ldb_module *module){	const struct ldb_map_context *data = map_get_context(module);	if (!data->remote_base_dn || !data->local_base_dn) {		return false;	}	return true;}/* Copy a DN with the base DN of the local partition. */static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn){	struct ldb_dn *new_dn;	new_dn = ldb_dn_copy(mem_ctx, dn);	if ( ! ldb_dn_validate(new_dn)) {		talloc_free(new_dn);		return NULL;	}	/* may be we don't need to rebase at all */	if ( ! data->remote_base_dn || ! data->local_base_dn) {		return new_dn;	}	if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->remote_base_dn))) {		talloc_free(new_dn);		return NULL;	}	if ( ! ldb_dn_add_base(new_dn, data->local_base_dn)) {		talloc_free(new_dn);		return NULL;	}	return new_dn;}/* Copy a DN with the base DN of the remote partition. */static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn){	struct ldb_dn *new_dn;	new_dn = ldb_dn_copy(mem_ctx, dn);	if ( ! ldb_dn_validate(new_dn)) {		talloc_free(new_dn);		return NULL;	}	/* may be we don't need to rebase at all */	if ( ! data->remote_base_dn || ! data->local_base_dn) {		return new_dn;	}	if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->local_base_dn))) {		talloc_free(new_dn);		return NULL;	}	if ( ! ldb_dn_add_base(new_dn, data->remote_base_dn)) {		talloc_free(new_dn);		return NULL;	}	return new_dn;}/* Run a request and make sure it targets the remote partition. *//* TODO: free old DNs and messages? */int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request){	const struct ldb_map_context *data = map_get_context(module);	struct ldb_message *msg;	switch (request->operation) {	case LDB_SEARCH:		if (request->op.search.base) {			request->op.search.base = ldb_dn_rebase_remote(request, data, request->op.search.base);		} else {			request->op.search.base = data->remote_base_dn;			/* TODO: adjust scope? */		}		break;	case LDB_ADD:		msg = ldb_msg_copy_shallow(request, request->op.add.message);		msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn);		request->op.add.message = msg;		break;	case LDB_MODIFY:		msg = ldb_msg_copy_shallow(request, request->op.mod.message);		msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn);		request->op.mod.message = msg;		break;	case LDB_DELETE:		request->op.del.dn = ldb_dn_rebase_remote(request, data, request->op.del.dn);		break;	case LDB_RENAME:		request->op.rename.olddn = ldb_dn_rebase_remote(request, data, request->op.rename.olddn);		request->op.rename.newdn = ldb_dn_rebase_remote(request, data, request->op.rename.newdn);		break;	default:		ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "			  "Invalid remote request!\n");		return LDB_ERR_OPERATIONS_ERROR;	}	return ldb_next_request(module, request);}/* Finding mappings for attributes and objectClasses * ================================================= *//* Find an objectClass mapping by the local name. */static const struct ldb_map_objectclass *map_objectclass_find_local(const struct ldb_map_context *data, const char *name){	int i;	for (i = 0; data->objectclass_maps && data->objectclass_maps[i].local_name; i++) {		if (ldb_attr_cmp(data->objectclass_maps[i].local_name, name) == 0) {			return &data->objectclass_maps[i];		}	}	return NULL;}/* Find an objectClass mapping by the remote name. */static const struct ldb_map_objectclass *map_objectclass_find_remote(const struct ldb_map_context *data, const char *name){	int i;	for (i = 0; data->objectclass_maps && data->objectclass_maps[i].remote_name; i++) {		if (ldb_attr_cmp(data->objectclass_maps[i].remote_name, name) == 0) {			return &data->objectclass_maps[i];		}	}	return NULL;}/* Find an attribute mapping by the local name. */const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name){	int i;	for (i = 0; data->attribute_maps[i].local_name; i++) {		if (ldb_attr_cmp(data->attribute_maps[i].local_name, name) == 0) {			return &data->attribute_maps[i];		}	}	for (i = 0; data->attribute_maps[i].local_name; i++) {		if (ldb_attr_cmp(data->attribute_maps[i].local_name, "*") == 0) {			return &data->attribute_maps[i];		}	}	return NULL;}/* Find an attribute mapping by the remote name. */const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name){	const struct ldb_map_attribute *map;	const struct ldb_map_attribute *wildcard = NULL;	int i, j;	for (i = 0; data->attribute_maps[i].local_name; i++) {		map = &data->attribute_maps[i];		if (ldb_attr_cmp(map->local_name, "*") == 0) {			wildcard = &data->attribute_maps[i];		}		switch (map->type) {		case MAP_IGNORE:			break;		case MAP_KEEP:			if (ldb_attr_cmp(map->local_name, name) == 0) {				return map;			}			break;		case MAP_RENAME:		case MAP_CONVERT:			if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) {				return map;			}			break;		case MAP_GENERATE:			for (j = 0; map->u.generate.remote_names && map->u.generate.remote_names[j]; j++) {				if (ldb_attr_cmp(map->u.generate.remote_names[j], name) == 0) {					return map;				}			}			break;		}	}	/* We didn't find it, so return the wildcard record if one was configured */	return wildcard;}/* Mapping attributes * ================== *//* Check whether an attribute will be mapped into the remote partition. */bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr){	const struct ldb_map_attribute *map = map_attr_find_local(data, attr);	if (map == NULL) {		return false;	}	if (map->type == MAP_IGNORE) {		return false;	}	return true;}/* Map an attribute name into the remote partition. */const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr){	if (map == NULL) {		return talloc_strdup(mem_ctx, attr);	}	switch (map->type) {	case MAP_KEEP:		return talloc_strdup(mem_ctx, attr);	case MAP_RENAME:	case MAP_CONVERT:		return talloc_strdup(mem_ctx, map->u.rename.remote_name);	default:		return NULL;	}}/* Map an attribute name back into the local partition. */const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr){	if (map == NULL) {		return talloc_strdup(mem_ctx, attr);	}	if (map->type == MAP_KEEP) {		return talloc_strdup(mem_ctx, attr);	}	return talloc_strdup(mem_ctx, map->local_name);}/* Merge two lists of attributes into a single one. */int map_attrs_merge(struct ldb_module *module, void *mem_ctx, 		    const char ***attrs, const char * const *more_attrs){	int i, j, k;	for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ;	for (j = 0; more_attrs && more_attrs[j]; j++) /* noop */ ;		*attrs = talloc_realloc(mem_ctx, *attrs, const char *, i+j+1);	if (*attrs == NULL) {		map_oom(module);		return -1;	}	for (k = 0; k < j; k++) {		(*attrs)[i + k] = more_attrs[k];	}	(*attrs)[i+k] = NULL;

⌨️ 快捷键说明

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