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

📄 repl_meta_data.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    ldb database library   Copyright (C) Simo Sorce  2004-2006   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005   Copyright (C) Andrew Tridgell 2005   Copyright (C) Stefan Metzmacher <metze@samba.org> 2007     ** 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 repl_meta_data module * *  Description: - add a unique objectGUID onto every new record, *               - handle whenCreated, whenChanged timestamps *               - handle uSNCreated, uSNChanged numbers *               - handle replPropertyMetaData attribute * *  Author: Simo Sorce *  Author: Stefan Metzmacher */#include "includes.h"#include "lib/ldb/include/ldb.h"#include "lib/ldb/include/ldb_errors.h"#include "lib/ldb/include/ldb_private.h"#include "dsdb/samdb/samdb.h"#include "dsdb/common/flags.h"#include "librpc/gen_ndr/ndr_misc.h"#include "librpc/gen_ndr/ndr_drsuapi.h"#include "librpc/gen_ndr/ndr_drsblobs.h"#include "param/param.h"struct replmd_replicated_request {	struct ldb_module *module;	struct ldb_handle *handle;	struct ldb_request *orig_req;	const struct dsdb_schema *schema;	struct dsdb_extended_replicated_objects *objs;	uint32_t index_current;	struct {		TALLOC_CTX *mem_ctx;		struct ldb_request *search_req;		struct ldb_message *search_msg;		int search_ret;		struct ldb_request *change_req;		int change_ret;	} sub;};static struct replmd_replicated_request *replmd_replicated_init_handle(struct ldb_module *module,								       struct ldb_request *req,								       struct dsdb_extended_replicated_objects *objs){	struct replmd_replicated_request *ar;	struct ldb_handle *h;	const struct dsdb_schema *schema;	schema = dsdb_get_schema(module->ldb);	if (!schema) {		ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,			      "replmd_replicated_init_handle: no loaded schema found\n");		return NULL;	}	h = talloc_zero(req, struct ldb_handle);	if (h == NULL) {		ldb_set_errstring(module->ldb, "Out of Memory");		return NULL;	}	h->module	= module;	h->state	= LDB_ASYNC_PENDING;	h->status	= LDB_SUCCESS;	ar = talloc_zero(h, struct replmd_replicated_request);	if (ar == NULL) {		ldb_set_errstring(module->ldb, "Out of Memory");		talloc_free(h);		return NULL;	}	h->private_data	= ar;	ar->module	= module;	ar->handle	= h;	ar->orig_req	= req;	ar->schema	= schema;	ar->objs	= objs;	req->handle = h;	return ar;}/*  add a time element to a record*/static int add_time_element(struct ldb_message *msg, const char *attr, time_t t){	struct ldb_message_element *el;	char *s;	if (ldb_msg_find_element(msg, attr) != NULL) {		return 0;	}	s = ldb_timestring(msg, t);	if (s == NULL) {		return -1;	}	if (ldb_msg_add_string(msg, attr, s) != 0) {		return -1;	}	el = ldb_msg_find_element(msg, attr);	/* always set as replace. This works because on add ops, the flag	   is ignored */	el->flags = LDB_FLAG_MOD_REPLACE;	return 0;}/*  add a uint64_t element to a record*/static int add_uint64_element(struct ldb_message *msg, const char *attr, uint64_t v){	struct ldb_message_element *el;	if (ldb_msg_find_element(msg, attr) != NULL) {		return 0;	}	if (ldb_msg_add_fmt(msg, attr, "%llu", (unsigned long long)v) != 0) {		return -1;	}	el = ldb_msg_find_element(msg, attr);	/* always set as replace. This works because on add ops, the flag	   is ignored */	el->flags = LDB_FLAG_MOD_REPLACE;	return 0;}static int replmd_replPropertyMetaData1_attid_sort(const struct replPropertyMetaData1 *m1,						   const struct replPropertyMetaData1 *m2,						   const uint32_t *rdn_attid){	if (m1->attid == m2->attid) {		return 0;	}	/*	 * the rdn attribute should be at the end!	 * so we need to return a value greater than zero	 * which means m1 is greater than m2	 */	if (m1->attid == *rdn_attid) {		return 1;	}	/*	 * the rdn attribute should be at the end!	 * so we need to return a value less than zero	 * which means m2 is greater than m1	 */	if (m2->attid == *rdn_attid) {		return -1;	}	return m1->attid - m2->attid;}static void replmd_replPropertyMetaDataCtr1_sort(struct replPropertyMetaDataCtr1 *ctr1,						 const uint32_t *rdn_attid){	ldb_qsort(ctr1->array, ctr1->count, sizeof(struct replPropertyMetaData1),		  discard_const_p(void, rdn_attid), (ldb_qsort_cmp_fn_t)replmd_replPropertyMetaData1_attid_sort);}static int replmd_ldb_message_element_attid_sort(const struct ldb_message_element *e1,						 const struct ldb_message_element *e2,						 const struct dsdb_schema *schema){	const struct dsdb_attribute *a1;	const struct dsdb_attribute *a2;	/* 	 * TODO: make this faster by caching the dsdb_attribute pointer	 *       on the ldb_messag_element	 */	a1 = dsdb_attribute_by_lDAPDisplayName(schema, e1->name);	a2 = dsdb_attribute_by_lDAPDisplayName(schema, e2->name);	/*	 * TODO: remove this check, we should rely on e1 and e2 having valid attribute names	 *       in the schema	 */	if (!a1 || !a2) {		return strcasecmp(e1->name, e2->name);	}	return a1->attributeID_id - a2->attributeID_id;}static void replmd_ldb_message_sort(struct ldb_message *msg,				    const struct dsdb_schema *schema){	ldb_qsort(msg->elements, msg->num_elements, sizeof(struct ldb_message_element),		  discard_const_p(void, schema), (ldb_qsort_cmp_fn_t)replmd_ldb_message_element_attid_sort);}static int replmd_prepare_originating(struct ldb_module *module, struct ldb_request *req,				      struct ldb_dn *dn, const char *fn_name,				      int (*fn)(struct ldb_module *,			 			struct ldb_request *,						const struct dsdb_schema *)){	const struct dsdb_schema *schema; 	/* do not manipulate our control entries */	if (ldb_dn_is_special(dn)) {		return ldb_next_request(module, req);	}	schema = dsdb_get_schema(module->ldb);	if (!schema) {		ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,			      "%s: no dsdb_schema loaded",			      fn_name);		return LDB_ERR_CONSTRAINT_VIOLATION;	}	return fn(module, req, schema);}static int replmd_add_originating(struct ldb_module *module,				  struct ldb_request *req,				  const struct dsdb_schema *schema){	enum ndr_err_code ndr_err;	struct ldb_request *down_req;	struct ldb_message *msg;	const struct dsdb_attribute *rdn_attr = NULL;	struct GUID guid;	struct ldb_val guid_value;	struct replPropertyMetaDataBlob nmd;	struct ldb_val nmd_value;	uint64_t seq_num;	const struct GUID *our_invocation_id;	time_t t = time(NULL);	NTTIME now;	char *time_str;	int ret;	uint32_t i, ni=0;	ldb_debug(module->ldb, LDB_DEBUG_TRACE, "replmd_add_originating\n");	if (ldb_msg_find_element(req->op.add.message, "objectGUID")) {		ldb_debug_set(module->ldb, LDB_DEBUG_ERROR,			      "replmd_add_originating: it's not allowed to add an object with objectGUID\n");		return LDB_ERR_UNWILLING_TO_PERFORM;	}	/* Get a sequence number from the backend */	ret = ldb_sequence_number(module->ldb, LDB_SEQ_NEXT, &seq_num);	if (ret != LDB_SUCCESS) {		return ret;	}	/* a new GUID */	guid = GUID_random();	/* get our invicationId */	our_invocation_id = samdb_ntds_invocation_id(module->ldb);	if (!our_invocation_id) {		ldb_debug_set(module->ldb, LDB_DEBUG_ERROR,			      "replmd_add_originating: unable to find invocationId\n");		return LDB_ERR_OPERATIONS_ERROR;	}	/* create a copy of the request */	down_req = talloc(req, struct ldb_request);	if (down_req == NULL) {		ldb_oom(module->ldb);		return LDB_ERR_OPERATIONS_ERROR;	}	*down_req = *req;	/* we have to copy the message as the caller might have it as a const */	down_req->op.add.message = msg = ldb_msg_copy_shallow(down_req, req->op.add.message);	if (msg == NULL) {		talloc_free(down_req);		ldb_oom(module->ldb);		return LDB_ERR_OPERATIONS_ERROR;	}	/* generated times */	unix_to_nt_time(&now, t);	time_str = ldb_timestring(msg, t);	if (!time_str) {		talloc_free(down_req);		return LDB_ERR_OPERATIONS_ERROR;	}	/* 	 * remove autogenerated attributes	 */	ldb_msg_remove_attr(msg, "whenCreated");	ldb_msg_remove_attr(msg, "whenChanged");	ldb_msg_remove_attr(msg, "uSNCreated");	ldb_msg_remove_attr(msg, "uSNChanged");	ldb_msg_remove_attr(msg, "replPropertyMetaData");	/*	 * readd replicated attributes	 */	ret = ldb_msg_add_string(msg, "whenCreated", time_str);	if (ret != LDB_SUCCESS) {		talloc_free(down_req);		ldb_oom(module->ldb);		return LDB_ERR_OPERATIONS_ERROR;	}	/* build the replication meta_data */	ZERO_STRUCT(nmd);	nmd.version		= 1;	nmd.ctr.ctr1.count	= msg->num_elements;	nmd.ctr.ctr1.array	= talloc_array(msg,					       struct replPropertyMetaData1,					       nmd.ctr.ctr1.count);	if (!nmd.ctr.ctr1.array) {		talloc_free(down_req);		ldb_oom(module->ldb);		return LDB_ERR_OPERATIONS_ERROR;	}	for (i=0; i < msg->num_elements; i++) {		struct ldb_message_element *e = &msg->elements[i];		struct replPropertyMetaData1 *m = &nmd.ctr.ctr1.array[ni];		const struct dsdb_attribute *sa;		if (e->name[0] == '@') continue;		sa = dsdb_attribute_by_lDAPDisplayName(schema, e->name);		if (!sa) {			ldb_debug_set(module->ldb, LDB_DEBUG_ERROR,				      "replmd_add_originating: attribute '%s' not defined in schema\n",				      e->name);			talloc_free(down_req);			return LDB_ERR_NO_SUCH_ATTRIBUTE;		}		if ((sa->systemFlags & 0x00000001) || (sa->systemFlags & 0x00000004)) {			/* if the attribute is not replicated (0x00000001)			 * or constructed (0x00000004) it has no metadata			 */			continue;		}		m->attid			= sa->attributeID_id;		m->version			= 1;		m->originating_change_time	= now;		m->originating_invocation_id	= *our_invocation_id;		m->originating_usn		= seq_num;		m->local_usn			= seq_num;		ni++;		if (ldb_attr_cmp(e->name, ldb_dn_get_rdn_name(msg->dn))) {			rdn_attr = sa;		}	}

⌨️ 快捷键说明

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