Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : NBT name registration 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 "lib/socket/socket.h"
24 : #include "libcli/resolve/resolve.h"
25 : #include "system/network.h"
26 : #include "lib/socket/netif.h"
27 : #include "torture/torture.h"
28 : #include "torture/nbt/proto.h"
29 : #include "param/param.h"
30 :
31 : #define CHECK_VALUE(tctx, v, correct) \
32 : torture_assert_int_equal(tctx, v, correct, "Incorrect value")
33 :
34 : #define CHECK_STRING(tctx, v, correct) \
35 : torture_assert_casestr_equal(tctx, v, correct, "Incorrect value")
36 :
37 :
38 :
39 :
40 : /*
41 : test that a server responds correctly to attempted registrations of its name
42 : */
43 1 : static bool nbt_register_own(struct torture_context *tctx)
44 : {
45 0 : struct nbt_name_register io;
46 0 : NTSTATUS status;
47 1 : struct nbt_name_socket *nbtsock = torture_init_nbt_socket(tctx);
48 0 : struct socket_address *socket_address;
49 0 : struct nbt_name name;
50 0 : const char *address;
51 0 : const char *myaddress;
52 0 : struct interface *ifaces;
53 :
54 1 : if (!torture_nbt_get_name(tctx, &name, &address))
55 0 : return false;
56 :
57 1 : load_interface_list(tctx, tctx->lp_ctx, &ifaces);
58 :
59 1 : myaddress = iface_list_best_ip(ifaces, address);
60 :
61 1 : socket_address = socket_address_from_strings(tctx, nbtsock->sock->backend_name,
62 : myaddress, 0);
63 1 : torture_assert(tctx, socket_address != NULL, "Unable to get address");
64 :
65 1 : status = socket_listen(nbtsock->sock, socket_address, 0, 0);
66 1 : torture_assert_ntstatus_ok(tctx, status,
67 : "socket_listen for nbt_register_own failed");
68 :
69 1 : torture_comment(tctx, "Testing name defense to name registration\n");
70 :
71 1 : io.in.name = name;
72 1 : io.in.dest_addr = address;
73 1 : io.in.dest_port = lpcfg_nbt_port(tctx->lp_ctx);
74 1 : io.in.address = myaddress;
75 1 : io.in.nb_flags = NBT_NODE_B | NBT_NM_ACTIVE;
76 1 : io.in.register_demand = false;
77 1 : io.in.broadcast = true;
78 1 : io.in.multi_homed = false;
79 1 : io.in.ttl = 1234;
80 1 : io.in.timeout = 3;
81 1 : io.in.retries = 0;
82 :
83 1 : status = nbt_name_register(nbtsock, tctx, &io);
84 1 : torture_assert_ntstatus_ok(tctx, status,
85 : talloc_asprintf(tctx, "Bad response from %s for name register",
86 : address));
87 :
88 1 : CHECK_STRING(tctx, io.out.name.name, name.name);
89 1 : CHECK_VALUE(tctx, io.out.name.type, name.type);
90 1 : CHECK_VALUE(tctx, io.out.rcode, NBT_RCODE_ACT);
91 :
92 : /* check a register demand */
93 1 : io.in.address = myaddress;
94 1 : io.in.register_demand = true;
95 :
96 1 : status = nbt_name_register(nbtsock, tctx, &io);
97 :
98 1 : torture_assert_ntstatus_ok(tctx, status,
99 : talloc_asprintf(tctx, "Bad response from %s for name register demand", address));
100 :
101 1 : CHECK_STRING(tctx, io.out.name.name, name.name);
102 1 : CHECK_VALUE(tctx, io.out.name.type, name.type);
103 1 : CHECK_VALUE(tctx, io.out.rcode, NBT_RCODE_ACT);
104 :
105 1 : return true;
106 : }
107 :
108 :
109 : /*
110 : test that a server responds correctly to attempted name refresh requests
111 : */
112 1 : static bool nbt_refresh_own(struct torture_context *tctx)
113 : {
114 0 : struct nbt_name_refresh io;
115 0 : NTSTATUS status;
116 1 : struct nbt_name_socket *nbtsock = torture_init_nbt_socket(tctx);
117 0 : const char *myaddress;
118 0 : struct socket_address *socket_address;
119 0 : struct nbt_name name;
120 0 : const char *address;
121 0 : struct interface *ifaces;
122 :
123 1 : if (!torture_nbt_get_name(tctx, &name, &address))
124 0 : return false;
125 :
126 1 : load_interface_list(tctx, tctx->lp_ctx, &ifaces);
127 :
128 1 : myaddress = iface_list_best_ip(ifaces, address);
129 :
130 1 : socket_address = socket_address_from_strings(tctx, nbtsock->sock->backend_name,
131 : myaddress, 0);
132 1 : torture_assert(tctx, socket_address != NULL,
133 : "Can't parse socket address");
134 :
135 1 : status = socket_listen(nbtsock->sock, socket_address, 0, 0);
136 1 : torture_assert_ntstatus_ok(tctx, status,
137 : "socket_listen for nbt_referesh_own failed");
138 :
139 1 : torture_comment(tctx, "Testing name defense to name refresh\n");
140 :
141 1 : io.in.name = name;
142 1 : io.in.dest_addr = address;
143 1 : io.in.dest_port = lpcfg_nbt_port(tctx->lp_ctx);
144 1 : io.in.address = myaddress;
145 1 : io.in.nb_flags = NBT_NODE_B | NBT_NM_ACTIVE;
146 1 : io.in.broadcast = false;
147 1 : io.in.ttl = 1234;
148 1 : io.in.timeout = 3;
149 1 : io.in.retries = 0;
150 :
151 1 : status = nbt_name_refresh(nbtsock, tctx, &io);
152 :
153 1 : torture_assert_ntstatus_ok(tctx, status,
154 : talloc_asprintf(tctx, "Bad response from %s for name refresh", address));
155 :
156 1 : CHECK_STRING(tctx, io.out.name.name, name.name);
157 1 : CHECK_VALUE(tctx, io.out.name.type, name.type);
158 1 : CHECK_VALUE(tctx, io.out.rcode, NBT_RCODE_ACT);
159 :
160 1 : return true;
161 : }
162 :
163 :
164 : /*
165 : test name registration to a server
166 : */
167 2354 : struct torture_suite *torture_nbt_register(TALLOC_CTX *mem_ctx)
168 : {
169 125 : struct torture_suite *suite;
170 :
171 2354 : suite = torture_suite_create(mem_ctx, "register");
172 2354 : torture_suite_add_simple_test(suite, "register_own", nbt_register_own);
173 2354 : torture_suite_add_simple_test(suite, "refresh_own", nbt_refresh_own);
174 :
175 2354 : return suite;
176 : }
|