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 0 : NTSTATUS status;
45 0 : 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 0 : struct nbt_name_register io;
87 0 : 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 383 : static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname)
120 : {
121 11 : uint32_t refresh_time;
122 383 : uint32_t max_refresh_time = lpcfg_parm_int(iname->iface->nbtsrv->task->lp_ctx, NULL, "nbtd", "max_refresh_time", 7200);
123 :
124 383 : refresh_time = MIN(max_refresh_time, iname->ttl/2);
125 :
126 383 : 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 383 : }
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 389 : static void nbtd_register_name_handler(struct tevent_req *subreq)
141 : {
142 12 : struct nbtd_register_name_state *state =
143 389 : tevent_req_callback_data(subreq,
144 : struct nbtd_register_name_state);
145 389 : struct nbtd_iface_name *iname = state->iname;
146 12 : NTSTATUS status;
147 :
148 389 : status = nbt_name_register_bcast_recv(subreq);
149 389 : TALLOC_FREE(subreq);
150 389 : if (NT_STATUS_IS_OK(status)) {
151 : /* good - nobody complained about our registration */
152 383 : iname->nb_flags |= NBT_NM_ACTIVE;
153 383 : 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 383 : iname->registration_time = timeval_current();
157 383 : talloc_free(state);
158 383 : nbtd_start_refresh_timer(iname);
159 383 : return;
160 : }
161 :
162 : /* someone must have replied with an objection! */
163 6 : iname->nb_flags |= NBT_NM_CONFLICT;
164 :
165 6 : 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 6 : talloc_free(state);
170 : }
171 :
172 :
173 : /*
174 : register a name on a network interface
175 : */
176 1752 : 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 54 : struct nbtd_iface_name *iname;
181 1752 : const char *scope = lpcfg_netbios_scope(iface->nbtsrv->task->lp_ctx);
182 54 : struct nbtd_register_name_state *state;
183 54 : struct tevent_req *subreq;
184 1752 : struct nbtd_server *nbtsrv = iface->nbtsrv;
185 :
186 1752 : iname = talloc(iface, struct nbtd_iface_name);
187 1752 : if (!iname) return;
188 :
189 1752 : iname->iface = iface;
190 1752 : iname->name.name = strupper_talloc(iname, name);
191 1752 : iname->name.type = type;
192 1752 : if (scope && *scope) {
193 0 : iname->name.scope = strupper_talloc(iname, scope);
194 : } else {
195 1752 : iname->name.scope = NULL;
196 : }
197 1752 : iname->nb_flags = nb_flags;
198 1752 : iname->ttl = lpcfg_parm_int(iface->nbtsrv->task->lp_ctx, NULL, "nbtd", "bcast_ttl", 300000);
199 1752 : iname->registration_time = timeval_zero();
200 1752 : iname->wins_server = NULL;
201 :
202 1752 : DLIST_ADD_END(iface->names, iname);
203 :
204 1752 : if (nb_flags & NBT_NM_PERMANENT) {
205 : /* permanent names are not announced and are immediately active */
206 974 : iname->nb_flags |= NBT_NM_ACTIVE;
207 974 : iname->ttl = 0;
208 974 : return;
209 : }
210 :
211 : /* if this is the wins interface, then we need to do a special
212 : wins name registration */
213 778 : if (iface == iface->nbtsrv->wins_interface) {
214 389 : nbtd_winsclient_register(iname);
215 389 : return;
216 : }
217 :
218 389 : state = talloc_zero(iname, struct nbtd_register_name_state);
219 389 : if (state == NULL) {
220 0 : return;
221 : }
222 :
223 389 : state->iname = iname;
224 :
225 : /* setup a broadcast name registration request */
226 389 : state->io.in.name = iname->name;
227 389 : state->io.in.dest_addr = iface->bcast_address;
228 389 : state->io.in.dest_port = lpcfg_nbt_port(iface->nbtsrv->task->lp_ctx);
229 389 : state->io.in.address = iface->ip_address;
230 389 : state->io.in.nb_flags = nb_flags;
231 389 : state->io.in.ttl = iname->ttl;
232 :
233 389 : nbtsrv->stats.total_sent++;
234 :
235 389 : subreq = nbt_name_register_bcast_send(state, nbtsrv->task->event_ctx,
236 : iface->nbtsock, &state->io);
237 389 : if (subreq == NULL) {
238 0 : return;
239 : }
240 :
241 389 : tevent_req_set_callback(subreq, nbtd_register_name_handler, state);
242 : }
243 :
244 :
245 : /*
246 : register one name on all our interfaces
247 : */
248 584 : void nbtd_register_name(struct nbtd_server *nbtsrv,
249 : const char *name, enum nbt_name_type type,
250 : uint16_t nb_flags)
251 : {
252 18 : struct nbtd_interface *iface;
253 :
254 : /* register with all the local interfaces */
255 1168 : for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
256 584 : nbtd_register_name_iface(iface, name, type, nb_flags);
257 : }
258 :
259 : /* register on our general broadcast interface as a permanent name */
260 584 : if (nbtsrv->bcast_interface) {
261 584 : nbtd_register_name_iface(nbtsrv->bcast_interface, name, type,
262 : nb_flags | NBT_NM_PERMANENT);
263 : }
264 :
265 : /* register with our WINS servers */
266 584 : if (nbtsrv->wins_interface) {
267 584 : nbtd_register_name_iface(nbtsrv->wins_interface, name, type, nb_flags);
268 : }
269 584 : }
270 :
271 :
272 : /*
273 : register our names on all interfaces
274 : */
275 65 : void nbtd_register_names(struct nbtd_server *nbtsrv)
276 : {
277 65 : uint16_t nb_flags = NBT_NODE_M;
278 2 : 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 65 : nbtd_register_name(nbtsrv, lpcfg_netbios_name(nbtsrv->task->lp_ctx), NBT_NAME_CLIENT, nb_flags);
283 65 : nbtd_register_name(nbtsrv, lpcfg_netbios_name(nbtsrv->task->lp_ctx), NBT_NAME_USER, nb_flags);
284 65 : nbtd_register_name(nbtsrv, lpcfg_netbios_name(nbtsrv->task->lp_ctx), NBT_NAME_SERVER, nb_flags);
285 :
286 65 : aliases = lpcfg_netbios_aliases(nbtsrv->task->lp_ctx);
287 74 : 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 65 : if (lpcfg_server_role(nbtsrv->task->lp_ctx) == ROLE_ACTIVE_DIRECTORY_DC) {
294 59 : bool is_pdc = samdb_is_pdc(nbtsrv->sam_ctx);
295 59 : if (is_pdc) {
296 52 : nbtd_register_name(nbtsrv, lpcfg_workgroup(nbtsrv->task->lp_ctx),
297 : NBT_NAME_PDC, nb_flags);
298 : }
299 59 : nbtd_register_name(nbtsrv, lpcfg_workgroup(nbtsrv->task->lp_ctx),
300 : NBT_NAME_LOGON, nb_flags | NBT_NM_GROUP);
301 : }
302 :
303 65 : nb_flags |= NBT_NM_GROUP;
304 65 : nbtd_register_name(nbtsrv, lpcfg_workgroup(nbtsrv->task->lp_ctx), NBT_NAME_CLIENT, nb_flags);
305 :
306 65 : nb_flags |= NBT_NM_PERMANENT;
307 65 : nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_CLIENT, nb_flags);
308 65 : nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_SERVER, nb_flags);
309 65 : nbtd_register_name(nbtsrv, "*", NBT_NAME_CLIENT, nb_flags);
310 65 : }
|