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