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

📄 winsdb.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
			break;		}	}	for (; addresses[i]; i++) {		addresses[i] = addresses[i+1];	}	return;}struct winsdb_addr *winsdb_addr_list_check(struct winsdb_addr **addresses, const char *address){	size_t i;	for (i=0; addresses[i]; i++) {		if (strcmp(addresses[i]->address, address) == 0) {			return addresses[i];		}	}	return NULL;}size_t winsdb_addr_list_length(struct winsdb_addr **addresses){	size_t i;	for (i=0; addresses[i]; i++);	return i;}const char **winsdb_addr_string_list(TALLOC_CTX *mem_ctx, struct winsdb_addr **addresses){	size_t len = winsdb_addr_list_length(addresses);	const char **str_list=NULL;	size_t i;	for (i=0; i < len; i++) {		str_list = str_list_add(str_list, addresses[i]->address);		if (!str_list[i]) {			return NULL;		}	}	talloc_steal(mem_ctx, str_list);	return str_list;}/*  load a WINS entry from the database*/NTSTATUS winsdb_lookup(struct winsdb_handle *h, 		       struct nbt_name *name,		       TALLOC_CTX *mem_ctx,		       struct winsdb_record **_rec){	NTSTATUS status;	struct ldb_result *res = NULL;	int ret;	struct winsdb_record *rec;	struct ldb_context *wins_db = h->ldb;	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);	time_t now = time(NULL);	/* find the record in the WINS database */	ret = ldb_search(wins_db, winsdb_dn(tmp_ctx, wins_db, name), LDB_SCOPE_BASE, 			 NULL, NULL, &res);	talloc_steal(tmp_ctx, res);	if (ret != LDB_SUCCESS || res->count > 1) {		status = NT_STATUS_INTERNAL_DB_CORRUPTION;		goto failed;	} else if (res->count== 0) {		status = NT_STATUS_OBJECT_NAME_NOT_FOUND;		goto failed;	}	status = winsdb_record(h, res->msgs[0], tmp_ctx, now, &rec);	if (!NT_STATUS_IS_OK(status)) goto failed;	talloc_steal(mem_ctx, rec);	talloc_free(tmp_ctx);	*_rec = rec;	return NT_STATUS_OK;failed:	talloc_free(tmp_ctx);	return status;}NTSTATUS winsdb_record(struct winsdb_handle *h, struct ldb_message *msg, TALLOC_CTX *mem_ctx, time_t now, struct winsdb_record **_rec){	NTSTATUS status;	struct winsdb_record *rec;	struct ldb_message_element *el;	struct nbt_name *name;	uint32_t i, j, num_values;	bool we_are_owner = false;	rec = talloc(mem_ctx, struct winsdb_record);	if (rec == NULL) {		status = NT_STATUS_NO_MEMORY;		goto failed;	}	status = winsdb_nbt_name(rec, msg->dn, &name);	if (!NT_STATUS_IS_OK(status)) goto failed;	if (strlen(name->name) > 15) {		status = NT_STATUS_INTERNAL_DB_CORRUPTION;		goto failed;	}	if (name->scope && strlen(name->scope) > 238) {		status = NT_STATUS_INTERNAL_DB_CORRUPTION;		goto failed;	}	/* parse it into a more convenient winsdb_record structure */	rec->name		= name;	rec->type		= ldb_msg_find_attr_as_int(msg, "recordType", WREPL_TYPE_UNIQUE);	rec->state		= ldb_msg_find_attr_as_int(msg, "recordState", WREPL_STATE_RELEASED);	rec->node		= ldb_msg_find_attr_as_int(msg, "nodeType", WREPL_NODE_B);	rec->is_static		= ldb_msg_find_attr_as_int(msg, "isStatic", 0);	rec->expire_time	= ldb_string_to_time(ldb_msg_find_attr_as_string(msg, "expireTime", NULL));	rec->version		= ldb_msg_find_attr_as_uint64(msg, "versionID", 0);	rec->wins_owner		= ldb_msg_find_attr_as_string(msg, "winsOwner", NULL);	rec->registered_by	= ldb_msg_find_attr_as_string(msg, "registeredBy", NULL);	talloc_steal(rec, rec->wins_owner);	talloc_steal(rec, rec->registered_by);	if (!rec->wins_owner || strcmp(rec->wins_owner, "0.0.0.0") == 0) {		rec->wins_owner = h->local_owner;	}	el = ldb_msg_find_element(msg, "address");	if (el) {		num_values = el->num_values;	} else {		num_values = 0;	}	if (rec->type == WREPL_TYPE_UNIQUE || rec->type == WREPL_TYPE_GROUP) {		if (num_values != 1) {			status = NT_STATUS_INTERNAL_DB_CORRUPTION;			goto failed;		}	}	if (rec->state == WREPL_STATE_ACTIVE) {		if (num_values < 1) {			status = NT_STATUS_INTERNAL_DB_CORRUPTION;			goto failed;		}	}	if (num_values > 25) {		status = NT_STATUS_INTERNAL_DB_CORRUPTION;		goto failed;	}	if (strcmp(rec->wins_owner, h->local_owner) == 0) {		we_are_owner = true;	}	/* 	 * see if it has already expired	 * 	 * NOTE: only expire owned records this way!	 *       w2k3 resolves expired replicas	 *       which are in active state	 */	if (!rec->is_static &&	    rec->expire_time <= now &&	    rec->state == WREPL_STATE_ACTIVE &&	    we_are_owner) {		DEBUG(5,("WINS: expiring name %s (expired at %s)\n", 			 nbt_name_string(mem_ctx, rec->name), timestring(mem_ctx, rec->expire_time)));		rec->state = WREPL_STATE_RELEASED;	}	rec->addresses     = talloc_array(rec, struct winsdb_addr *, num_values+1);	if (rec->addresses == NULL) {		status = NT_STATUS_NO_MEMORY;		goto failed;	}	for (i=0,j=0;i<num_values;i++) {		status = winsdb_addr_decode(h, rec, &el->values[i], rec->addresses, &rec->addresses[j]);		if (!NT_STATUS_IS_OK(status)) goto failed;		/*		 * the record isn't static and is active		 * then don't add the address if it's expired		 */		if (!rec->is_static &&		    rec->addresses[j]->expire_time <= now &&		    rec->state == WREPL_STATE_ACTIVE &&		    we_are_owner) {			DEBUG(5,("WINS: expiring name addr %s of %s (expired at %s)\n", 				 rec->addresses[j]->address, nbt_name_string(rec->addresses[j], rec->name),				 timestring(rec->addresses[j], rec->addresses[j]->expire_time)));			talloc_free(rec->addresses[j]);			rec->addresses[j] = NULL;			continue;		}		j++;	}	rec->addresses[j] = NULL;	num_values = j;	if (rec->is_static && rec->state == WREPL_STATE_ACTIVE) {		rec->expire_time = get_time_t_max();		for (i=0;rec->addresses[i];i++) {			rec->addresses[i]->expire_time = rec->expire_time;		}	}	if (rec->state == WREPL_STATE_ACTIVE) {		if (num_values < 1) {			DEBUG(5,("WINS: expiring name %s (because it has no active addresses)\n", 				 nbt_name_string(mem_ctx, rec->name)));			rec->state = WREPL_STATE_RELEASED;		}	}	*_rec = rec;	return NT_STATUS_OK;failed:	if (NT_STATUS_EQUAL(NT_STATUS_INTERNAL_DB_CORRUPTION, status)) {		DEBUG(1,("winsdb_record: corrupted record: %s\n", ldb_dn_get_linearized(msg->dn)));	}	talloc_free(rec);	return status;}/*  form a ldb_message from a winsdb_record*/struct ldb_message *winsdb_message(struct ldb_context *ldb, 				   struct winsdb_record *rec, TALLOC_CTX *mem_ctx){	int i, ret=0;	size_t addr_count;	const char *expire_time;	struct ldb_message *msg = ldb_msg_new(mem_ctx);	if (msg == NULL) goto failed;	/* make sure we don't put in corrupted records */	addr_count = winsdb_addr_list_length(rec->addresses);	if (rec->state == WREPL_STATE_ACTIVE && addr_count == 0) {		rec->state = WREPL_STATE_RELEASED;	}	if (rec->type == WREPL_TYPE_UNIQUE && addr_count > 1) {		rec->type = WREPL_TYPE_MHOMED;	}	expire_time = ldb_timestring(msg, rec->expire_time);	if (!expire_time) {		goto failed;	}	msg->dn = winsdb_dn(msg, ldb, rec->name);	if (msg->dn == NULL) goto failed;	ret |= ldb_msg_add_fmt(msg, "type", "0x%02X", rec->name->type);	if (rec->name->name && *rec->name->name) {		ret |= ldb_msg_add_string(msg, "name", rec->name->name);	}	if (rec->name->scope && *rec->name->scope) {		ret |= ldb_msg_add_string(msg, "scope", rec->name->scope);	}	ret |= ldb_msg_add_fmt(msg, "objectClass", "winsRecord");	ret |= ldb_msg_add_fmt(msg, "recordType", "%u", rec->type);	ret |= ldb_msg_add_fmt(msg, "recordState", "%u", rec->state);	ret |= ldb_msg_add_fmt(msg, "nodeType", "%u", rec->node);	ret |= ldb_msg_add_fmt(msg, "isStatic", "%u", rec->is_static);	ret |= ldb_msg_add_empty(msg, "expireTime", 0, NULL);	if (!(rec->is_static && rec->state == WREPL_STATE_ACTIVE)) {		ret |= ldb_msg_add_string(msg, "expireTime", expire_time);	}	ret |= ldb_msg_add_fmt(msg, "versionID", "%llu", (long long)rec->version);	ret |= ldb_msg_add_string(msg, "winsOwner", rec->wins_owner);	ret |= ldb_msg_add_empty(msg, "address", 0, NULL);	for (i=0;rec->addresses[i];i++) {		ret |= ldb_msg_add_winsdb_addr(msg, rec, "address", rec->addresses[i]);	}	ret |= ldb_msg_add_empty(msg, "registeredBy", 0, NULL);	if (rec->registered_by) {		ret |= ldb_msg_add_string(msg, "registeredBy", rec->registered_by);		if (ret != 0) goto failed;	}	return msg;failed:	talloc_free(msg);	return NULL;}/*  save a WINS record into the database*/uint8_t winsdb_add(struct winsdb_handle *h, struct winsdb_record *rec, uint32_t flags){	struct ldb_message *msg;	struct ldb_context *wins_db = h->ldb;	TALLOC_CTX *tmp_ctx = talloc_new(wins_db);	int trans = -1;	int ret = 0;	trans = ldb_transaction_start(wins_db);	if (trans != LDB_SUCCESS) goto failed;	if (flags & WINSDB_FLAG_ALLOC_VERSION) {		/* passing '0' means auto-allocate a new one */		rec->version = winsdb_set_maxVersion(h, 0);		if (rec->version == 0) goto failed;	}	if (flags & WINSDB_FLAG_TAKE_OWNERSHIP) {		rec->wins_owner = h->local_owner;	}	msg = winsdb_message(wins_db, rec, tmp_ctx);	if (msg == NULL) goto failed;	ret = ldb_add(wins_db, msg);	if (ret != 0) goto failed;	trans = ldb_transaction_commit(wins_db);	if (trans != LDB_SUCCESS) goto failed;	wins_hook(h, rec, WINS_HOOK_ADD, h->hook_script);	talloc_free(tmp_ctx);	return NBT_RCODE_OK;failed:	if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);	talloc_free(tmp_ctx);	return NBT_RCODE_SVR;}/*  modify a WINS record in the database*/uint8_t winsdb_modify(struct winsdb_handle *h, struct winsdb_record *rec, uint32_t flags){	struct ldb_message *msg;	struct ldb_context *wins_db = h->ldb;	TALLOC_CTX *tmp_ctx = talloc_new(wins_db);	int trans;	int ret;	int i;	trans = ldb_transaction_start(wins_db);	if (trans != LDB_SUCCESS) goto failed;	if (flags & WINSDB_FLAG_ALLOC_VERSION) {		/* passing '0' means auto-allocate a new one */		rec->version = winsdb_set_maxVersion(h, 0);		if (rec->version == 0) goto failed;	}	if (flags & WINSDB_FLAG_TAKE_OWNERSHIP) {		rec->wins_owner = h->local_owner;	}	msg = winsdb_message(wins_db, rec, tmp_ctx);	if (msg == NULL) goto failed;	for (i=0;i<msg->num_elements;i++) {		msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;	}	ret = ldb_modify(wins_db, msg);	if (ret != 0) goto failed;	trans = ldb_transaction_commit(wins_db);	if (trans != LDB_SUCCESS) goto failed;	wins_hook(h, rec, WINS_HOOK_MODIFY, h->hook_script);	talloc_free(tmp_ctx);	return NBT_RCODE_OK;failed:	if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);	talloc_free(tmp_ctx);	return NBT_RCODE_SVR;}/*  delete a WINS record from the database*/uint8_t winsdb_delete(struct winsdb_handle *h, struct winsdb_record *rec){	struct ldb_context *wins_db = h->ldb;	TALLOC_CTX *tmp_ctx = talloc_new(wins_db);	struct ldb_dn *dn;	int trans;	int ret;	trans = ldb_transaction_start(wins_db);	if (trans != LDB_SUCCESS) goto failed;	dn = winsdb_dn(tmp_ctx, wins_db, rec->name);	if (dn == NULL) goto failed;	ret = ldb_delete(wins_db, dn);	if (ret != 0) goto failed;	trans = ldb_transaction_commit(wins_db);	if (trans != LDB_SUCCESS) goto failed;	wins_hook(h, rec, WINS_HOOK_DELETE, h->hook_script);	talloc_free(tmp_ctx);	return NBT_RCODE_OK;failed:	if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);	talloc_free(tmp_ctx);	return NBT_RCODE_SVR;}static bool winsdb_check_or_add_module_list(struct event_context *ev_ctx, 					    struct loadparm_context *lp_ctx, struct winsdb_handle *h){	int trans;	int ret;	struct ldb_dn *dn;	struct ldb_result *res = NULL;	struct ldb_message *msg = NULL;	TALLOC_CTX *tmp_ctx = talloc_new(h);	unsigned int flags = 0;	trans = ldb_transaction_start(h->ldb);	if (trans != LDB_SUCCESS) goto failed;	/* check if we have a special @MODULES record already */	dn = ldb_dn_new(tmp_ctx, h->ldb, "@MODULES");	if (!dn) goto failed;	/* find the record in the WINS database */	ret = ldb_search(h->ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res);	if (ret != LDB_SUCCESS) goto failed;	talloc_steal(tmp_ctx, res);	if (res->count > 0) goto skip;	/* if there's no record, add one */	msg = ldb_msg_new(tmp_ctx);	if (!msg) goto failed;	msg->dn = dn;	ret = ldb_msg_add_string(msg, "@LIST", "wins_ldb");	if (ret != 0) goto failed;	ret = ldb_add(h->ldb, msg);	if (ret != 0) goto failed;	trans = ldb_transaction_commit(h->ldb);	if (trans != LDB_SUCCESS) goto failed;	/* close and reopen the database, with the modules */	trans = LDB_ERR_OTHER;	talloc_free(h->ldb);	h->ldb = NULL;	if (lp_parm_bool(lp_ctx, NULL,"winsdb", "nosync", false)) {		flags |= LDB_FLG_NOSYNC;	}	h->ldb = ldb_wrap_connect(h, ev_ctx, lp_ctx, lock_path(h, lp_ctx, lp_wins_url(lp_ctx)),				  NULL, NULL, flags, NULL);	if (!h->ldb) goto failed;	talloc_free(tmp_ctx);	return true;skip:	if (trans == LDB_SUCCESS) ldb_transaction_cancel(h->ldb);	talloc_free(tmp_ctx);	return true;failed:	if (trans == LDB_SUCCESS) ldb_transaction_cancel(h->ldb);	talloc_free(tmp_ctx);	return false;}struct winsdb_handle *winsdb_connect(TALLOC_CTX *mem_ctx, 				     struct event_context *ev_ctx,				     struct loadparm_context *lp_ctx,				     const char *owner,				     enum winsdb_handle_caller caller){	struct winsdb_handle *h = NULL;	unsigned int flags = 0;	bool ret;	int ldb_err;	h = talloc(mem_ctx, struct winsdb_handle);	if (!h) return NULL;	if (lp_parm_bool(lp_ctx, NULL,"winsdb", "nosync", false)) {		flags |= LDB_FLG_NOSYNC;	}	h->ldb = ldb_wrap_connect(h, ev_ctx, lp_ctx, lock_path(h, lp_ctx, lp_wins_url(lp_ctx)),				  NULL, NULL, flags, NULL);	if (!h->ldb) goto failed;		h->caller = caller;	h->hook_script = lp_wins_hook(lp_ctx);	h->local_owner = talloc_strdup(h, owner);	if (!h->local_owner) goto failed;	/* make sure the module list is available and used */	ret = winsdb_check_or_add_module_list(ev_ctx, lp_ctx, h);	if (!ret) goto failed;	ldb_err = ldb_set_opaque(h->ldb, "winsdb_handle", h);	if (ldb_err != LDB_SUCCESS) goto failed;	return h;failed:	talloc_free(h);	return NULL;}

⌨️ 快捷键说明

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