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

📄 partition.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* Figure out which partition it is under */	/* Skip the lot if 'data' isn't here yet (initialistion) */	for (i=0; data && data->partitions && data->partitions[i]; i++) {		struct ldb_module *next = make_module_for_next_request(module, module->ldb, data->partitions[i]->module);				ret = ldb_next_end_trans(next);		talloc_free(next);		if (ret != LDB_SUCCESS) {			ret2 = ret;		}	}	if (ret != LDB_SUCCESS) {		/* Back it out, if it fails on one */		for (i=0; data && data->partitions && data->partitions[i]; i++) {			struct ldb_module *next = make_module_for_next_request(module, module->ldb, data->partitions[i]->module);			ldb_next_del_trans(next);			talloc_free(next);		}	}	return ret;}/* delete a transaction */static int partition_del_trans(struct ldb_module *module){	int i, ret, ret2 = LDB_SUCCESS;	struct partition_private_data *data = talloc_get_type(module->private_data, 							      struct partition_private_data);	ret = ldb_next_del_trans(module);	if (ret != LDB_SUCCESS) {		ret2 = ret;	}	/* Look at base DN */	/* Figure out which partition it is under */	/* Skip the lot if 'data' isn't here yet (initialistion) */	for (i=0; data && data->partitions && data->partitions[i]; i++) {		struct ldb_module *next = make_module_for_next_request(module, module->ldb, data->partitions[i]->module);				ret = ldb_next_del_trans(next);		talloc_free(next);		if (ret != LDB_SUCCESS) {			ret2 = ret;		}	}	return ret2;}static int partition_sequence_number(struct ldb_module *module, struct ldb_request *req){	int i, ret;	uint64_t seq_number = 0;	uint64_t timestamp_sequence = 0;	uint64_t timestamp = 0;	struct partition_private_data *data = talloc_get_type(module->private_data, 							      struct partition_private_data);	switch (req->op.seq_num.type) {	case LDB_SEQ_NEXT:	case LDB_SEQ_HIGHEST_SEQ:	       	ret = ldb_next_request(module, req);		if (ret != LDB_SUCCESS) {			return ret;		}		if (req->op.seq_num.flags & LDB_SEQ_TIMESTAMP_SEQUENCE) {			timestamp_sequence = req->op.seq_num.seq_num;		} else {			seq_number = seq_number + req->op.seq_num.seq_num;		}		/* Look at base DN */		/* Figure out which partition it is under */		/* Skip the lot if 'data' isn't here yet (initialistion) */		for (i=0; data && data->partitions && data->partitions[i]; i++) {			struct ldb_module *next = make_module_for_next_request(req, module->ldb, data->partitions[i]->module);						ret = ldb_next_request(next, req);			talloc_free(next);			if (ret != LDB_SUCCESS) {				return ret;			}			if (req->op.seq_num.flags & LDB_SEQ_TIMESTAMP_SEQUENCE) {				timestamp_sequence = MAX(timestamp_sequence, req->op.seq_num.seq_num);			} else {				seq_number = seq_number + req->op.seq_num.seq_num;			}		}		/* fall though */	case LDB_SEQ_HIGHEST_TIMESTAMP:	{		struct ldb_request *date_req = talloc(req, struct ldb_request);		if (!date_req) {			return LDB_ERR_OPERATIONS_ERROR;		}		*date_req = *req;		date_req->op.seq_num.flags = LDB_SEQ_HIGHEST_TIMESTAMP;		ret = ldb_next_request(module, date_req);		if (ret != LDB_SUCCESS) {			return ret;		}		timestamp = date_req->op.seq_num.seq_num;				/* Look at base DN */		/* Figure out which partition it is under */		/* Skip the lot if 'data' isn't here yet (initialistion) */		for (i=0; data && data->partitions && data->partitions[i]; i++) {			struct ldb_module *next = make_module_for_next_request(req, module->ldb, data->partitions[i]->module);						ret = ldb_next_request(next, date_req);			talloc_free(next);			if (ret != LDB_SUCCESS) {				return ret;			}			timestamp = MAX(timestamp, date_req->op.seq_num.seq_num);		}		break;	}	}	switch (req->op.seq_num.flags) {	case LDB_SEQ_NEXT:	case LDB_SEQ_HIGHEST_SEQ:				req->op.seq_num.flags = 0;		/* Has someone above set a timebase sequence? */		if (timestamp_sequence) {			req->op.seq_num.seq_num = (((unsigned long long)timestamp << 24) | (seq_number & 0xFFFFFF));		} else {			req->op.seq_num.seq_num = seq_number;		}		if (timestamp_sequence > req->op.seq_num.seq_num) {			req->op.seq_num.seq_num = timestamp_sequence;			req->op.seq_num.flags |= LDB_SEQ_TIMESTAMP_SEQUENCE;		}		req->op.seq_num.flags |= LDB_SEQ_GLOBAL_SEQUENCE;		break;	case LDB_SEQ_HIGHEST_TIMESTAMP:		req->op.seq_num.seq_num = timestamp;		break;	}	switch (req->op.seq_num.flags) {	case LDB_SEQ_NEXT:		req->op.seq_num.seq_num++;	}	return LDB_SUCCESS;}static int partition_extended_replicated_objects(struct ldb_module *module, struct ldb_request *req){	struct dsdb_extended_replicated_objects *ext;	ext = talloc_get_type(req->op.extended.data, struct dsdb_extended_replicated_objects);	if (!ext) {		ldb_debug(module->ldb, LDB_DEBUG_FATAL, "partition_extended_replicated_objects: invalid extended data\n");		return LDB_ERR_PROTOCOL_ERROR;	}	if (ext->version != DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION) {		ldb_debug(module->ldb, LDB_DEBUG_FATAL, "partition_extended_replicated_objects: extended data invalid version [%u != %u]\n",			  ext->version, DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION);		return LDB_ERR_PROTOCOL_ERROR;	}	return partition_replicate(module, req, ext->partition_dn);}/* extended */static int partition_extended(struct ldb_module *module, struct ldb_request *req){	struct partition_context *ac;	if (strcmp(req->op.extended.oid, DSDB_EXTENDED_REPLICATED_OBJECTS_OID) == 0) {		return partition_extended_replicated_objects(module, req);	}	/* 	 * as the extended operation has no dn	 * we need to send it to all partitions	 */	ac = partition_init_handle(req, module);	if (!ac) {		return LDB_ERR_OPERATIONS_ERROR;	}				return partition_send_all(module, ac, req);}static int sort_compare(void *void1,			void *void2, void *opaque){	struct dsdb_control_current_partition **pp1 = 		(struct dsdb_control_current_partition **)void1;	struct dsdb_control_current_partition **pp2 = 		(struct dsdb_control_current_partition **)void2;	struct dsdb_control_current_partition *partition1 = talloc_get_type(*pp1,							    struct dsdb_control_current_partition);	struct dsdb_control_current_partition *partition2 = talloc_get_type(*pp2,							    struct dsdb_control_current_partition);	return ldb_dn_compare(partition1->dn, partition2->dn);}static int partition_init(struct ldb_module *module){	int ret, i;	TALLOC_CTX *mem_ctx = talloc_new(module);	const char *attrs[] = { "partition", "replicateEntries", "modules", NULL };	struct ldb_result *res;	struct ldb_message *msg;	struct ldb_message_element *partition_attributes;	struct ldb_message_element *replicate_attributes;	struct ldb_message_element *modules_attributes;	struct partition_private_data *data;	if (!mem_ctx) {		return LDB_ERR_OPERATIONS_ERROR;	}	data = talloc(mem_ctx, struct partition_private_data);	if (data == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	ret = ldb_search(module->ldb, ldb_dn_new(mem_ctx, module->ldb, "@PARTITION"),			 LDB_SCOPE_BASE,			 NULL, attrs,			 &res);	if (ret != LDB_SUCCESS) {		talloc_free(mem_ctx);		return ret;	}	talloc_steal(mem_ctx, res);	if (res->count == 0) {		talloc_free(mem_ctx);		return ldb_next_init(module);	}	if (res->count > 1) {		talloc_free(mem_ctx);		return LDB_ERR_CONSTRAINT_VIOLATION;	}	msg = res->msgs[0];	partition_attributes = ldb_msg_find_element(msg, "partition");	if (!partition_attributes) {		ldb_set_errstring(module->ldb, "partition_init: no partitions specified");		talloc_free(mem_ctx);		return LDB_ERR_CONSTRAINT_VIOLATION;	}	data->partitions = talloc_array(data, struct dsdb_control_current_partition *, partition_attributes->num_values + 1);	if (!data->partitions) {		talloc_free(mem_ctx);		return LDB_ERR_OPERATIONS_ERROR;	}	for (i=0; i < partition_attributes->num_values; i++) {		char *base = talloc_strdup(data->partitions, (char *)partition_attributes->values[i].data);		char *p = strchr(base, ':');		if (!p) {			ldb_asprintf_errstring(module->ldb, 						"partition_init: "						"invalid form for partition record (missing ':'): %s", base);			talloc_free(mem_ctx);			return LDB_ERR_CONSTRAINT_VIOLATION;		}		p[0] = '\0';		p++;		if (!p[0]) {			ldb_asprintf_errstring(module->ldb, 						"partition_init: "						"invalid form for partition record (missing backend database): %s", base);			talloc_free(mem_ctx);			return LDB_ERR_CONSTRAINT_VIOLATION;		}		data->partitions[i] = talloc(data->partitions, struct dsdb_control_current_partition);		if (!data->partitions[i]) {			talloc_free(mem_ctx);			return LDB_ERR_OPERATIONS_ERROR;		}		data->partitions[i]->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;		data->partitions[i]->dn = ldb_dn_new(data->partitions[i], module->ldb, base);		if (!data->partitions[i]->dn) {			ldb_asprintf_errstring(module->ldb, 						"partition_init: invalid DN in partition record: %s", base);			talloc_free(mem_ctx);			return LDB_ERR_CONSTRAINT_VIOLATION;		}		data->partitions[i]->backend = samdb_relative_path(module->ldb, 								   data->partitions[i], 								   p);		if (!data->partitions[i]->backend) {			ldb_asprintf_errstring(module->ldb, 						"partition_init: unable to determine an relative path for partition: %s", base);			talloc_free(mem_ctx);					}		ret = ldb_connect_backend(module->ldb, data->partitions[i]->backend, NULL, &data->partitions[i]->module);		if (ret != LDB_SUCCESS) {			talloc_free(mem_ctx);			return ret;		}	}	data->partitions[i] = NULL;	/* sort these into order, most to least specific */	ldb_qsort(data->partitions, partition_attributes->num_values, sizeof(*data->partitions), 		  module->ldb, sort_compare);	for (i=0; data->partitions[i]; i++) {		struct ldb_request *req;		req = talloc_zero(mem_ctx, struct ldb_request);		if (req == NULL) {			ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: Out of memory!\n");			talloc_free(mem_ctx);			return LDB_ERR_OPERATIONS_ERROR;		}				req->operation = LDB_REQ_REGISTER_PARTITION;		req->op.reg_partition.dn = data->partitions[i]->dn;				ret = ldb_request(module->ldb, req);		if (ret != LDB_SUCCESS) {			ldb_debug(module->ldb, LDB_DEBUG_ERROR, "partition: Unable to register partition with rootdse!\n");			talloc_free(mem_ctx);			return LDB_ERR_OTHER;		}		talloc_free(req);	}	replicate_attributes = ldb_msg_find_element(msg, "replicateEntries");	if (!replicate_attributes) {		data->replicate = NULL;	} else {		data->replicate = talloc_array(data, struct ldb_dn *, replicate_attributes->num_values + 1);		if (!data->replicate) {			talloc_free(mem_ctx);			return LDB_ERR_OPERATIONS_ERROR;		}				for (i=0; i < replicate_attributes->num_values; i++) {			data->replicate[i] = ldb_dn_new(data->replicate, module->ldb, (const char *)replicate_attributes->values[i].data);			if (!ldb_dn_validate(data->replicate[i])) {				ldb_asprintf_errstring(module->ldb, 							"partition_init: "							"invalid DN in partition replicate record: %s", 							replicate_attributes->values[i].data);				talloc_free(mem_ctx);				return LDB_ERR_CONSTRAINT_VIOLATION;			}		}		data->replicate[i] = NULL;	}	/* Make the private data available to any searches the modules may trigger in initialisation */	module->private_data = data;	talloc_steal(module, data);		modules_attributes = ldb_msg_find_element(msg, "modules");	if (modules_attributes) {		for (i=0; i < modules_attributes->num_values; i++) {			struct ldb_dn *base_dn;			int partition_idx;			struct dsdb_control_current_partition *partition = NULL;			const char **modules = NULL;			char *base = talloc_strdup(data->partitions, (char *)modules_attributes->values[i].data);			char *p = strchr(base, ':');			if (!p) {				ldb_asprintf_errstring(module->ldb, 							"partition_init: "							"invalid form for partition module record (missing ':'): %s", base);				talloc_free(mem_ctx);				return LDB_ERR_CONSTRAINT_VIOLATION;			}			p[0] = '\0';			p++;			if (!p[0]) {				ldb_asprintf_errstring(module->ldb, 							"partition_init: "							"invalid form for partition module record (missing backend database): %s", base);				talloc_free(mem_ctx);				return LDB_ERR_CONSTRAINT_VIOLATION;			}			modules = ldb_modules_list_from_string(module->ldb, mem_ctx,							       p);						base_dn = ldb_dn_new(mem_ctx, module->ldb, base);			if (!ldb_dn_validate(base_dn)) {				talloc_free(mem_ctx);				return LDB_ERR_OPERATIONS_ERROR;			}						for (partition_idx = 0; data->partitions[partition_idx]; partition_idx++) {				if (ldb_dn_compare(data->partitions[partition_idx]->dn, base_dn) == 0) {					partition = data->partitions[partition_idx];					break;				}			}						if (!partition) {				ldb_asprintf_errstring(module->ldb, 							"partition_init: "							"invalid form for partition module record (no such partition): %s", base);				talloc_free(mem_ctx);				return LDB_ERR_CONSTRAINT_VIOLATION;			}						ret = ldb_load_modules_list(module->ldb, modules, partition->module, &partition->module);			if (ret != LDB_SUCCESS) {				ldb_asprintf_errstring(module->ldb, 						       "partition_init: "						       "loading backend for %s failed: %s", 						       base, ldb_errstring(module->ldb));				talloc_free(mem_ctx);				return ret;			}			ret = ldb_init_module_chain(module->ldb, partition->module);			if (ret != LDB_SUCCESS) {				ldb_asprintf_errstring(module->ldb, 						       "partition_init: "						       "initialising backend for %s failed: %s", 						       base, ldb_errstring(module->ldb));				talloc_free(mem_ctx);				return ret;			}		}	}	talloc_free(mem_ctx);	return ldb_next_init(module);}static int partition_wait_none(struct ldb_handle *handle) {	struct partition_context *ac;	int ret;	int i;    	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 partition_context);	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;		}	}	ret = LDB_SUCCESS;done:	handle->state = LDB_ASYNC_DONE;	return ret;}static int partition_wait_all(struct ldb_handle *handle) {	int ret;	while (handle->state != LDB_ASYNC_DONE) {		ret = partition_wait_none(handle);		if (ret != LDB_SUCCESS) {			return ret;		}	}	return handle->status;}static int partition_wait(struct ldb_handle *handle, enum ldb_wait_type type){	if (type == LDB_WAIT_ALL) {		return partition_wait_all(handle);	} else {		return partition_wait_none(handle);	}}_PUBLIC_ const struct ldb_module_ops ldb_partition_module_ops = {	.name		   = "partition",	.init_context	   = partition_init,	.search            = partition_search,	.add               = partition_add,	.modify            = partition_modify,	.del               = partition_delete,	.rename            = partition_rename,	.extended          = partition_extended,	.sequence_number   = partition_sequence_number,	.start_transaction = partition_start_trans,	.end_transaction   = partition_end_trans,	.del_transaction   = partition_del_trans,	.wait              = partition_wait};

⌨️ 快捷键说明

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