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