static NTSTATUS winsdb_addr_decode(struct winsdb_handle *h, struct winsdb_record *rec, struct ldb_val *val,
				   TALLOC_CTX *mem_ctx, struct winsdb_addr **_addr)
{
	NTSTATUS status;
	struct winsdb_addr *addr;
	const char *address;
	const char *wins_owner;
	const char *expire_time;
	char *p;

	addr = talloc(mem_ctx, struct winsdb_addr);
	if (!addr) {
		status = NT_STATUS_NO_MEMORY;
		goto failed;
	}

	address = (char *)val->data;

	p = strchr(address, ';');
	if (!p) {
		/* support old entries, with only the address */
		addr->address		= (const char *)talloc_steal(addr, val->data);
		addr->wins_owner	= talloc_strdup(addr, rec->wins_owner);
		if (!addr->wins_owner) {
			status = NT_STATUS_NO_MEMORY;
			goto failed;
		}
		addr->expire_time	= rec->expire_time;
		*_addr = addr;
		return NT_STATUS_OK;
	}

	*p = '\0'; p++;
	addr->address = talloc_strdup(addr, address);
	if (!addr->address) {
		status = NT_STATUS_NO_MEMORY;
		goto failed;
	}

	if (strncmp("winsOwner:", p, 10) != 0) {
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto failed;
	}
	wins_owner = p + 10;
	p = strchr(wins_owner, ';');
	if (!p) {
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto failed;
	}

	*p = '\0';p++;
	if (strcmp(wins_owner, "0.0.0.0") == 0) {
		wins_owner = h->local_owner;
	}
	addr->wins_owner = talloc_strdup(addr, wins_owner);
	if (!addr->wins_owner) {
		status = NT_STATUS_NO_MEMORY;
		goto failed;
	}

	if (strncmp("expireTime:", p, 11) != 0) {
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto failed;
	}

	expire_time = p + 11;
	p = strchr(expire_time, ';');
	if (!p) {
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto failed;
	}

	*p = '\0';p++;
	addr->expire_time = ldb_string_to_time(expire_time);

	*_addr = addr;
	return NT_STATUS_OK;
failed:
	talloc_free(addr);
	return status;
}
static NTSTATUS winsdb_addr_decode(struct winsdb_handle *h, struct winsdb_record *rec, struct ldb_val *val,
				   TALLOC_CTX *mem_ctx, struct winsdb_addr **_addr)
{
	NTSTATUS status;
	struct winsdb_addr *addr;
	const char *address;
	const char *wins_owner;
	const char *expire_time;
	char *p;

	addr = talloc(mem_ctx, struct winsdb_addr);
	if (!addr) {
		status = NT_STATUS_NO_MEMORY;
		goto failed;
	}

	address = (char *)val->data;

	p = strchr(address, ';');
	if (!p) {
		 
		addr->address		= (const char *)talloc_steal(addr, val->data);
		addr->wins_owner	= talloc_strdup(addr, rec->wins_owner);
		if (!addr->wins_owner) {
			status = NT_STATUS_NO_MEMORY;
			goto failed;
		}
		addr->expire_time	= rec->expire_time;
		*_addr = addr;
		return NT_STATUS_OK;
	}

	*p = '\0'; p++;
	addr->address = talloc_strdup(addr, address);
	if (!addr->address) {
		status = NT_STATUS_NO_MEMORY;
		goto failed;
	}

	if (strncmp("winsOwner:", p, 10) != 0) {
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto failed;
	}
	wins_owner = p + 10;
	p = strchr(wins_owner, ';');
	if (!p) {
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto failed;
	}

	*p = '\0';p++;
	if (strcmp(wins_owner, "0.0.0.0") == 0) {
		wins_owner = h->local_owner;
	}
	addr->wins_owner = talloc_strdup(addr, wins_owner);
	if (!addr->wins_owner) {
		status = NT_STATUS_NO_MEMORY;
		goto failed;
	}

	if (strncmp("expireTime:", p, 11) != 0) {
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto failed;
	}

	expire_time = p + 11;
	p = strchr(expire_time, ';');
	if (!p) {
		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
		goto failed;
	}

	*p = '\0';p++;
	addr->expire_time = ldb_string_to_time(expire_time);

	*_addr = addr;
	return NT_STATUS_OK;
failed:
	talloc_free(addr);
	return status;
}