r5213: do our name broadcast refresh requests as register packets not refresh
[idra/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/raw/libcliraw.h"
29 #include "libcli/composite/composite.h"
30
31
32 static void nbtd_start_refresh_timer(struct nbt_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 nbt_iface_name *iname = talloc_get_type(req->async.private, struct nbt_iface_name);
40         NTSTATUS status;
41         struct nbt_name_refresh io;
42         TALLOC_CTX *tmp_ctx = talloc_new(iname);
43
44         status = nbt_name_refresh_recv(req, tmp_ctx, &io);
45         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
46                 DEBUG(4,("Refreshed name %s<%02x> on %s\n", 
47                          iname->name.name, iname->name.type, iname->iface->ip_address));
48                 iname->registration_time = timeval_current();
49                 nbtd_start_refresh_timer(iname);
50                 talloc_free(tmp_ctx);
51                 return;
52         }
53
54         iname->nb_flags |= NBT_NM_CONFLICT;
55         iname->nb_flags &= ~NBT_NM_ACTIVE;
56
57         if (NT_STATUS_IS_OK(status)) {
58                 DEBUG(1,("Name conflict from %s refreshing name %s<%02x> on %s - rcode %d\n", 
59                          io.out.reply_addr, iname->name.name, iname->name.type, 
60                          iname->iface->ip_address, io.out.rcode));
61         } else {
62                 DEBUG(1,("Error refreshing name %s<%02x> on %s - %s\n", 
63                          iname->name.name, iname->name.type, iname->iface->ip_address,
64                          nt_errstr(status)));
65         }
66
67         talloc_free(tmp_ctx);
68 }
69
70
71 /*
72   handle name refresh timer events
73 */
74 static void name_refresh_handler(struct event_context *ev, struct timed_event *te, 
75                                  struct timeval t, void *private)
76 {
77         struct nbt_iface_name *iname = talloc_get_type(private, struct nbt_iface_name);
78         struct nbt_interface *iface = iname->iface;
79         struct nbt_name_register io;
80         struct nbt_name_request *req;
81
82         /* setup a single name register request. Notice that we don't
83            use a name refresh request, as Windows and Samba3 do not
84            defend against broadcast name refresh packets. So for this
85            to be of any use at all, we need to refresh using name
86            registration packets */
87         io.in.name            = iname->name;
88         io.in.dest_addr       = iface->bcast_address;
89         io.in.address         = iface->ip_address;
90         io.in.nb_flags        = iname->nb_flags;
91         io.in.ttl             = iname->ttl;
92         io.in.register_demand = False;
93         io.in.broadcast       = True;
94         io.in.timeout         = 3;
95
96         req = nbt_name_register_send(iface->nbtsock, &io);
97         if (req == NULL) return;
98
99         req->async.fn = refresh_completion_handler;
100         req->async.private = iname;
101 }
102
103
104 /*
105   start a timer to refresh this name
106 */
107 static void nbtd_start_refresh_timer(struct nbt_iface_name *iname)
108 {
109         uint32_t refresh_time;
110         uint32_t max_refresh_time = lp_parm_int(-1, "nbtd", "max_refresh_time", 7200);
111
112         refresh_time = MIN(max_refresh_time, iname->ttl/2);
113         
114         event_add_timed(iname->iface->nbtsrv->task->event_ctx, 
115                         iname, 
116                         timeval_add(&iname->registration_time, refresh_time, 0),
117                         name_refresh_handler, iname);
118 }
119
120
121 /*
122   a name registration has completed
123 */
124 static void nbtd_register_handler(struct composite_context *req)
125 {
126         struct nbt_iface_name *iname = talloc_get_type(req->async.private, 
127                                                        struct nbt_iface_name);
128         NTSTATUS status;
129
130         status = nbt_name_register_bcast_recv(req);
131         if (NT_STATUS_IS_OK(status)) {
132                 /* good - nobody complained about our registration */
133                 iname->nb_flags |= NBT_NM_ACTIVE;
134                 DEBUG(3,("Registered %s<%02x> on interface %s\n",
135                          iname->name.name, iname->name.type, iname->iface->bcast_address));
136                 iname->registration_time = timeval_current();
137                 nbtd_start_refresh_timer(iname);
138                 return;
139         }
140
141         /* someone must have replied with an objection! */
142         iname->nb_flags |= NBT_NM_CONFLICT;
143
144         DEBUG(1,("Error registering %s<%02x> on interface %s - %s\n",
145                  iname->name.name, iname->name.type, iname->iface->bcast_address,
146                  nt_errstr(status)));
147 }
148
149
150 /*
151   register a name on a network interface
152 */
153 static void nbtd_register_name_iface(struct nbt_interface *iface,
154                                      const char *name, enum nbt_name_type type,
155                                      uint16_t nb_flags)
156 {
157         struct nbt_iface_name *iname;
158         const char *scope = lp_netbios_scope();
159         struct nbt_name_register_bcast io;
160         struct composite_context *req;
161
162         iname = talloc(iface, struct nbt_iface_name);
163         if (!iname) return;
164
165         iname->iface     = iface;
166         iname->name.name = talloc_strdup(iname, name);
167         iname->name.type = type;
168         if (scope && *scope) {
169                 iname->name.scope = talloc_strdup(iname, scope);
170         } else {
171                 iname->name.scope = NULL;
172         }
173         iname->nb_flags          = nb_flags;
174         iname->ttl               = lp_parm_int(-1, "nbtd", "bcast_ttl", 300000);
175         iname->registration_time = timeval_zero();
176
177         DLIST_ADD_END(iface->names, iname, struct nbt_iface_name *);
178
179         if (nb_flags & NBT_NM_PERMANENT) {
180                 /* permanent names are not announced and are immediately active */
181                 iname->nb_flags |= NBT_NM_ACTIVE;
182                 iname->ttl       = 0;
183                 return;
184         }
185
186         /* setup a broadcast name registration request */
187         io.in.name            = iname->name;
188         io.in.dest_addr       = iface->bcast_address;
189         io.in.address         = iface->ip_address;
190         io.in.nb_flags        = nb_flags;
191         io.in.ttl             = iname->ttl;
192
193         req = nbt_name_register_bcast_send(iface->nbtsock, &io);
194         if (req == NULL) return;
195
196         req->async.fn = nbtd_register_handler;
197         req->async.private = iname;
198 }
199
200
201 /*
202   register one name on all our interfaces
203 */
204 static void nbtd_register_name(struct nbt_server *nbtsrv, 
205                                const char *name, enum nbt_name_type type,
206                                uint16_t nb_flags)
207 {
208         struct nbt_interface *iface;
209         
210         /* register with all the local interfaces */
211         for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
212                 nbtd_register_name_iface(iface, name, type, nb_flags);
213         }
214
215         /* register on our general broadcast interface as a permanent name */
216         if (nbtsrv->bcast_interface) {
217                 nbtd_register_name_iface(nbtsrv->bcast_interface, name, type, 
218                                          nb_flags | NBT_NM_PERMANENT);
219         }
220
221         /* TODO: register with our WINS servers */
222 }
223
224
225 /*
226   register our names on all interfaces
227 */
228 void nbtd_register_names(struct nbt_server *nbtsrv)
229 {
230         uint16_t nb_flags = NBT_NODE_M;
231
232         /* note that we don't initially mark the names "ACTIVE". They are 
233            marked active once registration is successful */
234         nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_CLIENT, nb_flags);
235         nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_USER,   nb_flags);
236         nbtd_register_name(nbtsrv, lp_netbios_name(), NBT_NAME_SERVER, nb_flags);
237
238         nb_flags |= NBT_NM_GROUP;
239         nbtd_register_name(nbtsrv, lp_workgroup(),    NBT_NAME_CLIENT, nb_flags);
240
241         nb_flags |= NBT_NM_PERMANENT;
242         nbtd_register_name(nbtsrv, "__SAMBA__",       NBT_NAME_CLIENT, nb_flags);
243         nbtd_register_name(nbtsrv, "__SAMBA__",       NBT_NAME_SERVER, nb_flags);
244         nbtd_register_name(nbtsrv, "*",               NBT_NAME_CLIENT, nb_flags);
245 }