2 Unix SMB/CIFS implementation.
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 3 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, see <http://www.gnu.org/licenses/>.
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"
35 #define TEST_NAME "TORTURE_TEST"
38 reply handler for netlogon request
40 static void netlogon_handler(struct dgram_mailslot_handler *dgmslot,
41 struct nbt_dgram_packet *packet,
42 struct socket_address *src)
45 struct nbt_netlogon_response netlogon;
46 int *replies = (int *)dgmslot->private;
48 printf("netlogon reply from %s:%d\n", src->addr, src->port);
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);
61 /* test UDP/138 netlogon requests */
62 static bool nbt_test_netlogon(struct torture_context *tctx)
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;
72 struct timeval tv = timeval_current();
75 struct socket_address *socket_address;
80 struct interface *ifaces;
82 name.name = lp_workgroup(tctx->lp_ctx);
83 name.type = NBT_NAME_LOGON;
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));
91 load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
92 myaddress = talloc_strdup(dgmsock, iface_best_ip(ifaces, address));
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");
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,
108 torture_assert(tctx, socket_address != NULL, "Error getting address");
110 socket_listen(dgmsock->sock, socket_address, 0, 0);
113 /* setup a temporary mailslot listener for replies */
114 dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
115 netlogon_handler, &replies);
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;
126 make_nbt_name_client(&myname, TEST_NAME);
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");
132 status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
133 NBT_MAILSLOT_NETLOGON,
135 torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
137 while (timeval_elapsed(&tv) < 5 && replies == 0) {
138 event_loop_once(dgmsock->event_ctx);
145 /* test UDP/138 netlogon requests */
146 static bool nbt_test_netlogon2(struct torture_context *tctx)
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;
156 struct timeval tv = timeval_current();
159 struct socket_address *socket_address;
162 struct nbt_name name;
164 struct interface *ifaces;
165 struct test_join *join_ctx;
166 struct cli_credentials *machine_credentials;
167 const struct dom_sid *dom_sid;
169 name.name = lp_workgroup(tctx->lp_ctx);
170 name.type = NBT_NAME_LOGON;
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));
178 load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
179 myaddress = talloc_strdup(dgmsock, iface_best_ip(ifaces, address));
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");
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,
194 torture_assert(tctx, socket_address != NULL, "Error getting address");
196 socket_listen(dgmsock->sock, socket_address, 0, 0);
199 /* setup a temporary mailslot listener for replies */
200 dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
201 netlogon_handler, &replies);
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;
214 make_nbt_name_client(&myname, TEST_NAME);
216 dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
217 address, lp_dgram_port(tctx->lp_ctx));
219 torture_assert(tctx, dest != NULL, "Error getting address");
220 status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
221 NBT_MAILSLOT_NETLOGON,
223 torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
225 while (timeval_elapsed(&tv) < 5 && replies == 0) {
226 event_loop_once(dgmsock->event_ctx);
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;
239 make_nbt_name_client(&myname, TEST_NAME);
241 dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
242 address, lp_dgram_port(tctx->lp_ctx));
244 torture_assert(tctx, dest != NULL, "Error getting address");
245 status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
246 NBT_MAILSLOT_NETLOGON,
248 torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
250 while (timeval_elapsed(&tv) < 5 && replies == 0) {
251 event_loop_once(dgmsock->event_ctx);
254 join_ctx = torture_join_domain(tctx, TEST_NAME,
255 ACB_WSTRUST, &machine_credentials);
257 dom_sid = torture_join_sid(join_ctx);
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;
270 make_nbt_name_client(&myname, TEST_NAME);
272 dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
273 address, lp_dgram_port(tctx->lp_ctx));
275 torture_assert(tctx, dest != NULL, "Error getting address");
276 status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
277 NBT_MAILSLOT_NETLOGON,
279 torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");
281 while (timeval_elapsed(&tv) < 5 && replies == 0) {
282 event_loop_once(dgmsock->event_ctx);
285 torture_leave_domain(join_ctx);
290 /* test UDP/138 ntlogon requests */
291 static bool nbt_test_ntlogon(struct torture_context *tctx)
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;
300 const char *myaddress;
301 struct nbt_netlogon_packet logon;
302 struct nbt_name myname;
304 struct timeval tv = timeval_current();
307 struct socket_address *socket_address;
309 struct nbt_name name;
311 struct interface *ifaces;
313 name.name = lp_workgroup(tctx->lp_ctx);
314 name.type = NBT_NAME_LOGON;
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));
322 load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
323 myaddress = talloc_strdup(dgmsock, iface_best_ip(ifaces, address));
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");
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,
338 torture_assert(tctx, socket_address != NULL, "Error getting address");
340 socket_listen(dgmsock->sock, socket_address, 0, 0);
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));
349 /* setup a temporary mailslot listener for replies */
350 dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
351 netlogon_handler, &replies);
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;
366 make_nbt_name_client(&myname, TEST_NAME);
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,
373 NBT_MAILSLOT_NTLOGON,
375 torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
377 while (timeval_elapsed(&tv) < 5 && replies == 0) {
378 event_loop_once(dgmsock->event_ctx);
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;
390 make_nbt_name_client(&myname, TEST_NAME);
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,
397 NBT_MAILSLOT_NTLOGON,
399 torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
401 while (timeval_elapsed(&tv) < 5 && replies == 0) {
402 event_loop_once(dgmsock->event_ctx);
405 torture_leave_domain(join_ctx);
411 test nbt dgram operations
413 struct torture_suite *torture_nbt_dgram(TALLOC_CTX *mem_ctx)
415 struct torture_suite *suite = torture_suite_create(mem_ctx, "DGRAM");
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);