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

📄 linked_attributes.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
		}				/* Even link IDs are for the originating attribute */				/* Now find the target attribute */		target_attr = dsdb_attribute_by_linkID(schema, schema_attr->linkID + 1);		if (!target_attr) {			ldb_asprintf_errstring(module->ldb, 					       "attribute %s does not have valid link target", req->op.mod.message->elements[i].name);			return LDB_ERR_OBJECT_CLASS_VIOLATION;					}		/* Replace with new set of values */		if (((el->flags & LDB_FLAG_MOD_MASK) == LDB_FLAG_MOD_REPLACE)		    && el->num_values > 0) {			struct replace_context *ac2 = talloc(ac, struct replace_context);			const char **attrs = talloc_array(ac, const char *, 2);			if (!attrs || !ac2) {				ldb_oom(ac->module->ldb);				return LDB_ERR_OPERATIONS_ERROR;			}			attrs[0] = el->name;			attrs[1] = NULL;			ac2->ac = ac;			ac2->el = el;			/* We need to setup a search, compare with the list, and then setup add/del as required */						/* The callback does all the hard work here */			ret = ldb_build_search_req(&new_req, module->ldb, req,						   req->op.mod.message->dn, 						   LDB_SCOPE_BASE,						   "(objectClass=*)",						   attrs,						   NULL, 						   ac2, 						   linked_attributes_mod_replace_search_callback);						if (ret != LDB_SUCCESS) {				return ret;			}						talloc_steal(new_req, attrs);						ret = ldb_set_timeout_from_prev_req(module->ldb, req, new_req);						if (ret != LDB_SUCCESS) {				return ret;			}			/* Create a spot in the list for the requests */			ac->down_req = talloc_realloc(ac, ac->down_req, 						      struct ldb_request *, ac->num_requests + 1);			if (!ac->down_req) {				ldb_oom(ac->module->ldb);				return LDB_ERR_OPERATIONS_ERROR;			}			ac->down_req[ac->num_requests] = talloc_steal(ac->down_req, new_req);			ac->num_requests++;			ret = ldb_next_request(module, new_req);						if (ret != LDB_SUCCESS) {				return ret;			}						continue;			/* Delete all values case */		} else if (((el->flags & LDB_FLAG_MOD_MASK) & (LDB_FLAG_MOD_DELETE|LDB_FLAG_MOD_REPLACE)) 			   && el->num_values == 0) {			const char **attrs = talloc_array(ac, const char *, 2);			if (!attrs) {				ldb_oom(ac->module->ldb);				return LDB_ERR_OPERATIONS_ERROR;			}			attrs[0] = el->name;			attrs[1] = NULL;			/* We need to setup a search, and then setup del as required */						/* The callback does all the hard work here, acting identically to if we had delted the whole entry */			ret = ldb_build_search_req(&new_req, module->ldb, req,						   req->op.mod.message->dn, 						   LDB_SCOPE_BASE,						   "(objectClass=*)",						   attrs,						   NULL, 						   ac, 						   linked_attributes_rename_del_search_callback);			if (ret != LDB_SUCCESS) {				return ret;			}						talloc_steal(new_req, attrs);						ret = ldb_set_timeout_from_prev_req(module->ldb, req, new_req);						if (ret != LDB_SUCCESS) {				return ret;			}			/* Create a spot in the list for the requests */			ac->down_req = talloc_realloc(ac, ac->down_req, 						      struct ldb_request *, ac->num_requests + 1);			if (!ac->down_req) {				ldb_oom(ac->module->ldb);				return LDB_ERR_OPERATIONS_ERROR;			}			ac->down_req[ac->num_requests] = talloc_steal(ac->down_req, new_req);			ac->num_requests++;						ret = ldb_next_request(module, new_req);					if (ret != LDB_SUCCESS) {				return ret;			}						continue;		}		/* Prepare the modify (mod element) on the targets, for a normal modify request */		/* For each value being moded, we need to setup the modify */		for (j=0; j < el->num_values; j++) {			/* Create the modify request */			struct ldb_message *new_msg = ldb_msg_new(ac);			if (!new_msg) {				ldb_oom(module->ldb);				return LDB_ERR_OPERATIONS_ERROR;			}			new_msg->dn = ldb_dn_new(new_msg, module->ldb, (char *)el->values[j].data);			if (!new_msg->dn) {				ldb_asprintf_errstring(module->ldb, 					       "attribute %s value %s was not a valid DN", req->op.mod.message->elements[i].name,						       el->values[j].data);				return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;			}			ret = ldb_msg_add_empty(new_msg, target_attr->lDAPDisplayName, 						el->flags & LDB_FLAG_MOD_MASK, NULL);			if (ret != LDB_SUCCESS) {				return ret;			}						ret = ldb_msg_add_string(new_msg, target_attr->lDAPDisplayName, 						 ldb_dn_get_linearized(ac->orig_req->op.add.message->dn));			if (ret != LDB_SUCCESS) {				return ret;			}			ret = ldb_build_mod_req(&new_req, module->ldb, ac,						new_msg,						NULL,						NULL,						NULL);			if (ret != LDB_SUCCESS) {				return ret;			}						talloc_steal(new_req, new_msg);						ret = ldb_set_timeout_from_prev_req(module->ldb, req, new_req);						if (ret != LDB_SUCCESS) {				return ret;			}						/* Now add it to the list */			ac->down_req = talloc_realloc(ac, ac->down_req, 						      struct ldb_request *, ac->num_requests + 1);			if (!ac->down_req) {				ldb_oom(ac->module->ldb);				return LDB_ERR_OPERATIONS_ERROR;			}			ac->down_req[ac->num_requests] = talloc_steal(ac->down_req, new_req);			ac->num_requests++;			/* Run the new request */			ret = ldb_next_request(module, new_req);			if (ret != LDB_SUCCESS) {				return ret;			}		}	}	return LDB_SUCCESS;}static int linked_attributes_rename_del_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) {	struct linked_attributes_context *ac = talloc_get_type(context, struct linked_attributes_context);	struct ldb_dn *olddn, *newdn;    	switch (ac->orig_req->operation) {	case LDB_DELETE:	{		olddn = ac->orig_req->op.del.dn;		newdn = NULL;		break;	} 	/* This isn't the general modify case, just the modify when we are asked to delete all values */	case LDB_MODIFY:	{		olddn = ac->orig_req->op.mod.message->dn;		newdn = NULL;		break;	} 	case LDB_RENAME:	{		olddn = ac->orig_req->op.rename.olddn;		newdn = ac->orig_req->op.rename.newdn;		break;	}		default:		return LDB_ERR_OPERATIONS_ERROR;	}		/* OK, we have one search result here: */	/* Only entries are interesting, and we only want the olddn */	if (ares->type == LDB_REPLY_ENTRY	    && ldb_dn_compare(ares->message->dn, olddn) == 0) {		/* only bother at all if there were some linked attributes found */		if (ares->message->num_elements > 0) {			return setup_modifies(ldb, ac, ac,					      ares->message, olddn, newdn);		}		talloc_free(ares);		return LDB_SUCCESS;	} else if (ares->type == LDB_REPLY_ENTRY) {		/* Guh?  We only asked for this DN */		return LDB_ERR_OPERATIONS_ERROR;	} else {		talloc_free(ares);		return LDB_SUCCESS;	}		}/* rename */static int linked_attributes_rename(struct ldb_module *module, struct ldb_request *req){	/* Look up list of linked attributes */	const char **attrs;	WERROR werr;	int ret;	struct linked_attributes_context *ac;	struct ldb_request *new_req;	const struct dsdb_schema *schema = dsdb_get_schema(module->ldb);	if (!schema) {		/* without schema, this doesn't make any sense */		return ldb_next_request(module, req);	}	/* This gets complex:  We need to:	   - Do a search for the entry 	   - Wait for these result to appear	   - In the callback for the result, issue a modify request based on the linked attributes found	   - Wait for each modify result	   - Regain our sainity 	*/	ac = linked_attributes_init_handle(req, module);	if (!ac) {		return LDB_ERR_OPERATIONS_ERROR;	}		werr = dsdb_linked_attribute_lDAPDisplayName_list(schema, ac, &attrs);	if (!W_ERROR_IS_OK(werr)) {		return LDB_ERR_OPERATIONS_ERROR;	}		ret = ldb_build_search_req(&new_req, module->ldb, req,				   req->op.rename.olddn, 				   LDB_SCOPE_BASE,				   "(objectClass=*)",				   attrs,				   NULL, 				   ac, 				   linked_attributes_rename_del_search_callback);	if (ret != LDB_SUCCESS) {		return ret;	}	talloc_steal(new_req, attrs);	ret = ldb_set_timeout_from_prev_req(module->ldb, req, new_req);	if (ret != LDB_SUCCESS) {		return ret;	}	ac->search_req = new_req;	ac->step = LA_SEARCH;	return ldb_next_request(module, new_req);}/* delete */static int linked_attributes_delete(struct ldb_module *module, struct ldb_request *req){	/* Look up list of linked attributes */	const char **attrs;	WERROR werr;	int ret;	struct ldb_request *new_req;	struct linked_attributes_context *ac;	const struct dsdb_schema *schema = dsdb_get_schema(module->ldb);	if (!schema) {		/* without schema, this doesn't make any sense */		return ldb_next_request(module, req);	}	/* This gets complex:  We need to:	   - Do a search for the entry 	   - Wait for these result to appear	   - In the callback for the result, issue a modify request based on the linked attributes found	   - Wait for each modify result	   - Regain our sainity 	*/	ac = linked_attributes_init_handle(req, module);	if (!ac) {		return LDB_ERR_OPERATIONS_ERROR;	}		werr = dsdb_linked_attribute_lDAPDisplayName_list(schema, ac, &attrs);	if (!W_ERROR_IS_OK(werr)) {		return LDB_ERR_OPERATIONS_ERROR;	};		ret = ldb_build_search_req(&new_req, module->ldb, req,				   req->op.del.dn, 				   LDB_SCOPE_BASE,				   "(objectClass=*)",				   attrs,				   NULL, 				   ac, 				   linked_attributes_rename_del_search_callback);	if (ret != LDB_SUCCESS) {		return ret;	}	talloc_steal(new_req, attrs);	ret = ldb_set_timeout_from_prev_req(module->ldb, req, new_req);	if (ret != LDB_SUCCESS) {		return ret;	}	ac->search_req = new_req;	ac->step = LA_SEARCH;	return ldb_next_request(module, new_req);}static int linked_attributes_wait_none(struct ldb_handle *handle) {	struct linked_attributes_context *ac;	int i, ret = LDB_ERR_OPERATIONS_ERROR;	if (!handle || !handle->private_data) {		return LDB_ERR_OPERATIONS_ERROR;	}	if (handle->state == LDB_ASYNC_DONE) {		return handle->status;	}	handle->state = LDB_ASYNC_PENDING;	handle->status = LDB_SUCCESS;	ac = talloc_get_type(handle->private_data, struct linked_attributes_context);	switch (ac->step) {	case LA_SEARCH:		ret = ldb_wait(ac->search_req->handle, LDB_WAIT_NONE);				if (ret != LDB_SUCCESS) {			handle->status = ret;			goto done;		}		if (ac->search_req->handle->status != LDB_SUCCESS) {			handle->status = ac->search_req->handle->status;			goto done;		}				if (ac->search_req->handle->state != LDB_ASYNC_DONE) {			return LDB_SUCCESS;		}		ac->step = LA_DO_OPS;		return LDB_SUCCESS;	case LA_DO_OPS:		for (i=0; i < ac->num_requests; i++) {			ret = ldb_wait(ac->down_req[i]->handle, LDB_WAIT_NONE);						if (ret != LDB_SUCCESS) {				handle->status = ret;				goto done;			}			if (ac->down_req[i]->handle->status != LDB_SUCCESS) {				handle->status = ac->down_req[i]->handle->status;				goto done;			}						if (ac->down_req[i]->handle->state != LDB_ASYNC_DONE) {				return LDB_SUCCESS;			}		}		/* Now run the original request */		ac->step = LA_DO_ORIG;		return ldb_next_request(ac->module, ac->orig_down_req);	case LA_DO_ORIG:		ret = ldb_wait(ac->orig_down_req->handle, LDB_WAIT_NONE);				if (ret != LDB_SUCCESS) {			handle->status = ret;			goto done;		}		if (ac->orig_down_req->handle->status != LDB_SUCCESS) {			handle->status = ac->orig_down_req->handle->status;			goto done;		}				if (ac->orig_down_req->handle->state != LDB_ASYNC_DONE) {			return LDB_SUCCESS;		}		ret = LDB_SUCCESS;	}done:	handle->state = LDB_ASYNC_DONE;	return ret;}static int linked_attributes_wait_all(struct ldb_handle *handle) {	int ret;	while (handle->state != LDB_ASYNC_DONE) {		ret = linked_attributes_wait_none(handle);		if (ret != LDB_SUCCESS) {			return ret;		}	}	return handle->status;}static int linked_attributes_wait(struct ldb_handle *handle, enum ldb_wait_type type){	if (type == LDB_WAIT_ALL) {		return linked_attributes_wait_all(handle);	} else {		return linked_attributes_wait_none(handle);	}}_PUBLIC_ const struct ldb_module_ops ldb_linked_attributes_module_ops = {	.name		   = "linked_attributes",	.add               = linked_attributes_add,	.modify            = linked_attributes_modify,	.del               = linked_attributes_delete,	.rename            = linked_attributes_rename,	.wait              = linked_attributes_wait,};

⌨️ 快捷键说明

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