r10164: - add first assoc_ctx test
[abartlet/samba.git/.git] / source4 / torture / nbt / winsreplication.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    WINS replication testing
5
6    Copyright (C) Andrew Tridgell 2005
7    
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.
12    
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.
17    
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.
21 */
22
23 #include "includes.h"
24 #include "libcli/nbt/libnbt.h"
25 #include "libcli/wrepl/winsrepl.h"
26
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)); \
31                 ret = False; \
32                 goto done; \
33         }} while (0)
34
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); \
39                 ret = False; \
40                 goto done; \
41         }} while (0)
42
43 /*
44   test how assoc_ctx's are only usable on the connection
45   they are created on.
46 */
47 static BOOL test_assoc_ctx1(TALLOC_CTX *mem_ctx, const char *address)
48 {
49         BOOL ret = True;
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;
56         NTSTATUS status;
57
58         printf("Test if assoc_ctx is only valid on the conection it was created on\n");
59
60         wrepl_socket1 = wrepl_socket_init(mem_ctx, NULL);
61         wrepl_socket2 = wrepl_socket_init(mem_ctx, NULL);
62         
63         printf("Setup 2 wrepl connections\n");
64         status = wrepl_connect(wrepl_socket1, address);
65         CHECK_STATUS(status, NT_STATUS_OK);
66
67         status = wrepl_connect(wrepl_socket2, address);
68         CHECK_STATUS(status, NT_STATUS_OK);
69
70         printf("Send a start association request (conn1)\n");
71         status = wrepl_associate(wrepl_socket1, &associate1);
72         CHECK_STATUS(status, NT_STATUS_OK);
73
74         printf("association context (conn1): 0x%x\n", associate1.out.assoc_ctx);
75
76         printf("Send a start association request (conn2)\n");
77         status = wrepl_associate(wrepl_socket2, &associate2);
78         CHECK_STATUS(status, NT_STATUS_OK);
79
80         printf("association context (conn2): 0x%x\n", associate2.out.assoc_ctx);
81
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);
85         talloc_free(req);
86
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);
90
91 done:
92         printf("Close 2 wrepl connections\n");
93         talloc_free(wrepl_socket1);
94         talloc_free(wrepl_socket2);
95         return ret;
96 }
97
98 /*
99   display a replication entry
100 */
101 static void display_entry(TALLOC_CTX *mem_ctx, struct wrepl_name *name)
102 {
103         int i;
104
105         printf("%s\n", nbt_name_string(mem_ctx, &name->name));
106         for (i=0;i<name->num_addresses;i++) {
107                 printf("\t%s %s\n", 
108                        name->addresses[i].owner, name->addresses[i].address);
109         }
110 }
111
112 /*
113   test a full replication dump from a WINS server
114 */
115 static BOOL test_wins_replication(TALLOC_CTX *mem_ctx, const char *address)
116 {
117         BOOL ret = True;
118         struct wrepl_socket *wrepl_socket;
119         NTSTATUS status;
120         int i, j;
121         struct wrepl_associate associate;
122         struct wrepl_pull_table pull_table;
123         struct wrepl_pull_names pull_names;
124
125         printf("Test one pull replication cycle\n");
126
127         wrepl_socket = wrepl_socket_init(mem_ctx, NULL);
128         
129         printf("Setup wrepl connections\n");
130         status = wrepl_connect(wrepl_socket, address);
131         CHECK_STATUS(status, NT_STATUS_OK);
132
133         printf("Send a start association request\n");
134
135         status = wrepl_associate(wrepl_socket, &associate);
136         CHECK_STATUS(status, NT_STATUS_OK);
137
138         printf("association context: 0x%x\n", associate.out.assoc_ctx);
139
140         printf("Send a replication table query\n");
141         pull_table.in.assoc_ctx = associate.out.assoc_ctx;
142
143         status = wrepl_pull_table(wrepl_socket, mem_ctx, &pull_table);
144         if (NT_STATUS_EQUAL(NT_STATUS_NETWORK_ACCESS_DENIED,status)) {
145                 struct wrepl_packet packet;
146                 struct wrepl_request *req;
147
148                 printf("We are not a valid pull partner for the server\n");
149
150                 ZERO_STRUCT(packet);
151                 packet.opcode                      = WREPL_OPCODE_BITS;
152                 packet.assoc_ctx                   = associate.out.assoc_ctx;
153                 packet.mess_type                   = WREPL_STOP_ASSOCIATION;
154                 packet.message.stop.reason         = 0;
155
156                 req = wrepl_request_send(wrepl_socket, &packet);
157                 talloc_free(req);
158                 ret = False;
159                 goto done;
160         }
161         CHECK_STATUS(status, NT_STATUS_OK);
162
163         printf("Found %d replication partners\n", pull_table.out.num_partners);
164
165         for (i=0;i<pull_table.out.num_partners;i++) {
166                 struct wrepl_wins_owner *partner = &pull_table.out.partners[i];
167                 printf("%s   max_version=%6llu   min_version=%6llu type=%d\n",
168                        partner->address, 
169                        partner->max_version, 
170                        partner->min_version, 
171                        partner->type);
172
173                 pull_names.in.assoc_ctx = associate.out.assoc_ctx;
174                 pull_names.in.partner = *partner;
175                 
176                 status = wrepl_pull_names(wrepl_socket, mem_ctx, &pull_names);
177                 CHECK_STATUS(status, NT_STATUS_OK);
178
179                 printf("Received %d names\n", pull_names.out.num_names);
180
181                 for (j=0;j<pull_names.out.num_names;j++) {
182                         display_entry(mem_ctx, &pull_names.out.names[j]);
183                 }
184         }
185
186 done:
187         printf("Close wrepl connections\n");
188         talloc_free(wrepl_socket);
189         return ret;
190 }
191
192 /*
193   test WINS replication operations
194 */
195 BOOL torture_nbt_winsreplication(void)
196 {
197         const char *address;
198         struct nbt_name name;
199         TALLOC_CTX *mem_ctx = talloc_new(NULL);
200         NTSTATUS status;
201         BOOL ret = True;
202         
203         make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
204
205         /* do an initial name resolution to find its IP */
206         status = resolve_name(&name, mem_ctx, &address, NULL);
207         if (!NT_STATUS_IS_OK(status)) {
208                 printf("Failed to resolve %s - %s\n",
209                        name.name, nt_errstr(status));
210                 talloc_free(mem_ctx);
211                 return False;
212         }
213
214         ret &= test_assoc_ctx1(mem_ctx, address);
215
216         ret &= test_wins_replication(mem_ctx, address);
217
218         talloc_free(mem_ctx);
219
220         return ret;
221 }