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/ndr_samr.h"
26 #include "lib/socket/socket.h"
27 #include "lib/events/events.h"
28 #include "torture/rpc/proto.h"
29 #include "libcli/resolve/resolve.h"
30 #include "system/network.h"
31 #include "netif/netif.h"
33 #define TEST_NAME "TORTURE_TEST"
36 reply handler for netlogon request
38 static void netlogon_handler(struct dgram_mailslot_handler *dgmslot,
39 struct nbt_dgram_packet *packet,
40 struct socket_address *src)
43 struct nbt_netlogon_packet netlogon;
44 int *replies = dgmslot->private;
46 printf("netlogon reply from %s:%d\n", src->addr, src->port);
48 status = dgram_mailslot_netlogon_parse(dgmslot, dgmslot, packet, &netlogon);
49 if (!NT_STATUS_IS_OK(status)) {
50 printf("Failed to parse netlogon packet from %s:%d\n",
51 src->addr, src->port);
55 NDR_PRINT_DEBUG(nbt_netlogon_packet, &netlogon);
61 /* test UDP/138 netlogon requests */
62 static BOOL nbt_test_netlogon(TALLOC_CTX *mem_ctx,
63 struct nbt_name name, const char *address)
65 struct dgram_mailslot_handler *dgmslot;
66 struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL);
67 struct socket_address *dest;
68 const char *myaddress = talloc_strdup(dgmsock, iface_best_ip(address));
69 struct nbt_netlogon_packet logon;
70 struct nbt_name myname;
72 struct timeval tv = timeval_current();
75 struct socket_address *socket_address;
77 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
78 myaddress, lp_dgram_port());
79 if (!socket_address) {
83 /* try receiving replies on port 138 first, which will only
84 work if we are root and smbd/nmbd are not running - fall
85 back to listening on any port, which means replies from
86 some windows versions won't be seen */
87 status = socket_listen(dgmsock->sock, socket_address, 0, 0);
88 if (!NT_STATUS_IS_OK(status)) {
89 talloc_free(socket_address);
90 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
92 if (!socket_address) {
96 socket_listen(dgmsock->sock, socket_address, 0, 0);
99 /* setup a temporary mailslot listener for replies */
100 dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
101 netlogon_handler, &replies);
104 logon.command = NETLOGON_QUERY_FOR_PDC;
105 logon.req.pdc.computer_name = TEST_NAME;
106 logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
107 logon.req.pdc.unicode_name = TEST_NAME;
108 logon.req.pdc.nt_version = 1;
109 logon.req.pdc.lmnt_token = 0xFFFF;
110 logon.req.pdc.lm20_token = 0xFFFF;
112 make_nbt_name_client(&myname, TEST_NAME);
114 dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
120 status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
122 if (!NT_STATUS_IS_OK(status)) {
123 printf("Failed to send netlogon request - %s\n", nt_errstr(status));
127 while (timeval_elapsed(&tv) < 5 && replies == 0) {
128 event_loop_once(dgmsock->event_ctx);
131 talloc_free(dgmsock);
135 talloc_free(dgmsock);
140 /* test UDP/138 netlogon requests */
141 static BOOL nbt_test_netlogon2(TALLOC_CTX *mem_ctx,
142 struct nbt_name name, const char *address)
144 struct dgram_mailslot_handler *dgmslot;
145 struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL);
146 struct socket_address *dest;
147 const char *myaddress = talloc_strdup(dgmsock, iface_best_ip(address));
148 struct nbt_netlogon_packet logon;
149 struct nbt_name myname;
151 struct timeval tv = timeval_current();
154 struct socket_address *socket_address;
156 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
157 myaddress, lp_dgram_port());
158 if (!socket_address) {
162 /* try receiving replies on port 138 first, which will only
163 work if we are root and smbd/nmbd are not running - fall
164 back to listening on any port, which means replies from
165 some windows versions won't be seen */
166 status = socket_listen(dgmsock->sock, socket_address, 0, 0);
167 if (!NT_STATUS_IS_OK(status)) {
168 talloc_free(socket_address);
169 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
171 if (!socket_address) {
175 socket_listen(dgmsock->sock, socket_address, 0, 0);
178 /* setup a temporary mailslot listener for replies */
179 dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
180 netlogon_handler, &replies);
184 logon.command = NETLOGON_QUERY_FOR_PDC2;
185 logon.req.pdc2.request_count = 0;
186 logon.req.pdc2.computer_name = TEST_NAME;
187 logon.req.pdc2.user_name = "";
188 logon.req.pdc2.mailslot_name = dgmslot->mailslot_name;
189 logon.req.pdc2.nt_version = 11;
190 logon.req.pdc2.lmnt_token = 0xFFFF;
191 logon.req.pdc2.lm20_token = 0xFFFF;
193 make_nbt_name_client(&myname, TEST_NAME);
195 dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
200 status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
202 if (!NT_STATUS_IS_OK(status)) {
203 printf("Failed to send netlogon request - %s\n", nt_errstr(status));
208 while (timeval_elapsed(&tv) < 5 && replies == 0) {
209 event_loop_once(dgmsock->event_ctx);
212 talloc_free(dgmsock);
216 talloc_free(dgmsock);
222 reply handler for ntlogon request
224 static void ntlogon_handler(struct dgram_mailslot_handler *dgmslot,
225 struct nbt_dgram_packet *packet,
226 struct socket_address *src)
229 struct nbt_ntlogon_packet ntlogon;
230 int *replies = dgmslot->private;
232 printf("ntlogon reply from %s:%d\n", src->addr, src->port);
234 status = dgram_mailslot_ntlogon_parse(dgmslot, dgmslot, packet, &ntlogon);
235 if (!NT_STATUS_IS_OK(status)) {
236 printf("Failed to parse ntlogon packet from %s:%d\n",
237 src->addr, src->port);
241 NDR_PRINT_DEBUG(nbt_ntlogon_packet, &ntlogon);
247 /* test UDP/138 ntlogon requests */
248 static BOOL nbt_test_ntlogon(TALLOC_CTX *mem_ctx,
249 struct nbt_name name, const char *address)
251 struct dgram_mailslot_handler *dgmslot;
252 struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL);
253 struct socket_address *dest;
254 struct test_join *join_ctx;
255 struct cli_credentials *machine_credentials;
256 const struct dom_sid *dom_sid;
258 const char *myaddress = talloc_strdup(dgmsock, iface_best_ip(address));
259 struct nbt_ntlogon_packet logon;
260 struct nbt_name myname;
262 struct timeval tv = timeval_current();
265 struct socket_address *socket_address;
267 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
268 myaddress, lp_dgram_port());
269 if (!socket_address) {
273 /* try receiving replies on port 138 first, which will only
274 work if we are root and smbd/nmbd are not running - fall
275 back to listening on any port, which means replies from
276 some windows versions won't be seen */
277 status = socket_listen(dgmsock->sock, socket_address, 0, 0);
278 if (!NT_STATUS_IS_OK(status)) {
279 talloc_free(socket_address);
280 socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
282 if (!socket_address) {
286 socket_listen(dgmsock->sock, socket_address, 0, 0);
289 join_ctx = torture_join_domain(TEST_NAME,
290 ACB_WSTRUST, &machine_credentials);
291 if (join_ctx == NULL) {
292 printf("Failed to join domain %s as %s\n", lp_workgroup(), TEST_NAME);
293 talloc_free(dgmsock);
297 dom_sid = torture_join_sid(join_ctx);
299 /* setup a temporary mailslot listener for replies */
300 dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
301 ntlogon_handler, &replies);
305 logon.command = NTLOGON_SAM_LOGON;
306 logon.req.logon.request_count = 0;
307 logon.req.logon.computer_name = TEST_NAME;
308 logon.req.logon.user_name = TEST_NAME"$";
309 logon.req.logon.mailslot_name = dgmslot->mailslot_name;
310 logon.req.logon.acct_control = ACB_WSTRUST;
311 logon.req.logon.sid = *dom_sid;
312 logon.req.logon.nt_version = 1;
313 logon.req.logon.lmnt_token = 0xFFFF;
314 logon.req.logon.lm20_token = 0xFFFF;
316 make_nbt_name_client(&myname, TEST_NAME);
318 dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
323 status = dgram_mailslot_ntlogon_send(dgmsock, DGRAM_DIRECT_UNIQUE,
324 &name, dest, &myname, &logon);
325 if (!NT_STATUS_IS_OK(status)) {
326 printf("Failed to send ntlogon request - %s\n", nt_errstr(status));
331 while (timeval_elapsed(&tv) < 5 && replies == 0) {
332 event_loop_once(dgmsock->event_ctx);
335 torture_leave_domain(join_ctx);
336 talloc_free(dgmsock);
340 torture_leave_domain(join_ctx);
341 talloc_free(dgmsock);
347 test nbt dgram operations
349 BOOL torture_nbt_dgram(void)
352 struct nbt_name name;
353 TALLOC_CTX *mem_ctx = talloc_new(NULL);
357 name.name = lp_workgroup();
358 name.type = NBT_NAME_LOGON;
361 /* do an initial name resolution to find its IP */
362 status = resolve_name(&name, mem_ctx, &address, event_context_find(mem_ctx));
363 if (!NT_STATUS_IS_OK(status)) {
364 printf("Failed to resolve %s - %s\n",
365 name.name, nt_errstr(status));
366 talloc_free(mem_ctx);
370 ret &= nbt_test_netlogon(mem_ctx, name, address);
371 ret &= nbt_test_netlogon2(mem_ctx, name, address);
372 ret &= nbt_test_ntlogon(mem_ctx, name, address);
374 talloc_free(mem_ctx);