f5517b249a543daee1b8a2babb64afd4529f1b88
[obnox/samba/samba-obnox.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 3 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, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "lib/events/events.h"
24 #include "../lib/util/dlinklist.h"
25 #include "nbt_server/nbt_server.h"
26 #include "smbd/service_task.h"
27 #include "libcli/composite/composite.h"
28 #include "librpc/gen_ndr/ndr_samr.h"
29 #include "nbt_server/wins/winsserver.h"
30 #include "librpc/gen_ndr/ndr_nbt.h"
31 #include "dsdb/samdb/samdb.h"
32 #include "param/param.h"
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_data,
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 tevent_context *ev, struct tevent_timer *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.dest_port       = lpcfg_nbt_port(iface->nbtsrv->task->lp_ctx);
97         io.in.address         = iface->ip_address;
98         io.in.nb_flags        = iname->nb_flags;
99         io.in.ttl             = iname->ttl;
100         io.in.register_demand = false;
101         io.in.broadcast       = true;
102         io.in.multi_homed     = false;
103         io.in.timeout         = 3;
104         io.in.retries         = 0;
105
106         nbtsrv->stats.total_sent++;
107         req = nbt_name_register_send(iface->nbtsock, &io);
108         if (req == NULL) return;
109
110         req->async.fn = refresh_completion_handler;
111         req->async.private_data = iname;
112 }
113
114
115 /*
116   start a timer to refresh this name
117 */
118 static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname)
119 {
120         uint32_t refresh_time;
121         uint32_t max_refresh_time = lpcfg_parm_int(iname->iface->nbtsrv->task->lp_ctx, NULL, "nbtd", "max_refresh_time", 7200);
122
123         refresh_time = MIN(max_refresh_time, iname->ttl/2);
124         
125         tevent_add_timer(iname->iface->nbtsrv->task->event_ctx,
126                         iname, 
127                         timeval_add(&iname->registration_time, refresh_time, 0),
128                         name_refresh_handler, iname);
129 }
130
131 struct nbtd_register_name_state {
132         struct nbtd_iface_name *iname;
133         struct nbt_name_register_bcast io;
134 };
135
136 /*
137   a name registration has completed
138 */
139 static void nbtd_register_name_handler(struct tevent_req *subreq)
140 {
141         struct nbtd_register_name_state *state =
142                 tevent_req_callback_data(subreq,
143                 struct nbtd_register_name_state);
144         struct nbtd_iface_name *iname = state->iname;
145         NTSTATUS status;
146
147         status = nbt_name_register_bcast_recv(subreq);
148         TALLOC_FREE(subreq);
149         if (NT_STATUS_IS_OK(status)) {
150                 /* good - nobody complained about our registration */
151                 iname->nb_flags |= NBT_NM_ACTIVE;
152                 DEBUG(3,("Registered %s with %s on interface %s\n",
153                          nbt_name_string(state, &iname->name),
154                          iname->iface->ip_address, iname->iface->bcast_address));
155                 iname->registration_time = timeval_current();
156                 talloc_free(state);
157                 nbtd_start_refresh_timer(iname);
158                 return;
159         }
160
161         /* someone must have replied with an objection! */
162         iname->nb_flags |= NBT_NM_CONFLICT;
163
164         DEBUG(1,("Error registering %s with %s on interface %s - %s\n",
165                  nbt_name_string(state, &iname->name),
166                  iname->iface->ip_address, iname->iface->bcast_address,
167                  nt_errstr(status)));
168         talloc_free(state);
169 }
170
171
172 /*
173   register a name on a network interface
174 */
175 static void nbtd_register_name_iface(struct nbtd_interface *iface,
176                                      const char *name, enum nbt_name_type type,
177                                      uint16_t nb_flags)
178 {
179         struct nbtd_iface_name *iname;
180         const char *scope = lpcfg_netbios_scope(iface->nbtsrv->task->lp_ctx);
181         struct nbtd_register_name_state *state;
182         struct tevent_req *subreq;
183         struct nbtd_server *nbtsrv = iface->nbtsrv;
184
185         iname = talloc(iface, struct nbtd_iface_name);
186         if (!iname) return;
187
188         iname->iface     = iface;
189         iname->name.name = strupper_talloc(iname, name);
190         iname->name.type = type;
191         if (scope && *scope) {
192                 iname->name.scope = strupper_talloc(iname, scope);
193         } else {
194                 iname->name.scope = NULL;
195         }
196         iname->nb_flags          = nb_flags;
197         iname->ttl               = lpcfg_parm_int(iface->nbtsrv->task->lp_ctx, NULL, "nbtd", "bcast_ttl", 300000);
198         iname->registration_time = timeval_zero();
199         iname->wins_server       = NULL;
200
201         DLIST_ADD_END(iface->names, iname, struct nbtd_iface_name *);
202
203         if (nb_flags & NBT_NM_PERMANENT) {
204                 /* permanent names are not announced and are immediately active */
205                 iname->nb_flags |= NBT_NM_ACTIVE;
206                 iname->ttl       = 0;
207                 return;
208         }
209
210         /* if this is the wins interface, then we need to do a special
211            wins name registration */
212         if (iface == iface->nbtsrv->wins_interface) {
213                 nbtd_winsclient_register(iname);
214                 return;
215         }
216
217         state = talloc_zero(iname, struct nbtd_register_name_state);
218         if (state == NULL) {
219                 return;
220         }
221
222         state->iname = iname;
223
224         /* setup a broadcast name registration request */
225         state->io.in.name      = iname->name;
226         state->io.in.dest_addr = iface->bcast_address;
227         state->io.in.dest_port = lpcfg_nbt_port(iface->nbtsrv->task->lp_ctx);
228         state->io.in.address   = iface->ip_address;
229         state->io.in.nb_flags  = nb_flags;
230         state->io.in.ttl       = iname->ttl;
231
232         nbtsrv->stats.total_sent++;
233
234         subreq = nbt_name_register_bcast_send(state, nbtsrv->task->event_ctx,
235                                               iface->nbtsock, &state->io);
236         if (subreq == NULL) {
237                 return;
238         }
239
240         tevent_req_set_callback(subreq, nbtd_register_name_handler, state);
241 }
242
243
244 /*
245   register one name on all our interfaces
246 */
247 void nbtd_register_name(struct nbtd_server *nbtsrv, 
248                         const char *name, enum nbt_name_type type,
249                         uint16_t nb_flags)
250 {
251         struct nbtd_interface *iface;
252         
253         /* register with all the local interfaces */
254         for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
255                 nbtd_register_name_iface(iface, name, type, nb_flags);
256         }
257
258         /* register on our general broadcast interface as a permanent name */
259         if (nbtsrv->bcast_interface) {
260                 nbtd_register_name_iface(nbtsrv->bcast_interface, name, type, 
261                                          nb_flags | NBT_NM_PERMANENT);
262         }
263
264         /* register with our WINS servers */
265         if (nbtsrv->wins_interface) {
266                 nbtd_register_name_iface(nbtsrv->wins_interface, name, type, nb_flags);
267         }
268 }
269
270
271 /*
272   register our names on all interfaces
273 */
274 void nbtd_register_names(struct nbtd_server *nbtsrv)
275 {
276         uint16_t nb_flags = NBT_NODE_M;
277         const char **aliases;
278
279         /* note that we don't initially mark the names "ACTIVE". They are 
280            marked active once registration is successful */
281         nbtd_register_name(nbtsrv, lpcfg_netbios_name(nbtsrv->task->lp_ctx), NBT_NAME_CLIENT, nb_flags);
282         nbtd_register_name(nbtsrv, lpcfg_netbios_name(nbtsrv->task->lp_ctx), NBT_NAME_USER,   nb_flags);
283         nbtd_register_name(nbtsrv, lpcfg_netbios_name(nbtsrv->task->lp_ctx), NBT_NAME_SERVER, nb_flags);
284
285         aliases = lpcfg_netbios_aliases(nbtsrv->task->lp_ctx);
286         while (aliases && aliases[0]) {
287                 nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_CLIENT, nb_flags);
288                 nbtd_register_name(nbtsrv, aliases[0], NBT_NAME_SERVER, nb_flags);
289                 aliases++;
290         }
291
292         if (lpcfg_server_role(nbtsrv->task->lp_ctx) == ROLE_ACTIVE_DIRECTORY_DC)        {
293                 bool is_pdc = samdb_is_pdc(nbtsrv->sam_ctx);
294                 if (is_pdc) {
295                         nbtd_register_name(nbtsrv, lpcfg_workgroup(nbtsrv->task->lp_ctx),
296                                            NBT_NAME_PDC, nb_flags);
297                 }
298                 nbtd_register_name(nbtsrv, lpcfg_workgroup(nbtsrv->task->lp_ctx),
299                                    NBT_NAME_LOGON, nb_flags | NBT_NM_GROUP);
300         }
301
302         nb_flags |= NBT_NM_GROUP;
303         nbtd_register_name(nbtsrv, lpcfg_workgroup(nbtsrv->task->lp_ctx), NBT_NAME_CLIENT, nb_flags);
304
305         nb_flags |= NBT_NM_PERMANENT;
306         nbtd_register_name(nbtsrv, "__SAMBA__",       NBT_NAME_CLIENT, nb_flags);
307         nbtd_register_name(nbtsrv, "__SAMBA__",       NBT_NAME_SERVER, nb_flags);
308         nbtd_register_name(nbtsrv, "*",               NBT_NAME_CLIENT, nb_flags);
309 }