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