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

📄 ldb_map_outbound.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	return 0;}/* Collect subtrees that query attributes in the remote partition */static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree){	const struct ldb_map_context *data = map_get_context(module);	const struct ldb_map_attribute *map;	if (tree == NULL) {		return 0;	}	if (tree->operation == LDB_OP_NOT) {		return map_subtree_collect_remote_not(module, mem_ctx, new, tree);	}	if ((tree->operation == LDB_OP_AND) || (tree->operation == LDB_OP_OR)) {		return map_subtree_collect_remote_list(module, mem_ctx, new, tree);	}	if (!map_attr_check_remote(data, tree->u.equality.attr)) {		*new = NULL;		return 0;	}	map = map_attr_find_local(data, tree->u.equality.attr);	if (map->convert_operator) {		return map->convert_operator(module, mem_ctx, new, tree);	}	if (map->type == MAP_GENERATE) {		ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: "			  "Skipping attribute '%s': "			  "'convert_operator' not set\n",			  tree->u.equality.attr);		*new = NULL;		return 0;	}	return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, map);}/* Split subtrees that query attributes in the local partition from * those that query the remote partition. */static int ldb_parse_tree_partition(struct ldb_module *module, void *local_ctx, void *remote_ctx, struct ldb_parse_tree **local_tree, struct ldb_parse_tree **remote_tree, const struct ldb_parse_tree *tree){	int ret;	*local_tree = NULL;	*remote_tree = NULL;	/* No original tree */	if (tree == NULL) {		return 0;	}	/* Generate local tree */	ret = map_subtree_select_local(module, local_ctx, local_tree, tree);	if (ret) {		return ret;	}	/* Generate remote tree */	ret = map_subtree_collect_remote(module, remote_ctx, remote_tree, tree);	if (ret) {		talloc_free(*local_tree);		return ret;	}	return 0;}/* Collect a list of attributes required either explicitly from a * given list or implicitly  from a given parse tree; split the * collected list into local and remote parts. */static int map_attrs_collect_and_partition(struct ldb_module *module, struct map_context *ac,					   const char * const *search_attrs, 					   const struct ldb_parse_tree *tree){	void *tmp_ctx;	const char **tree_attrs;	const char **remote_attrs;	const char **local_attrs;	int ret;	/* There is no tree, just partition the searched attributes */	if (tree == NULL) {		ret = map_attrs_partition(module, ac, 					  &local_attrs, &remote_attrs, search_attrs);		if (ret == 0) {			ac->local_attrs = local_attrs;			ac->remote_attrs = remote_attrs;			ac->all_attrs = search_attrs;		}		return ret; 	}	/* Create context for temporary memory */	tmp_ctx = talloc_new(ac);	if (tmp_ctx == NULL) {		goto oom;	}	/* Prepare list of attributes from tree */	tree_attrs = talloc_array(tmp_ctx, const char *, 1);	if (tree_attrs == NULL) {		talloc_free(tmp_ctx);		goto oom;	}	tree_attrs[0] = NULL;	/* Collect attributes from tree */	ret = ldb_parse_tree_collect_attrs(module, tmp_ctx, &tree_attrs, tree);	if (ret) {		goto done;	}	/* Merge attributes from search operation */	ret = map_attrs_merge(module, tmp_ctx, &tree_attrs, search_attrs);	if (ret) {		goto done;	}	/* Split local from remote attributes */	ret = map_attrs_partition(module, ac, &local_attrs, 				  &remote_attrs, tree_attrs);		if (ret == 0) {		ac->local_attrs = local_attrs;		ac->remote_attrs = remote_attrs;		talloc_steal(ac, tree_attrs);		ac->all_attrs = tree_attrs;	}done:	/* Free temporary memory */	talloc_free(tmp_ctx);	return ret;oom:	map_oom(module);	return -1;}/* Outbound requests: search * ========================= *//* Pass a merged search result up the callback chain. */int map_up_callback(struct ldb_context *ldb, const struct ldb_request *req, struct ldb_reply *ares){	int i;	/* No callback registered, stop */	if (req->callback == NULL) {		return LDB_SUCCESS;	}	/* Only records need special treatment */	if (ares->type != LDB_REPLY_ENTRY) {		return req->callback(ldb, req->context, ares);	}	/* Merged result doesn't match original query, skip */	if (!ldb_match_msg(ldb, ares->message, req->op.search.tree, req->op.search.base, req->op.search.scope)) {		ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: "			  "Skipping record '%s': "			  "doesn't match original search\n",			  ldb_dn_get_linearized(ares->message->dn));		return LDB_SUCCESS;	}	/* Limit result to requested attrs */	if ((req->op.search.attrs) && (!ldb_attr_in_list(req->op.search.attrs, "*"))) {		for (i = 0; i < ares->message->num_elements; ) {			struct ldb_message_element *el = &ares->message->elements[i];			if (!ldb_attr_in_list(req->op.search.attrs, el->name)) {				ldb_msg_remove_element(ares->message, el);			} else {				i++;			}		}	}	return req->callback(ldb, req->context, ares);}/* Merge the remote and local parts of a search result. */int map_local_merge_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares){	struct map_search_context *sc;	int ret;	if (context == NULL || ares == NULL) {		ldb_set_errstring(ldb, talloc_asprintf(ldb, "ldb_map: "						       "NULL Context or Result in `map_local_merge_callback`"));		return LDB_ERR_OPERATIONS_ERROR;	}	sc = talloc_get_type(context, struct map_search_context);	switch (ares->type) {	case LDB_REPLY_ENTRY:		/* We have already found a local record */		if (sc->local_res) {			ldb_set_errstring(ldb, talloc_asprintf(ldb, "ldb_map: "							       "Too many results to base search for local entry"));			talloc_free(ares);			return LDB_ERR_OPERATIONS_ERROR;		}		/* Store local result */		sc->local_res = ares;		/* Merge remote into local message */		ret = ldb_msg_merge_local(sc->ac->module, ares->message, sc->remote_res->message);		if (ret) {			talloc_free(ares);			return LDB_ERR_OPERATIONS_ERROR;		}		return map_up_callback(ldb, sc->ac->orig_req, ares);	case LDB_REPLY_DONE:		/* No local record found, continue with remote record */		if (sc->local_res == NULL) {			return map_up_callback(ldb, sc->ac->orig_req, sc->remote_res);		}		return LDB_SUCCESS;	default:		ldb_set_errstring(ldb, talloc_asprintf(ldb, "ldb_map: "						       "Unexpected result type in base search for local entry"));		talloc_free(ares);		return LDB_ERR_OPERATIONS_ERROR;	}}/* Search the local part of a remote search result. */int map_remote_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares){	struct map_context *ac;	struct map_search_context *sc;	struct ldb_request *req;	int ret;	if (context == NULL || ares == NULL) {		ldb_set_errstring(ldb, talloc_asprintf(ldb, "ldb_map: "						       "NULL Context or Result in `map_remote_search_callback`"));		return LDB_ERR_OPERATIONS_ERROR;	}	ac = talloc_get_type(context, struct map_context);	/* It's not a record, stop searching */	if (ares->type != LDB_REPLY_ENTRY) {		return map_up_callback(ldb, ac->orig_req, ares);	}	/* Map result record into a local message */	ret = map_reply_remote(ac, ares);	if (ret) {		talloc_free(ares);		return LDB_ERR_OPERATIONS_ERROR;	}	/* There is no local db, stop searching */	if (!map_check_local_db(ac->module)) {		return map_up_callback(ldb, ac->orig_req, ares);	}	/* Prepare local search context */	sc = map_init_search_context(ac, ares);	if (sc == NULL) {		talloc_free(ares);		return LDB_ERR_OPERATIONS_ERROR;	}	/* Prepare local search request */	/* TODO: use GUIDs here instead? */	ac->search_reqs = talloc_realloc(ac, ac->search_reqs, struct ldb_request *, ac->num_searches + 2);	if (ac->search_reqs == NULL) {		talloc_free(ares);		return LDB_ERR_OPERATIONS_ERROR;	}	ac->search_reqs[ac->num_searches]		= req = map_search_base_req(ac, ares->message->dn, 					    NULL, NULL, sc, map_local_merge_callback);	if (req == NULL) {		talloc_free(sc);		talloc_free(ares);		return LDB_ERR_OPERATIONS_ERROR;	}	ac->num_searches++;	ac->search_reqs[ac->num_searches] = NULL;	return ldb_next_request(ac->module, req);}/* Search a record. */int map_search(struct ldb_module *module, struct ldb_request *req){	struct ldb_handle *h;	struct map_context *ac;	struct ldb_parse_tree *local_tree, *remote_tree;	int ret;	const char *wildcard[] = { "*", NULL };	const char * const *attrs;	if (!module->private_data) /* if we're not yet initialized, go to the next module */		return ldb_next_request(module, req);	/* Do not manipulate our control entries */	if (ldb_dn_is_special(req->op.search.base))		return ldb_next_request(module, req);	/* No mapping requested, skip to next module */	if ((req->op.search.base) && (!ldb_dn_check_local(module, req->op.search.base))) {		return ldb_next_request(module, req);	}	/* TODO: How can we be sure about which partition we are	 *	 targetting when there is no search base? */	/* Prepare context and handle */	h = map_init_handle(req, module);	if (h == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	ac = talloc_get_type(h->private_data, struct map_context);	ac->search_reqs = talloc_array(ac, struct ldb_request *, 2);	if (ac->search_reqs == NULL) {		talloc_free(h);		return LDB_ERR_OPERATIONS_ERROR;	}	ac->num_searches = 1;	ac->search_reqs[1] = NULL;	/* Prepare the remote operation */	ac->search_reqs[0] = talloc(ac, struct ldb_request);	if (ac->search_reqs[0] == NULL) {		goto oom;	}	*(ac->search_reqs[0]) = *req;	/* copy the request */	ac->search_reqs[0]->handle = h;	/* return our own handle to deal with this call */	ac->search_reqs[0]->context = ac;	ac->search_reqs[0]->callback = map_remote_search_callback;	/* It is easier to deal with the two different ways of	 * expressing the wildcard in the same codepath */	attrs = req->op.search.attrs;	if (attrs == NULL) {		attrs = wildcard;	}	/* Split local from remote attrs */	ret = map_attrs_collect_and_partition(module, ac, 					      attrs, req->op.search.tree);	if (ret) {		goto failed;	}	ac->search_reqs[0]->op.search.attrs = ac->remote_attrs;	/* Split local from remote tree */	ret = ldb_parse_tree_partition(module, ac, ac->search_reqs[0], 				       &local_tree, &remote_tree, 				       req->op.search.tree);	if (ret) {		goto failed;	}	if (((local_tree != NULL) && (remote_tree != NULL)) &&	    (!ldb_parse_tree_check_splittable(req->op.search.tree))) {		/* The query can't safely be split, enumerate the remote partition */		local_tree = NULL;		remote_tree = NULL;	}	if (local_tree == NULL) {		/* Construct default local parse tree */		local_tree = talloc_zero(ac, struct ldb_parse_tree);		if (local_tree == NULL) {			map_oom(ac->module);			goto failed;		}		local_tree->operation = LDB_OP_PRESENT;		local_tree->u.present.attr = talloc_strdup(local_tree, IS_MAPPED);	}	if (remote_tree == NULL) {		/* Construct default remote parse tree */		remote_tree = ldb_parse_tree(ac->search_reqs[0], NULL);		if (remote_tree == NULL) {			goto failed;		}	}	ac->local_tree = local_tree;	ac->search_reqs[0]->op.search.tree = remote_tree;	ldb_set_timeout_from_prev_req(module->ldb, req, ac->search_reqs[0]);	h->state = LDB_ASYNC_INIT;	h->status = LDB_SUCCESS;	ac->step = MAP_SEARCH_REMOTE;	ret = ldb_next_remote_request(module, ac->search_reqs[0]);	if (ret == LDB_SUCCESS) {		req->handle = h;	}	return ret;oom:	map_oom(module);failed:	talloc_free(h);	return LDB_ERR_OPERATIONS_ERROR;}

⌨️ 快捷键说明

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