1) updated ipc.c NetUserGetInfo - load \\%L\%U instead of \\%L\HOMES
[kai/samba.git] / source3 / namepacket.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
5    Copyright (C) Andrew Tridgell 1994-1995
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21    Revision History:
22
23    14 jan 96: lkcl@pires.co.uk
24    added multiple workgroup domain master support
25
26 */
27
28 #include "includes.h"
29
30 extern int ClientNMB;
31 extern int ClientDGRAM;
32
33 extern int DEBUGLEVEL;
34
35 extern int num_response_packets;
36
37 BOOL CanRecurse = True;
38 extern pstring scope;
39 extern struct in_addr ipgrp;
40
41 static uint16 name_trn_id=0;
42
43
44 /***************************************************************************
45   updates the unique transaction identifier
46   **************************************************************************/
47 void debug_browse_data(char *outbuf, int len)
48 {
49     int i,j;
50     for (i = 0; i < len; i+= 16)
51       {
52         DEBUG(4, ("%3x char ", i));
53         
54         for (j = 0; j < 16; j++)
55           {
56             unsigned char x = outbuf[i+j];
57             if (x < 32 || x > 127) x = '.';
58             
59             if (i+j >= len) break;
60             DEBUG(4, ("%c", x));
61           }
62         
63         DEBUG(4, (" hex ", i));
64         
65         for (j = 0; j < 16; j++)
66           {
67             if (i+j >= len) break;
68             DEBUG(4, (" %02x", outbuf[i+j]));
69           }
70         
71         DEBUG(4, ("\n"));
72       }
73     
74 }
75
76
77 /***************************************************************************
78   updates the unique transaction identifier
79   **************************************************************************/
80 static void update_name_trn_id(void)
81 {
82   if (!name_trn_id)
83   {
84     name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
85   }
86   name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
87 }
88
89
90 /****************************************************************************
91   initiate a netbios packet
92   ****************************************************************************/
93 void initiate_netbios_packet(uint16 *id,
94                                 int fd,int quest_type,char *name,int name_type,
95                             int nb_flags,BOOL bcast,BOOL recurse,
96                             struct in_addr to_ip)
97 {
98   struct packet_struct p;
99   struct nmb_packet *nmb = &p.packet.nmb;
100   struct res_rec additional_rec;
101   char *packet_type = "unknown";
102   int opcode = -1;
103
104   if (!id) return;
105
106   if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
107   if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
108   if (quest_type == NMB_REG   ) { packet_type = "nmb_reg"; opcode = 5; }
109   if (quest_type == NMB_REG_REFRESH ) { packet_type = "nmb_reg_refresh"; opcode = 9; }
110   if (quest_type == NMB_REL   ) { packet_type = "nmb_rel"; opcode = 6; }
111   
112   DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
113            packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
114
115   if (opcode == -1) return;
116
117   bzero((char *)&p,sizeof(p));
118
119   if (*id == 0xffff) {
120     update_name_trn_id();
121     *id = name_trn_id; /* allow resending with same id */
122   }
123
124   nmb->header.name_trn_id = *id;
125   nmb->header.opcode = opcode;
126   nmb->header.response = False;
127
128   nmb->header.nm_flags.bcast = bcast;
129   nmb->header.nm_flags.recursion_available = False;
130   nmb->header.nm_flags.recursion_desired = recurse;
131   nmb->header.nm_flags.trunc = False;
132   nmb->header.nm_flags.authoritative = False;
133
134   nmb->header.rcode = 0;
135   nmb->header.qdcount = 1;
136   nmb->header.ancount = 0;
137   nmb->header.nscount = 0;
138   nmb->header.arcount = (quest_type==NMB_REG || 
139                          quest_type==NMB_REL ||
140                          quest_type==NMB_REG_REFRESH) ? 1 : 0;
141   
142   make_nmb_name(&nmb->question.question_name,name,name_type,scope);
143   
144   nmb->question.question_type = 0x20;
145   nmb->question.question_class = 0x1;
146   
147   if (quest_type == NMB_REG ||
148       quest_type == NMB_REG_REFRESH ||
149       quest_type == NMB_REL)
150   {
151       nmb->additional = &additional_rec;
152       bzero((char *)nmb->additional,sizeof(*nmb->additional));
153       
154       nmb->additional->rr_name  = nmb->question.question_name;
155       nmb->additional->rr_type  = 0x20;
156       nmb->additional->rr_class = 0x1;
157       
158       if (quest_type == NMB_REG || quest_type == NMB_REG_REFRESH)
159         nmb->additional->ttl = lp_max_ttl();
160       else
161         nmb->additional->ttl = 0;
162
163       nmb->additional->rdlength = 6;
164       nmb->additional->rdata[0] = nb_flags;
165       putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
166   }
167   
168   p.ip = to_ip;
169   p.port = NMB_PORT;
170   p.fd = fd;
171   p.timestamp = time(NULL);
172   p.packet_type = NMB_PACKET;
173   
174   debug_nmb_packet(&p);
175   
176   if (!send_packet(&p)) {
177     DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
178     *id = 0xffff;
179   }
180   
181   return;
182 }
183
184
185 /****************************************************************************
186   reply to a netbios name packet 
187   ****************************************************************************/
188 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
189                                 int rcode, int rcv_code, int opcode, BOOL recurse,
190                                 struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
191                                 char *data,int len)
192 {
193   struct packet_struct p;
194   struct nmb_packet *nmb = &p.packet.nmb;
195   struct res_rec answers;
196   char *packet_type = "unknown";
197   BOOL recursion_desired = False;
198   
199   p = *p1;
200
201   switch (rcv_code)
202   {
203     case NMB_STATUS:
204         {
205       packet_type = "nmb_status";
206       recursion_desired = True;
207       break;
208     }
209     case NMB_QUERY:
210         {
211       packet_type = "nmb_query";
212       recursion_desired = True;
213       break;
214     }
215     case NMB_REG:
216         {
217       packet_type = "nmb_reg";
218       recursion_desired = True;
219       break;
220     }
221     case NMB_REL:
222         {
223       packet_type = "nmb_rel";
224       recursion_desired = False;
225       break;
226     }
227     case NMB_WAIT_ACK:
228         {
229       packet_type = "nmb_wack";
230       recursion_desired = False;
231       break;
232     }
233     default:
234     {
235       DEBUG(1,("replying netbios packet: %s %s\n",
236                     packet_type, namestr(rr_name), inet_ntoa(p.ip)));
237
238       return;
239     }
240   }
241
242   DEBUG(4,("replying netbios packet: %s %s\n",
243            packet_type, namestr(rr_name), inet_ntoa(p.ip)));
244
245   nmb->header.name_trn_id = trn_id;
246   nmb->header.opcode = opcode;
247   nmb->header.response = True;
248   nmb->header.nm_flags.bcast = False;
249   nmb->header.nm_flags.recursion_available = recurse;
250   nmb->header.nm_flags.recursion_desired = recursion_desired;
251   nmb->header.nm_flags.trunc = False;
252   nmb->header.nm_flags.authoritative = True;
253   
254   nmb->header.qdcount = 0;
255   nmb->header.ancount = 1;
256   nmb->header.nscount = 0;
257   nmb->header.arcount = 0;
258   nmb->header.rcode = rcode;
259   
260   bzero((char*)&nmb->question,sizeof(nmb->question));
261   
262   nmb->answers = &answers;
263   bzero((char*)nmb->answers,sizeof(*nmb->answers));
264   
265   nmb->answers->rr_name  = *rr_name;
266   nmb->answers->rr_type  = rr_type;
267   nmb->answers->rr_class = rr_class;
268   nmb->answers->ttl      = ttl;
269   
270   if (data && len)
271     {
272       nmb->answers->rdlength = len;
273       memcpy(nmb->answers->rdata, data, len);
274     }
275   
276   p.packet_type = NMB_PACKET;
277   
278   debug_nmb_packet(&p);
279   
280   send_packet(&p);
281 }
282
283
284 /*******************************************************************
285   the global packet linked-list. incoming entries are added to the
286   end of this list.  it is supposed to remain fairly short so we
287   won't bother with an end pointer.
288   ******************************************************************/
289 static struct packet_struct *packet_queue = NULL;
290
291 /*******************************************************************
292   queue a packet into the packet queue
293   ******************************************************************/
294 void queue_packet(struct packet_struct *packet)
295 {
296   struct packet_struct *p;
297
298   if (!packet_queue) {
299     packet->prev = NULL;
300     packet->next = NULL;
301     packet_queue = packet;
302     return;
303   }
304   
305   /* find the bottom */
306   for (p=packet_queue;p->next;p=p->next) ;
307
308   p->next = packet;
309   packet->next = NULL;
310   packet->prev = p;
311 }
312
313 /****************************************************************************
314   determine if a packet is for us. Note that to have any chance of
315   being efficient we need to drop as many packets as possible at this
316   stage as subsequent processing is expensive. 
317
318   We also must make absolutely sure we don't tread on another machines
319   property by answering a packet that is not for us.
320   ****************************************************************************/
321 static BOOL listening(struct packet_struct *p,struct nmb_name *n)
322 {
323   struct subnet_record *d;
324   struct name_record *n1;
325
326   d = find_subnet(p->ip);
327   
328   n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
329
330   return (n1 != NULL);
331 }
332
333
334 /****************************************************************************
335   process udp 138 datagrams
336   ****************************************************************************/
337 static void process_dgram(struct packet_struct *p)
338 {
339   char *buf;
340   char *buf2;
341   int len;
342   struct dgram_packet *dgram = &p->packet.dgram;
343
344   /* if we aren't listening to the destination name then ignore the packet */
345   if (!listening(p,&dgram->dest_name))
346     return;
347
348
349   if (dgram->header.msg_type != 0x10 &&
350       dgram->header.msg_type != 0x11 &&
351       dgram->header.msg_type != 0x12) {
352     /* don't process error packets etc yet */
353     return;
354   }
355
356   buf = &dgram->data[0];
357   buf -= 4; /* XXXX for the pseudo tcp length - 
358                someday I need to get rid of this */
359
360   if (CVAL(buf,smb_com) != SMBtrans) return;
361
362   len = SVAL(buf,smb_vwv11);
363   buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
364
365   DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
366            namestr(&dgram->source_name),namestr(&dgram->dest_name),
367            smb_buf(buf),CVAL(buf2,0),len));
368
369  
370   if (len <= 0) return;
371
372    /* datagram packet received for the browser mailslot */
373    if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
374      process_browse_packet(p,buf2,len);
375      return;
376    }
377
378    /* datagram packet received for the domain log on mailslot */
379    if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
380      process_logon_packet(p,buf2,len);
381      return;
382    }
383 }
384
385 /****************************************************************************
386   process a nmb packet
387   ****************************************************************************/
388 static void process_nmb(struct packet_struct *p)
389 {
390   struct nmb_packet *nmb = &p->packet.nmb;
391
392   debug_nmb_packet(p);
393
394   switch (nmb->header.opcode) 
395   {
396     case 8: /* what is this?? */
397     case NMB_REG:
398     case NMB_REG_REFRESH:
399     {
400         if (nmb->header.response)
401         {
402           if (nmb->header.ancount ==0) break;
403           response_netbios_packet(p); /* response to registration dealt 
404                                          with here */
405         }
406         else
407         {
408           if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
409           reply_name_reg(p);
410         }
411         break;
412     }
413       
414     case 0:
415     {
416           if (nmb->header.response)
417           {
418             switch (nmb->question.question_type)
419               {
420               case 0x0:
421                 {
422                   response_netbios_packet(p);
423                   break;
424                 }
425               }
426             return;
427           }
428       else if (nmb->header.qdcount>0) 
429           {
430             switch (nmb->question.question_type)
431               {
432               case NMB_QUERY:
433                 {
434                   reply_name_query(p);
435                   break;
436                 }
437               case NMB_STATUS:
438                 {
439                   reply_name_status(p);
440                   break;
441                 }
442               }
443             return;
444           }
445         break;
446       }
447       
448     case NMB_REL:
449     {
450         if (nmb->header.response)
451         {
452           if (nmb->header.ancount ==0) break;
453           response_netbios_packet(p); /* response to release dealt 
454                                          with here */
455         }
456         else
457         {
458           if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
459           reply_name_release(p);
460         }
461       break;
462     }
463   }
464 }
465
466
467 /*******************************************************************
468   run elements off the packet queue till its empty
469   ******************************************************************/
470 void run_packet_queue()
471 {
472   struct packet_struct *p;
473
474   while ((p=packet_queue))
475     {
476       switch (p->packet_type)
477         {
478         case NMB_PACKET:
479           process_nmb(p);
480           break;
481           
482         case DGRAM_PACKET:
483           process_dgram(p);
484           break;
485         }
486       
487       packet_queue = packet_queue->next;
488       if (packet_queue) packet_queue->prev = NULL;
489       free_packet(p);
490     }
491 }
492
493 /****************************************************************************
494   listens for NMB or DGRAM packets, and queues them
495   ***************************************************************************/
496 void listen_for_packets(BOOL run_election)
497 {
498         fd_set fds;
499         int selrtn;
500         struct timeval timeout;
501
502         FD_ZERO(&fds);
503         FD_SET(ClientNMB,&fds);
504         FD_SET(ClientDGRAM,&fds);
505
506         /* during elections and when expecting a netbios response packet we
507         need to send election packets at tighter intervals 
508
509         ideally it needs to be the interval (in ms) between time now and
510         the time we are expecting the next netbios packet */
511
512         timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
513         timeout.tv_usec = 0;
514
515         selrtn = sys_select(&fds,&timeout);
516
517         if (FD_ISSET(ClientNMB,&fds))
518         {
519                 struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
520                 if (packet)
521                 {
522                         if (ismyip(packet->ip) && packet->port == NMB_PORT)
523                         {
524                                 DEBUG(7,("discarding own packet from %s:%d\n",
525                                           inet_ntoa(packet->ip),packet->port));   
526                                 free_packet(packet);
527                         }
528                         else
529                         {
530                                 queue_packet(packet);
531                         }
532                 }
533         }
534
535         if (FD_ISSET(ClientDGRAM,&fds))
536         {
537                 struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
538                 if (packet)
539                 {
540                         if (ismyip(packet->ip) && packet->port == DGRAM_PORT)
541                         {
542                                 DEBUG(7,("discarding own packet from %s:%d\n",
543                                           inet_ntoa(packet->ip),packet->port));   
544                                 free_packet(packet);
545                         }
546                         else
547                         {
548                                 queue_packet(packet);
549                         }
550                 }
551         }
552 }
553
554
555
556 /****************************************************************************
557   construct and send a netbios DGRAM
558
559   Note that this currently sends all answers to port 138. thats the
560   wrong things to do! I should send to the requestors port. XXX
561   **************************************************************************/
562 BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname,
563                          char *dstname,int src_type,int dest_type,
564                          struct in_addr dest_ip,struct in_addr src_ip)
565 {
566   struct packet_struct p;
567   struct dgram_packet *dgram = &p.packet.dgram;
568   struct in_addr wins_ip = ipgrp;
569   char *ptr,*p2;
570   char tmp[4];
571
572   /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
573   if (ip_equal(wins_ip, dest_ip)) return False;
574
575   bzero((char *)&p,sizeof(p));
576
577   update_name_trn_id();
578
579   /* DIRECT GROUP or UNIQUE datagram */
580   dgram->header.msg_type = unique ? 0x10 : 0x11; 
581   dgram->header.flags.node_type = M_NODE;
582   dgram->header.flags.first = True;
583   dgram->header.flags.more = False;
584   dgram->header.dgm_id = name_trn_id;
585   dgram->header.source_ip = src_ip;
586   dgram->header.source_port = DGRAM_PORT;
587   dgram->header.dgm_length = 0; /* let build_dgram() handle this */
588   dgram->header.packet_offset = 0;
589   
590   make_nmb_name(&dgram->source_name,srcname,src_type,scope);
591   make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
592
593   ptr = &dgram->data[0];
594
595   /* now setup the smb part */
596   ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
597   memcpy(tmp,ptr,4);
598   set_message(ptr,17,17 + len,True);
599   memcpy(ptr,tmp,4);
600
601   CVAL(ptr,smb_com) = SMBtrans;
602   SSVAL(ptr,smb_vwv1,len);
603   SSVAL(ptr,smb_vwv11,len);
604   SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
605   SSVAL(ptr,smb_vwv13,3);
606   SSVAL(ptr,smb_vwv14,1);
607   SSVAL(ptr,smb_vwv15,1);
608   SSVAL(ptr,smb_vwv16,2);
609   p2 = smb_buf(ptr);
610   strcpy(p2,mailslot);
611   p2 = skip_string(p2,1);
612
613   memcpy(p2,buf,len);
614   p2 += len;
615
616   dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
617
618   p.ip = dest_ip;
619   p.port = DGRAM_PORT;
620   p.fd = ClientDGRAM;
621   p.timestamp = time(NULL);
622   p.packet_type = DGRAM_PACKET;
623
624   DEBUG(4,("send mailslot %s from %s %s", mailslot,
625                     inet_ntoa(src_ip),namestr(&dgram->source_name)));
626   DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
627
628   return(send_packet(&p));
629 }