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

📄 wrepl_scavenging.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	return NT_STATUS_OK;}struct verify_state {	struct messaging_context *msg_ctx;	struct wreplsrv_service *service;	struct winsdb_record *rec;	struct nbtd_proxy_wins_challenge r;};static void verify_handler(struct irpc_request *ireq){	struct verify_state *s = talloc_get_type(ireq->async.private,				 struct verify_state);	struct winsdb_record *rec = s->rec;	const char *action;	const char *old_state = "active";	const char *new_state = "active";	const char *new_owner = "replica";	uint32_t modify_flags = 0;	bool modify_record = false;	bool delete_record = false;	bool different = false;	int ret;	NTSTATUS status;	uint32_t i, j;	/*	 * - if the name isn't present anymore remove our record	 * - if the name is found and not a normal group check if the addresses match,	 *   - if they don't match remove the record	 *   - if they match do nothing	 * - if an error happens do nothing	 */	status = irpc_call_recv(ireq);	if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {		delete_record = true;		new_state = "deleted";	} else if (NT_STATUS_IS_OK(status) && rec->type != WREPL_TYPE_GROUP) {		for (i=0; i < s->r.out.num_addrs; i++) {			bool found = false;			for (j=0; rec->addresses[j]; j++) {				if (strcmp(s->r.out.addrs[i].addr, rec->addresses[j]->address) == 0) {					found = true;					break;				}			}			if (!found) {				different = true;				break;			}		}	} else if (NT_STATUS_IS_OK(status) && rec->type == WREPL_TYPE_GROUP) {		if (s->r.out.num_addrs != 1 || strcmp(s->r.out.addrs[0].addr, "255.255.255.255") != 0) {			different = true;		}	}	if (different) {		/*		 * if the reply from the owning wins server has different addresses		 * then take the ownership of the record and make it a tombstone		 * this will then hopefully replicated to the original owner of the record		 * which will then propagate it's own record, so that the current record will		 * be replicated to to us		 */		DEBUG(0,("WINS scavenging: replica %s verify got different addresses from winsserver: %s: tombstoning record\n",			nbt_name_string(rec, rec->name), rec->wins_owner));		rec->state	= WREPL_STATE_TOMBSTONE;		rec->expire_time= time(NULL) + s->service->config.tombstone_timeout;		for (i=0; rec->addresses[i]; i++) {			rec->addresses[i]->expire_time = rec->expire_time;		}		modify_record	= true;		modify_flags	= WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP;		new_state	= "tombstone";		new_owner	= "owned";	} else if (NT_STATUS_IS_OK(status)) {		/* if the addresses are the same, just update the timestamps */		rec->expire_time = time(NULL) + s->service->config.verify_interval;		for (i=0; rec->addresses[i]; i++) {			rec->addresses[i]->expire_time = rec->expire_time;		}		modify_record	= true;		modify_flags	= 0;		new_state	= "active";	}	if (modify_record) {		action = "modify";		ret = winsdb_modify(s->service->wins_db, rec, modify_flags);	} else if (delete_record) {		action = "delete";		ret = winsdb_delete(s->service->wins_db, rec);	} else {		action = "skip";		ret = NBT_RCODE_OK;	}	if (ret != NBT_RCODE_OK) {		DEBUG(1,("WINS scavenging: failed to %s name %s (replica:%s -> %s:%s): error:%u\n",			action, nbt_name_string(rec, rec->name), old_state, new_owner, new_state, ret));	} else {		DEBUG(4,("WINS scavenging: %s name: %s (replica:%s -> %s:%s): %s: %s\n",			action, nbt_name_string(rec, rec->name), old_state, new_owner, new_state,			rec->wins_owner, nt_errstr(status)));	}	talloc_free(s);}static NTSTATUS wreplsrv_scavenging_replica_active_records(struct wreplsrv_service *service, TALLOC_CTX *tmp_mem){	NTSTATUS status;	struct winsdb_record *rec = NULL;	struct ldb_result *res = NULL;	const char *owner_filter;	const char *filter;	uint32_t i;	int ret;	time_t now = time(NULL);	const char *now_timestr;	struct irpc_request *ireq;	struct verify_state *s;	struct server_id *nbt_servers;	nbt_servers = irpc_servers_byname(service->task->msg_ctx, tmp_mem, "nbt_server");	if ((nbt_servers == NULL) || (nbt_servers[0].id == 0)) {		return NT_STATUS_INTERNAL_ERROR;	}	now_timestr = ldb_timestring(tmp_mem, now);	NT_STATUS_HAVE_NO_MEMORY(now_timestr);	owner_filter = wreplsrv_owner_filter(service, tmp_mem,					     service->wins_db->local_owner);	NT_STATUS_HAVE_NO_MEMORY(owner_filter);	filter = talloc_asprintf(tmp_mem,				 "(&(!%s)(objectClass=winsRecord)"				 "(recordState=%u)(expireTime<=%s))",				 owner_filter, WREPL_STATE_ACTIVE, now_timestr);	NT_STATUS_HAVE_NO_MEMORY(filter);	ret = ldb_search(service->wins_db->ldb, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res);	if (ret != LDB_SUCCESS) return NT_STATUS_INTERNAL_DB_CORRUPTION;	talloc_steal(tmp_mem, res);	DEBUG(10,("WINS scavenging: filter '%s' count %d\n", filter, res->count));	for (i=0; i < res->count; i++) {		/*		 * we pass '0' as 'now' here,		 * because we want to get the raw timestamps which are in the DB		 */		status = winsdb_record(service->wins_db, res->msgs[i], tmp_mem, 0, &rec);		NT_STATUS_NOT_OK_RETURN(status);		talloc_free(res->msgs[i]);		if (rec->state != WREPL_STATE_ACTIVE) {			DEBUG(0,("%s: corrupted record: %s\n",				__location__, nbt_name_string(rec, rec->name)));			return NT_STATUS_INTERNAL_DB_CORRUPTION;		}		/* 		 * ask the owning wins server if the record still exists,		 * if not delete the record		 *		 * TODO: NOTE: this is a simpliefied version, to verify that		 *             a record still exist, I assume that w2k3 uses		 *             DCERPC calls or some WINSREPL packets for this,		 *             but we use a wins name query		 */		DEBUG(0,("ask wins server '%s' if '%s' with version_id:%llu still exists\n",			 rec->wins_owner, nbt_name_string(rec, rec->name), 			 (unsigned long long)rec->version));		s = talloc_zero(tmp_mem, struct verify_state);		NT_STATUS_HAVE_NO_MEMORY(s);		s->msg_ctx	= service->task->msg_ctx;		s->service	= service;		s->rec		= talloc_steal(s, rec);		s->r.in.name		= *rec->name;		s->r.in.num_addrs	= 1;		s->r.in.addrs		= talloc_array(s, struct nbtd_proxy_wins_addr, s->r.in.num_addrs);		NT_STATUS_HAVE_NO_MEMORY(s->r.in.addrs);		/* TODO: fix pidl to handle inline ipv4address arrays */		s->r.in.addrs[0].addr	= rec->wins_owner;		ireq = IRPC_CALL_SEND(s->msg_ctx, nbt_servers[0],				      irpc, NBTD_PROXY_WINS_CHALLENGE,				      &s->r, s);		NT_STATUS_HAVE_NO_MEMORY(ireq);		ireq->async.fn		= verify_handler;		ireq->async.private	= s;		talloc_steal(service, s);	}	return NT_STATUS_OK;}NTSTATUS wreplsrv_scavenging_run(struct wreplsrv_service *service){	NTSTATUS status;	TALLOC_CTX *tmp_mem;	bool skip_first_run = false;	if (!timeval_expired(&service->scavenging.next_run)) {		return NT_STATUS_OK;	}	if (timeval_is_zero(&service->scavenging.next_run)) {		skip_first_run = true;	}	service->scavenging.next_run = timeval_current_ofs(service->config.scavenging_interval, 0);	status = wreplsrv_periodic_schedule(service, service->config.scavenging_interval);	NT_STATUS_NOT_OK_RETURN(status);	/*	 * if it's the first time this functions is called (startup)	 * the next_run is zero, in this case we should not do scavenging	 */	if (skip_first_run) {		return NT_STATUS_OK;	}	if (service->scavenging.processing) {		return NT_STATUS_OK;	}	DEBUG(4,("wreplsrv_scavenging_run(): start\n"));	tmp_mem = talloc_new(service);	NT_STATUS_HAVE_NO_MEMORY(tmp_mem);	service->scavenging.processing = true;	status = wreplsrv_scavenging_owned_records(service,tmp_mem);	service->scavenging.processing = false;	talloc_free(tmp_mem);	NT_STATUS_NOT_OK_RETURN(status);	tmp_mem = talloc_new(service);		NT_STATUS_HAVE_NO_MEMORY(tmp_mem);	service->scavenging.processing = true;	status = wreplsrv_scavenging_replica_non_active_records(service, tmp_mem);	service->scavenging.processing = false;	talloc_free(tmp_mem);	NT_STATUS_NOT_OK_RETURN(status);	tmp_mem = talloc_new(service);	NT_STATUS_HAVE_NO_MEMORY(tmp_mem);	service->scavenging.processing = true;	status = wreplsrv_scavenging_replica_active_records(service, tmp_mem);	service->scavenging.processing = false;	talloc_free(tmp_mem);	NT_STATUS_NOT_OK_RETURN(status);	DEBUG(4,("wreplsrv_scavenging_run(): end\n"));	return NT_STATUS_OK;}

⌨️ 快捷键说明

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