r6339: set the NBT_SERVER_LDAP and NBT_SERVER_KDC bits based on config
[samba.git] / source / nbt_server / packet.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    packet utility functions
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 "dlinklist.h"
25 #include "nbt_server/nbt_server.h"
26
27 /*
28   we received a badly formed packet - log it
29 */
30 void nbtd_bad_packet(struct nbt_name_packet *packet, 
31                      const char *src_address, const char *reason)
32 {
33         DEBUG(2,("nbtd: bad packet '%s' from %s\n", reason, src_address));
34         if (DEBUGLVL(5)) {
35                 NDR_PRINT_DEBUG(nbt_name_packet, packet);               
36         }
37 }
38
39
40 /*
41   see if an incoming packet is a broadcast packet from one of our own
42   interfaces
43 */
44 BOOL nbtd_self_packet(struct nbt_name_socket *nbtsock, 
45                       struct nbt_name_packet *packet, 
46                       const char *src_address, int src_port)
47 {
48         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, 
49                                                        struct nbtd_interface);
50         struct nbtd_server *nbtsrv = iface->nbtsrv;
51         
52         /* if its not a broadcast then its not considered a self packet */
53         if (!(packet->operation & NBT_FLAG_BROADCAST)) {
54                 return False;
55         }
56
57         /* if its not from the nbt port, then it wasn't a broadcast from us */
58         if (src_port != lp_nbt_port()) {
59                 return False;
60         }
61
62         /* this uses the fact that iface->nbtsock is our non-broadcast
63            listen address */
64         if (iface->nbtsock == nbtsock &&
65             iface != iface->nbtsrv->bcast_interface) {
66                 return False;
67         }
68
69         /* we have to loop over our interface list, seeing if its from
70            one of our own interfaces */
71         for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
72                 if (strcmp(src_address, iface->ip_address) == 0) {
73                         return True;
74                 }
75         }
76
77         return False;
78 }
79
80
81 /*
82   send a name query reply
83 */
84 void nbtd_name_query_reply(struct nbt_name_socket *nbtsock, 
85                            struct nbt_name_packet *request_packet, 
86                            const char *src_address, int src_port,
87                            struct nbt_name *name, uint32_t ttl,
88                            uint16_t nb_flags, const char **addresses)
89 {
90         struct nbt_name_packet *packet;
91         size_t num_addresses = str_list_length(addresses);
92         int i;
93
94         if (num_addresses == 0) {
95                 DEBUG(3,("No addresses in name query reply - failing\n"));
96                 return;
97         }
98
99         packet = talloc_zero(nbtsock, struct nbt_name_packet);
100         if (packet == NULL) return;
101
102         packet->name_trn_id = request_packet->name_trn_id;
103         packet->ancount = 1;
104         packet->operation = 
105                 NBT_FLAG_REPLY | 
106                 NBT_OPCODE_QUERY | 
107                 NBT_FLAG_AUTHORITIVE |
108                 NBT_FLAG_RECURSION_DESIRED |
109                 NBT_FLAG_RECURSION_AVAIL;
110
111         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
112         if (packet->answers == NULL) goto failed;
113
114         packet->answers[0].name     = *name;
115         packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
116         packet->answers[0].rr_class = NBT_QCLASS_IP;
117         packet->answers[0].ttl      = ttl;
118         packet->answers[0].rdata.netbios.length = num_addresses*6;
119         packet->answers[0].rdata.netbios.addresses = 
120                 talloc_array(packet->answers, struct nbt_rdata_address, num_addresses);
121         if (packet->answers[0].rdata.netbios.addresses == NULL) goto failed;
122
123         for (i=0;i<num_addresses;i++) {
124                 struct nbt_rdata_address *addr = 
125                         &packet->answers[0].rdata.netbios.addresses[i];
126                 addr->nb_flags = nb_flags;
127                 addr->ipaddr = talloc_strdup(packet->answers, addresses[i]);
128                 if (addr->ipaddr == NULL) goto failed;
129         }
130
131         DEBUG(7,("Sending name query reply for %s at %s to %s:%d\n", 
132                  nbt_name_string(packet, name), addresses[0], src_address, src_port));
133         
134         nbt_name_reply_send(nbtsock, src_address, src_port, packet);
135
136 failed:
137         talloc_free(packet);
138 }
139
140
141 /*
142   send a negative name query reply
143 */
144 void nbtd_negative_name_query_reply(struct nbt_name_socket *nbtsock, 
145                                     struct nbt_name_packet *request_packet, 
146                                     const char *src_address, int src_port)
147 {
148         struct nbt_name_packet *packet;
149         struct nbt_name *name = &request_packet->questions[0].name;
150
151         packet = talloc_zero(nbtsock, struct nbt_name_packet);
152         if (packet == NULL) return;
153
154         packet->name_trn_id = request_packet->name_trn_id;
155         packet->ancount = 1;
156         packet->operation = 
157                 NBT_FLAG_REPLY | 
158                 NBT_OPCODE_QUERY | 
159                 NBT_FLAG_AUTHORITIVE |
160                 NBT_RCODE_NAM;
161
162         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
163         if (packet->answers == NULL) goto failed;
164
165         packet->answers[0].name      = *name;
166         packet->answers[0].rr_type   = NBT_QTYPE_NULL;
167         packet->answers[0].rr_class  = NBT_QCLASS_IP;
168         packet->answers[0].ttl       = 0;
169         ZERO_STRUCT(packet->answers[0].rdata);
170
171         DEBUG(7,("Sending negative name query reply for %s to %s:%d\n", 
172                  nbt_name_string(packet, name), src_address, src_port));
173         
174         nbt_name_reply_send(nbtsock, src_address, src_port, packet);
175
176 failed:
177         talloc_free(packet);
178 }
179
180 /*
181   send a name registration reply
182 */
183 void nbtd_name_registration_reply(struct nbt_name_socket *nbtsock, 
184                                   struct nbt_name_packet *request_packet, 
185                                   const char *src_address, int src_port,
186                                   uint8_t rcode)
187 {
188         struct nbt_name_packet *packet;
189         struct nbt_name *name = &request_packet->questions[0].name;
190
191         packet = talloc_zero(nbtsock, struct nbt_name_packet);
192         if (packet == NULL) return;
193
194         packet->name_trn_id = request_packet->name_trn_id;
195         packet->ancount = 1;
196         packet->operation = 
197                 NBT_FLAG_REPLY | 
198                 NBT_OPCODE_REGISTER |
199                 NBT_FLAG_AUTHORITIVE |
200                 NBT_FLAG_RECURSION_DESIRED |
201                 NBT_FLAG_RECURSION_AVAIL |
202                 rcode;
203         
204         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
205         if (packet->answers == NULL) goto failed;
206
207         packet->answers[0].name     = *name;
208         packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
209         packet->answers[0].rr_class = NBT_QCLASS_IP;
210         packet->answers[0].ttl      = request_packet->additional[0].ttl;
211         packet->answers[0].rdata    = request_packet->additional[0].rdata;
212
213         DEBUG(7,("Sending %s name registration reply for %s to %s:%d\n", 
214                  rcode==0?"positive":"negative",
215                  nbt_name_string(packet, name), src_address, src_port));
216         
217         nbt_name_reply_send(nbtsock, src_address, src_port, packet);
218
219 failed:
220         talloc_free(packet);
221 }
222
223
224 /*
225   send a name release reply
226 */
227 void nbtd_name_release_reply(struct nbt_name_socket *nbtsock, 
228                              struct nbt_name_packet *request_packet, 
229                              const char *src_address, int src_port,
230                              uint8_t rcode)
231 {
232         struct nbt_name_packet *packet;
233         struct nbt_name *name = &request_packet->questions[0].name;
234
235         packet = talloc_zero(nbtsock, struct nbt_name_packet);
236         if (packet == NULL) return;
237
238         packet->name_trn_id = request_packet->name_trn_id;
239         packet->ancount = 1;
240         packet->operation = 
241                 NBT_FLAG_REPLY | 
242                 NBT_OPCODE_RELEASE |
243                 NBT_FLAG_AUTHORITIVE |
244                 rcode;
245         
246         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
247         if (packet->answers == NULL) goto failed;
248
249         packet->answers[0].name     = *name;
250         packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
251         packet->answers[0].rr_class = NBT_QCLASS_IP;
252         packet->answers[0].ttl      = request_packet->additional[0].ttl;
253         packet->answers[0].rdata    = request_packet->additional[0].rdata;
254
255         DEBUG(7,("Sending %s name release reply for %s to %s:%d\n", 
256                  rcode==0?"positive":"negative",
257                  nbt_name_string(packet, name), src_address, src_port));
258         
259         nbt_name_reply_send(nbtsock, src_address, src_port, packet);
260
261 failed:
262         talloc_free(packet);
263 }
264
265
266 /*
267   send a WACK reply
268 */
269 void nbtd_wack_reply(struct nbt_name_socket *nbtsock, 
270                      struct nbt_name_packet *request_packet, 
271                      const char *src_address, int src_port,
272                      uint32_t ttl)
273 {
274         struct nbt_name_packet *packet;
275         struct nbt_name *name = &request_packet->questions[0].name;
276
277         packet = talloc_zero(nbtsock, struct nbt_name_packet);
278         if (packet == NULL) return;
279
280         packet->name_trn_id = request_packet->name_trn_id;
281         packet->ancount = 1;
282         packet->operation = 
283                 NBT_FLAG_REPLY | 
284                 NBT_OPCODE_WACK |
285                 NBT_FLAG_AUTHORITIVE;
286         
287         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
288         if (packet->answers == NULL) goto failed;
289
290         packet->answers[0].name              = *name;
291         packet->answers[0].rr_type           = NBT_QTYPE_NETBIOS;
292         packet->answers[0].rr_class          = NBT_QCLASS_IP;
293         packet->answers[0].ttl               = ttl;
294         packet->answers[0].rdata.data.length = 2;
295         packet->answers[0].rdata.data.data   = talloc_size(packet, 2);
296         if (packet->answers[0].rdata.data.data == NULL) goto failed;
297         RSSVAL(packet->answers[0].rdata.data.data, 0, request_packet->operation);
298
299         DEBUG(7,("Sending WACK reply for %s to %s:%d\n", 
300                  nbt_name_string(packet, name), src_address, src_port));
301         
302         nbt_name_reply_send(nbtsock, src_address, src_port, packet);
303
304 failed:
305         talloc_free(packet);
306 }