2 Unix SMB/CIFS implementation.
4 WINS replication testing
6 Copyright (C) Andrew Tridgell 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "libcli/nbt/libnbt.h"
25 #include "libcli/wrepl/winsrepl.h"
27 #define CHECK_STATUS(status, correct) do { \
28 if (!NT_STATUS_EQUAL(status, correct)) { \
29 printf("(%s) Incorrect status %s - should be %s\n", \
30 __location__, nt_errstr(status), nt_errstr(correct)); \
35 #define CHECK_VALUE(v, correct) do { \
36 if ((v) != (correct)) { \
37 printf("(%s) Incorrect value %s=%d - should be %d\n", \
38 __location__, #v, v, correct); \
44 test how assoc_ctx's are only usable on the connection
47 static BOOL
test_assoc_ctx1(TALLOC_CTX
*mem_ctx
, const char *address
)
50 struct wrepl_request
*req
;
51 struct wrepl_socket
*wrepl_socket1
;
52 struct wrepl_associate associate1
;
53 struct wrepl_socket
*wrepl_socket2
;
54 struct wrepl_associate associate2
;
55 struct wrepl_pull_table pull_table
;
58 printf("Test if assoc_ctx is only valid on the conection it was created on\n");
60 wrepl_socket1
= wrepl_socket_init(mem_ctx
, NULL
);
61 wrepl_socket2
= wrepl_socket_init(mem_ctx
, NULL
);
63 printf("Setup 2 wrepl connections\n");
64 status
= wrepl_connect(wrepl_socket1
, address
);
65 CHECK_STATUS(status
, NT_STATUS_OK
);
67 status
= wrepl_connect(wrepl_socket2
, address
);
68 CHECK_STATUS(status
, NT_STATUS_OK
);
70 printf("Send a start association request (conn1)\n");
71 status
= wrepl_associate(wrepl_socket1
, &associate1
);
72 CHECK_STATUS(status
, NT_STATUS_OK
);
74 printf("association context (conn1): 0x%x\n", associate1
.out
.assoc_ctx
);
76 printf("Send a start association request (conn2)\n");
77 status
= wrepl_associate(wrepl_socket2
, &associate2
);
78 CHECK_STATUS(status
, NT_STATUS_OK
);
80 printf("association context (conn2): 0x%x\n", associate2
.out
.assoc_ctx
);
82 printf("Send a replication table query, with assoc 1 (conn2), should be ignored\n");
83 pull_table
.in
.assoc_ctx
= associate1
.out
.assoc_ctx
;
84 req
= wrepl_pull_table_send(wrepl_socket2
, &pull_table
);
87 printf("Send a association request (conn2), to make sure the last request was ignored\n");
88 status
= wrepl_associate(wrepl_socket2
, &associate2
);
89 CHECK_STATUS(status
, NT_STATUS_OK
);
92 printf("Close 2 wrepl connections\n");
93 talloc_free(wrepl_socket1
);
94 talloc_free(wrepl_socket2
);
99 test if we always get back the same assoc_ctx
101 static BOOL
test_assoc_ctx2(TALLOC_CTX
*mem_ctx
, const char *address
)
104 struct wrepl_socket
*wrepl_socket
;
105 struct wrepl_associate associate
;
109 printf("Test if we always get back the same assoc_ctx\n");
111 wrepl_socket
= wrepl_socket_init(mem_ctx
, NULL
);
113 printf("Setup wrepl connections\n");
114 status
= wrepl_connect(wrepl_socket
, address
);
115 CHECK_STATUS(status
, NT_STATUS_OK
);
118 printf("Send 1st start association request\n");
119 status
= wrepl_associate(wrepl_socket
, &associate
);
120 CHECK_STATUS(status
, NT_STATUS_OK
);
121 assoc_ctx1
= associate
.out
.assoc_ctx
;
122 printf("1st association context: 0x%x\n", associate
.out
.assoc_ctx
);
124 printf("Send 2nd start association request\n");
125 status
= wrepl_associate(wrepl_socket
, &associate
);
126 CHECK_VALUE(associate
.out
.assoc_ctx
, assoc_ctx1
);
127 CHECK_STATUS(status
, NT_STATUS_OK
);
128 printf("2nd association context: 0x%x\n", associate
.out
.assoc_ctx
);
130 printf("Send 3rd start association request\n");
131 status
= wrepl_associate(wrepl_socket
, &associate
);
132 CHECK_VALUE(associate
.out
.assoc_ctx
, assoc_ctx1
);
133 CHECK_STATUS(status
, NT_STATUS_OK
);
134 printf("3rd association context: 0x%x\n", associate
.out
.assoc_ctx
);
137 printf("Close wrepl connections\n");
138 talloc_free(wrepl_socket
);
143 display a replication entry
145 static void display_entry(TALLOC_CTX
*mem_ctx
, struct wrepl_name
*name
)
149 printf("%s\n", nbt_name_string(mem_ctx
, &name
->name
));
150 printf("\tFLAGS: 0x%08X G_FLAG: 0x%08X VERSION_ID: %llu\n",
151 name
->flags
, name
->group_flag
, name
->version_id
);
152 printf("\tOWNER: %-15s\n", name
->owner
);
153 for (i
=0;i
<name
->num_addresses
;i
++) {
154 printf("\tADDR: %-15s OWNER: %-15s\n",
155 name
->addresses
[i
].address
, name
->addresses
[i
].owner
);
160 test a full replication dump from a WINS server
162 static BOOL
test_wins_replication(TALLOC_CTX
*mem_ctx
, const char *address
)
165 struct wrepl_socket
*wrepl_socket
;
168 struct wrepl_associate associate
;
169 struct wrepl_pull_table pull_table
;
170 struct wrepl_pull_names pull_names
;
172 printf("Test one pull replication cycle\n");
174 wrepl_socket
= wrepl_socket_init(mem_ctx
, NULL
);
176 printf("Setup wrepl connections\n");
177 status
= wrepl_connect(wrepl_socket
, address
);
178 CHECK_STATUS(status
, NT_STATUS_OK
);
180 printf("Send a start association request\n");
182 status
= wrepl_associate(wrepl_socket
, &associate
);
183 CHECK_STATUS(status
, NT_STATUS_OK
);
185 printf("association context: 0x%x\n", associate
.out
.assoc_ctx
);
187 printf("Send a replication table query\n");
188 pull_table
.in
.assoc_ctx
= associate
.out
.assoc_ctx
;
190 status
= wrepl_pull_table(wrepl_socket
, mem_ctx
, &pull_table
);
191 if (NT_STATUS_EQUAL(NT_STATUS_NETWORK_ACCESS_DENIED
,status
)) {
192 struct wrepl_packet packet
;
193 struct wrepl_request
*req
;
196 packet
.opcode
= WREPL_OPCODE_BITS
;
197 packet
.assoc_ctx
= associate
.out
.assoc_ctx
;
198 packet
.mess_type
= WREPL_STOP_ASSOCIATION
;
199 packet
.message
.stop
.reason
= 0;
201 req
= wrepl_request_send(wrepl_socket
, &packet
);
204 printf("failed - We are not a valid pull partner for the server\n");
208 CHECK_STATUS(status
, NT_STATUS_OK
);
210 printf("Found %d replication partners\n", pull_table
.out
.num_partners
);
212 for (i
=0;i
<pull_table
.out
.num_partners
;i
++) {
213 struct wrepl_wins_owner
*partner
= &pull_table
.out
.partners
[i
];
214 printf("%s max_version=%6llu min_version=%6llu type=%d\n",
216 partner
->max_version
,
217 partner
->min_version
,
220 pull_names
.in
.assoc_ctx
= associate
.out
.assoc_ctx
;
221 pull_names
.in
.partner
= *partner
;
223 status
= wrepl_pull_names(wrepl_socket
, mem_ctx
, &pull_names
);
224 CHECK_STATUS(status
, NT_STATUS_OK
);
226 printf("Received %d names\n", pull_names
.out
.num_names
);
228 for (j
=0;j
<pull_names
.out
.num_names
;j
++) {
229 display_entry(mem_ctx
, &pull_names
.out
.names
[j
]);
234 printf("Close wrepl connections\n");
235 talloc_free(wrepl_socket
);
240 test WINS replication operations
242 BOOL
torture_nbt_winsreplication(void)
245 struct nbt_name name
;
246 TALLOC_CTX
*mem_ctx
= talloc_new(NULL
);
250 make_nbt_name_server(&name
, lp_parm_string(-1, "torture", "host"));
252 /* do an initial name resolution to find its IP */
253 status
= resolve_name(&name
, mem_ctx
, &address
, NULL
);
254 if (!NT_STATUS_IS_OK(status
)) {
255 printf("Failed to resolve %s - %s\n",
256 name
.name
, nt_errstr(status
));
257 talloc_free(mem_ctx
);
261 ret
&= test_assoc_ctx1(mem_ctx
, address
);
262 ret
&= test_assoc_ctx2(mem_ctx
, address
);
264 ret
&= test_wins_replication(mem_ctx
, address
);
266 talloc_free(mem_ctx
);