Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : register our names
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/events/events.h"
24 : #include "../lib/util/dlinklist.h"
25 : #include "nbt_server/nbt_server.h"
26 : #include "samba/service_task.h"
27 : #include "libcli/composite/composite.h"
28 : #include "librpc/gen_ndr/ndr_samr.h"
29 : #include "nbt_server/wins/winsserver.h"
30 : #include "librpc/gen_ndr/ndr_nbt.h"
31 : #include "dsdb/samdb/samdb.h"
32 : #include "param/param.h"
33 : #include "libds/common/roles.h"
34 :
35 : static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname);
36 :
37 : /*
38 : a name refresh request has completed
39 : */
40 0 : static void refresh_completion_handler(struct nbt_name_request *req)
41 : {
42 0 : struct nbtd_iface_name *iname = talloc_get_type(req->async.private_data,
43 : struct nbtd_iface_name);
44 : NTSTATUS status;
45 : struct nbt_name_refresh io;
46 0 : TALLOC_CTX *tmp_ctx = talloc_new(iname);
47 :
48 0 : status = nbt_name_refresh_recv(req, tmp_ctx, &io);
49 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
50 0 : DEBUG(4,("Refreshed name %s with %s on interface %s\n",
51 : nbt_name_string(tmp_ctx, &iname->name),
52 : iname->iface->ip_address, iname->iface->bcast_address));
53 0 : iname->registration_time = timeval_current();
54 0 : nbtd_start_refresh_timer(iname);
55 0 : talloc_free(tmp_ctx);
56 0 : return;
57 : }
58 :
59 0 : iname->nb_flags |= NBT_NM_CONFLICT;
60 0 : iname->nb_flags &= ~NBT_NM_ACTIVE;
61 :
62 0 : if (NT_STATUS_IS_OK(status)) {
63 0 : DEBUG(1,("Name conflict from %s refreshing name %s with %s on interface %s - %s\n",
64 : io.out.reply_addr, nbt_name_string(tmp_ctx, &iname->name),
65 : iname->iface->ip_address, iname->iface->bcast_address,
66 : nt_errstr(nbt_rcode_to_ntstatus(io.out.rcode))));
67 : } else {
68 0 : DEBUG(1,("Error refreshing name %s with %s on interface %s - %s\n",
69 : nbt_name_string(tmp_ctx, &iname->name),
70 : iname->iface->ip_address, iname->iface->bcast_address,
71 : nt_errstr(status)));
72 : }
73 :
74 0 : talloc_free(tmp_ctx);
75 : }
76 :
77 :
78 : /*
79 : handle name refresh timer events
80 : */
81 0 : static void name_refresh_handler(struct tevent_context *ev, struct tevent_timer *te,
82 : struct timeval t, void *private_data)
83 : {
84 0 : struct nbtd_iface_name *iname = talloc_get_type(private_data, struct nbtd_iface_name);
85 0 : struct nbtd_interface *iface = iname->iface;
86 : struct nbt_name_register io;
87 : struct nbt_name_request *req;
88 0 : struct nbtd_server *nbtsrv = iface->nbtsrv;
89 :
90 : /* setup a single name register request. Notice that we don't
91 : use a name refresh request, as Windows and Samba3 do not
92 : defend against broadcast name refresh packets. So for this
93 : to be of any use at all, we need to refresh using name
94 : registration packets */
95 0 : io.in.name = iname->name;
96 0 : io.in.dest_addr = iface->bcast_address;
97 0 : io.in.dest_port = lpcfg_nbt_port(iface->nbtsrv->task->lp_ctx);
98 0 : io.in.address = iface->ip_address;
99 0 : io.in.nb_flags = iname->nb_flags;
100 0 : io.in.ttl = iname->ttl;
101 0 : io.in.register_demand = false;
102 0 : io.in.broadcast = true;
103 0 : io.in.multi_homed = false;
104 0 : io.in.timeout = 3;
105 0 : io.in.retries = 0;
106 :
107 0 : nbtsrv->stats.total_sent++;
108 0 : req = nbt_name_register_send(iface->nbtsock, &io);
109 0 : if (req == NULL) return;
110 :
111 0 : req->async.fn = refresh_completion_handler;
112 0 : req->async.private_data = iname;
113 : }
114 :
115 :
116 : /*
117 : start a timer to refresh this name
118 : */
119 316 : static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname)
120 : {
121 : uint32_t refresh_time;
122 316 : uint32_t max_refresh_time = lpcfg_parm_int(iname->iface->nbtsrv->task->lp_ctx, NULL, "nbtd", "max_refresh_time", 7200);
123 :
124 316 : refresh_time = MIN(max_refresh_time, iname->ttl/2);
125 :
126 316 : tevent_add_timer(iname->iface->nbtsrv->task->event_ctx,
127 : iname,
128 : timeval_add(&iname->registration_time, refresh_time, 0),
129 : name_refresh_handler, iname);
130 316 : }
131 :
132 : struct nbtd_register_name_state {
133 : struct nbtd_iface_name *iname;
134 : struct nbt_name_register_bcast io;
135 : };
136 :
137 : /*
138 : a name registration has completed
139 : */
140 319 : static void nbtd_register_name_handler(struct tevent_req *subreq)
141 : {
142 229 : struct nbtd_register_name_state *state =
143 319 : tevent_req_callback_data(subreq,
144 : struct nbtd_register_name_state);
145 319 : struct nbtd_iface_name *iname = state->iname;
146 : NTSTATUS status;
147 :
148 319 : status = nbt_name_register_bcast_recv(subreq);
149 319 : TALLOC_FREE(subreq);
150 319 : if (NT_STATUS_IS_OK(status)) {
151 : /* good - nobody complained about our registration */
152 316 : iname->nb_flags |= NBT_NM_ACTIVE;
153 316 : DEBUG(3,("Registered %s with %s on interface %s\n",
154 : nbt_name_string(state, &iname->name),
155 : iname->iface->ip_address, iname->iface->bcast_address));
156 316 : iname->registration_time = timeval_current();
157 316 : talloc_free(state);
158 316 : nbtd_start_refresh_timer(iname);
159 316 : return;
160 : }
161 :
162 : /* someone must have replied with an objection! */
163 3 : iname->nb_flags |= NBT_NM_CONFLICT;
164 :
165 3 : DEBUG(1,("Error registering %s with %s on interface %s - %s\n",
166 : nbt_name_string(state, &iname->name),
167 : iname->iface->ip_address, iname->iface->bcast_address,
168 : nt_errstr(status)));
169 3 : talloc_free(state);
170 : }
171 :
172 :
173 : /*
174 : register a name on a network interface
175 : */
176 1434 : static void nbtd_register_name_iface(struct nbtd_interface *iface,
177 : const char *name, enum nbt_name_type type,
178 : uint16_t nb_flags)
179 : {
180 : struct nbtd_iface_name *iname;
181 1434 : const char *scope = lpcfg_netbios_scope(iface->nbtsrv->task->lp_ctx);
182 : struct nbtd_register_name_state *state;
183 : struct tevent_req *subreq;
184 1434 : struct nbtd_server *nbtsrv = iface->nbtsrv;
185 :
186 1434 : iname = talloc(iface, struct nbtd_iface_name);
187 1434 : if (!iname) return;
188 :
189 1434 : iname->iface = iface;
190 1434 : iname->name.name = strupper_talloc(iname, name);
191 1434 : iname->name.type = type;
192 1434 : if (scope && *scope) {
193 0 : iname->name.scope = strupper_talloc(iname, scope);
194 : } else {
195 1434 : iname->name.scope = NULL;
196 : }
197 1434 : iname->nb_flags = nb_flags;
198 1434 : iname->ttl = lpcfg_parm_int(iface->nbtsrv->task->lp_ctx, NULL, "nbtd", "bcast_ttl", 300000);
199 1434 : iname->registration_time = timeval_zero();
200 1434 : iname->wins_server = NULL;
201 :
202 1434 : DLIST_ADD_END(iface->names, iname);
203 :
204 1434 : if (nb_flags & NBT_NM_PERMANENT) {
205 : /* permanent names are not announced and are immediately active */
206 796 : iname->nb_flags |= NBT_NM_ACTIVE;
207 796 : iname->ttl = 0;
208 796 : return;
209 : }
210 :
211 : /* if this is the wins interface, then we need to do a special
212 : wins name registration */
213 638 : if (iface == iface->nbtsrv->wins_interface) {
214 319 : nbtd_winsclient_register(iname);
215 319 : return;
216 : }
217 :
218 319 : state = talloc_zero(iname, struct nbtd_register_name_state);
219 319 : if (state == NULL) {
220 0 : return;
221 : }
222 :
223 319 : state->iname = iname;
224 :
225 : /* setup a broadcast name registration request */
226 319 : state->io.in.name = iname->name;
227 319 : state->io.in.dest_addr = iface->bcast_address;
228 319 : state->io.in.dest_port = lpcfg_nbt_port(iface->nbtsrv->task->lp_ctx);
229 319 : state->io.in.address = iface->ip_address;
230 319 : state->io.in.nb_flags = nb_flags;
231 319 : state->io.in.ttl = iname->ttl;
232 :
233 319 : nbtsrv->stats.total_sent++;
234 :
235 319 : subreq = nbt_name_register_bcast_send(state, nbtsrv->task->event_ctx,
236 : iface->nbtsock, &state->io);
237 319 : if (subreq == NULL) {
238 0 : return;
239 : }
240 :
241 319 : tevent_req_set_callback(subreq, nbtd_register_name_handler, state);
242 : }
243 :
244 :
245 : /*
246 : register one name on all our interfaces
247 : */
248 478 : void nbtd_register_name(struct nbtd_server *nbtsrv,
249 : const char *name, enum nbt_name_type type,
250 : uint16_t nb_flags)
251 : {
252 : struct nbtd_interface *iface;
253 :
254 : /* register with all the local interfaces */
255 956 : for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
256 478 : nbtd_register_name_iface(iface, name, type, nb_flags);
257 : }
258 :
259 : /* register on our general broadcast interface as a permanent name */
260 478 : if (nbtsrv->bcast_interface) {
261 478 : nbtd_register_name_iface(nbtsrv->bcast_interface, name, type,
262 : nb_flags | NBT_NM_PERMANENT);
263 : }
264 :
265 : /* register with our WINS servers */
266 478 : if (nbtsrv->wins_interface) {
267 478 : nbtd_register_name_iface(nbtsrv->wins_interface, name, type, nb_flags);
268 : }
269 478 : }
270 :
271 :
272 : /*
273 : register our names on all interfaces
274 : */
275 53 : void nbtd_register_names(struct nbtd_server *nbtsrv)
276 : {
277 53 : uint16_t nb_flags = NBT_NODE_M;
278 : const char **aliases;
279 :
280 : /* note that we don't initially mark the names "ACTIVE". They are
281 : marked active once registration is successful */
282 53 : nbtd_register_name(nbtsrv, lpcfg_netbios_name(nbtsrv->task->lp_ctx), NBT_NAME_CLIENT, nb_flags);
283 53 : nbtd_register_name(nbtsrv, lpcfg_netbios_name(nbtsrv->task->lp_ctx), NBT_NAME_USER, nb_flags);
284 53 : nbtd_register_name(nbtsrv, lpcfg_netbios_name(nbtsrv->task->lp_ctx), NBT_NAME_SERVER, nb_flags);
285 :
286 53 : aliases = lpcfg_netbios_aliases(nbtsrv->task->lp_ctx);
287 100 : while (aliases && aliases[0]) {
288 9 : nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_CLIENT, nb_flags);
289 9 : nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_SERVER, nb_flags);
290 9 : aliases++;
291 : }
292 :
293 53 : if (lpcfg_server_role(nbtsrv->task->lp_ctx) == ROLE_ACTIVE_DIRECTORY_DC) {
294 47 : bool is_pdc = samdb_is_pdc(nbtsrv->sam_ctx);
295 47 : if (is_pdc) {
296 42 : nbtd_register_name(nbtsrv, lpcfg_workgroup(nbtsrv->task->lp_ctx),
297 : NBT_NAME_PDC, nb_flags);
298 : }
299 47 : nbtd_register_name(nbtsrv, lpcfg_workgroup(nbtsrv->task->lp_ctx),
300 : NBT_NAME_LOGON, nb_flags | NBT_NM_GROUP);
301 : }
302 :
303 53 : nb_flags |= NBT_NM_GROUP;
304 53 : nbtd_register_name(nbtsrv, lpcfg_workgroup(nbtsrv->task->lp_ctx), NBT_NAME_CLIENT, nb_flags);
305 :
306 53 : nb_flags |= NBT_NM_PERMANENT;
307 53 : nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_CLIENT, nb_flags);
308 53 : nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_SERVER, nb_flags);
309 53 : nbtd_register_name(nbtsrv, "*", NBT_NAME_CLIENT, nb_flags);
310 53 : }
|