r17939: Fix compiler warnings spotted on buildfarm.
[Samba/ekacnet.git] / source / nbt_server / register.c
blob64ceaffd9c437ba77a7522dcc506da07fabffd7c
1 /*
2 Unix SMB/CIFS implementation.
4 register our names
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.
23 #include "includes.h"
24 #include "lib/events/events.h"
25 #include "lib/util/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"
30 #include "nbt_server/wins/winsserver.h"
31 #include "librpc/gen_ndr/ndr_nbt.h"
34 static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname);
37 a name refresh request has completed
39 static void refresh_completion_handler(struct nbt_name_request *req)
41 struct nbtd_iface_name *iname = talloc_get_type(req->async.private,
42 struct nbtd_iface_name);
43 NTSTATUS status;
44 struct nbt_name_refresh io;
45 TALLOC_CTX *tmp_ctx = talloc_new(iname);
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;
58 iname->nb_flags |= NBT_NM_CONFLICT;
59 iname->nb_flags &= ~NBT_NM_ACTIVE;
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)));
73 talloc_free(tmp_ctx);
78 handle name refresh timer events
80 static void name_refresh_handler(struct event_context *ev, struct timed_event *te,
81 struct timeval t, void *private_data)
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;
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.address = iface->ip_address;
97 io.in.nb_flags = iname->nb_flags;
98 io.in.ttl = iname->ttl;
99 io.in.register_demand = False;
100 io.in.broadcast = True;
101 io.in.multi_homed = False;
102 io.in.timeout = 3;
103 io.in.retries = 0;
105 nbtsrv->stats.total_sent++;
106 req = nbt_name_register_send(iface->nbtsock, &io);
107 if (req == NULL) return;
109 req->async.fn = refresh_completion_handler;
110 req->async.private = iname;
115 start a timer to refresh this name
117 static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname)
119 uint32_t refresh_time;
120 uint32_t max_refresh_time = lp_parm_int(-1, "nbtd", "max_refresh_time", 7200);
122 refresh_time = MIN(max_refresh_time, iname->ttl/2);
124 event_add_timed(iname->iface->nbtsrv->task->event_ctx,
125 iname,
126 timeval_add(&iname->registration_time, refresh_time, 0),
127 name_refresh_handler, iname);
132 a name registration has completed
134 static void nbtd_register_handler(struct composite_context *creq)
136 struct nbtd_iface_name *iname = talloc_get_type(creq->async.private_data,
137 struct nbtd_iface_name);
138 NTSTATUS status;
139 TALLOC_CTX *tmp_ctx = talloc_new(iname);
141 status = nbt_name_register_bcast_recv(creq);
142 if (NT_STATUS_IS_OK(status)) {
143 /* good - nobody complained about our registration */
144 iname->nb_flags |= NBT_NM_ACTIVE;
145 DEBUG(3,("Registered %s with %s on interface %s\n",
146 nbt_name_string(tmp_ctx, &iname->name),
147 iname->iface->ip_address, iname->iface->bcast_address));
148 iname->registration_time = timeval_current();
149 talloc_free(tmp_ctx);
150 nbtd_start_refresh_timer(iname);
151 return;
154 /* someone must have replied with an objection! */
155 iname->nb_flags |= NBT_NM_CONFLICT;
157 DEBUG(1,("Error registering %s with %s on interface %s - %s\n",
158 nbt_name_string(tmp_ctx, &iname->name),
159 iname->iface->ip_address, iname->iface->bcast_address,
160 nt_errstr(status)));
161 talloc_free(tmp_ctx);
166 register a name on a network interface
168 static void nbtd_register_name_iface(struct nbtd_interface *iface,
169 const char *name, enum nbt_name_type type,
170 uint16_t nb_flags)
172 struct nbtd_iface_name *iname;
173 const char *scope = lp_netbios_scope();
174 struct nbt_name_register_bcast io;
175 struct composite_context *creq;
176 struct nbtd_server *nbtsrv = iface->nbtsrv;
178 iname = talloc(iface, struct nbtd_iface_name);
179 if (!iname) return;
181 iname->iface = iface;
182 iname->name.name = strupper_talloc(iname, name);
183 iname->name.type = type;
184 if (scope && *scope) {
185 iname->name.scope = strupper_talloc(iname, scope);
186 } else {
187 iname->name.scope = NULL;
189 iname->nb_flags = nb_flags;
190 iname->ttl = lp_parm_int(-1, "nbtd", "bcast_ttl", 300000);
191 iname->registration_time = timeval_zero();
192 iname->wins_server = NULL;
194 DLIST_ADD_END(iface->names, iname, struct nbtd_iface_name *);
196 if (nb_flags & NBT_NM_PERMANENT) {
197 /* permanent names are not announced and are immediately active */
198 iname->nb_flags |= NBT_NM_ACTIVE;
199 iname->ttl = 0;
200 return;
203 /* if this is the wins interface, then we need to do a special
204 wins name registration */
205 if (iface == iface->nbtsrv->wins_interface) {
206 nbtd_winsclient_register(iname);
207 return;
210 /* setup a broadcast name registration request */
211 io.in.name = iname->name;
212 io.in.dest_addr = iface->bcast_address;
213 io.in.address = iface->ip_address;
214 io.in.nb_flags = nb_flags;
215 io.in.ttl = iname->ttl;
217 nbtsrv->stats.total_sent++;
218 creq = nbt_name_register_bcast_send(iface->nbtsock, &io);
219 if (creq == NULL) return;
221 creq->async.fn = nbtd_register_handler;
222 creq->async.private_data = iname;
227 register one name on all our interfaces
229 static void nbtd_register_name(struct nbtd_server *nbtsrv,
230 const char *name, enum nbt_name_type type,
231 uint16_t nb_flags)
233 struct nbtd_interface *iface;
235 /* register with all the local interfaces */
236 for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
237 nbtd_register_name_iface(iface, name, type, nb_flags);
240 /* register on our general broadcast interface as a permanent name */
241 if (nbtsrv->bcast_interface) {
242 nbtd_register_name_iface(nbtsrv->bcast_interface, name, type,
243 nb_flags | NBT_NM_PERMANENT);
246 /* register with our WINS servers */
247 if (nbtsrv->wins_interface) {
248 nbtd_register_name_iface(nbtsrv->wins_interface, name, type, nb_flags);
254 register our names on all interfaces
256 void nbtd_register_names(struct nbtd_server *nbtsrv)
258 uint16_t nb_flags = NBT_NODE_M;
259 const char **aliases;
261 /* note that we don't initially mark the names "ACTIVE". They are
262 marked active once registration is successful */
263 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_CLIENT, nb_flags);
264 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_USER, nb_flags);
265 nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_SERVER, nb_flags);
267 aliases = lp_netbios_aliases();
268 while (aliases && aliases[0]) {
269 nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_CLIENT, nb_flags);
270 nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_SERVER, nb_flags);
271 aliases++;
274 switch (lp_server_role()) {
275 case ROLE_DOMAIN_PDC:
276 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_PDC, nb_flags);
277 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_LOGON, nb_flags | NBT_NM_GROUP);
278 break;
279 case ROLE_DOMAIN_BDC:
280 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_LOGON, nb_flags | NBT_NM_GROUP);
281 default:
282 break;
285 nb_flags |= NBT_NM_GROUP;
286 nbtd_register_name(nbtsrv, lp_workgroup(), NBT_NAME_CLIENT, nb_flags);
288 nb_flags |= NBT_NM_PERMANENT;
289 nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_CLIENT, nb_flags);
290 nbtd_register_name(nbtsrv, "__SAMBA__", NBT_NAME_SERVER, nb_flags);
291 nbtd_register_name(nbtsrv, "*", NBT_NAME_CLIENT, nb_flags);