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"
32 static void nbtd_start_refresh_timer(struct nbt_iface_name *iname);
35 a name refresh request has completed
37 static void refresh_completion_handler(struct nbt_name_request *req)
39 struct nbt_iface_name *iname = talloc_get_type(req->async.private, struct nbt_iface_name);
41 struct nbt_name_refresh io;
42 TALLOC_CTX *tmp_ctx = talloc_new(iname);
44 status = nbt_name_refresh_recv(req, tmp_ctx, &io);
45 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
46 DEBUG(4,("Refreshed name %s<%02x> on %s\n",
47 iname->name.name, iname->name.type, iname->iface->ip_address));
48 iname->registration_time = timeval_current();
49 nbtd_start_refresh_timer(iname);
54 iname->nb_flags |= NBT_NM_CONFLICT;
55 iname->nb_flags &= ~NBT_NM_ACTIVE;
57 if (NT_STATUS_IS_OK(status)) {
58 DEBUG(1,("Name conflict from %s refreshing name %s<%02x> on %s - rcode %d\n",
59 io.out.reply_addr, iname->name.name, iname->name.type,
60 iname->iface->ip_address, io.out.rcode));
62 DEBUG(1,("Error refreshing name %s<%02x> on %s - %s\n",
63 iname->name.name, iname->name.type, iname->iface->ip_address,
72 handle name refresh timer events
74 static void name_refresh_handler(struct event_context *ev, struct timed_event *te,
75 struct timeval t, void *private)
77 struct nbt_iface_name *iname = talloc_get_type(private, struct nbt_iface_name);
78 struct nbt_interface *iface = iname->iface;
79 struct nbt_name_register io;
80 struct nbt_name_request *req;
82 /* setup a single name register request. Notice that we don't
83 use a name refresh request, as Windows and Samba3 do not
84 defend against broadcast name refresh packets. So for this
85 to be of any use at all, we need to refresh using name
86 registration packets */
87 io.in.name = iname->name;
88 io.in.dest_addr = iface->bcast_address;
89 io.in.address = iface->ip_address;
90 io.in.nb_flags = iname->nb_flags;
91 io.in.ttl = iname->ttl;
92 io.in.register_demand = False;
93 io.in.broadcast = True;
96 req = nbt_name_register_send(iface->nbtsock, &io);
97 if (req == NULL) return;
99 req->async.fn = refresh_completion_handler;
100 req->async.private = iname;
105 start a timer to refresh this name
107 static void nbtd_start_refresh_timer(struct nbt_iface_name *iname)
109 uint32_t refresh_time;
110 uint32_t max_refresh_time = lp_parm_int(-1, "nbtd", "max_refresh_time", 7200);
112 refresh_time = MIN(max_refresh_time, iname->ttl/2);
114 event_add_timed(iname->iface->nbtsrv->task->event_ctx,
116 timeval_add(&iname->registration_time, refresh_time, 0),
117 name_refresh_handler, iname);
122 a name registration has completed
124 static void nbtd_register_handler(struct composite_context *req)
126 struct nbt_iface_name *iname = talloc_get_type(req->async.private,
127 struct nbt_iface_name);
130 status = nbt_name_register_bcast_recv(req);
131 if (NT_STATUS_IS_OK(status)) {
132 /* good - nobody complained about our registration */
133 iname->nb_flags |= NBT_NM_ACTIVE;
134 DEBUG(3,("Registered %s<%02x> on interface %s\n",
135 iname->name.name, iname->name.type, iname->iface->bcast_address));
136 iname->registration_time = timeval_current();
137 nbtd_start_refresh_timer(iname);
141 /* someone must have replied with an objection! */
142 iname->nb_flags |= NBT_NM_CONFLICT;
144 DEBUG(1,("Error registering %s<%02x> on interface %s - %s\n",
145 iname->name.name, iname->name.type, iname->iface->bcast_address,
151 register a name on a network interface
153 static void nbtd_register_name_iface(struct nbt_interface *iface,
154 const char *name, enum nbt_name_type type,
157 struct nbt_iface_name *iname;
158 const char *scope = lp_netbios_scope();
159 struct nbt_name_register_bcast io;
160 struct composite_context *req;
162 iname = talloc(iface, struct nbt_iface_name);
165 iname->iface = iface;
166 iname->name.name = talloc_strdup(iname, name);
167 iname->name.type = type;
168 if (scope && *scope) {
169 iname->name.scope = talloc_strdup(iname, scope);
171 iname->name.scope = NULL;
173 iname->nb_flags = nb_flags;
174 iname->ttl = lp_parm_int(-1, "nbtd", "bcast_ttl", 300000);
175 iname->registration_time = timeval_zero();
177 DLIST_ADD_END(iface->names, iname, struct nbt_iface_name *);
179 if (nb_flags & NBT_NM_PERMANENT) {
180 /* permanent names are not announced and are immediately active */
181 iname->nb_flags |= NBT_NM_ACTIVE;
186 /* setup a broadcast name registration request */
187 io.in.name = iname->name;
188 io.in.dest_addr = iface->bcast_address;
189 io.in.address = iface->ip_address;
190 io.in.nb_flags = nb_flags;
191 io.in.ttl = iname->ttl;
193 req = nbt_name_register_bcast_send(iface->nbtsock, &io);
194 if (req == NULL) return;
196 req->async.fn = nbtd_register_handler;
197 req->async.private = iname;
202 register one name on all our interfaces
204 static void nbtd_register_name(struct nbt_server *nbtsrv,
205 const char *name, enum nbt_name_type type,
208 struct nbt_interface *iface;
210 /* register with all the local interfaces */
211 for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
212 nbtd_register_name_iface(iface, name, type, nb_flags);
215 /* register on our general broadcast interface as a permanent name */
216 if (nbtsrv->bcast_interface) {
217 nbtd_register_name_iface(nbtsrv->bcast_interface, name, type,
218 nb_flags | NBT_NM_PERMANENT);
221 /* TODO: register with our WINS servers */
226 register our names on all interfaces
228 void nbtd_register_names(struct nbt_server *nbtsrv)
230 uint16_t nb_flags = NBT_NODE_M;
232 /* note that we don't initially mark the names "ACTIVE". They are
233 marked active once registration is successful */
234 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_CLIENT, nb_flags);
235 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_USER, nb_flags);
236 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_SERVER, nb_flags);
238 nb_flags |= NBT_NM_GROUP;
239 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_CLIENT, nb_flags);
241 nb_flags |= NBT_NM_PERMANENT;
242 nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_CLIENT, nb_flags);
243 nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_SERVER, nb_flags);
244 nbtd_register_name(nbtsrv, "*", NBT_NAME_CLIENT, nb_flags);