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