r14464: Don't include ndr_BASENAME.h files unless strictly required, instead
[kai/samba.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/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"
32
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)
40 {
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);
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 event_context *ev, struct timed_event *te, 
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.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;
104
105         nbtsrv->stats.total_sent++;
106         req = nbt_name_register_send(iface->nbtsock, &io);
107         if (req == NULL) return;
108
109         req->async.fn = refresh_completion_handler;
110         req->async.private = iname;
111 }
112
113
114 /*
115   start a timer to refresh this name
116 */
117 static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname)
118 {
119         uint32_t refresh_time;
120         uint32_t max_refresh_time = lp_parm_int(-1, "nbtd", "max_refresh_time", 7200);
121
122         refresh_time = MIN(max_refresh_time, iname->ttl/2);
123         
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);
128 }
129
130
131 /*
132   a name registration has completed
133 */
134 static void nbtd_register_handler(struct composite_context *creq)
135 {
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);
140
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;
152         }
153
154         /* someone must have replied with an objection! */
155         iname->nb_flags |= NBT_NM_CONFLICT;
156
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);
162 }
163
164
165 /*
166   register a name on a network interface
167 */
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)
171 {
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;
177
178         iname = talloc(iface, struct nbtd_iface_name);
179         if (!iname) return;
180
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;
188         }
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;
193
194         DLIST_ADD_END(iface->names, iname, struct nbtd_iface_name *);
195
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;
201         }
202
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;
208         }
209
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;
216
217         nbtsrv->stats.total_sent++;
218         creq = nbt_name_register_bcast_send(iface->nbtsock, &io);
219         if (creq == NULL) return;
220
221         creq->async.fn = nbtd_register_handler;
222         creq->async.private_data = iname;
223 }
224
225
226 /*
227   register one name on all our interfaces
228 */
229 static void nbtd_register_name(struct nbtd_server *nbtsrv, 
230                                const char *name, enum nbt_name_type type,
231                                uint16_t nb_flags)
232 {
233         struct nbtd_interface *iface;
234         
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);
238         }
239
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);
244         }
245
246         /* register with our WINS servers */
247         if (nbtsrv->wins_interface) {
248                 nbtd_register_name_iface(nbtsrv->wins_interface, name, type, nb_flags);
249         }
250 }
251
252
253 /*
254   register our names on all interfaces
255 */
256 void nbtd_register_names(struct nbtd_server *nbtsrv)
257 {
258         uint16_t nb_flags = NBT_NODE_M;
259         const char **aliases;
260
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);
266
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++;
272         }
273
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;
283         }
284
285         nb_flags |= NBT_NM_GROUP;
286         nbtd_register_name(nbtsrv, lp_workgroup(),    NBT_NAME_CLIENT, nb_flags);
287
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);
292 }