[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Mon Feb 1 09:17:55 MST 2010
The branch, master has been updated
via 431d75f... s4:NBT-WINS: test large scopes
via 70779a4... s4:NBT-WINS: pass the expected rcode of the name registration to the test code
via c1d8dc0... s4:NBT-WINSREPLICATION: test replication with names including scopes
via 331505f... s4:NBT-WINSREPLICATION: fix compiler warnings
via 07b06e5... s4:NBT-WINSREPLICATION: use an array of nbt_names to loop over different names
via ea7ec4f... s4:winsserver: reject name registrations with a scope length > 237
via 7a02a2b... s4:wrepl_server: truncate the scope of a netbios name to 237 bytes as Windows 2008 does
via e37dc56... libcli/nbt: fix ndr_push_nbt_string() string labels with a length of 63 (0x3F) are allowed
from 93142e4... s4/ldif: Handle Schema:prefixMap blobs in W2K3 and W2K8
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 431d75fc9c7f942dcbd31f80380dda59887ac229
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Feb 1 15:32:37 2010 +0100
s4:NBT-WINS: test large scopes
metze
commit 70779a46a7b7f6e5c00eba048dbf653d86bc07d4
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Feb 1 14:55:14 2010 +0100
s4:NBT-WINS: pass the expected rcode of the name registration to the test code
metze
commit c1d8dc01fc6f0fa3a22a405419917d880b832761
Author: Stefan Metzmacher <metze at samba.org>
Date: Sat Jan 30 10:50:33 2010 +0100
s4:NBT-WINSREPLICATION: test replication with names including scopes
metze
commit 331505f09d61cdc5c920293fc36ac1853235177b
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jan 29 16:42:24 2010 +0100
s4:NBT-WINSREPLICATION: fix compiler warnings
metze
commit 07b06e51bbf95168899081ba2aa92a4e6a5bac12
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jan 29 16:33:58 2010 +0100
s4:NBT-WINSREPLICATION: use an array of nbt_names to loop over different names
metze
commit ea7ec4fb30a261cedb882c9325815679e5e20d57
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Feb 1 14:39:13 2010 +0100
s4:winsserver: reject name registrations with a scope length > 237
This matches Windows 2008 behavior. Name releases are just ignored.
metze
commit 7a02a2ba80c2997947a2b2c48c33f8c7647f7471
Author: Stefan Metzmacher <metze at samba.org>
Date: Sun Jan 31 18:59:41 2010 +0100
s4:wrepl_server: truncate the scope of a netbios name to 237 bytes as Windows 2008 does
metze
commit e37dc56e971f44c00791529a39144d1a972e3ca2
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Feb 1 15:18:15 2010 +0100
libcli/nbt: fix ndr_push_nbt_string() string labels with a length of 63 (0x3F) are allowed
metze
-----------------------------------------------------------------------
Summary of changes:
libcli/nbt/nbtname.c | 4 +-
source4/nbt_server/wins/winsserver.c | 9 +++
source4/torture/nbt/wins.c | 94 ++++++++++++++++++++++-----
source4/torture/nbt/winsreplication.c | 93 ++++++++++++++++++++++------
source4/wrepl_server/wrepl_apply_records.c | 14 ++++
5 files changed, 175 insertions(+), 39 deletions(-)
Changeset truncated at 500 lines:
diff --git a/libcli/nbt/nbtname.c b/libcli/nbt/nbtname.c
index 792b340..136379a 100644
--- a/libcli/nbt/nbtname.c
+++ b/libcli/nbt/nbtname.c
@@ -173,9 +173,9 @@ _PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_fla
complen = strcspn(s, ".");
/* we need to make sure the length fits into 6 bytes */
- if (complen >= 0x3F) {
+ if (complen > 0x3F) {
return ndr_push_error(ndr, NDR_ERR_STRING,
- "component length %u[%08X] > 0x00003F",
+ "component length %u[%08X] > 0x0000003F",
(unsigned)complen, (unsigned)complen);
}
diff --git a/source4/nbt_server/wins/winsserver.c b/source4/nbt_server/wins/winsserver.c
index 4b8b8cc..ca8daed 100644
--- a/source4/nbt_server/wins/winsserver.c
+++ b/source4/nbt_server/wins/winsserver.c
@@ -496,6 +496,11 @@ static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock,
goto done;
}
+ if (name->scope && strlen(name->scope) > 237) {
+ rcode = NBT_RCODE_SVR;
+ goto done;
+ }
+
duplicate_packet = wins_check_wack_queue(iface, packet, src);
if (duplicate_packet) {
/* just ignore the packet */
@@ -874,6 +879,10 @@ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock,
goto done;
}
+ if (name->scope && strlen(name->scope) > 237) {
+ goto done;
+ }
+
status = winsdb_lookup(winssrv->wins_db, name, packet, &rec);
if (!NT_STATUS_IS_OK(status)) {
goto done;
diff --git a/source4/torture/nbt/wins.c b/source4/torture/nbt/wins.c
index d69c518..b372de8 100644
--- a/source4/torture/nbt/wins.c
+++ b/source4/torture/nbt/wins.c
@@ -49,7 +49,8 @@
*/
static bool nbt_test_wins_name(struct torture_context *tctx, const char *address,
struct nbt_name *name, uint16_t nb_flags,
- bool try_low_port)
+ bool try_low_port,
+ uint8_t register_rcode)
{
struct nbt_name_register_wins io;
struct nbt_name_register name_register;
@@ -200,7 +201,11 @@ static bool nbt_test_wins_name(struct torture_context *tctx, const char *address
torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name register", address));
CHECK_STRING(tctx, io.out.wins_server, address);
- CHECK_VALUE(tctx, io.out.rcode, 0);
+ CHECK_VALUE(tctx, io.out.rcode, register_rcode);
+
+ if (register_rcode != NBT_RCODE_OK) {
+ return true;
+ }
if (name->type != NBT_NAME_MASTER &&
name->type != NBT_NAME_LOGON &&
@@ -400,6 +405,35 @@ static bool nbt_test_wins_name(struct torture_context *tctx, const char *address
}
+static char *test_nbt_wins_scope_string(TALLOC_CTX *mem_ctx, uint8_t count)
+{
+ char *res;
+ uint8_t i;
+
+ res = talloc_array(mem_ctx, char, count+1);
+ if (res == NULL) {
+ return NULL;
+ }
+
+ for (i=0; i < count; i++) {
+ switch (i) {
+ case 63:
+ case 63 + 1 + 63:
+ case 63 + 1 + 63 + 1 + 63:
+ res[i] = '.';
+ break;
+ default:
+ res[i] = '0' + (i%10);
+ break;
+ }
+ }
+
+ res[count] = '\0';
+
+ talloc_set_name_const(res, res);
+
+ return res;
+}
/*
test operations against a WINS server
@@ -418,54 +452,78 @@ static bool nbt_test_wins(struct torture_context *tctx)
name.type = NBT_NAME_CLIENT;
name.scope = NULL;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, true);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, true, NBT_RCODE_OK);
name.type = NBT_NAME_MASTER;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, false, NBT_RCODE_OK);
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H | NBT_NM_GROUP, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H | NBT_NM_GROUP, false, NBT_RCODE_OK);
name.type = NBT_NAME_SERVER;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, true);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, true, NBT_RCODE_OK);
name.type = NBT_NAME_LOGON;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H | NBT_NM_GROUP, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H | NBT_NM_GROUP, false, NBT_RCODE_OK);
name.type = NBT_NAME_BROWSER;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H | NBT_NM_GROUP, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H | NBT_NM_GROUP, false, NBT_RCODE_OK);
name.type = NBT_NAME_PDC;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, true);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, true, NBT_RCODE_OK);
name.type = 0xBF;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, true);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, true, NBT_RCODE_OK);
name.type = 0xBE;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, false, NBT_RCODE_OK);
name.scope = "example";
name.type = 0x72;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, true);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, true, NBT_RCODE_OK);
name.scope = "example";
name.type = 0x71;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H | NBT_NM_GROUP, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H | NBT_NM_GROUP, false, NBT_RCODE_OK);
name.scope = "foo.example.com";
name.type = 0x72;
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, false, NBT_RCODE_OK);
name.name = talloc_asprintf(tctx, "_T\01-%5u.foo", r);
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, false, NBT_RCODE_OK);
name.name = "";
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, false, NBT_RCODE_OK);
name.name = talloc_asprintf(tctx, ".");
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, false, NBT_RCODE_OK);
name.name = talloc_asprintf(tctx, "%5u-\377\200\300FOO", r);
- ret &= nbt_test_wins_name(tctx, address, &name, NBT_NODE_H, false);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, false, NBT_RCODE_OK);
+
+ name.scope = test_nbt_wins_scope_string(tctx, 237);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, false, NBT_RCODE_OK);
+
+ name.scope = test_nbt_wins_scope_string(tctx, 238);
+ ret &= nbt_test_wins_name(tctx, address, &name,
+ NBT_NODE_H, false, NBT_RCODE_SVR);
return ret;
}
diff --git a/source4/torture/nbt/winsreplication.c b/source4/torture/nbt/winsreplication.c
index 1ad0543..f363c9e 100644
--- a/source4/torture/nbt/winsreplication.c
+++ b/source4/torture/nbt/winsreplication.c
@@ -799,9 +799,16 @@ static bool test_wrepl_is_applied(struct torture_context *tctx,
names[0].state,
names[0].node,
names[0].is_static);
+ char *expected_scope = NULL;
CHECK_VALUE(tctx, names[0].name.type, name->name->type);
CHECK_VALUE_STRING(tctx, names[0].name.name, name->name->name);
- CHECK_VALUE_STRING(tctx, names[0].name.scope, name->name->scope);
+
+ if (names[0].name.scope) {
+ expected_scope = talloc_strndup(tctx,
+ name->name->scope,
+ 237);
+ }
+ CHECK_VALUE_STRING(tctx, names[0].name.scope, expected_scope);
CHECK_VALUE(tctx, flags, name->flags);
CHECK_VALUE_UINT64(tctx, names[0].version_id, name->id);
@@ -1004,18 +1011,63 @@ static bool test_wrepl_sgroup_merged(struct torture_context *tctx,
return true;
}
+static char *test_nbt_winsrepl_scope_string(TALLOC_CTX *mem_ctx, uint8_t count)
+{
+ char *res;
+ uint8_t i;
+
+ res = talloc_array(mem_ctx, char, count+1);
+ if (res == NULL) {
+ return NULL;
+ }
+
+ for (i=0; i < count; i++) {
+ res[i] = '0' + (i%10);
+ }
+
+ res[count] = '\0';
+
+ talloc_set_name_const(res, res);
+
+ return res;
+}
+
static bool test_conflict_same_owner(struct torture_context *tctx,
struct test_wrepl_conflict_conn *ctx)
{
static bool ret = true;
- struct nbt_name name;
struct wrepl_wins_name wins_name1;
struct wrepl_wins_name wins_name2;
struct wrepl_wins_name *wins_name_tmp;
struct wrepl_wins_name *wins_name_last;
struct wrepl_wins_name *wins_name_cur;
uint32_t i,j;
- uint8_t types[] = { 0x00, 0x1C };
+ struct nbt_name names[] = {
+ _NBT_NAME("_SAME_OWNER_A", 0x00, NULL),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 1)),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 2)),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 3)),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 4)),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 5)),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 6)),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 7)),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 8)),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 9)),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 237)),
+ _NBT_NAME("_SAME_OWNER_A", 0x00,
+ test_nbt_winsrepl_scope_string(tctx, 238)),
+ _NBT_NAME("_SAME_OWNER_A", 0x1C, NULL),
+ };
struct {
enum wrepl_name_type type;
enum wrepl_name_state state;
@@ -1112,18 +1164,13 @@ static bool test_conflict_same_owner(struct torture_context *tctx,
}
};
- name.name = "_SAME_OWNER_A";
- name.type = 0;
- name.scope = NULL;
-
wins_name_tmp = NULL;
wins_name_last = &wins_name2;
wins_name_cur = &wins_name1;
- for (j=0; ret && j < ARRAY_SIZE(types); j++) {
- name.type = types[j];
+ for (j=0; ret && j < ARRAY_SIZE(names); j++) {
torture_comment(tctx, "Test Replica Conflicts with same owner[%s] for %s\n",
- nbt_name_string(ctx, &name), ctx->a.address);
+ nbt_name_string(ctx, &names[j]), ctx->a.address);
for(i=0; ret && i < ARRAY_SIZE(records); i++) {
wins_name_tmp = wins_name_last;
@@ -1142,7 +1189,7 @@ static bool test_conflict_same_owner(struct torture_context *tctx,
"REPLACE");
}
- wins_name_cur->name = &name;
+ wins_name_cur->name = &names[j];
wins_name_cur->flags = WREPL_NAME_FLAGS(records[i].type,
records[i].state,
records[i].node,
@@ -1150,7 +1197,8 @@ static bool test_conflict_same_owner(struct torture_context *tctx,
wins_name_cur->id = ++ctx->a.max_version;
if (wins_name_cur->flags & 2) {
wins_name_cur->addresses.addresses.num_ips = records[i].num_ips;
- wins_name_cur->addresses.addresses.ips = discard_const(records[i].ips);
+ wins_name_cur->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
+ records[i].ips);
} else {
wins_name_cur->addresses.ip = records[i].ips[0].ip;
}
@@ -4833,7 +4881,8 @@ static bool test_conflict_different_owner(struct torture_context *tctx,
wins_name_r1->id = ++records[i].r1.owner->max_version;
if (wins_name_r1->flags & 2) {
wins_name_r1->addresses.addresses.num_ips = records[i].r1.num_ips;
- wins_name_r1->addresses.addresses.ips = discard_const(records[i].r1.ips);
+ wins_name_r1->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
+ records[i].r1.ips);
} else {
wins_name_r1->addresses.ip = records[i].r1.ips[0].ip;
}
@@ -4855,7 +4904,8 @@ static bool test_conflict_different_owner(struct torture_context *tctx,
wins_name_r2->id = ++records[i].r2.owner->max_version;
if (wins_name_r2->flags & 2) {
wins_name_r2->addresses.addresses.num_ips = records[i].r2.num_ips;
- wins_name_r2->addresses.addresses.ips = discard_const(records[i].r2.ips);
+ wins_name_r2->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
+ records[i].r2.ips);
} else {
wins_name_r2->addresses.ip = records[i].r2.ips[0].ip;
}
@@ -4932,7 +4982,8 @@ static bool test_conflict_different_owner(struct torture_context *tctx,
WREPL_NODE_B, false);
wins_name_r2->id = ++records[i].r2.owner->max_version;
wins_name_r2->addresses.addresses.num_ips = ARRAY_SIZE(addresses_B_1);
- wins_name_r2->addresses.addresses.ips = discard_const(addresses_B_1);
+ wins_name_r2->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
+ addresses_B_1);
wins_name_r2->unknown = "255.255.255.255";
ret &= test_wrepl_update_one(tctx, ctx, records[i].r2.owner, wins_name_r2);
ret &= test_wrepl_is_applied(tctx, ctx, records[i].r2.owner, wins_name_r2, true);
@@ -4944,7 +4995,8 @@ static bool test_conflict_different_owner(struct torture_context *tctx,
WREPL_NODE_B, false);
wins_name_r2->id = ++records[i].r2.owner->max_version;
wins_name_r2->addresses.addresses.num_ips = ARRAY_SIZE(addresses_B_1);
- wins_name_r2->addresses.addresses.ips = discard_const(addresses_B_1);
+ wins_name_r2->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
+ addresses_B_1);
wins_name_r2->unknown = "255.255.255.255";
ret &= test_wrepl_update_one(tctx, ctx, records[i].r2.owner, wins_name_r2);
ret &= test_wrepl_is_applied(tctx, ctx, records[i].r2.owner, wins_name_r2, true);
@@ -6592,7 +6644,8 @@ static bool test_conflict_owned_released_vs_replica(struct torture_context *tctx
wins_name->id = ++ctx->b.max_version;
if (wins_name->flags & 2) {
wins_name->addresses.addresses.num_ips = records[i].replica.num_ips;
- wins_name->addresses.addresses.ips = discard_const(records[i].replica.ips);
+ wins_name->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
+ records[i].replica.ips);
} else {
wins_name->addresses.ip = records[i].replica.ips[0].ip;
}
@@ -9289,7 +9342,8 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx,
wins_name->id = ++ctx->b.max_version;
if (wins_name->flags & 2) {
wins_name->addresses.addresses.num_ips = records[i].replica.num_ips;
- wins_name->addresses.addresses.ips = discard_const(records[i].replica.ips);
+ wins_name->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
+ records[i].replica.ips);
} else {
wins_name->addresses.ip = records[i].replica.ips[0].ip;
}
@@ -9404,7 +9458,8 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx,
WREPL_NODE_B, false);
wins_name->id = ++ctx->b.max_version;
wins_name->addresses.addresses.num_ips = ARRAY_SIZE(addresses_B_1);
- wins_name->addresses.addresses.ips = discard_const(addresses_B_1);
+ wins_name->addresses.addresses.ips = discard_const_p(struct wrepl_ip,
+ addresses_B_1);
wins_name->unknown = "255.255.255.255";
ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name, true);
diff --git a/source4/wrepl_server/wrepl_apply_records.c b/source4/wrepl_server/wrepl_apply_records.c
index e6ff9a0..878f689 100644
--- a/source4/wrepl_server/wrepl_apply_records.c
+++ b/source4/wrepl_server/wrepl_apply_records.c
@@ -1358,6 +1358,20 @@ static NTSTATUS wreplsrv_apply_one_record(struct wreplsrv_partner *partner,
bool replica_vs_replica = false;
bool local_vs_replica = false;
+ if (replica->name.scope) {
+ TALLOC_CTX *parent;
+ const char *scope;
+
+ /*
+ * Windows 2008 truncates the scope to 237 bytes,
+ * so we do...
+ */
+ parent = talloc_parent(replica->name.scope);
+ scope = talloc_strndup(parent, replica->name.scope, 237);
+ NT_STATUS_HAVE_NO_MEMORY(scope);
+ replica->name.scope = scope;
+ }
+
status = winsdb_lookup(partner->service->wins_db,
&replica->name, mem_ctx, &rec);
if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list