Line data Source code
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 "lib/socket/socket.h"
25 : #include "lib/events/events.h"
26 : #include "torture/rpc/torture_rpc.h"
27 : #include "torture/nbt/proto.h"
28 : #include "libcli/resolve/resolve.h"
29 : #include "system/network.h"
30 : #include "lib/socket/netif.h"
31 : #include "param/param.h"
32 :
33 : #define TEST_NAME "TORTURE_TEST"
34 :
35 : /*
36 : reply handler for netlogon request
37 : */
38 42 : static void netlogon_handler(struct dgram_mailslot_handler *dgmslot,
39 : struct nbt_dgram_packet *packet,
40 : struct socket_address *src)
41 : {
42 0 : NTSTATUS status;
43 42 : struct nbt_netlogon_response *netlogon = dgmslot->private_data;
44 :
45 42 : dgmslot->private_data = netlogon = talloc(dgmslot, struct nbt_netlogon_response);
46 :
47 42 : if (!dgmslot->private_data) {
48 0 : return;
49 : }
50 :
51 42 : printf("netlogon reply from %s:%d\n", src->addr, src->port);
52 :
53 : /* Fills in the netlogon pointer */
54 42 : status = dgram_mailslot_netlogon_parse_response(netlogon, packet,
55 : netlogon);
56 42 : if (!NT_STATUS_IS_OK(status)) {
57 0 : printf("Failed to parse netlogon packet from %s:%d\n",
58 : src->addr, src->port);
59 0 : return;
60 : }
61 :
62 : }
63 :
64 :
65 : /* test UDP/138 netlogon requests */
66 5 : static bool nbt_test_netlogon(struct torture_context *tctx)
67 : {
68 0 : struct dgram_mailslot_handler *dgmslot;
69 5 : struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev);
70 0 : struct socket_address *dest;
71 0 : const char *myaddress;
72 0 : struct nbt_netlogon_packet logon;
73 0 : struct nbt_netlogon_response *response;
74 0 : struct nbt_name myname;
75 0 : NTSTATUS status;
76 5 : struct timeval tv = timeval_current();
77 :
78 0 : struct socket_address *socket_address;
79 :
80 0 : const char *address;
81 0 : struct nbt_name name;
82 :
83 0 : struct interface *ifaces;
84 :
85 5 : name.name = lpcfg_workgroup(tctx->lp_ctx);
86 5 : name.type = NBT_NAME_LOGON;
87 5 : name.scope = NULL;
88 :
89 : /* do an initial name resolution to find its IP */
90 5 : torture_assert_ntstatus_ok(tctx,
91 : resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
92 : 0, 0,
93 : &name, tctx, &address, tctx->ev),
94 : talloc_asprintf(tctx, "Failed to resolve %s", name.name));
95 :
96 5 : load_interface_list(tctx, tctx->lp_ctx, &ifaces);
97 5 : myaddress = talloc_strdup(dgmsock, iface_list_best_ip(ifaces, address));
98 :
99 :
100 5 : socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
101 : myaddress, lpcfg_dgram_port(tctx->lp_ctx));
102 5 : torture_assert(tctx, socket_address != NULL, "Error getting address");
103 :
104 : /* try receiving replies on port 138 first, which will only
105 : work if we are root and smbd/nmbd are not running - fall
106 : back to listening on any port, which means replies from
107 : most windows versions won't be seen */
108 5 : status = socket_listen(dgmsock->sock, socket_address, 0, 0);
109 5 : if (!NT_STATUS_IS_OK(status)) {
110 0 : talloc_free(socket_address);
111 0 : socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
112 : myaddress, 0);
113 0 : torture_assert(tctx, socket_address != NULL, "Error getting address");
114 :
115 0 : socket_listen(dgmsock->sock, socket_address, 0, 0);
116 : }
117 :
118 : /* setup a temporary mailslot listener for replies */
119 5 : dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
120 : netlogon_handler, NULL);
121 5 : torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");
122 :
123 5 : ZERO_STRUCT(logon);
124 5 : logon.command = LOGON_PRIMARY_QUERY;
125 5 : logon.req.pdc.computer_name = TEST_NAME;
126 5 : logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
127 5 : logon.req.pdc.unicode_name = TEST_NAME;
128 5 : logon.req.pdc.nt_version = 1;
129 5 : logon.req.pdc.lmnt_token = 0xFFFF;
130 5 : logon.req.pdc.lm20_token = 0xFFFF;
131 :
132 5 : make_nbt_name_client(&myname, TEST_NAME);
133 :
134 5 : dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
135 : address, lpcfg_dgram_port(tctx->lp_ctx));
136 5 : torture_assert(tctx, dest != NULL, "Error getting address");
137 :
138 5 : status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
139 : NBT_MAILSLOT_NETLOGON,
140 : &myname, &logon);
141 5 : torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
142 :
143 15 : while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) {
144 10 : tevent_loop_once(dgmsock->event_ctx);
145 : }
146 :
147 5 : response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);
148 :
149 5 : torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
150 :
151 5 : torture_assert(tctx, response->response_type == NETLOGON_GET_PDC, "Got incorrect type of netlogon response");
152 5 : torture_assert(tctx, response->data.get_pdc.command == NETLOGON_RESPONSE_FROM_PDC, "Got incorrect netlogon response command");
153 :
154 5 : return true;
155 : }
156 :
157 :
158 : /* test UDP/138 netlogon requests */
159 5 : static bool nbt_test_netlogon2(struct torture_context *tctx)
160 : {
161 0 : struct dgram_mailslot_handler *dgmslot;
162 5 : struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev);
163 0 : struct socket_address *dest;
164 0 : const char *myaddress;
165 0 : struct nbt_netlogon_packet logon;
166 0 : struct nbt_netlogon_response *response;
167 0 : struct nbt_name myname;
168 0 : NTSTATUS status;
169 5 : struct timeval tv = timeval_current();
170 :
171 0 : struct socket_address *socket_address;
172 :
173 0 : const char *address;
174 0 : struct nbt_name name;
175 :
176 0 : struct interface *ifaces;
177 0 : struct test_join *join_ctx;
178 0 : struct cli_credentials *machine_credentials;
179 0 : const struct dom_sid *dom_sid;
180 :
181 5 : name.name = lpcfg_workgroup(tctx->lp_ctx);
182 5 : name.type = NBT_NAME_LOGON;
183 5 : name.scope = NULL;
184 :
185 : /* do an initial name resolution to find its IP */
186 5 : torture_assert_ntstatus_ok(tctx,
187 : resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
188 : 0, 0,
189 : &name, tctx, &address, tctx->ev),
190 : talloc_asprintf(tctx, "Failed to resolve %s", name.name));
191 :
192 5 : load_interface_list(tctx, tctx->lp_ctx, &ifaces);
193 5 : myaddress = talloc_strdup(dgmsock, iface_list_best_ip(ifaces, address));
194 :
195 5 : socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
196 : myaddress, lpcfg_dgram_port(tctx->lp_ctx));
197 5 : torture_assert(tctx, socket_address != NULL, "Error getting address");
198 :
199 : /* try receiving replies on port 138 first, which will only
200 : work if we are root and smbd/nmbd are not running - fall
201 : back to listening on any port, which means replies from
202 : some windows versions won't be seen */
203 5 : status = socket_listen(dgmsock->sock, socket_address, 0, 0);
204 5 : if (!NT_STATUS_IS_OK(status)) {
205 0 : talloc_free(socket_address);
206 0 : socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
207 : myaddress, 0);
208 0 : torture_assert(tctx, socket_address != NULL, "Error getting address");
209 :
210 0 : socket_listen(dgmsock->sock, socket_address, 0, 0);
211 : }
212 :
213 : /* setup a temporary mailslot listener for replies */
214 5 : dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
215 : netlogon_handler, NULL);
216 5 : torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");
217 :
218 5 : ZERO_STRUCT(logon);
219 5 : logon.command = LOGON_SAM_LOGON_REQUEST;
220 5 : logon.req.logon.request_count = 0;
221 5 : logon.req.logon.computer_name = TEST_NAME;
222 5 : logon.req.logon.user_name = "";
223 5 : logon.req.logon.mailslot_name = dgmslot->mailslot_name;
224 5 : logon.req.logon.nt_version = NETLOGON_NT_VERSION_5EX_WITH_IP|NETLOGON_NT_VERSION_5|NETLOGON_NT_VERSION_1;
225 5 : logon.req.logon.lmnt_token = 0xFFFF;
226 5 : logon.req.logon.lm20_token = 0xFFFF;
227 :
228 5 : make_nbt_name_client(&myname, TEST_NAME);
229 :
230 5 : dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
231 : address, lpcfg_dgram_port(tctx->lp_ctx));
232 :
233 5 : torture_assert(tctx, dest != NULL, "Error getting address");
234 5 : status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
235 : NBT_MAILSLOT_NETLOGON,
236 : &myname, &logon);
237 5 : torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
238 :
239 15 : while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
240 10 : tevent_loop_once(dgmsock->event_ctx);
241 : }
242 :
243 5 : response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);
244 :
245 5 : torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
246 :
247 5 : torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
248 5 : map_netlogon_samlogon_response(&response->data.samlogon);
249 :
250 5 : torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX, "Got incorrect netlogon response command");
251 :
252 3 : torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.nt_version, NETLOGON_NT_VERSION_5EX_WITH_IP|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_1, "Got incorrect netlogon response command");
253 :
254 3 : torture_assert(tctx,
255 : strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") == NULL,
256 : "PDC name should not be in UNC form");
257 :
258 : /* setup (another) temporary mailslot listener for replies */
259 3 : dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
260 : netlogon_handler, NULL);
261 3 : torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");
262 :
263 3 : ZERO_STRUCT(logon);
264 3 : logon.command = LOGON_SAM_LOGON_REQUEST;
265 3 : logon.req.logon.request_count = 0;
266 3 : logon.req.logon.computer_name = TEST_NAME;
267 3 : logon.req.logon.user_name = TEST_NAME"$";
268 3 : logon.req.logon.mailslot_name = dgmslot->mailslot_name;
269 3 : logon.req.logon.nt_version = 1;
270 3 : logon.req.logon.lmnt_token = 0xFFFF;
271 3 : logon.req.logon.lm20_token = 0xFFFF;
272 :
273 3 : make_nbt_name_client(&myname, TEST_NAME);
274 :
275 3 : dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
276 : address, lpcfg_dgram_port(tctx->lp_ctx));
277 :
278 3 : torture_assert(tctx, dest != NULL, "Error getting address");
279 3 : status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
280 : NBT_MAILSLOT_NETLOGON,
281 : &myname, &logon);
282 3 : torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
283 :
284 9 : while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
285 6 : tevent_loop_once(dgmsock->event_ctx);
286 : }
287 :
288 3 : response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);
289 :
290 3 : torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
291 :
292 3 : torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
293 3 : map_netlogon_samlogon_response(&response->data.samlogon);
294 :
295 3 : torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
296 :
297 3 : torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
298 :
299 3 : torture_assert(tctx,
300 : strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
301 : "PDC name should be in UNC form");
302 :
303 3 : join_ctx = torture_join_domain(tctx, TEST_NAME,
304 : ACB_WSTRUST, &machine_credentials);
305 :
306 3 : torture_assert(tctx, join_ctx != NULL,
307 : talloc_asprintf(tctx, "Failed to join domain %s as %s\n",
308 : lpcfg_workgroup(tctx->lp_ctx), TEST_NAME));
309 :
310 3 : dom_sid = torture_join_sid(join_ctx);
311 :
312 : /* setup (another) temporary mailslot listener for replies */
313 3 : dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
314 : netlogon_handler, NULL);
315 3 : torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");
316 :
317 3 : ZERO_STRUCT(logon);
318 3 : logon.command = LOGON_SAM_LOGON_REQUEST;
319 3 : logon.req.logon.request_count = 0;
320 3 : logon.req.logon.computer_name = TEST_NAME;
321 3 : logon.req.logon.user_name = TEST_NAME"$";
322 3 : logon.req.logon.mailslot_name = dgmslot->mailslot_name;
323 3 : logon.req.logon.sid = *dom_sid;
324 3 : logon.req.logon.nt_version = 1;
325 3 : logon.req.logon.lmnt_token = 0xFFFF;
326 3 : logon.req.logon.lm20_token = 0xFFFF;
327 :
328 3 : make_nbt_name_client(&myname, TEST_NAME);
329 :
330 3 : dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
331 : address, lpcfg_dgram_port(tctx->lp_ctx));
332 :
333 3 : torture_assert(tctx, dest != NULL, "Error getting address");
334 3 : status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
335 : NBT_MAILSLOT_NETLOGON,
336 : &myname, &logon);
337 3 : torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
338 :
339 :
340 9 : while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
341 6 : tevent_loop_once(dgmsock->event_ctx);
342 : }
343 :
344 3 : response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);
345 :
346 3 : torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
347 :
348 3 : torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
349 3 : map_netlogon_samlogon_response(&response->data.samlogon);
350 :
351 3 : torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
352 :
353 3 : torture_assert(tctx,
354 : strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
355 : "PDC name should be in UNC form");
356 :
357 : /* setup (another) temporary mailslot listener for replies */
358 3 : dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
359 : netlogon_handler, NULL);
360 3 : torture_assert(tctx, dgmslot != NULL, "Error getting a Mailslot for GetDC reply");
361 :
362 3 : ZERO_STRUCT(logon);
363 3 : logon.command = LOGON_SAM_LOGON_REQUEST;
364 3 : logon.req.logon.request_count = 0;
365 3 : logon.req.logon.computer_name = TEST_NAME;
366 3 : logon.req.logon.user_name = TEST_NAME"$";
367 3 : logon.req.logon.mailslot_name = dgmslot->mailslot_name;
368 3 : logon.req.logon.sid = *dom_sid;
369 3 : logon.req.logon.acct_control = ACB_WSTRUST;
370 3 : logon.req.logon.nt_version = 1;
371 3 : logon.req.logon.lmnt_token = 0xFFFF;
372 3 : logon.req.logon.lm20_token = 0xFFFF;
373 :
374 3 : make_nbt_name_client(&myname, TEST_NAME);
375 :
376 3 : dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
377 : address, lpcfg_dgram_port(tctx->lp_ctx));
378 :
379 3 : torture_assert(tctx, dest != NULL, "Error getting address");
380 3 : status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
381 : NBT_MAILSLOT_NETLOGON,
382 : &myname, &logon);
383 3 : torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
384 :
385 :
386 9 : while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
387 6 : tevent_loop_once(dgmsock->event_ctx);
388 : }
389 :
390 3 : response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);
391 :
392 3 : torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
393 :
394 3 : torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
395 3 : map_netlogon_samlogon_response(&response->data.samlogon);
396 :
397 3 : torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
398 :
399 3 : torture_assert(tctx,
400 : strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
401 : "PDC name should be in UNC form");
402 :
403 3 : dgmslot->private_data = NULL;
404 :
405 3 : ZERO_STRUCT(logon);
406 3 : logon.command = LOGON_SAM_LOGON_REQUEST;
407 3 : logon.req.logon.request_count = 0;
408 3 : logon.req.logon.computer_name = TEST_NAME;
409 3 : logon.req.logon.user_name = TEST_NAME"$";
410 3 : logon.req.logon.mailslot_name = dgmslot->mailslot_name;
411 3 : logon.req.logon.sid = *dom_sid;
412 3 : logon.req.logon.acct_control = ACB_NORMAL;
413 3 : logon.req.logon.nt_version = 1;
414 3 : logon.req.logon.lmnt_token = 0xFFFF;
415 3 : logon.req.logon.lm20_token = 0xFFFF;
416 :
417 3 : make_nbt_name_client(&myname, TEST_NAME);
418 :
419 3 : dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
420 : address, lpcfg_dgram_port(tctx->lp_ctx));
421 :
422 3 : torture_assert(tctx, dest != NULL, "Error getting address");
423 3 : status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
424 : NBT_MAILSLOT_NETLOGON,
425 : &myname, &logon);
426 3 : torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
427 :
428 :
429 9 : while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
430 6 : tevent_loop_once(dgmsock->event_ctx);
431 : }
432 :
433 3 : response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);
434 :
435 3 : torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
436 :
437 3 : torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
438 3 : map_netlogon_samlogon_response(&response->data.samlogon);
439 :
440 3 : torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
441 :
442 3 : torture_assert(tctx,
443 : strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
444 : "PDC name should be in UNC form");
445 :
446 3 : torture_leave_domain(tctx, join_ctx);
447 3 : return true;
448 : }
449 :
450 :
451 : /* test UDP/138 ntlogon requests */
452 5 : static bool nbt_test_ntlogon(struct torture_context *tctx)
453 : {
454 0 : struct dgram_mailslot_handler *dgmslot;
455 5 : struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev);
456 0 : struct socket_address *dest;
457 0 : struct test_join *join_ctx;
458 0 : const struct dom_sid *dom_sid;
459 0 : struct cli_credentials *machine_credentials;
460 :
461 0 : const char *myaddress;
462 0 : struct nbt_netlogon_packet logon;
463 0 : struct nbt_netlogon_response *response;
464 0 : struct nbt_name myname;
465 0 : NTSTATUS status;
466 5 : struct timeval tv = timeval_current();
467 :
468 0 : struct socket_address *socket_address;
469 0 : const char *address;
470 0 : struct nbt_name name;
471 :
472 0 : struct interface *ifaces;
473 :
474 5 : name.name = lpcfg_workgroup(tctx->lp_ctx);
475 5 : name.type = NBT_NAME_LOGON;
476 5 : name.scope = NULL;
477 :
478 : /* do an initial name resolution to find its IP */
479 5 : torture_assert_ntstatus_ok(tctx,
480 : resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
481 : 0, 0, &name, tctx, &address, tctx->ev),
482 : talloc_asprintf(tctx, "Failed to resolve %s", name.name));
483 :
484 5 : load_interface_list(tctx, tctx->lp_ctx, &ifaces);
485 5 : myaddress = talloc_strdup(dgmsock, iface_list_best_ip(ifaces, address));
486 :
487 5 : socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
488 : myaddress, lpcfg_dgram_port(tctx->lp_ctx));
489 5 : torture_assert(tctx, socket_address != NULL, "Error getting address");
490 :
491 : /* try receiving replies on port 138 first, which will only
492 : work if we are root and smbd/nmbd are not running - fall
493 : back to listening on any port, which means replies from
494 : most windows versions won't be seen */
495 5 : status = socket_listen(dgmsock->sock, socket_address, 0, 0);
496 5 : if (!NT_STATUS_IS_OK(status)) {
497 0 : talloc_free(socket_address);
498 0 : socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
499 : myaddress, 0);
500 0 : torture_assert(tctx, socket_address != NULL, "Error getting address");
501 :
502 0 : socket_listen(dgmsock->sock, socket_address, 0, 0);
503 : }
504 :
505 5 : join_ctx = torture_join_domain(tctx, TEST_NAME,
506 : ACB_WSTRUST, &machine_credentials);
507 :
508 5 : torture_assert(tctx, join_ctx != NULL,
509 : talloc_asprintf(tctx, "Failed to join domain %s as %s\n",
510 : lpcfg_workgroup(tctx->lp_ctx), TEST_NAME));
511 5 : dom_sid = torture_join_sid(join_ctx);
512 :
513 : /* setup a temporary mailslot listener for replies */
514 5 : dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
515 : netlogon_handler, NULL);
516 5 : torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");
517 :
518 5 : ZERO_STRUCT(logon);
519 5 : logon.command = LOGON_SAM_LOGON_REQUEST;
520 5 : logon.req.logon.request_count = 0;
521 5 : logon.req.logon.computer_name = TEST_NAME;
522 5 : logon.req.logon.user_name = TEST_NAME"$";
523 5 : logon.req.logon.mailslot_name = dgmslot->mailslot_name;
524 5 : logon.req.logon.acct_control = ACB_WSTRUST;
525 : /* Try with a SID this time */
526 5 : logon.req.logon.sid = *dom_sid;
527 5 : logon.req.logon.nt_version = 1;
528 5 : logon.req.logon.lmnt_token = 0xFFFF;
529 5 : logon.req.logon.lm20_token = 0xFFFF;
530 :
531 5 : make_nbt_name_client(&myname, TEST_NAME);
532 :
533 5 : dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
534 : address, lpcfg_dgram_port(tctx->lp_ctx));
535 5 : torture_assert(tctx, dest != NULL, "Error getting address");
536 5 : status = dgram_mailslot_netlogon_send(dgmsock,
537 : &name, dest,
538 : NBT_MAILSLOT_NTLOGON,
539 : &myname, &logon);
540 5 : torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
541 :
542 15 : while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
543 10 : tevent_loop_once(dgmsock->event_ctx);
544 : }
545 :
546 5 : response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);
547 :
548 5 : torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
549 :
550 5 : torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
551 5 : map_netlogon_samlogon_response(&response->data.samlogon);
552 :
553 5 : torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
554 :
555 5 : torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
556 :
557 5 : torture_assert(tctx,
558 : strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
559 : "PDC name should be in UNC form");
560 :
561 : /* setup a temporary mailslot listener for replies */
562 5 : dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
563 : netlogon_handler, NULL);
564 5 : torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");
565 :
566 5 : ZERO_STRUCT(logon);
567 5 : logon.command = LOGON_SAM_LOGON_REQUEST;
568 5 : logon.req.logon.request_count = 0;
569 5 : logon.req.logon.computer_name = TEST_NAME;
570 5 : logon.req.logon.user_name = TEST_NAME"$";
571 5 : logon.req.logon.mailslot_name = dgmslot->mailslot_name;
572 5 : logon.req.logon.acct_control = ACB_WSTRUST;
573 : /* Leave sid as all zero */
574 5 : logon.req.logon.nt_version = 1;
575 5 : logon.req.logon.lmnt_token = 0xFFFF;
576 5 : logon.req.logon.lm20_token = 0xFFFF;
577 :
578 5 : make_nbt_name_client(&myname, TEST_NAME);
579 :
580 5 : dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
581 : address, lpcfg_dgram_port(tctx->lp_ctx));
582 5 : torture_assert(tctx, dest != NULL, "Error getting address");
583 5 : status = dgram_mailslot_netlogon_send(dgmsock,
584 : &name, dest,
585 : NBT_MAILSLOT_NTLOGON,
586 : &myname, &logon);
587 5 : torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
588 :
589 15 : while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
590 10 : tevent_loop_once(dgmsock->event_ctx);
591 : }
592 :
593 5 : response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);
594 :
595 5 : torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
596 :
597 5 : torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
598 5 : map_netlogon_samlogon_response(&response->data.samlogon);
599 :
600 5 : torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
601 :
602 5 : torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
603 :
604 5 : torture_assert(tctx,
605 : strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
606 : "PDC name should be in UNC form");
607 :
608 : /* setup (another) temporary mailslot listener for replies */
609 5 : dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
610 : netlogon_handler, NULL);
611 5 : torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");
612 :
613 5 : ZERO_STRUCT(logon);
614 5 : logon.command = LOGON_PRIMARY_QUERY;
615 5 : logon.req.pdc.computer_name = TEST_NAME;
616 5 : logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
617 5 : logon.req.pdc.unicode_name = TEST_NAME;
618 5 : logon.req.pdc.nt_version = 1;
619 5 : logon.req.pdc.lmnt_token = 0xFFFF;
620 5 : logon.req.pdc.lm20_token = 0xFFFF;
621 :
622 5 : make_nbt_name_client(&myname, TEST_NAME);
623 :
624 5 : dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
625 : address, lpcfg_dgram_port(tctx->lp_ctx));
626 5 : torture_assert(tctx, dest != NULL, "Error getting address");
627 5 : status = dgram_mailslot_netlogon_send(dgmsock,
628 : &name, dest,
629 : NBT_MAILSLOT_NTLOGON,
630 : &myname, &logon);
631 5 : torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
632 :
633 15 : while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) {
634 10 : tevent_loop_once(dgmsock->event_ctx);
635 : }
636 :
637 5 : response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);
638 :
639 5 : torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
640 :
641 5 : torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response");
642 5 : torture_assert_int_equal(tctx, response->data.get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");
643 :
644 5 : torture_leave_domain(tctx, join_ctx);
645 :
646 : /* setup (another) temporary mailslot listener for replies */
647 5 : dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
648 : netlogon_handler, NULL);
649 5 : torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");
650 :
651 5 : ZERO_STRUCT(logon);
652 5 : logon.command = LOGON_PRIMARY_QUERY;
653 5 : logon.req.pdc.computer_name = TEST_NAME;
654 5 : logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
655 5 : logon.req.pdc.unicode_name = TEST_NAME;
656 5 : logon.req.pdc.nt_version = 1;
657 5 : logon.req.pdc.lmnt_token = 0xFFFF;
658 5 : logon.req.pdc.lm20_token = 0xFFFF;
659 :
660 5 : make_nbt_name_client(&myname, TEST_NAME);
661 :
662 5 : dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
663 : address, lpcfg_dgram_port(tctx->lp_ctx));
664 5 : torture_assert(tctx, dest != NULL, "Error getting address");
665 5 : status = dgram_mailslot_netlogon_send(dgmsock,
666 : &name, dest,
667 : NBT_MAILSLOT_NTLOGON,
668 : &myname, &logon);
669 5 : torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
670 :
671 15 : while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) {
672 10 : tevent_loop_once(dgmsock->event_ctx);
673 : }
674 :
675 5 : response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);
676 :
677 5 : torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
678 :
679 5 : torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response");
680 5 : torture_assert_int_equal(tctx, response->data.get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");
681 :
682 :
683 5 : return true;
684 : }
685 :
686 :
687 : /*
688 : test nbt dgram operations
689 : */
690 2354 : struct torture_suite *torture_nbt_dgram(TALLOC_CTX *mem_ctx)
691 : {
692 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "dgram");
693 :
694 2354 : torture_suite_add_simple_test(suite, "netlogon", nbt_test_netlogon);
695 2354 : torture_suite_add_simple_test(suite, "netlogon2", nbt_test_netlogon2);
696 2354 : torture_suite_add_simple_test(suite, "ntlogon", nbt_test_ntlogon);
697 :
698 2354 : return suite;
699 : }
|