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/composite/composite.h"
29 #include "librpc/gen_ndr/ndr_samr.h"
32 static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname);
35 a name refresh request has completed
37 static void refresh_completion_handler(struct nbt_name_request *req)
39 struct nbtd_iface_name *iname = talloc_get_type(req->async.private,
40 struct nbtd_iface_name);
42 struct nbt_name_refresh io;
43 TALLOC_CTX *tmp_ctx = talloc_new(iname);
45 status = nbt_name_refresh_recv(req, tmp_ctx, &io);
46 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
47 DEBUG(4,("Refreshed name %s on %s\n",
48 nbt_name_string(tmp_ctx, &iname->name),
49 iname->iface->ip_address));
50 iname->registration_time = timeval_current();
51 nbtd_start_refresh_timer(iname);
56 iname->nb_flags |= NBT_NM_CONFLICT;
57 iname->nb_flags &= ~NBT_NM_ACTIVE;
59 if (NT_STATUS_IS_OK(status)) {
60 DEBUG(1,("Name conflict from %s refreshing name %s on %s - %s\n",
61 io.out.reply_addr, nbt_name_string(tmp_ctx, &iname->name),
62 iname->iface->ip_address,
63 nt_errstr(nbt_rcode_to_ntstatus(io.out.rcode))));
65 DEBUG(1,("Error refreshing name %s on %s - %s\n",
66 nbt_name_string(tmp_ctx, &iname->name),
67 iname->iface->ip_address,
76 handle name refresh timer events
78 static void name_refresh_handler(struct event_context *ev, struct timed_event *te,
79 struct timeval t, void *private_data)
81 struct nbtd_iface_name *iname = talloc_get_type(private_data, struct nbtd_iface_name);
82 struct nbtd_interface *iface = iname->iface;
83 struct nbt_name_register io;
84 struct nbt_name_request *req;
85 struct nbtd_server *nbtsrv = iface->nbtsrv;
87 /* setup a single name register request. Notice that we don't
88 use a name refresh request, as Windows and Samba3 do not
89 defend against broadcast name refresh packets. So for this
90 to be of any use at all, we need to refresh using name
91 registration packets */
92 io.in.name = iname->name;
93 io.in.dest_addr = iface->bcast_address;
94 io.in.address = iface->ip_address;
95 io.in.nb_flags = iname->nb_flags;
96 io.in.ttl = iname->ttl;
97 io.in.register_demand = False;
98 io.in.broadcast = True;
99 io.in.multi_homed = False;
103 nbtsrv->stats.total_sent++;
104 req = nbt_name_register_send(iface->nbtsock, &io);
105 if (req == NULL) return;
107 req->async.fn = refresh_completion_handler;
108 req->async.private = iname;
113 start a timer to refresh this name
115 static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname)
117 uint32_t refresh_time;
118 uint32_t max_refresh_time = lp_parm_int(-1, "nbtd", "max_refresh_time", 7200);
120 refresh_time = MIN(max_refresh_time, iname->ttl/2);
122 event_add_timed(iname->iface->nbtsrv->task->event_ctx,
124 timeval_add(&iname->registration_time, refresh_time, 0),
125 name_refresh_handler, iname);
130 a name registration has completed
132 static void nbtd_register_handler(struct composite_context *creq)
134 struct nbtd_iface_name *iname = talloc_get_type(creq->async.private_data,
135 struct nbtd_iface_name);
137 TALLOC_CTX *tmp_ctx = talloc_new(iname);
139 status = nbt_name_register_bcast_recv(creq);
140 if (NT_STATUS_IS_OK(status)) {
141 /* good - nobody complained about our registration */
142 iname->nb_flags |= NBT_NM_ACTIVE;
143 DEBUG(3,("Registered %s on interface %s\n",
144 nbt_name_string(tmp_ctx, &iname->name),
145 iname->iface->bcast_address));
146 iname->registration_time = timeval_current();
147 talloc_free(tmp_ctx);
148 nbtd_start_refresh_timer(iname);
152 /* someone must have replied with an objection! */
153 iname->nb_flags |= NBT_NM_CONFLICT;
155 DEBUG(1,("Error registering %s on interface %s - %s\n",
156 nbt_name_string(tmp_ctx, &iname->name), iname->iface->bcast_address,
158 talloc_free(tmp_ctx);
163 register a name on a network interface
165 static void nbtd_register_name_iface(struct nbtd_interface *iface,
166 const char *name, enum nbt_name_type type,
169 struct nbtd_iface_name *iname;
170 const char *scope = lp_netbios_scope();
171 struct nbt_name_register_bcast io;
172 struct composite_context *creq;
173 struct nbtd_server *nbtsrv = iface->nbtsrv;
175 iname = talloc(iface, struct nbtd_iface_name);
178 iname->iface = iface;
179 iname->name.name = strupper_talloc(iname, name);
180 iname->name.type = type;
181 if (scope && *scope) {
182 iname->name.scope = strupper_talloc(iname, scope);
184 iname->name.scope = NULL;
186 iname->nb_flags = nb_flags;
187 iname->ttl = lp_parm_int(-1, "nbtd", "bcast_ttl", 300000);
188 iname->registration_time = timeval_zero();
189 iname->wins_server = NULL;
191 DLIST_ADD_END(iface->names, iname, struct nbtd_iface_name *);
193 if (nb_flags & NBT_NM_PERMANENT) {
194 /* permanent names are not announced and are immediately active */
195 iname->nb_flags |= NBT_NM_ACTIVE;
200 /* if this is the wins interface, then we need to do a special
201 wins name registration */
202 if (iface == iface->nbtsrv->wins_interface) {
203 nbtd_winsclient_register(iname);
207 /* setup a broadcast name registration request */
208 io.in.name = iname->name;
209 io.in.dest_addr = iface->bcast_address;
210 io.in.address = iface->ip_address;
211 io.in.nb_flags = nb_flags;
212 io.in.ttl = iname->ttl;
214 nbtsrv->stats.total_sent++;
215 creq = nbt_name_register_bcast_send(iface->nbtsock, &io);
216 if (creq == NULL) return;
218 creq->async.fn = nbtd_register_handler;
219 creq->async.private_data = iname;
224 register one name on all our interfaces
226 static void nbtd_register_name(struct nbtd_server *nbtsrv,
227 const char *name, enum nbt_name_type type,
230 struct nbtd_interface *iface;
232 /* register with all the local interfaces */
233 for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
234 nbtd_register_name_iface(iface, name, type, nb_flags);
237 /* register on our general broadcast interface as a permanent name */
238 if (nbtsrv->bcast_interface) {
239 nbtd_register_name_iface(nbtsrv->bcast_interface, name, type,
240 nb_flags | NBT_NM_PERMANENT);
243 /* register with our WINS servers */
244 if (nbtsrv->wins_interface) {
245 nbtd_register_name_iface(nbtsrv->wins_interface, name, type, nb_flags);
251 register our names on all interfaces
253 void nbtd_register_names(struct nbtd_server *nbtsrv)
255 uint16_t nb_flags = NBT_NODE_M;
256 const char **aliases;
258 /* note that we don't initially mark the names "ACTIVE". They are
259 marked active once registration is successful */
260 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_CLIENT, nb_flags);
261 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_USER, nb_flags);
262 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_SERVER, nb_flags);
264 aliases = lp_netbios_aliases();
265 while (aliases && aliases[0]) {
266 nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_CLIENT, nb_flags);
267 nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_SERVER, nb_flags);
271 switch (lp_server_role()) {
272 case ROLE_DOMAIN_PDC:
273 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_PDC, nb_flags);
274 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_LOGON, nb_flags | NBT_NM_GROUP);
276 case ROLE_DOMAIN_BDC:
277 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_LOGON, nb_flags | NBT_NM_GROUP);
282 nb_flags |= NBT_NM_GROUP;
283 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_CLIENT, nb_flags);
285 nb_flags |= NBT_NM_PERMANENT;
286 nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_CLIENT, nb_flags);
287 nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_SERVER, nb_flags);
288 nbtd_register_name(nbtsrv, "*", NBT_NAME_CLIENT, nb_flags);