Revert addition of 'mailslot' parameter.
[bbaumbach/samba-autobuild/.git] / source4 / torture / nbt / dgram.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    NBT dgram 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 3 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, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "libcli/dgram/libdgram.h"
24 #include "librpc/gen_ndr/samr.h"
25 #include "librpc/gen_ndr/ndr_nbt.h"
26 #include "librpc/gen_ndr/ndr_netlogon.h"
27 #include "lib/socket/socket.h"
28 #include "lib/events/events.h"
29 #include "torture/rpc/rpc.h"
30 #include "libcli/resolve/resolve.h"
31 #include "system/network.h"
32 #include "lib/socket/netif.h"
33 #include "param/param.h"
34
35 #define TEST_NAME "TORTURE_TEST"
36
37 /*
38   reply handler for netlogon request
39 */
40 static void netlogon_handler(struct dgram_mailslot_handler *dgmslot, 
41                              struct nbt_dgram_packet *packet, 
42                              struct socket_address *src)
43 {
44         NTSTATUS status;
45         struct nbt_netlogon_response netlogon;
46         int *replies = (int *)dgmslot->private;
47
48         printf("netlogon reply from %s:%d\n", src->addr, src->port);
49
50         status = dgram_mailslot_netlogon_parse_response(dgmslot, dgmslot, packet, &netlogon);
51         if (!NT_STATUS_IS_OK(status)) {
52                 printf("Failed to parse netlogon packet from %s:%d\n",
53                        src->addr, src->port);
54                 return;
55         }
56         
57         (*replies)++;
58 }
59
60
61 /* test UDP/138 netlogon requests */
62 static bool nbt_test_netlogon(struct torture_context *tctx)
63 {
64         struct dgram_mailslot_handler *dgmslot;
65         struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev, 
66                                                                  lp_iconv_convenience(tctx->lp_ctx));
67         struct socket_address *dest;
68         const char *myaddress;
69         struct nbt_netlogon_packet logon;
70         struct nbt_name myname;
71         NTSTATUS status;
72         struct timeval tv = timeval_current();
73         int replies = 0;
74
75         struct socket_address *socket_address;
76
77         const char *address;
78         struct nbt_name name;
79
80         struct interface *ifaces;
81         
82         name.name = lp_workgroup(tctx->lp_ctx);
83         name.type = NBT_NAME_LOGON;
84         name.scope = NULL;
85
86         /* do an initial name resolution to find its IP */
87         torture_assert_ntstatus_ok(tctx, 
88                                    resolve_name(lp_resolve_context(tctx->lp_ctx), &name, tctx, &address, tctx->ev),
89                                    talloc_asprintf(tctx, "Failed to resolve %s", name.name));
90
91         load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
92         myaddress = talloc_strdup(dgmsock, iface_best_ip(ifaces, address));
93
94
95         socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
96                                                      myaddress, lp_dgram_port(tctx->lp_ctx));
97         torture_assert(tctx, socket_address != NULL, "Error getting address");
98
99         /* try receiving replies on port 138 first, which will only
100            work if we are root and smbd/nmbd are not running - fall
101            back to listening on any port, which means replies from
102            most windows versions won't be seen */
103         status = socket_listen(dgmsock->sock, socket_address, 0, 0);
104         if (!NT_STATUS_IS_OK(status)) {
105                 talloc_free(socket_address);
106                 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
107                                                              myaddress, 0);
108                 torture_assert(tctx, socket_address != NULL, "Error getting address");
109
110                 socket_listen(dgmsock->sock, socket_address, 0, 0);
111         }
112
113         /* setup a temporary mailslot listener for replies */
114         dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
115                                       netlogon_handler, &replies);
116
117         ZERO_STRUCT(logon);
118         logon.command = LOGON_PRIMARY_QUERY;
119         logon.req.pdc.computer_name = TEST_NAME;
120         logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
121         logon.req.pdc.unicode_name  = TEST_NAME;
122         logon.req.pdc.nt_version    = 1;
123         logon.req.pdc.lmnt_token    = 0xFFFF;
124         logon.req.pdc.lm20_token    = 0xFFFF;
125
126         make_nbt_name_client(&myname, TEST_NAME);
127
128         dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
129                                            address, lp_dgram_port(tctx->lp_ctx));
130         torture_assert(tctx, dest != NULL, "Error getting address");
131
132         status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
133                                               NBT_MAILSLOT_NETLOGON, 
134                                               &myname, &logon);
135         torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
136
137         while (timeval_elapsed(&tv) < 5 && replies == 0) {
138                 event_loop_once(dgmsock->event_ctx);
139         }
140
141         return true;
142 }
143
144
145 /* test UDP/138 netlogon requests */
146 static bool nbt_test_netlogon2(struct torture_context *tctx)
147 {
148         struct dgram_mailslot_handler *dgmslot;
149         struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev,
150                                                                  lp_iconv_convenience(tctx->lp_ctx));
151         struct socket_address *dest;
152         const char *myaddress;
153         struct nbt_netlogon_packet logon;
154         struct nbt_name myname;
155         NTSTATUS status;
156         struct timeval tv = timeval_current();
157         int replies = 0;
158
159         struct socket_address *socket_address;
160
161         const char *address;
162         struct nbt_name name;
163
164         struct interface *ifaces;
165         struct test_join *join_ctx;
166         struct cli_credentials *machine_credentials;
167         const struct dom_sid *dom_sid;
168         
169         name.name = lp_workgroup(tctx->lp_ctx);
170         name.type = NBT_NAME_LOGON;
171         name.scope = NULL;
172
173         /* do an initial name resolution to find its IP */
174         torture_assert_ntstatus_ok(tctx, 
175                                    resolve_name(lp_resolve_context(tctx->lp_ctx), &name, tctx, &address, tctx->ev),
176                                    talloc_asprintf(tctx, "Failed to resolve %s", name.name));
177
178         load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
179         myaddress = talloc_strdup(dgmsock, iface_best_ip(ifaces, address));
180
181         socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
182                                                      myaddress, lp_dgram_port(tctx->lp_ctx));
183         torture_assert(tctx, socket_address != NULL, "Error getting address");
184
185         /* try receiving replies on port 138 first, which will only
186            work if we are root and smbd/nmbd are not running - fall
187            back to listening on any port, which means replies from
188            some windows versions won't be seen */
189         status = socket_listen(dgmsock->sock, socket_address, 0, 0);
190         if (!NT_STATUS_IS_OK(status)) {
191                 talloc_free(socket_address);
192                 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
193                                                              myaddress, 0);
194                 torture_assert(tctx, socket_address != NULL, "Error getting address");
195
196                 socket_listen(dgmsock->sock, socket_address, 0, 0);
197         }
198
199         /* setup a temporary mailslot listener for replies */
200         dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
201                                       netlogon_handler, &replies);
202         
203
204         ZERO_STRUCT(logon);
205         logon.command = LOGON_SAM_LOGON_REQUEST;
206         logon.req.logon.request_count = 0;
207         logon.req.logon.computer_name = TEST_NAME;
208         logon.req.logon.user_name     = "";
209         logon.req.logon.mailslot_name = dgmslot->mailslot_name;
210         logon.req.logon.nt_version    = 11;
211         logon.req.logon.lmnt_token    = 0xFFFF;
212         logon.req.logon.lm20_token    = 0xFFFF;
213
214         make_nbt_name_client(&myname, TEST_NAME);
215
216         dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
217                                            address, lp_dgram_port(tctx->lp_ctx));
218
219         torture_assert(tctx, dest != NULL, "Error getting address");
220         status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
221                                               NBT_MAILSLOT_NETLOGON, 
222                                               &myname, &logon);
223         torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
224
225         while (timeval_elapsed(&tv) < 5 && replies == 0) {
226                 event_loop_once(dgmsock->event_ctx);
227         }
228
229         ZERO_STRUCT(logon);
230         logon.command = LOGON_SAM_LOGON_REQUEST;
231         logon.req.logon.request_count = 0;
232         logon.req.logon.computer_name = TEST_NAME;
233         logon.req.logon.user_name     = TEST_NAME"$";
234         logon.req.logon.mailslot_name = dgmslot->mailslot_name;
235         logon.req.logon.nt_version    = 1;
236         logon.req.logon.lmnt_token    = 0xFFFF;
237         logon.req.logon.lm20_token    = 0xFFFF;
238
239         make_nbt_name_client(&myname, TEST_NAME);
240
241         dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
242                                            address, lp_dgram_port(tctx->lp_ctx));
243
244         torture_assert(tctx, dest != NULL, "Error getting address");
245         status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
246                                               NBT_MAILSLOT_NETLOGON, 
247                                               &myname, &logon);
248         torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
249
250         while (timeval_elapsed(&tv) < 5 && replies == 0) {
251                 event_loop_once(dgmsock->event_ctx);
252         }
253
254         join_ctx = torture_join_domain(tctx, TEST_NAME, 
255                                        ACB_WSTRUST, &machine_credentials);
256
257         dom_sid = torture_join_sid(join_ctx);
258
259         ZERO_STRUCT(logon);
260         logon.command = LOGON_SAM_LOGON_REQUEST;
261         logon.req.logon.request_count = 0;
262         logon.req.logon.computer_name = TEST_NAME;
263         logon.req.logon.user_name     = TEST_NAME"$";
264         logon.req.logon.mailslot_name = dgmslot->mailslot_name;
265         logon.req.logon.sid           = *dom_sid;
266         logon.req.logon.nt_version    = 1;
267         logon.req.logon.lmnt_token    = 0xFFFF;
268         logon.req.logon.lm20_token    = 0xFFFF;
269
270         make_nbt_name_client(&myname, TEST_NAME);
271
272         dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
273                                            address, lp_dgram_port(tctx->lp_ctx));
274
275         torture_assert(tctx, dest != NULL, "Error getting address");
276         status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
277                                               NBT_MAILSLOT_NETLOGON, 
278                                               &myname, &logon);
279         torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
280
281         while (timeval_elapsed(&tv) < 5 && replies == 0) {
282                 event_loop_once(dgmsock->event_ctx);
283         }
284
285         torture_leave_domain(join_ctx);
286         return true;
287 }
288
289
290 /* test UDP/138 ntlogon requests */
291 static bool nbt_test_ntlogon(struct torture_context *tctx)
292 {
293         struct dgram_mailslot_handler *dgmslot;
294         struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev,
295                                                                  lp_iconv_convenience(tctx->lp_ctx));
296         struct socket_address *dest;
297         struct test_join *join_ctx;
298         struct cli_credentials *machine_credentials;
299
300         const char *myaddress;
301         struct nbt_netlogon_packet logon;
302         struct nbt_name myname;
303         NTSTATUS status;
304         struct timeval tv = timeval_current();
305         int replies = 0;
306
307         struct socket_address *socket_address;
308         const char *address;
309         struct nbt_name name;
310
311         struct interface *ifaces;
312         
313         name.name = lp_workgroup(tctx->lp_ctx);
314         name.type = NBT_NAME_LOGON;
315         name.scope = NULL;
316
317         /* do an initial name resolution to find its IP */
318         torture_assert_ntstatus_ok(tctx, 
319                                    resolve_name(lp_resolve_context(tctx->lp_ctx), &name, tctx, &address, tctx->ev),
320                                    talloc_asprintf(tctx, "Failed to resolve %s", name.name));
321
322         load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
323         myaddress = talloc_strdup(dgmsock, iface_best_ip(ifaces, address));
324
325         socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
326                                                      myaddress, lp_dgram_port(tctx->lp_ctx));
327         torture_assert(tctx, socket_address != NULL, "Error getting address");
328
329         /* try receiving replies on port 138 first, which will only
330            work if we are root and smbd/nmbd are not running - fall
331            back to listening on any port, which means replies from
332            most windows versions won't be seen */
333         status = socket_listen(dgmsock->sock, socket_address, 0, 0);
334         if (!NT_STATUS_IS_OK(status)) {
335                 talloc_free(socket_address);
336                 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
337                                                              myaddress, 0);
338                 torture_assert(tctx, socket_address != NULL, "Error getting address");
339
340                 socket_listen(dgmsock->sock, socket_address, 0, 0);
341         }
342
343         join_ctx = torture_join_domain(tctx, TEST_NAME, 
344                                        ACB_WSTRUST, &machine_credentials);
345         torture_assert(tctx, join_ctx != NULL,
346                        talloc_asprintf(tctx, "Failed to join domain %s as %s\n",
347                                        lp_workgroup(tctx->lp_ctx), TEST_NAME));
348
349         /* setup a temporary mailslot listener for replies */
350         dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
351                                       netlogon_handler, &replies);
352         
353
354         ZERO_STRUCT(logon);
355         logon.command = LOGON_SAM_LOGON_REQUEST;
356         logon.req.logon.request_count = 0;
357         logon.req.logon.computer_name = TEST_NAME;
358         logon.req.logon.user_name     = TEST_NAME"$";
359         logon.req.logon.mailslot_name = dgmslot->mailslot_name;
360         logon.req.logon.acct_control  = ACB_WSTRUST;
361         /* Leave sid as all zero */
362         logon.req.logon.nt_version    = 1;
363         logon.req.logon.lmnt_token    = 0xFFFF;
364         logon.req.logon.lm20_token    = 0xFFFF;
365
366         make_nbt_name_client(&myname, TEST_NAME);
367
368         dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
369                                            address, lp_dgram_port(tctx->lp_ctx));
370         torture_assert(tctx, dest != NULL, "Error getting address");
371         status = dgram_mailslot_netlogon_send(dgmsock, 
372                                               &name, dest, 
373                                               NBT_MAILSLOT_NTLOGON, 
374                                               &myname, &logon);
375         torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
376
377         while (timeval_elapsed(&tv) < 5 && replies == 0) {
378                 event_loop_once(dgmsock->event_ctx);
379         }
380
381         ZERO_STRUCT(logon);
382         logon.command = LOGON_PRIMARY_QUERY;
383         logon.req.pdc.computer_name = TEST_NAME;
384         logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
385         logon.req.pdc.unicode_name  = TEST_NAME;
386         logon.req.pdc.nt_version    = 1;
387         logon.req.pdc.lmnt_token    = 0xFFFF;
388         logon.req.pdc.lm20_token    = 0xFFFF;
389
390         make_nbt_name_client(&myname, TEST_NAME);
391
392         dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
393                                            address, lp_dgram_port(tctx->lp_ctx));
394         torture_assert(tctx, dest != NULL, "Error getting address");
395         status = dgram_mailslot_netlogon_send(dgmsock, 
396                                               &name, dest, 
397                                               NBT_MAILSLOT_NTLOGON, 
398                                               &myname, &logon);
399         torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
400
401         while (timeval_elapsed(&tv) < 5 && replies == 0) {
402                 event_loop_once(dgmsock->event_ctx);
403         }
404
405         torture_leave_domain(join_ctx);
406         return true;
407 }
408
409
410 /*
411   test nbt dgram operations
412 */
413 struct torture_suite *torture_nbt_dgram(TALLOC_CTX *mem_ctx)
414 {
415         struct torture_suite *suite = torture_suite_create(mem_ctx, "DGRAM");
416
417         torture_suite_add_simple_test(suite, "netlogon", nbt_test_netlogon);
418         torture_suite_add_simple_test(suite, "netlogon2", nbt_test_netlogon2);
419         torture_suite_add_simple_test(suite, "ntlogon", nbt_test_ntlogon);
420
421         return suite;
422 }