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 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/dgram/libdgram.h"
25 #include "librpc/gen_ndr/samr.h"
26 #include "librpc/gen_ndr/ndr_nbt.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "lib/socket/socket.h"
29 #include "lib/events/events.h"
30 #include "torture/rpc/rpc.h"
31 #include "libcli/resolve/resolve.h"
32 #include "system/network.h"
33 #include "netif/netif.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_packet netlogon;
46 int *replies = dgmslot->private;
48 printf("netlogon reply from %s:%d\n", src->addr, src->port);
50 status = dgram_mailslot_netlogon_parse(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);
57 NDR_PRINT_DEBUG(nbt_netlogon_packet, &netlogon);
63 /* test UDP/138 netlogon requests */
64 static BOOL nbt_test_netlogon(TALLOC_CTX *mem_ctx,
65 struct nbt_name name, const char *address)
67 struct dgram_mailslot_handler *dgmslot;
68 struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL);
69 struct socket_address *dest;
70 const char *myaddress = talloc_strdup(dgmsock, iface_best_ip(address));
71 struct nbt_netlogon_packet logon;
72 struct nbt_name myname;
74 struct timeval tv = timeval_current();
77 struct socket_address *socket_address;
79 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
80 myaddress, lp_dgram_port());
81 if (!socket_address) {
85 /* try receiving replies on port 138 first, which will only
86 work if we are root and smbd/nmbd are not running - fall
87 back to listening on any port, which means replies from
88 some windows versions won't be seen */
89 status = socket_listen(dgmsock->sock, socket_address, 0, 0);
90 if (!NT_STATUS_IS_OK(status)) {
91 talloc_free(socket_address);
92 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
94 if (!socket_address) {
98 socket_listen(dgmsock->sock, socket_address, 0, 0);
101 /* setup a temporary mailslot listener for replies */
102 dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
103 netlogon_handler, &replies);
106 logon.command = NETLOGON_QUERY_FOR_PDC;
107 logon.req.pdc.computer_name = TEST_NAME;
108 logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
109 logon.req.pdc.unicode_name = TEST_NAME;
110 logon.req.pdc.nt_version = 1;
111 logon.req.pdc.lmnt_token = 0xFFFF;
112 logon.req.pdc.lm20_token = 0xFFFF;
114 make_nbt_name_client(&myname, TEST_NAME);
116 dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
122 status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
124 if (!NT_STATUS_IS_OK(status)) {
125 printf("Failed to send netlogon request - %s\n", nt_errstr(status));
129 while (timeval_elapsed(&tv) < 5 && replies == 0) {
130 event_loop_once(dgmsock->event_ctx);
133 talloc_free(dgmsock);
137 talloc_free(dgmsock);
142 /* test UDP/138 netlogon requests */
143 static BOOL nbt_test_netlogon2(TALLOC_CTX *mem_ctx,
144 struct nbt_name name, const char *address)
146 struct dgram_mailslot_handler *dgmslot;
147 struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL);
148 struct socket_address *dest;
149 const char *myaddress = talloc_strdup(dgmsock, iface_best_ip(address));
150 struct nbt_netlogon_packet logon;
151 struct nbt_name myname;
153 struct timeval tv = timeval_current();
156 struct socket_address *socket_address;
158 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
159 myaddress, lp_dgram_port());
160 if (!socket_address) {
164 /* try receiving replies on port 138 first, which will only
165 work if we are root and smbd/nmbd are not running - fall
166 back to listening on any port, which means replies from
167 some windows versions won't be seen */
168 status = socket_listen(dgmsock->sock, socket_address, 0, 0);
169 if (!NT_STATUS_IS_OK(status)) {
170 talloc_free(socket_address);
171 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
173 if (!socket_address) {
177 socket_listen(dgmsock->sock, socket_address, 0, 0);
180 /* setup a temporary mailslot listener for replies */
181 dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
182 netlogon_handler, &replies);
186 logon.command = NETLOGON_QUERY_FOR_PDC2;
187 logon.req.pdc2.request_count = 0;
188 logon.req.pdc2.computer_name = TEST_NAME;
189 logon.req.pdc2.user_name = "";
190 logon.req.pdc2.mailslot_name = dgmslot->mailslot_name;
191 logon.req.pdc2.nt_version = 11;
192 logon.req.pdc2.lmnt_token = 0xFFFF;
193 logon.req.pdc2.lm20_token = 0xFFFF;
195 make_nbt_name_client(&myname, TEST_NAME);
197 dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
202 status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
204 if (!NT_STATUS_IS_OK(status)) {
205 printf("Failed to send netlogon request - %s\n", nt_errstr(status));
210 while (timeval_elapsed(&tv) < 5 && replies == 0) {
211 event_loop_once(dgmsock->event_ctx);
214 talloc_free(dgmsock);
218 talloc_free(dgmsock);
224 reply handler for ntlogon request
226 static void ntlogon_handler(struct dgram_mailslot_handler *dgmslot,
227 struct nbt_dgram_packet *packet,
228 struct socket_address *src)
231 struct nbt_ntlogon_packet ntlogon;
232 int *replies = dgmslot->private;
234 printf("ntlogon reply from %s:%d\n", src->addr, src->port);
236 status = dgram_mailslot_ntlogon_parse(dgmslot, dgmslot, packet, &ntlogon);
237 if (!NT_STATUS_IS_OK(status)) {
238 printf("Failed to parse ntlogon packet from %s:%d\n",
239 src->addr, src->port);
243 NDR_PRINT_DEBUG(nbt_ntlogon_packet, &ntlogon);
249 /* test UDP/138 ntlogon requests */
250 static BOOL nbt_test_ntlogon(TALLOC_CTX *mem_ctx,
251 struct nbt_name name, const char *address)
253 struct dgram_mailslot_handler *dgmslot;
254 struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL);
255 struct socket_address *dest;
256 struct test_join *join_ctx;
257 struct cli_credentials *machine_credentials;
258 const struct dom_sid *dom_sid;
260 const char *myaddress = talloc_strdup(dgmsock, iface_best_ip(address));
261 struct nbt_ntlogon_packet logon;
262 struct nbt_name myname;
264 struct timeval tv = timeval_current();
267 struct socket_address *socket_address;
269 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
270 myaddress, lp_dgram_port());
271 if (!socket_address) {
275 /* try receiving replies on port 138 first, which will only
276 work if we are root and smbd/nmbd are not running - fall
277 back to listening on any port, which means replies from
278 some windows versions won't be seen */
279 status = socket_listen(dgmsock->sock, socket_address, 0, 0);
280 if (!NT_STATUS_IS_OK(status)) {
281 talloc_free(socket_address);
282 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
284 if (!socket_address) {
288 socket_listen(dgmsock->sock, socket_address, 0, 0);
291 join_ctx = torture_join_domain(TEST_NAME,
292 ACB_WSTRUST, &machine_credentials);
293 if (join_ctx == NULL) {
294 printf("Failed to join domain %s as %s\n", lp_workgroup(), TEST_NAME);
295 talloc_free(dgmsock);
299 dom_sid = torture_join_sid(join_ctx);
301 /* setup a temporary mailslot listener for replies */
302 dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
303 ntlogon_handler, &replies);
307 logon.command = NTLOGON_SAM_LOGON;
308 logon.req.logon.request_count = 0;
309 logon.req.logon.computer_name = TEST_NAME;
310 logon.req.logon.user_name = TEST_NAME"$";
311 logon.req.logon.mailslot_name = dgmslot->mailslot_name;
312 logon.req.logon.acct_control = ACB_WSTRUST;
313 logon.req.logon.sid = *dom_sid;
314 logon.req.logon.nt_version = 1;
315 logon.req.logon.lmnt_token = 0xFFFF;
316 logon.req.logon.lm20_token = 0xFFFF;
318 make_nbt_name_client(&myname, TEST_NAME);
320 dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
325 status = dgram_mailslot_ntlogon_send(dgmsock, DGRAM_DIRECT_UNIQUE,
326 &name, dest, &myname, &logon);
327 if (!NT_STATUS_IS_OK(status)) {
328 printf("Failed to send ntlogon request - %s\n", nt_errstr(status));
333 while (timeval_elapsed(&tv) < 5 && replies == 0) {
334 event_loop_once(dgmsock->event_ctx);
337 torture_leave_domain(join_ctx);
338 talloc_free(dgmsock);
342 torture_leave_domain(join_ctx);
343 talloc_free(dgmsock);
349 test nbt dgram operations
351 BOOL torture_nbt_dgram(struct torture_context *torture)
354 struct nbt_name name;
355 TALLOC_CTX *mem_ctx = talloc_new(NULL);
359 name.name = lp_workgroup();
360 name.type = NBT_NAME_LOGON;
363 /* do an initial name resolution to find its IP */
364 status = resolve_name(&name, mem_ctx, &address, event_context_find(mem_ctx));
365 if (!NT_STATUS_IS_OK(status)) {
366 printf("Failed to resolve %s - %s\n",
367 name.name, nt_errstr(status));
368 talloc_free(mem_ctx);
372 ret &= nbt_test_netlogon(mem_ctx, name, address);
373 ret &= nbt_test_netlogon2(mem_ctx, name, address);
374 ret &= nbt_test_ntlogon(mem_ctx, name, address);
376 talloc_free(mem_ctx);