svn commit: samba r11036 - in branches/SAMBA_4_0: . source/nbt_server/wins source/wrepl_server

metze at samba.org metze at samba.org
Fri Oct 14 12:54:32 GMT 2005


Author: metze
Date: 2005-10-14 12:54:26 +0000 (Fri, 14 Oct 2005)
New Revision: 11036

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=11036

Log:
 r10349 at SERNOX:  metze | 2005-09-20 15:38:31 +0200
 we know answer send_requests correctly
 
 metze

Modified:
   branches/SAMBA_4_0/
   branches/SAMBA_4_0/source/nbt_server/wins/winsdb.c
   branches/SAMBA_4_0/source/wrepl_server/wrepl_in_call.c


Changeset:

Property changes on: branches/SAMBA_4_0
___________________________________________________________________
Name: svk:merge
   - 0c0555d6-39d7-0310-84fc-f1cc0bd64818:/branches/tmp/samba4-winsrepl:10347
3a72dc49-98ff-0310-ab52-9b7ed7945d91:/local/samba4:9495
a953eb74-4aff-0310-a63c-855d20285ebb:/local/samba4:11632
d349723c-e9fc-0310-b8a8-fdedf1c27407:/local/SAMBA_4_0:5616
d349723c-e9fc-0310-b8a8-fdedf1c27407:/local/samba-SAMBA_4_0:5609
   + 0c0555d6-39d7-0310-84fc-f1cc0bd64818:/branches/tmp/samba4-winsrepl:10349
3a72dc49-98ff-0310-ab52-9b7ed7945d91:/local/samba4:9495
a953eb74-4aff-0310-a63c-855d20285ebb:/local/samba4:11632
d349723c-e9fc-0310-b8a8-fdedf1c27407:/local/SAMBA_4_0:5616
d349723c-e9fc-0310-b8a8-fdedf1c27407:/local/samba-SAMBA_4_0:5609

Modified: branches/SAMBA_4_0/source/nbt_server/wins/winsdb.c
===================================================================
--- branches/SAMBA_4_0/source/nbt_server/wins/winsdb.c	2005-10-14 12:54:06 UTC (rev 11035)
+++ branches/SAMBA_4_0/source/nbt_server/wins/winsdb.c	2005-10-14 12:54:26 UTC (rev 11036)
@@ -93,6 +93,46 @@
 	return dn;
 }
 
