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

📄 ldb_map_outbound.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
/*   ldb database mapping module   Copyright (C) Jelmer Vernooij 2005   Copyright (C) Martin Kuehl <mkhl@samba.org> 2006   Copyright (C) Andrew Bartlett <abartlet@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/>.*/#include "ldb_includes.h"#include "ldb_map.h"#include "ldb_map_private.h"/* Mapping attributes * ================== *//* Select attributes that stay in the local partition. */static const char **map_attrs_select_local(struct ldb_module *module, void *mem_ctx, const char * const *attrs){	const struct ldb_map_context *data = map_get_context(module);	const char **result;	int i, last;	if (attrs == NULL)		return NULL;	last = 0;	result = talloc_array(mem_ctx, const char *, 1);	if (result == NULL) {		goto failed;	}	result[0] = NULL;	for (i = 0; attrs[i]; i++) {		/* Wildcards and ignored attributes are kept locally */		if ((ldb_attr_cmp(attrs[i], "*") == 0) ||		    (!map_attr_check_remote(data, attrs[i]))) {			result = talloc_realloc(mem_ctx, result, const char *, last+2);			if (result == NULL) {				goto failed;			}			result[last] = talloc_strdup(result, attrs[i]);			result[last+1] = NULL;			last++;		}	}	return result;failed:	talloc_free(result);	map_oom(module);	return NULL;}/* Collect attributes that are mapped into the remote partition. */static const char **map_attrs_collect_remote(struct ldb_module *module, void *mem_ctx, 					     const char * const *attrs){	const struct ldb_map_context *data = map_get_context(module);	const char **result;	const struct ldb_map_attribute *map;	const char *name=NULL;	int i, j, last;	int ret;	last = 0;	result = talloc_array(mem_ctx, const char *, 1);	if (result == NULL) {		goto failed;	}	result[0] = NULL;	for (i = 0; attrs[i]; i++) {		/* Wildcards are kept remotely, too */		if (ldb_attr_cmp(attrs[i], "*") == 0) {			const char **new_attrs = NULL;			ret = map_attrs_merge(module, mem_ctx, &new_attrs, attrs);			if (ret != LDB_SUCCESS) {				goto failed;			}			ret = map_attrs_merge(module, mem_ctx, &new_attrs, data->wildcard_attributes);			if (ret != LDB_SUCCESS) {				goto failed;			}			attrs = new_attrs;			break;		}	}	for (i = 0; attrs[i]; i++) {		/* Wildcards are kept remotely, too */		if (ldb_attr_cmp(attrs[i], "*") == 0) {			/* Add all 'include in wildcard' attributes */			name = attrs[i];			goto named;		}		/* Add remote names of mapped attrs */		map = map_attr_find_local(data, attrs[i]);		if (map == NULL) {			continue;		}		switch (map->type) {		case MAP_IGNORE:			continue;		case MAP_KEEP:			name = attrs[i];			goto named;		case MAP_RENAME:		case MAP_CONVERT:			name = map->u.rename.remote_name;			goto named;		case MAP_GENERATE:			/* Add all remote names of "generate" attrs */			for (j = 0; map->u.generate.remote_names[j]; j++) {				result = talloc_realloc(mem_ctx, result, const char *, last+2);				if (result == NULL) {					goto failed;				}				result[last] = talloc_strdup(result, map->u.generate.remote_names[j]);				result[last+1] = NULL;				last++;			}			continue;		}	named:	/* We found a single remote name, add that */		result = talloc_realloc(mem_ctx, result, const char *, last+2);		if (result == NULL) {			goto failed;		}		result[last] = talloc_strdup(result, name);		result[last+1] = NULL;		last++;	}	return result;failed:	talloc_free(result);	map_oom(module);	return NULL;}/* Split attributes that stay in the local partition from those that * are mapped into the remote partition. */static int map_attrs_partition(struct ldb_module *module, void *mem_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *attrs){	*local_attrs = map_attrs_select_local(module, mem_ctx, attrs);	*remote_attrs = map_attrs_collect_remote(module, mem_ctx, attrs);	return 0;}/* Mapping message elements * ======================== *//* Add an element to a message, overwriting any old identically named elements. */static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_element *el){	struct ldb_message_element *old;	old = ldb_msg_find_element(msg, el->name);	/* no local result, add as new element */	if (old == NULL) {		if (ldb_msg_add_empty(msg, el->name, 0, &old) != 0) {			return -1;		}		talloc_free(old->name);	}	/* copy new element */	*old = *el;	/* and make sure we reference the contents */	if (!talloc_reference(msg->elements, el->name)) {		return -1;	}	if (!talloc_reference(msg->elements, el->values)) {		return -1;	}	return 0;}/* Map a message element back into the local partition. */static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *module, 							 void *mem_ctx, 							 const struct ldb_map_attribute *map, 							 const char *attr_name,							 const struct ldb_message_element *old){	struct ldb_message_element *el;	int i;	el = talloc_zero(mem_ctx, struct ldb_message_element);	if (el == NULL) {		map_oom(module);		return NULL;	}	el->values = talloc_array(el, struct ldb_val, old->num_values);	if (el->values == NULL) {		talloc_free(el);		map_oom(module);		return NULL;	}	el->name = talloc_strdup(el, attr_name);	if (el->name == NULL) {		talloc_free(el);		map_oom(module);		return NULL;	}	for (i = 0; i < old->num_values; i++) {		el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]);		/* Conversions might fail, in which case bail */		if (!el->values[i].data) {			talloc_free(el);			return NULL;		}		el->num_values++;	}	return el;}/* Merge a remote message element into a local message. */static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local, 			    struct ldb_message *remote, const char *attr_name){	const struct ldb_map_context *data = map_get_context(module);	const struct ldb_map_attribute *map;	struct ldb_message_element *old, *el=NULL;	const char *remote_name = NULL;	/* We handle wildcards in ldb_msg_el_merge_wildcard */	if (ldb_attr_cmp(attr_name, "*") == 0) {		return LDB_SUCCESS;	}	map = map_attr_find_local(data, attr_name);	/* Unknown attribute in remote message:	 * skip, attribute was probably auto-generated */	if (map == NULL) {		return LDB_SUCCESS;	}	switch (map->type) {	case MAP_IGNORE:		break;	case MAP_CONVERT:		remote_name = map->u.convert.remote_name;		break;	case MAP_KEEP:		remote_name = attr_name;		break;	case MAP_RENAME:		remote_name = map->u.rename.remote_name;		break;	case MAP_GENERATE:		break;	}	switch (map->type) {	case MAP_IGNORE:		return LDB_SUCCESS;	case MAP_CONVERT:		if (map->u.convert.convert_remote == NULL) {			ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "				  "Skipping attribute '%s': "				  "'convert_remote' not set\n",				  attr_name);			return LDB_SUCCESS;		}		/* fall through */	case MAP_KEEP:	case MAP_RENAME:		old = ldb_msg_find_element(remote, remote_name);		if (old) {			el = ldb_msg_el_map_remote(module, local, map, attr_name, old);		} else {			return LDB_ERR_NO_SUCH_ATTRIBUTE;		}		break;	case MAP_GENERATE:		if (map->u.generate.generate_local == NULL) {			ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "				  "Skipping attribute '%s': "				  "'generate_local' not set\n",				  attr_name);			return LDB_SUCCESS;		}		el = map->u.generate.generate_local(module, local, attr_name, remote);		if (!el) {			/* Generation failure is probably due to lack of source attributes */			return LDB_ERR_NO_SUCH_ATTRIBUTE;		}		break;	}	if (el == NULL) {		return LDB_ERR_NO_SUCH_ATTRIBUTE;	}	return ldb_msg_replace(local, el);}/* Handle wildcard parts of merging a remote message element into a local message. */static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_message *local, 				     struct ldb_message *remote){	const struct ldb_map_context *data = map_get_context(module);	const struct ldb_map_attribute *map = map_attr_find_local(data, "*");	struct ldb_message_element *el=NULL;	int i, ret;	/* Perhaps we have a mapping for "*" */	if (map && map->type == MAP_KEEP) {		/* We copy everything over, and hope that anything with a 		   more specific rule is overwritten */		for (i = 0; i < remote->num_elements; i++) {			el = ldb_msg_el_map_remote(module, local, map, remote->elements[i].name,						   &remote->elements[i]);			if (el == NULL) {				return LDB_ERR_OPERATIONS_ERROR;			}						ret = ldb_msg_replace(local, el);			if (ret) {				return ret;			}		}	}		/* Now walk the list of possible mappings, and apply each */	for (i = 0; data->attribute_maps[i].local_name; i++) {		ret = ldb_msg_el_merge(module, local, remote, 				       data->attribute_maps[i].local_name);		if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {			continue;		} else if (ret) {			return ret;		} else {			continue;		}	}	return LDB_SUCCESS;}/* Mapping messages * ================ *//* Merge two local messages into a single one. */static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *msg1, struct ldb_message *msg2){	int i, ret;	for (i = 0; i < msg2->num_elements; i++) {		ret = ldb_msg_replace(msg1, &msg2->elements[i]);		if (ret) {			return ret;		}	}	return LDB_SUCCESS;}/* Merge a local and a remote message into a single local one. */static int ldb_msg_merge_remote(struct map_context *ac, struct ldb_message *local, 				struct ldb_message *remote){	int i, ret;	const char * const *attrs = ac->all_attrs;	if (!attrs) {		ret = ldb_msg_el_merge_wildcard(ac->module, local, remote);		if (ret) {			return ret;		}	}	for (i = 0; attrs && attrs[i]; i++) {		if (ldb_attr_cmp(attrs[i], "*") == 0) {			ret = ldb_msg_el_merge_wildcard(ac->module, local, remote);			if (ret) {				return ret;			}			break;		}	}	/* Try to map each attribute back;	 * Add to local message is possible,	 * Overwrite old local attribute if necessary */	for (i = 0; attrs && attrs[i]; i++) {

⌨️ 快捷键说明

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