0d0526b94e67908789fb03250c6669ddb1e54ed1
[abartlet/samba.git/.git] / source4 / nbt_server / register.c
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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
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"
31
32
33 static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname);
34
35 /*
36   a name refresh request has completed
37 */
38 static void refresh_completion_handler(struct nbt_name_request *req)
39 {
40         struct nbtd_iface_name *iname = talloc_get_type(req->async.private, 
41                                                         struct nbtd_iface_name);
42         NTSTATUS status;
43         struct nbt_name_refresh io;
44         TALLOC_CTX *tmp_ctx = talloc_new(iname);
45
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);
53                 talloc_free(tmp_ctx);
54                 return;
55         }
56
57         iname->nb_flags |= NBT_NM_CONFLICT;
58         iname->nb_flags &= ~NBT_NM_ACTIVE;
59
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))));
65         } else {
66                 DEBUG(1,("Error refreshing name %s on %s - %s\n", 
67                          nbt_name_string(tmp_ctx, &iname->name), 
68                          iname->iface->ip_address,
69                          nt_errstr(status)));
70         }
71
72         talloc_free(tmp_ctx);
73 }
74
75
76 /*
77   handle name refresh timer events
78 */
79 static void name_refresh_handler(struct event_context *ev, struct timed_event *te, 
80                                  struct timeval t, void *private)
81 {
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;
87
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;
101         io.in.timeout         = 3;
102         io.in.retries         = 0;
103
104         nbtsrv->stats.total_sent++;
105         req = nbt_name_register_send(iface->nbtsock, &io);
106         if (req == NULL) return;
107
108         req->async.fn = refresh_completion_handler;
109         req->async.private = iname;
110 }
111
112
113 /*
114   start a timer to refresh this name
115 */
116 static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname)
117 {
118         uint32_t refresh_time;
119         uint32_t max_refresh_time = lp_parm_int(-1, "nbtd", "max_refresh_time", 7200);
120
121         refresh_time = MIN(max_refresh_time, iname->ttl/2);
122         
123         event_add_timed(iname->iface->nbtsrv->task->event_ctx, 
124                         iname, 
125                         timeval_add(&iname->registration_time, refresh_time, 0),
126                         name_refresh_handler, iname);
127 }
128
129
130 /*
131   a name registration has completed
132 */
133 static void nbtd_register_handler(struct composite_context *req)
134 {
135         struct nbtd_iface_name *iname = talloc_get_type(req->async.private, 
136                                                         struct nbtd_iface_name);
137         NTSTATUS status;
138         TALLOC_CTX *tmp_ctx = talloc_new(iname);
139
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);
150                 return;
151         }
152
153         /* someone must have replied with an objection! */
154         iname->nb_flags |= NBT_NM_CONFLICT;
155
156         DEBUG(1,("Error registering %s on interface %s - %s\n",
157                  nbt_name_string(tmp_ctx, &iname->name), iname->iface->bcast_address,
158                  nt_errstr(status)));
159         talloc_free(tmp_ctx);
160 }
161
162
163 /*
164   register a name on a network interface
165 */
166 static void nbtd_register_name_iface(struct nbtd_interface *iface,
167                                      const char *name, enum nbt_name_type type,
168                                      uint16_t nb_flags)
169 {
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;
175
176         iname = talloc(iface, struct nbtd_iface_name);
177         if (!iname) return;
178
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);
184         } else {
185                 iname->name.scope = NULL;
186         }
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;
191
192         DLIST_ADD_END(iface->names, iname, struct nbtd_iface_name *);
193
194         if (nb_flags & NBT_NM_PERMANENT) {
195                 /* permanent names are not announced and are immediately active */
196                 iname->nb_flags |= NBT_NM_ACTIVE;
197                 iname->ttl       = 0;
198                 return;
199         }
200
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);
205                 return;
206         }
207
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;
214
215         nbtsrv->stats.total_sent++;
216         req = nbt_name_register_bcast_send(iface->nbtsock, &io);
217         if (req == NULL) return;
218
219         req->async.fn = nbtd_register_handler;
220         req->async.private = iname;
221 }
222
223
224 /*
225   register one name on all our interfaces
226 */
227 static void nbtd_register_name(struct nbtd_server *nbtsrv, 
228                                const char *name, enum nbt_name_type type,
229                                uint16_t nb_flags)
230 {
231         struct nbtd_interface *iface;
232         
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);
236         }
237
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);
242         }
243
244         /* register with our WINS servers */
245         if (nbtsrv->wins_interface) {
246                 nbtd_register_name_iface(nbtsrv->wins_interface, name, type, nb_flags);
247         }
248 }
249
250
251 /*
252   register our names on all interfaces
253 */
254 void nbtd_register_names(struct nbtd_server *nbtsrv)
255 {
256         uint16_t nb_flags = NBT_NODE_M;
257         const char **aliases;
258
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);
264
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);
269                 aliases++;
270         }
271
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);
276                 break;
277         case ROLE_DOMAIN_BDC:
278                 nbtd_register_name(nbtsrv, lp_workgroup(),    NBT_NAME_LOGON, nb_flags);
279         default:
280                 break;
281         }
282
283         nb_flags |= NBT_NM_GROUP;
284         nbtd_register_name(nbtsrv, lp_workgroup(),    NBT_NAME_CLIENT, nb_flags);
285
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);
290 }