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 "lib/events/events.h"
25 #include "dlinklist.h"
26 #include "nbt_server/nbt_server.h"
27 #include "smbd/service_task.h"
28 #include "libcli/raw/libcliraw.h"
29 #include "libcli/composite/composite.h"
30 #include "librpc/gen_ndr/ndr_samr.h"
33 static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname);
36 a name refresh request has completed
38 static void refresh_completion_handler(struct nbt_name_request *req)
40 struct nbtd_iface_name *iname = talloc_get_type(req->async.private,
41 struct nbtd_iface_name);
43 struct nbt_name_refresh io;
44 TALLOC_CTX *tmp_ctx = talloc_new(iname);
46 status = nbt_name_refresh_recv(req, tmp_ctx, &io);
47 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
48 DEBUG(4,("Refreshed name %s on %s\n",
49 nbt_name_string(tmp_ctx, &iname->name),
50 iname->iface->ip_address));
51 iname->registration_time = timeval_current();
52 nbtd_start_refresh_timer(iname);
57 iname->nb_flags |= NBT_NM_CONFLICT;
58 iname->nb_flags &= ~NBT_NM_ACTIVE;
60 if (NT_STATUS_IS_OK(status)) {
61 DEBUG(1,("Name conflict from %s refreshing name %s on %s - %s\n",
62 io.out.reply_addr, nbt_name_string(tmp_ctx, &iname->name),
63 iname->iface->ip_address,
64 nt_errstr(nbt_rcode_to_ntstatus(io.out.rcode))));
66 DEBUG(1,("Error refreshing name %s on %s - %s\n",
67 nbt_name_string(tmp_ctx, &iname->name),
68 iname->iface->ip_address,
77 handle name refresh timer events
79 static void name_refresh_handler(struct event_context *ev, struct timed_event *te,
80 struct timeval t, void *private)
82 struct nbtd_iface_name *iname = talloc_get_type(private, struct nbtd_iface_name);
83 struct nbtd_interface *iface = iname->iface;
84 struct nbt_name_register io;
85 struct nbt_name_request *req;
86 struct nbtd_server *nbtsrv = iface->nbtsrv;
88 /* setup a single name register request. Notice that we don't
89 use a name refresh request, as Windows and Samba3 do not
90 defend against broadcast name refresh packets. So for this
91 to be of any use at all, we need to refresh using name
92 registration packets */
93 io.in.name = iname->name;
94 io.in.dest_addr = iface->bcast_address;
95 io.in.address = iface->ip_address;
96 io.in.nb_flags = iname->nb_flags;
97 io.in.ttl = iname->ttl;
98 io.in.register_demand = False;
99 io.in.broadcast = True;
100 io.in.multi_homed = False;
104 nbtsrv->stats.total_sent++;
105 req = nbt_name_register_send(iface->nbtsock, &io);
106 if (req == NULL) return;
108 req->async.fn = refresh_completion_handler;
109 req->async.private = iname;
114 start a timer to refresh this name
116 static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname)
118 uint32_t refresh_time;
119 uint32_t max_refresh_time = lp_parm_int(-1, "nbtd", "max_refresh_time", 7200);
121 refresh_time = MIN(max_refresh_time, iname->ttl/2);
123 event_add_timed(iname->iface->nbtsrv->task->event_ctx,
125 timeval_add(&iname->registration_time, refresh_time, 0),
126 name_refresh_handler, iname);
131 a name registration has completed
133 static void nbtd_register_handler(struct composite_context *req)
135 struct nbtd_iface_name *iname = talloc_get_type(req->async.private,
136 struct nbtd_iface_name);
138 TALLOC_CTX *tmp_ctx = talloc_new(iname);
140 status = nbt_name_register_bcast_recv(req);
141 if (NT_STATUS_IS_OK(status)) {
142 /* good - nobody complained about our registration */
143 iname->nb_flags |= NBT_NM_ACTIVE;
144 DEBUG(3,("Registered %s on interface %s\n",
145 nbt_name_string(tmp_ctx, &iname->name),
146 iname->iface->bcast_address));
147 iname->registration_time = timeval_current();
148 talloc_free(tmp_ctx);
149 nbtd_start_refresh_timer(iname);
153 /* someone must have replied with an objection! */
154 iname->nb_flags |= NBT_NM_CONFLICT;
156 DEBUG(1,("Error registering %s on interface %s - %s\n",
157 nbt_name_string(tmp_ctx, &iname->name), iname->iface->bcast_address,
159 talloc_free(tmp_ctx);
164 register a name on a network interface
166 static void nbtd_register_name_iface(struct nbtd_interface *iface,
167 const char *name, enum nbt_name_type type,
170 struct nbtd_iface_name *iname;
171 const char *scope = lp_netbios_scope();
172 struct nbt_name_register_bcast io;
173 struct composite_context *req;
174 struct nbtd_server *nbtsrv = iface->nbtsrv;
176 iname = talloc(iface, struct nbtd_iface_name);
179 iname->iface = iface;
180 iname->name.name = strupper_talloc(iname, name);
181 iname->name.type = type;
182 if (scope && *scope) {
183 iname->name.scope = strupper_talloc(iname, scope);
185 iname->name.scope = NULL;
187 iname->nb_flags = nb_flags;
188 iname->ttl = lp_parm_int(-1, "nbtd", "bcast_ttl", 300000);
189 iname->registration_time = timeval_zero();
190 iname->wins_server = NULL;
192 DLIST_ADD_END(iface->names, iname, struct nbtd_iface_name *);
194 if (nb_flags & NBT_NM_PERMANENT) {
195 /* permanent names are not announced and are immediately active */
196 iname->nb_flags |= NBT_NM_ACTIVE;
201 /* if this is the wins interface, then we need to do a special
202 wins name registration */
203 if (iface == iface->nbtsrv->wins_interface) {
204 nbtd_winsclient_register(iname);
208 /* setup a broadcast name registration request */
209 io.in.name = iname->name;
210 io.in.dest_addr = iface->bcast_address;
211 io.in.address = iface->ip_address;
212 io.in.nb_flags = nb_flags;
213 io.in.ttl = iname->ttl;
215 nbtsrv->stats.total_sent++;
216 req = nbt_name_register_bcast_send(iface->nbtsock, &io);
217 if (req == NULL) return;
219 req->async.fn = nbtd_register_handler;
220 req->async.private = iname;
225 register one name on all our interfaces
227 static void nbtd_register_name(struct nbtd_server *nbtsrv,
228 const char *name, enum nbt_name_type type,
231 struct nbtd_interface *iface;
233 /* register with all the local interfaces */
234 for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
235 nbtd_register_name_iface(iface, name, type, nb_flags);
238 /* register on our general broadcast interface as a permanent name */
239 if (nbtsrv->bcast_interface) {
240 nbtd_register_name_iface(nbtsrv->bcast_interface, name, type,
241 nb_flags | NBT_NM_PERMANENT);
244 /* register with our WINS servers */
245 if (nbtsrv->wins_interface) {
246 nbtd_register_name_iface(nbtsrv->wins_interface, name, type, nb_flags);
252 register our names on all interfaces
254 void nbtd_register_names(struct nbtd_server *nbtsrv)
256 uint16_t nb_flags = NBT_NODE_M;
257 const char **aliases;
259 /* note that we don't initially mark the names "ACTIVE". They are
260 marked active once registration is successful */
261 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_CLIENT, nb_flags);
262 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_USER, nb_flags);
263 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_SERVER, nb_flags);
265 aliases = lp_netbios_aliases();
266 while (aliases && aliases[0]) {
267 nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_CLIENT, nb_flags);
268 nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_SERVER, nb_flags);
272 switch (lp_server_role()) {
273 case ROLE_DOMAIN_PDC:
274 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_PDC, nb_flags);
275 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_LOGON, nb_flags);
277 case ROLE_DOMAIN_BDC:
278 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_LOGON, nb_flags);
283 nb_flags |= NBT_NM_GROUP;
284 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_CLIENT, nb_flags);
286 nb_flags |= NBT_NM_PERMANENT;
287 nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_CLIENT, nb_flags);
288 nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_SERVER, nb_flags);
289 nbtd_register_name(nbtsrv, "*", NBT_NAME_CLIENT, nb_flags);