+struct nbt_name *winsdb_nbt_name(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
+{
+	struct nbt_name *name;
+	uint32_t cur = 0;
+
+	name = talloc(mem_ctx, struct nbt_name);
+	if (!name) goto failed;
+
+	if (dn->comp_num > 3) {
+		goto failed;
+	}
+
+	if (dn->comp_num > cur && strcasecmp("scope", dn->components[cur].name) == 0) {
+		name->scope	= talloc_steal(name, dn->components[cur].value.data);
+		cur++;
+	} else {
+		name->scope	= NULL;
+	}
+
+	if (dn->comp_num > cur && strcasecmp("name", dn->components[cur].name) == 0) {
+		name->name	= talloc_steal(name, dn->components[cur].value.data);
+		cur++;
+	} else {
+		name->name	= talloc_strdup(name, "");
+		if (!name->name) goto failed;
+	}
+
+	if (dn->comp_num > cur && strcasecmp("type", dn->components[cur].name) == 0) {
+		name->type	= strtoul((char *)dn->components[cur].value.data, NULL, 16);
+		cur++;
+	} else {
+		goto failed;
+	}
+
+	return name;
+failed:
+	talloc_free(name);
+	return NULL;
+}
+
 /*
  decode the winsdb_addr("address") attribute:
  "172.31.1.1" or 

Modified: branches/SAMBA_4_0/source/wrepl_server/wrepl_in_call.c
===================================================================
--- branches/SAMBA_4_0/source/wrepl_server/wrepl_in_call.c	2005-10-14 12:54:06 UTC (rev 11035)
+++ branches/SAMBA_4_0/source/wrepl_server/wrepl_in_call.c	2005-10-14 12:54:26 UTC (rev 11036)
@@ -28,8 +28,10 @@
 #include "smbd/service_stream.h"
 #include "lib/messaging/irpc.h"
 #include "librpc/gen_ndr/ndr_winsrepl.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
 #include "wrepl_server/wrepl_server.h"
 #include "nbt_server/wins/winsdb.h"
+#include "lib/ldb/include/ldb.h"
 
 static NTSTATUS wreplsrv_in_start_association(struct wreplsrv_in_call *call)
 {
@@ -147,16 +149,148 @@
 	return NT_STATUS_OK;
 }
 
+static int wreplsrv_in_sort_wins_name(struct wrepl_wins_name *n1,
+				      struct wrepl_wins_name *n2)
+{
+	if (n1->id < n2->id) return -1;
+	if (n1->id > n2->id) return 1;
+	return 0;
+}
+
+static NTSTATUS wreplsrv_record2wins_name(TALLOC_CTX *mem_ctx, struct wrepl_wins_name *name, struct winsdb_record *rec)
+{
+	uint8_t *namebuf;
+	uint32_t namebuf_len;
+	uint32_t name_len;
+
+	name_len = strlen(rec->name->name);
+	if (name_len > 15) {
+		return NT_STATUS_INVALID_PARAMETER_MIX;
+	}
+
+	namebuf = (uint8_t *)talloc_asprintf(mem_ctx, "%-15s%c%s",
+					    rec->name->name, rec->name->type,
+					    (rec->name->scope?rec->name->scope:""));
+	NT_STATUS_HAVE_NO_MEMORY(namebuf);
+	namebuf_len = strlen((char *)namebuf) + 1;
+
+	/* oh wow, what a nasty bug in windows ... */
+	if (namebuf[15] == 0x1b && namebuf_len >= 16) {
+		namebuf[15] = namebuf[0];
+		namebuf[0] = 0x1b;
+	}
+
+	name->name_len		= namebuf_len;
+	name->name		= namebuf;
+	name->id		= rec->version;
+	name->unknown		= WINSDB_GROUP_ADDRESS;
+
+	name->flags		= rec->nb_flags;
+	name->group_flag	= 0;
+
+	switch (name->flags & 2) {
+	case 0:
+		name->addresses.ip			= rec->addresses[0]->address;
+		talloc_steal(mem_ctx, rec->addresses[0]->address);
+		break;
+	case 2:
+		name->addresses.addresses.num_ips	= 0;
+		name->addresses.addresses.ips		= NULL;
+		break;
+	}
+
+	return NT_STATUS_OK;
+}
+
 static NTSTATUS wreplsrv_in_send_request(struct wreplsrv_in_call *call)
 {
+	struct wreplsrv_service *service = call->wreplconn->service;
+	struct wrepl_wins_owner *owner_in = &call->req_packet.message.replication.info.owner;
 	struct wrepl_replication *repl_out = &call->rep_packet.message.replication;
 	struct wrepl_send_reply *reply_out = &call->rep_packet.message.replication.info.reply;
+	struct wreplsrv_owner local_owner;
+	struct wreplsrv_owner *owner;
+	const char *filter;
+	struct ldb_message **res = NULL;
+	int ret;
+	struct wrepl_wins_name *names;
+	struct winsdb_record *rec;
+	NTSTATUS status;
+	uint32_t i;
 
-	repl_out->command = WREPL_REPL_SEND_REPLY;
+	if (strcmp(call->wreplconn->our_ip, owner_in->address) == 0) {
+		ZERO_STRUCT(local_owner);
+		local_owner.owner.address	= WINSDB_OWNER_LOCAL;
+		local_owner.owner.min_version	= 0;
+		local_owner.owner.max_version	= wreplsrv_local_max_version(service);
+		local_owner.owner.type		= 1;
+		owner = &local_owner;
+	} else {
+		owner = wreplsrv_find_owner(service->table, owner_in->address);
+	}
 
+	repl_out->command	= WREPL_REPL_SEND_REPLY;
 	reply_out->num_names	= 0;
 	reply_out->names	= NULL;
 
+	/*
+	 * if we didn't know this owner, must be a bug in the partners client code...
+	 * return an empty list.
+	 */
+	if (!owner) {
+		return NT_STATUS_OK;
+	}
+
+	/*
+	 * if the partner ask for nothing, or give invalid ranges,
+	 * return an empty list.
+	 */
+	if (owner_in->min_version >= owner_in->max_version) {
+		return NT_STATUS_OK;
+	}
+
+	/*
+	 * if the partner has already all records for nothing, or give invalid ranges,
+	 * return an empty list.
+	 */
+	if (owner_in->min_version >= owner->owner.max_version) {
+		return NT_STATUS_OK;
+	}
+
+	filter = talloc_asprintf(call, "(&(winsOwner=%s)(objectClass=wins)(active=1)(version>=%llu)(version<=%llu))",
+				 owner->owner.address, owner_in->min_version, owner_in->max_version);
+	NT_STATUS_HAVE_NO_MEMORY(filter);
+	ret = ldb_search(service->wins_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res);
+	if (res != NULL) {
+		talloc_steal(call, res);
+	}
+	if (ret < 0) return  NT_STATUS_INTERNAL_DB_CORRUPTION;
+	if (ret == 0) return NT_STATUS_OK;
+
+	names = talloc_array(call, struct wrepl_wins_name, ret);
+	NT_STATUS_HAVE_NO_MEMORY(names);
+
+	for (i=0; i < ret; i++) {
+		rec = winsdb_record(res[i], call);
+		NT_STATUS_HAVE_NO_MEMORY(rec);
+
+		rec->name	= winsdb_nbt_name(names, res[i]->dn);
+		if (!rec->name) {
+			return NT_STATUS_INTERNAL_DB_CORRUPTION;
+		}
+
+		status = wreplsrv_record2wins_name(names, &names[i], rec);
+		NT_STATUS_NOT_OK_RETURN(status);
+		talloc_free(rec);
+		talloc_free(res[i]);
+	}
+
+	/* sort the names before we send them */
+	qsort(names, ret, sizeof(struct wrepl_wins_name), (comparison_fn_t)wreplsrv_in_sort_wins_name);
+
+	reply_out->num_names	= ret;
+	reply_out->names	= names;
+
 	return NT_STATUS_OK;
 }
 



More information about the samba-cvs mailing list