added sequent fixes
[samba.git] / source / nameserv.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 */
22
23 #include "includes.h"
24 #include "loadparm.h"
25 #include "nameserv.h"
26
27
28 static void queue_packet(struct packet_struct *packet);
29 void process(void);
30 static void dump_names(void);
31 static void announce_request(char *group);
32 void sync_browse_lists(char *name,int name_type,char *myname,
33                        char *domain,struct in_addr ip);
34
35 extern int DEBUGLEVEL;
36
37 extern pstring debugf;
38 pstring servicesf = CONFIGFILE;
39
40 extern pstring scope;
41
42 extern BOOL CanRecurse;
43
44 extern struct in_addr myip;
45 extern struct in_addr bcast_ip;
46 extern struct in_addr Netmask;
47 extern pstring myhostname;
48 static pstring host_file;
49 static pstring myname="";
50
51 static int ClientNMB= -1;
52 static int ClientDGRAM= -1;
53
54 static BOOL needannounce=True;
55
56 /* this is our name database */
57 static struct name_record *namelist = NULL;
58
59 /* list of servers to be returned by NetServerEnum */
60 static struct server_record *serverlist = NULL;
61
62 /* this is the domain list. For the moment we will assume that our
63    primary domain is the first one listed in this list */
64 static struct domain_record *domainlist = NULL;
65
66 /* are we running as a daemon ? */
67 static BOOL is_daemon = False;
68
69 /* machine comment for host announcements */
70 static pstring ServerComment="";
71
72 static BOOL got_bcast = False;
73 static BOOL got_myip = False;
74 static BOOL got_nmask = False;
75
76 static BOOL updatedlists = False;
77 static int  updatecount=0;
78
79 /* what server type are we currently */
80 static int ServerType = 
81 SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_TIME_SOURCE |
82 SV_TYPE_SERVER_UNIX |
83 SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER;
84
85 /* here are my election parameters */
86
87 /* NTAS uses 2, NT uses 1, WfWg uses 0 */
88 #define MAINTAIN_LIST 1
89 #define ELECTION_VERSION 1
90
91 static BOOL RunningElection = False;
92 static BOOL needelection = False;
93 static int ElectionCount = 0;
94 static int StartupTime =0;
95
96
97 /* WfWg uses 01040b01 */
98 /* Win95 uses 01041501 */
99 /* NTAS uses ?? */
100 static uint32 ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
101
102 /* we currently support being the master for just one group. Being the
103    master for more than one group might be tricky as NetServerEnum is
104    often asked for a list without naming the group */
105 static fstring PrimaryGroup="";
106
107 #define AM_MASTER (PrimaryGroup[0] && (ServerType & SV_TYPE_MASTER_BROWSER))
108
109 #define MSBROWSE "\001\002__MSBROWSE__\002"
110
111 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
112
113 #define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
114
115 /****************************************************************************
116 catch a sighup
117 ****************************************************************************/
118 static int sig_hup()
119 {
120   BlockSignals(True);
121
122   DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
123   dump_names();
124   reload_services(True);
125
126   BlockSignals(False);
127 #ifndef DONT_REINSTALL_SIG
128   signal(SIGHUP,SIGNAL_CAST sig_hup);
129 #endif
130   return(0);
131 }
132
133 /****************************************************************************
134 catch a sigpipe
135 ****************************************************************************/
136 static int sig_pipe()
137 {
138   BlockSignals(True);
139
140   DEBUG(0,("Got SIGPIPE\n"));
141   if (!is_daemon)
142     exit(1);
143   BlockSignals(False);
144   return(0);
145 }
146
147 #if DUMP_CORE
148 /*******************************************************************
149 prepare to dump a core file - carefully!
150 ********************************************************************/
151 static BOOL dump_core(void)
152 {
153   char *p;
154   pstring dname;
155   strcpy(dname,debugf);
156   if ((p=strrchr(dname,'/'))) *p=0;
157   strcat(dname,"/corefiles");
158   mkdir(dname,0700);
159   sys_chown(dname,getuid(),getgid());
160   chmod(dname,0700);
161   if (chdir(dname)) return(False);
162   umask(~(0700));
163
164 #ifndef NO_GETRLIMIT
165 #ifdef RLIMIT_CORE
166   {
167     struct rlimit rlp;
168     getrlimit(RLIMIT_CORE, &rlp);
169     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
170     setrlimit(RLIMIT_CORE, &rlp);
171     getrlimit(RLIMIT_CORE, &rlp);
172     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
173   }
174 #endif
175 #endif
176
177
178   DEBUG(0,("Dumping core in %s\n",dname));
179   return(True);
180 }
181 #endif
182
183
184 /****************************************************************************
185 possibly continue after a fault
186 ****************************************************************************/
187 static void fault_continue(void)
188 {
189   static int errcount=1;
190
191   errcount--;
192
193   if (is_daemon && errcount)
194     process();
195
196 #if DUMP_CORE
197     if (dump_core()) return;
198 #endif
199
200   return;
201 }
202
203
204 /*******************************************************************
205   wrapper to get the DC
206   ******************************************************************/
207 static char *domain_controller(void)
208 {
209   char *dc = lp_domain_controller();
210   /* so many people mistake this for a bool that we need to handle it. sigh. */
211   if (!*dc || strequal(dc,"yes") || strequal(dc,"true"))
212     strcpy(dc,myname);
213   return(dc);
214 }
215
216
217
218 /****************************************************************************
219   true if two netbios names are equal
220 ****************************************************************************/
221 static BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
222 {
223   if (n1->name_type != n2->name_type) return(False);
224
225   return(strequal(n1->name,n2->name) && strequal(n1->scope,n2->scope));
226 }
227
228 /****************************************************************************
229   add a netbios name into the namelist
230   **************************************************************************/
231 static void add_name(struct name_record *n)
232 {
233   struct name_record *n2;
234
235   if (!namelist) {
236     namelist = n;
237     n->prev = NULL;
238     n->next = NULL;
239     return;
240   }
241
242   for (n2 = namelist; n2->next; n2 = n2->next) ;
243
244   n2->next = n;
245   n->next = NULL;
246   n->prev = n2;
247 }
248
249 /****************************************************************************
250   add a domain into the list
251   **************************************************************************/
252 static void add_domain(struct domain_record *d)
253 {
254   struct domain_record *d2;
255
256   if (!domainlist) {
257     domainlist = d;
258     d->prev = NULL;
259     d->next = NULL;
260     return;
261   }
262
263   for (d2 = domainlist; d2->next; d2 = d2->next) ;
264
265   d2->next = d;
266   d->next = NULL;
267   d->prev = d2;
268 }
269
270
271 /****************************************************************************
272   add a server into the list
273   **************************************************************************/
274 static void add_server(struct server_record *s)
275 {
276   struct server_record *s2;
277
278   if (!serverlist) {
279     serverlist = s;
280     s->prev = NULL;
281     s->next = NULL;
282     return;
283   }
284
285   for (s2 = serverlist; s2->next; s2 = s2->next) ;
286
287   s2->next = s;
288   s->next = NULL;
289   s->prev = s2;
290 }
291
292 /****************************************************************************
293   remove a name from the namelist. The pointer must be an element just 
294   retrieved
295   **************************************************************************/
296 static void remove_name(struct name_record *n)
297 {
298   struct name_record *nlist = namelist;
299   while (nlist && nlist != n) nlist = nlist->next;
300   if (nlist) {
301     if (nlist->next) nlist->next->prev = nlist->prev;
302     if (nlist->prev) nlist->prev->next = nlist->next;
303     free(nlist);
304   }
305 }
306
307 /****************************************************************************
308   find a name in the namelist 
309   **************************************************************************/
310 static struct name_record *find_name(struct nmb_name *n)
311 {
312   struct name_record *ret;
313   for (ret = namelist; ret; ret = ret->next)
314     if (name_equal(&ret->name,n)) return(ret);
315
316   return(NULL);
317 }
318
319 /****************************************************************************
320   dump a copy of the name table
321   **************************************************************************/
322 static void dump_names(void)
323 {
324   time_t t = time(NULL);
325   struct name_record *n;
326   struct domain_record *d;
327
328   DEBUG(3,("Dump of local name table:\n"));
329
330   for (n = namelist; n; n = n->next) {
331     DEBUG(3,("%s %s TTL=%d Unique=%s\n",
332              namestr(&n->name),
333              inet_ntoa(n->ip),
334              n->death_time?n->death_time-t:0,
335              BOOLSTR(n->unique)));
336     }
337
338   DEBUG(3,("\nDump of domain list:\n"));
339   for (d = domainlist; d; d = d->next)
340     DEBUG(3,("%s %s\n",d->name,inet_ntoa(d->bcast_ip)));
341 }
342
343
344 /****************************************************************************
345   add a host entry to the name list
346   ****************************************************************************/
347 static struct name_record *add_host_entry(char *name,int type,BOOL unique,int ttl,
348                                           enum name_source source,
349                                           struct in_addr ip)
350 {
351   struct name_record *n;
352   struct name_record *n2=NULL;
353
354   n = (struct name_record *)malloc(sizeof(*n));
355   if (!n) return(NULL);
356
357   bzero((char *)n,sizeof(*n));
358
359   make_nmb_name(&n->name,name,type,scope);
360   if ((n2=find_name(&n->name))) {
361     free(n);
362     n = n2;
363   }
364
365   if (ttl) n->death_time = time(NULL)+ttl*3;
366   n->ip = ip;
367   n->unique = unique;
368   n->source = source;
369   
370   if (!n2) add_name(n);
371
372   DEBUG(3,("Added host entry %s at %s ttl=%d unique=%s\n",
373            namestr(&n->name),inet_ntoa(ip),ttl,BOOLSTR(unique)));
374
375   return(n);
376 }
377
378
379 /****************************************************************************
380   add a domain entry
381   ****************************************************************************/
382 static struct domain_record *add_domain_entry(char *name,struct in_addr ip)
383 {
384   struct domain_record *d;
385
386   d = (struct domain_record *)malloc(sizeof(*d));
387
388   if (!d) return(NULL);
389
390   bzero((char *)d,sizeof(*d));
391
392   if (zero_ip(ip)) ip = bcast_ip;
393
394   StrnCpy(d->name,name,sizeof(d->name)-1);
395   d->bcast_ip = ip;
396
397   if (!PrimaryGroup[0] && ip_equal(bcast_ip,ip) && name[0] != '*') {
398     strcpy(PrimaryGroup,name);
399     strupper(PrimaryGroup);
400     DEBUG(3,("Setting primary group to %s (%s)\n",PrimaryGroup,inet_ntoa(ip)));
401   }
402
403   add_domain(d);
404
405   ip = *interpret_addr2("255.255.255.255");
406   if (name[0] != '*') add_host_entry(name,0x1e,False,0,SELF,ip);          
407
408   DEBUG(3,("Added domain entry %s at %s\n",
409            name,inet_ntoa(ip)));
410
411   return(d);
412 }
413
414 /****************************************************************************
415   add a server entry
416   ****************************************************************************/
417 struct server_record *add_server_entry(char *name,int servertype,
418                                        int ttl,char *comment,BOOL replace)
419 {
420   BOOL newentry=False;
421   struct server_record *s;
422
423   for (s = serverlist; s; s = s->next)
424     if (strequal(name,s->name)) break;
425
426   if (s && !replace) {
427     DEBUG(4,("Not replacing %s\n",name));
428     return(s);
429   }
430
431   updatedlists=True;
432
433   if (!s) {
434     newentry = True;
435     s = (struct server_record *)malloc(sizeof(*s));
436
437     if (!s) return(NULL);
438
439     bzero((char *)s,sizeof(*s));
440   }
441
442   /* update the entry */
443   StrnCpy(s->name,name,sizeof(s->name)-1);
444   StrnCpy(s->comment,comment,sizeof(s->comment)-1);
445   s->servertype = servertype;
446   s->death_time = ttl?time(NULL)+ttl*3:0;
447   strupper(s->name);
448   if (s->servertype & SV_TYPE_DOMAIN_ENUM) strupper(s->comment);
449
450   if (!newentry) return(s);
451
452   add_server(s);
453
454   if (newentry) {
455     DEBUG(3,("Added server entry %s of type %x (%s)\n",
456              name,servertype,comment));
457   } else {
458     DEBUG(3,("Updated server entry %s of type %x (%s)\n",
459              name,servertype,comment));
460   }
461
462   return(s);
463 }
464
465
466 /****************************************************************************
467   add the magic samba names, useful for finding samba servers
468   **************************************************************************/
469 static void add_my_names(void)
470 {
471   struct in_addr ip;
472
473   ip = *interpret_addr2("0.0.0.0");
474
475   add_host_entry(myname,0x20,True,0,SELF,ip);
476   add_host_entry(myname,0x0,True,0,SELF,ip);
477   add_host_entry(myname,0x1f,True,0,SELF,ip); /* used for chat?? */
478   add_host_entry(myname,0x3,True,0,SELF,ip); /* used for winpopup */
479                                                 
480   if (!domainlist)
481     add_domain_entry(lp_workgroup(),bcast_ip);
482   add_server_entry(myname,
483                    ServerType,
484                    0,ServerComment,True);
485
486   add_host_entry("__SAMBA__",0x20,True,0,SELF,ip);
487   add_host_entry("__SAMBA__",0x0,True,0,SELF,ip);
488
489   if (lp_preferred_master()) {
490     DEBUG(3,("Preferred master startup\n"));
491     needelection = True;
492     ElectionCriterion |= (1<<3);
493   }
494
495   ElectionCriterion |= (lp_os_level() << 24);
496 }
497
498
499 /*******************************************************************
500   write out browse.dat
501   ******************************************************************/
502 static void write_browse_list(void)
503 {
504   struct server_record *s;
505   pstring fname,fnamenew;
506   FILE *f;
507   
508   updatecount++;
509
510   strcpy(fname,lp_lockdir());
511   trim_string(fname,NULL,"/");
512   strcat(fname,"/");
513   strcat(fname,SERVER_LIST);
514   strcpy(fnamenew,fname);
515   strcat(fnamenew,".");
516   
517   f = fopen(fnamenew,"w");
518   
519   if (!f) {
520     DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
521     return;
522   }
523   
524   for (s=serverlist; s ; s = s->next) {
525     /* don't list domains I don't have a master for */
526     if ((s->servertype & SV_TYPE_DOMAIN_ENUM) && !s->comment[0]) continue;
527         
528     fprintf(f,"\"%s\"\t%08x\t\"%s\"\n",s->name,s->servertype,s->comment);
529   }
530   
531   
532   fclose(f);
533   chmod(fnamenew,0644);
534   /* unlink(fname); */
535   rename(fnamenew,fname);   
536   DEBUG(3,("Wrote browse list %s\n",fname));
537 }
538
539 /*******************************************************************
540   expire old names in the namelist and serverlist
541   ******************************************************************/
542 static void expire_names(void)
543 {
544   static time_t lastrun=0;
545   time_t t = time(NULL);
546   struct name_record *n;
547   struct name_record *next;
548   struct server_record *s;
549   struct server_record *nexts;
550
551   if (!lastrun) lastrun = t;
552   if (t < lastrun + 5) return;
553   lastrun = t;
554
555   /* expire old names */
556   for (n = namelist; n; n = next) {
557     if (n->death_time && n->death_time < t) {
558       DEBUG(3,("Removing dead name %s\n",
559                namestr(&n->name)));
560       next = n->next;
561       if (n->prev) n->prev->next = n->next;
562       if (n->next) n->next->prev = n->prev;
563       if (namelist == n) namelist = n->next; 
564       free(n);
565     } else {
566       next = n->next;
567     }
568   }
569
570   /* expire old entries in the serverlist */
571   for (s = serverlist; s; s = nexts) {
572     if (s->death_time && s->death_time < t) {
573       DEBUG(3,("Removing dead server %s\n",s->name));
574       updatedlists = True;
575       nexts = s->next;
576       if (s->prev) s->prev->next = s->next;
577       if (s->next) s->next->prev = s->prev;
578       if (serverlist == s) serverlist = s->next; 
579       free(s);
580     } else {
581       nexts = s->next;
582     }
583   }
584 }
585
586
587 /*******************************************************************
588   delete old names from the namelist
589   ******************************************************************/
590 static void housekeeping(void)
591 {
592   time_t t = time(NULL);
593
594   expire_names();
595
596   /* write out the browse.dat database for smbd to get */
597   if (updatedlists) {
598     write_browse_list();
599     updatedlists = False;
600   }
601
602   {
603     /* occasionally check to see if the master browser is around */
604     static time_t lastrun=0;
605     if (!lastrun) lastrun = t;
606     if (t < lastrun + 5*60) return;
607     lastrun = t;
608
609     if (!AM_MASTER && PrimaryGroup[0] &&
610         !name_query(ClientNMB,PrimaryGroup,0x1d,True,False,
611                     bcast_ip,NULL,queue_packet)) {
612       DEBUG(2,("Forcing election on %s\n",PrimaryGroup));
613       needelection = True;
614     }
615   }
616 }
617
618
619 /****************************************************************************
620   reload the services file
621   **************************************************************************/
622 BOOL reload_services(BOOL test)
623 {
624   BOOL ret;
625   extern fstring remote_machine;
626
627   strcpy(remote_machine,"nmbd");
628
629   if (lp_loaded())
630     {
631       pstring fname;
632       strcpy(fname,lp_configfile());
633       if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
634         {
635           strcpy(servicesf,fname);
636           test = False;
637         }
638     }
639
640   if (test && !lp_file_list_changed())
641     return(True);
642
643   ret = lp_load(servicesf,True);
644
645   /* perhaps the config filename is now set */
646   if (!test)
647     reload_services(True);
648
649   return(ret);
650 }
651
652
653
654 /****************************************************************************
655 load a netbios hosts file
656 ****************************************************************************/
657 static void load_hosts_file(char *fname)
658 {
659   FILE *f = fopen(fname,"r");
660   pstring line;
661   if (!f) {
662     DEBUG(2,("Can't open lmhosts file %s\n",fname));
663     return;
664   }
665
666   while (!feof(f))
667     {
668       if (!fgets_slash(line,sizeof(pstring),f)) continue;
669       
670       if (*line == '#') continue;
671
672       {
673         BOOL group=False;
674         string ip,name,flags,extra;
675         char *ptr;
676         int count = 0;
677         struct in_addr ipaddr;
678         enum name_source source = LMHOSTS;
679
680         *ip = *name = *flags = *extra = 0;
681
682         ptr = line;
683
684         if (next_token(&ptr,ip,NULL)) ++count;
685         if (next_token(&ptr,name,NULL)) ++count;
686         if (next_token(&ptr,flags,NULL)) ++count;
687         if (next_token(&ptr,extra,NULL)) ++count;
688
689         if (count <= 0) continue;
690
691         if (count > 0 && count < 2)
692           {
693             DEBUG(0,("Ill formed hosts line [%s]\n",line));         
694             continue;
695           }
696
697         if (strchr(flags,'G') || strchr(flags,'S'))
698           group = True;
699
700         if (strchr(flags,'M') && !group) {
701           source = SELF;
702           strcpy(myname,name);
703         }
704
705         ipaddr = *interpret_addr2(ip);
706
707         if (group) {
708           add_domain_entry(name,ipaddr);
709         } else {
710           add_host_entry(name,0x20,True,0,source,ipaddr);
711         }
712       }
713     }
714
715   fclose(f);
716 }
717
718 /*******************************************************************
719   check if 2 IPs are on the same net
720   we will assume the local netmask, although this could be wrong XXXX
721   ******************************************************************/
722 static BOOL same_net(struct in_addr ip1,struct in_addr ip2)
723 {
724   unsigned long net1,net2,nmask;
725
726   nmask = ntohl(Netmask.s_addr);
727   net1 = ntohl(ip1.s_addr);
728   net2 = ntohl(ip2.s_addr);
729             
730   return((net1 & nmask) == (net2 & nmask));
731 }
732
733 /****************************************************************************
734   send an election packet
735   **************************************************************************/
736 static void send_election(char *group,uint32 criterion,int timeup,char *name)
737 {
738   pstring outbuf;
739   char *p;
740
741   DEBUG(2,("Sending election to %s for workgroup %s\n",
742            inet_ntoa(bcast_ip),group));    
743
744   bzero(outbuf,sizeof(outbuf));
745   p = outbuf;
746   CVAL(p,0) = 8; /* election */
747   p++;
748
749   CVAL(p,0) = ELECTION_VERSION;
750   SIVAL(p,1,criterion);
751   SIVAL(p,5,timeup*1000); /* ms - despite the spec */
752   p += 13;
753   strcpy(p,name);
754   strupper(p);
755   p = skip_string(p,1);
756
757   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
758                       name,group,0,0x1e,bcast_ip,myip);
759 }
760
761
762 /****************************************************************************
763   send a backup list response
764   **************************************************************************/
765 static void send_backup_list(char *name,int token,struct nmb_name *to,
766                              struct in_addr ip)
767 {
768   pstring outbuf;
769   char *p;
770
771   DEBUG(2,("Sending backup list to %s for workgroup %s\n",
772            inet_ntoa(ip),PrimaryGroup));           
773
774   bzero(outbuf,sizeof(outbuf));
775   p = outbuf;
776   CVAL(p,0) = 10; /* backup list response */
777   p++;
778
779   CVAL(p,0) = 1; /* count */
780   SIVAL(p,1,token);
781   p += 5; 
782   strcpy(p,name);
783   strupper(p);
784   p = skip_string(p,1) + 1;
785
786   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
787                       myname,to->name,0,to->name_type,ip,myip);
788 }
789
790
791 /*******************************************************************
792   become the master browser
793   ******************************************************************/
794 static void become_master(void)
795 {
796   uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_SERVER_UNIX;
797   DEBUG(2,("Becoming master for %s\n",PrimaryGroup));
798
799   ServerType |= SV_TYPE_MASTER_BROWSER;
800   ServerType |= SV_TYPE_BACKUP_BROWSER;
801   ElectionCriterion |= 0x5;
802
803   add_host_entry(PrimaryGroup,0x1d,True,0,SELF,myip);
804   add_host_entry(PrimaryGroup,0x0,False,0,SELF,myip);
805   add_host_entry(MSBROWSE,1,False,0,SELF,myip);
806
807   if (lp_domain_master()) {
808     add_host_entry(myname,0x1b,True,0,SELF,myip);
809     add_host_entry(PrimaryGroup,0x1b,True,0,SELF,myip);
810     add_host_entry(PrimaryGroup,0x1c,False,0,SELF,myip);
811     ServerType |= SV_TYPE_DOMAIN_MASTER;
812     if (lp_domain_logons()) {
813       ServerType |= SV_TYPE_DOMAIN_CTRL;
814       ServerType |= SV_TYPE_DOMAIN_MEMBER;
815       domain_type |= SV_TYPE_DOMAIN_CTRL;
816     }
817   }
818
819   add_server_entry(PrimaryGroup,domain_type,0,myname,True);
820   add_server_entry(myname,ServerType,0,ServerComment,True);
821
822   announce_request(PrimaryGroup);
823
824   needannounce = True;
825 }
826
827
828 /*******************************************************************
829   unbecome the master browser
830   ******************************************************************/
831 static void become_nonmaster(void)
832 {
833   struct name_record *n;
834   struct nmb_name nn;
835
836   DEBUG(2,("Becoming non-master for %s\n",PrimaryGroup));
837
838   ServerType &= ~SV_TYPE_MASTER_BROWSER;
839   ServerType &= ~SV_TYPE_DOMAIN_CTRL;
840   ServerType &= ~SV_TYPE_DOMAIN_MASTER;
841
842   ElectionCriterion &= ~0x4;
843
844   make_nmb_name(&nn,PrimaryGroup,0x1d,scope);
845   n = find_name(&nn);
846   if (n && n->source == SELF) remove_name(n);
847
848   make_nmb_name(&nn,PrimaryGroup,0x1b,scope);
849   n = find_name(&nn);
850   if (n && n->source == SELF) remove_name(n);
851
852   make_nmb_name(&nn,MSBROWSE,1,scope);
853   n = find_name(&nn);
854   if (n && n->source == SELF) remove_name(n);
855 }
856
857
858 /*******************************************************************
859   run the election
860   ******************************************************************/
861 static void run_election(void)
862 {
863   time_t t = time(NULL);
864   static time_t lastime = 0;
865
866   if (!PrimaryGroup[0] || !RunningElection) return;
867
868   /* send election packets once a second */
869   if (lastime &&
870       t-lastime <= 0) return;
871
872   lastime = t;
873
874   send_election(PrimaryGroup,ElectionCriterion,t-StartupTime,myname);
875
876   if (ElectionCount++ < 4) return;
877    
878   /* I won! now what :-) */
879   RunningElection = False;
880   DEBUG(2,(">>> Won election on %s <<<\n",PrimaryGroup));
881   become_master();
882 }
883
884
885 /****************************************************************************
886   construct a host announcement unicast
887   **************************************************************************/
888 static void announce_host(struct domain_record *d,char *my_name,char *comment)
889 {
890   time_t t = time(NULL);
891   pstring outbuf;
892   char *p;
893   char *namep;
894   char *stypep;
895   char *commentp;
896   uint32 stype = ServerType;
897
898   if (needannounce) {
899     /* drop back to a max 3 minute announce - this is to prevent a
900        single lost packet from stuffing things up for too long */
901     d->announce_interval = MIN(d->announce_interval,3*60);
902     d->lastannounce_time = t - (d->announce_interval+1);
903   }
904
905   /* announce every minute at first then progress to every 12 mins */
906   if (d->lastannounce_time && 
907       (t - d->lastannounce_time) < d->announce_interval)
908     return;
909
910   if (d->announce_interval < 12*60) d->announce_interval += 60;
911   d->lastannounce_time = t;
912
913   DEBUG(2,("Sending announcement to %s for workgroup %s\n",
914            inet_ntoa(d->bcast_ip),d->name));
915
916   if (!strequal(PrimaryGroup,d->name) ||
917       !ip_equal(bcast_ip,d->bcast_ip)) {
918     stype &= ~(SV_TYPE_POTENTIAL_BROWSER | SV_TYPE_MASTER_BROWSER |
919                SV_TYPE_DOMAIN_MASTER | SV_TYPE_BACKUP_BROWSER |
920                SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_MEMBER);
921   }
922
923   if (!*comment) comment = "NoComment";
924   if (!*my_name) my_name = "NoName";
925
926   if (strlen(comment) > 43) comment[43] = 0;  
927
928   bzero(outbuf,sizeof(outbuf));
929   CVAL(outbuf,0) = 1; /* host announce */
930   p = outbuf+1;
931
932   CVAL(p,0) = updatecount;
933   SIVAL(p,1,d->announce_interval*1000); /* ms - despite the spec */
934   namep = p+5;
935   StrnCpy(p+5,my_name,16);
936   strupper(p+5);
937   CVAL(p,21) = 2; /* major version */
938   CVAL(p,22) = 2; /* minor version */
939   stypep = p+23;
940   SIVAL(p,23,stype);
941   SSVAL(p,27,0xaa55); /* browse signature */
942   SSVAL(p,29,1); /* browse version */
943   commentp = p+31;
944   strcpy(p+31,comment);
945   p += 31;
946   p = skip_string(p,1);
947
948   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
949                       my_name,d->name,0,0x1d,d->bcast_ip,myip);
950
951   /* if I'm the master then I also need to do a local master and
952      domain announcement */
953
954   if (AM_MASTER &&
955       strequal(d->name,PrimaryGroup) &&
956       ip_equal(bcast_ip,d->bcast_ip)) {
957
958     /* do master announcements as well */
959     SIVAL(stypep,0,ServerType);
960
961     CVAL(outbuf,0) = 15; /* local master announce */
962     send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
963                         my_name,PrimaryGroup,0,0x1e,d->bcast_ip,myip);
964
965     CVAL(outbuf,0) = 12; /* domain announce */
966     StrnCpy(namep,PrimaryGroup,15);
967     strupper(namep);
968     StrnCpy(commentp,myname,15);
969     strupper(commentp);
970     SIVAL(stypep,0,(unsigned)0x80000000);
971     p = commentp + strlen(commentp) + 1;
972
973     send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
974                         my_name,MSBROWSE,0,1,d->bcast_ip,myip);
975   }
976 }
977
978
979 /****************************************************************************
980   send a announce request to the local net
981   **************************************************************************/
982 static void announce_request(char *group)
983 {
984   pstring outbuf;
985   char *p;
986
987   DEBUG(2,("Sending announce request to %s for workgroup %s\n",
988            inet_ntoa(bcast_ip),group));
989
990   bzero(outbuf,sizeof(outbuf));
991   p = outbuf;
992   CVAL(p,0) = 2; /* announce request */
993   p++;
994
995   CVAL(p,0) = 0; /* flags?? */
996   p++;
997   StrnCpy(p,myname,16);
998   strupper(p);
999   p = skip_string(p,1);
1000
1001   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
1002                       myname,group,0,0,bcast_ip,myip);
1003 }
1004
1005 /****************************************************************************
1006   announce myself as a master to the PDC
1007   **************************************************************************/
1008 static void announce_master(char *group)
1009 {
1010   static time_t last=0;
1011   time_t t = time(NULL);
1012   pstring outbuf;
1013   char *p;
1014   struct in_addr ip,pdc_ip;
1015   fstring pdcname;
1016   *pdcname = 0;
1017
1018   if (strequal(domain_controller(),myname)) return;
1019
1020   if (!AM_MASTER || (last && (t-last < 10*60))) return;
1021   last = t;
1022
1023   ip = *interpret_addr2(domain_controller());
1024
1025   if (zero_ip(ip)) ip = bcast_ip;
1026
1027   if (!name_query(ClientNMB,PrimaryGroup,
1028                   0x1b,False,False,ip,&pdc_ip,queue_packet)) {
1029     DEBUG(2,("Failed to find PDC at %s\n",domain_controller()));
1030     return;
1031   }
1032
1033   name_status(ClientNMB,PrimaryGroup,0x1b,False,
1034               pdc_ip,NULL,pdcname,queue_packet);
1035
1036   if (!pdcname[0]) {
1037     DEBUG(3,("Can't find netbios name of PDC at %s\n",inet_ntoa(pdc_ip)));
1038   } else {
1039     sync_browse_lists(pdcname,0x20,myname,PrimaryGroup,pdc_ip);
1040   }
1041
1042
1043   DEBUG(2,("Sending master announce to %s for workgroup %s\n",
1044            inet_ntoa(pdc_ip),group));
1045
1046   bzero(outbuf,sizeof(outbuf));
1047   p = outbuf;
1048   CVAL(p,0) = 13; /* announce request */
1049   p++;
1050
1051   StrnCpy(p,myname,16);
1052   strupper(p);
1053   p = skip_string(p,1);
1054
1055   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
1056                       myname,PrimaryGroup,0x1b,0,pdc_ip,myip);
1057 }
1058
1059
1060 /*******************************************************************
1061   am I listening on a name. Should check name_type as well 
1062
1063   This is primarily used to prevent us gathering server lists from
1064   other workgroups we aren't a part of
1065   ******************************************************************/
1066 static BOOL listening(struct nmb_name *n)
1067 {
1068   if (!strequal(n->scope,scope)) return(False);
1069
1070   if (strequal(n->name,myname) ||
1071       strequal(n->name,PrimaryGroup) ||
1072       strequal(n->name,MSBROWSE))
1073     return(True);
1074
1075   return(False);
1076 }
1077
1078
1079 /*******************************************************************
1080   process a domain announcement frame
1081
1082   Announce frames come in 3 types. Servers send host announcements
1083   (command=1) to let the master browswer know they are
1084   available. Master browsers send local master announcements
1085   (command=15) to let other masters and backups that they are the
1086   master. They also send domain announcements (command=12) to register
1087   the domain
1088
1089   The comment field of domain announcements contains the master
1090   browser name. The servertype is used by NetServerEnum to select
1091   resources. We just have to pass it to smbd (via browser.dat) and let
1092   the client choose using bit masks.
1093   ******************************************************************/
1094 static void process_announce(struct packet_struct *p,int command,char *buf)
1095 {
1096   struct dgram_packet *dgram = &p->packet.dgram;
1097   int update_count = CVAL(buf,0);
1098   int ttl = IVAL(buf,1)/1000;
1099   char *name = buf+5;
1100   int osmajor=CVAL(buf,21);
1101   int osminor=CVAL(buf,22);
1102   uint32 servertype = IVAL(buf,23);
1103   char *comment = buf+31;
1104
1105   name[15] = 0;  
1106   comment[43] = 0;
1107   
1108   DEBUG(3,("Announce(%d) %s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
1109            command,name,update_count,ttl,osmajor,osminor,
1110            servertype,comment));
1111
1112   if (strequal(dgram->source_name.name,myname)) return;
1113
1114   if (!listening(&dgram->dest_name)) return;
1115
1116   ttl = GET_TTL(ttl);
1117
1118   /* add them to our browse list */
1119   add_server_entry(name,servertype,ttl,comment,True);
1120
1121 }
1122
1123 /*******************************************************************
1124   process a master announcement frame
1125   ******************************************************************/
1126 static void process_master_announce(struct packet_struct *p,char *buf)
1127 {
1128   struct dgram_packet *dgram = &p->packet.dgram;
1129   char *name = buf;
1130
1131   name[15] = 0;
1132   
1133   DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(p->ip)));
1134
1135   if (strequal(dgram->source_name.name,myname)) return;
1136
1137   if (!AM_MASTER || !listening(&dgram->dest_name)) return;
1138
1139   /* merge browse lists with them */
1140   if (lp_domain_master())
1141     sync_browse_lists(name,0x20,myname,PrimaryGroup,p->ip);
1142 }
1143
1144
1145 /*******************************************************************
1146   process a backup list request
1147
1148   A client send a backup list request to ask for a list of servers on
1149   the net that maintain server lists for a domain. A server is then
1150   chosen from this list to send NetServerEnum commands to to list
1151   available servers.
1152
1153   Currently samba only sends back one name in the backup list, its
1154   wn. For larger nets we'll have to add backups and send "become
1155   backup" requests occasionally.
1156   ******************************************************************/
1157 static void process_backup_list(struct packet_struct *p,char *buf)
1158 {
1159   struct dgram_packet *dgram = &p->packet.dgram;
1160   int count = CVAL(buf,0);
1161   int token = IVAL(buf,1);
1162   
1163   DEBUG(3,("Backup request to %s token=%d\n",
1164            namestr(&dgram->dest_name),
1165            token));
1166
1167   if (strequal(dgram->source_name.name,myname)) return;
1168
1169   if (count <= 0) return;
1170
1171   if (!AM_MASTER || 
1172       !strequal(PrimaryGroup,dgram->dest_name.name))
1173     return;
1174
1175   if (!listening(&dgram->dest_name)) return;
1176
1177   send_backup_list(myname,token,
1178                    &dgram->source_name,
1179                    p->ip);
1180 }
1181
1182
1183 /*******************************************************************
1184   work out if I win an election
1185   ******************************************************************/
1186 static BOOL win_election(int version,uint32 criterion,int timeup,char *name)
1187 {  
1188   time_t t = time(NULL);
1189   uint32 mycriterion;
1190   if (version > ELECTION_VERSION) return(False);
1191   if (version < ELECTION_VERSION) return(True);
1192   
1193   mycriterion = ElectionCriterion;
1194
1195   if (criterion > mycriterion) return(False);
1196   if (criterion < mycriterion) return(True);
1197
1198   if (timeup > (t - StartupTime)) return(False);
1199   if (timeup < (t - StartupTime)) return(True);
1200
1201   if (strcasecmp(myname,name) > 0) return(False);
1202   
1203   return(True);
1204 }
1205
1206
1207 /*******************************************************************
1208   process a election packet
1209
1210   An election dynamically decides who will be the master. 
1211   ******************************************************************/
1212 static void process_election(struct packet_struct *p,char *buf)
1213 {
1214   struct dgram_packet *dgram = &p->packet.dgram;
1215   int version = CVAL(buf,0);
1216   uint32 criterion = IVAL(buf,1);
1217   int timeup = IVAL(buf,5)/1000;
1218   char *name = buf+13;
1219
1220   name[15] = 0;  
1221   
1222   DEBUG(3,("Election request from %s vers=%d criterion=%08x timeup=%d\n",
1223            name,version,criterion,timeup));
1224
1225   if (strequal(dgram->source_name.name,myname)) return;
1226
1227   if (!listening(&dgram->dest_name)) return;
1228
1229   if (win_election(version,criterion,timeup,name)) {
1230     if (!RunningElection) {
1231       needelection = True;
1232       ElectionCount=0;
1233     }
1234   } else {
1235     needelection = False;
1236     if (RunningElection) {
1237       RunningElection = False;
1238       DEBUG(3,(">>> Lost election on %s <<<\n",PrimaryGroup));
1239
1240       /* if we are the master then remove our masterly names */
1241       if (AM_MASTER)
1242         become_nonmaster();
1243     }
1244   }
1245 }
1246
1247
1248 /*******************************************************************
1249   process a announcement request
1250
1251   clients send these when they want everyone to send an announcement
1252   immediately. This can cause quite a storm of packets!
1253   ******************************************************************/
1254 static void process_announce_request(struct packet_struct *p,char *buf)
1255 {
1256   struct dgram_packet *dgram = &p->packet.dgram;
1257   int flags = CVAL(buf,0);
1258   char *name = buf+1;
1259
1260   name[15] = 0;
1261
1262   DEBUG(3,("Announce request from %s flags=0x%X\n",name,flags));
1263
1264   if (strequal(dgram->source_name.name,myname)) return;
1265
1266   needannounce = True;
1267 }
1268
1269
1270 /****************************************************************************
1271 process a browse frame
1272 ****************************************************************************/
1273 static void process_browse_packet(struct packet_struct *p,char *buf,int len)
1274 {
1275   int command = CVAL(buf,0);
1276   switch (command) 
1277     {
1278     case 1: /* host announce */
1279     case 12: /* domain announce */
1280     case 15: /* local master announce */
1281       process_announce(p,command,buf+1);
1282       break;
1283
1284     case 2: /* announce request */
1285       process_announce_request(p,buf+1);
1286       break;
1287
1288     case 8: /* election */
1289       process_election(p,buf+1);
1290       break;
1291
1292     case 9: /* get backup list */
1293       process_backup_list(p,buf+1);
1294       break;
1295
1296     case 13: /* master announcement */
1297       process_master_announce(p,buf+1);
1298       break;
1299     }
1300 }
1301
1302
1303 /****************************************************************************
1304   process a domain logon packet
1305   **************************************************************************/
1306 static void process_logon_packet(struct packet_struct *p,char *buf,int len)
1307 {
1308   char *logname,*q;
1309   pstring outbuf;
1310   struct dgram_packet *dgram = &p->packet.dgram;
1311   int code;
1312
1313   if (!lp_domain_logons()) {
1314     DEBUG(3,("No domain logons\n"));
1315     return;
1316   }
1317   if (!listening(&dgram->dest_name)) {
1318     DEBUG(4,("Not listening to that domain\n"));
1319     return;
1320   }
1321
1322   q = outbuf;
1323   bzero(outbuf,sizeof(outbuf));
1324
1325   code = SVAL(buf,0);
1326   switch (code) {
1327   case 0:    
1328     {
1329       char *machine = buf+2;
1330       char *user = skip_string(machine,1);
1331       logname = skip_string(user,1);
1332
1333       SSVAL(q,0,6);
1334       q += 2;
1335       strcpy(q,"\\\\");
1336       q += 2;
1337       StrnCpy(q,myname,16);
1338       strupper(q);
1339       q = skip_string(q,1);
1340       SSVAL(q,0,0xFFFF);
1341       q += 2;
1342
1343       DEBUG(3,("Domain login request from %s(%s) user=%s\n",
1344                machine,inet_ntoa(p->ip),user));
1345     }
1346     break;
1347   case 7:    
1348     {
1349       char *machine = buf+2;
1350       logname = skip_string(machine,1);
1351
1352       SSVAL(q,0,0xc);
1353       q += 2;
1354       StrnCpy(q,domain_controller(),16);
1355       strupper(q);
1356       q = skip_string(q,1);
1357       q += PutUniCode(q,domain_controller());
1358       q += PutUniCode(q,dgram->dest_name.name);
1359       SSVAL(q,0,0xFFFF);
1360       q += 2;
1361
1362       DEBUG(3,("GETDC request from %s(%s)\n",
1363                machine,inet_ntoa(p->ip)));
1364     }
1365     break;
1366   default:
1367     DEBUG(3,("Unknown domain request %d\n",code));
1368     return;
1369   }
1370
1371
1372   send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
1373                       myname,&dgram->source_name.name[0],0,0,p->ip,myip);  
1374 }
1375
1376 /****************************************************************************
1377 process udp 138 datagrams
1378 ****************************************************************************/
1379 static void process_dgram(struct packet_struct *p)
1380 {
1381   char *buf;
1382   char *buf2;
1383   int len;
1384   struct dgram_packet *dgram = &p->packet.dgram;
1385
1386   if (dgram->header.msg_type != 0x10 &&
1387       dgram->header.msg_type != 0x11 &&
1388       dgram->header.msg_type != 0x12) {
1389     /* don't process error packets etc yet */
1390     return;
1391   }
1392
1393   buf = &dgram->data[0];
1394   buf -= 4; /* XXXX for the pseudo tcp length - 
1395                someday I need to get rid of this */
1396
1397   if (CVAL(buf,smb_com) != SMBtrans) return;
1398
1399   len = SVAL(buf,smb_vwv11);
1400   buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1401
1402   DEBUG(3,("datagram from %s to %s for %s of type %d len=%d\n",
1403            namestr(&dgram->source_name),namestr(&dgram->dest_name),
1404            smb_buf(buf),CVAL(buf2,0),len));
1405
1406   if (len <= 0) return;
1407
1408   if (strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE")) {
1409     process_browse_packet(p,buf2,len);
1410   } else if (strequal(smb_buf(buf),"\\MAILSLOT\\NET\\NETLOGON")) {
1411     process_logon_packet(p,buf2,len);
1412   }
1413
1414 }
1415
1416 /*******************************************************************
1417   find a workgroup using the specified broadcast
1418   ******************************************************************/
1419 static BOOL find_workgroup(char *name,struct in_addr ip)
1420 {
1421   fstring name1;
1422   BOOL ret;
1423   struct in_addr ipout;
1424
1425   strcpy(name1,MSBROWSE);
1426
1427   ret = name_query(ClientNMB,name1,0x1,True,False,ip,&ipout,queue_packet);
1428   if (!ret) return(False);
1429
1430   name_status(ClientNMB,name1,0x1,False,ipout,name,NULL,queue_packet);
1431
1432   if (name[0] != '*') {
1433     DEBUG(2,("Found workgroup %s on broadcast %s\n",name,inet_ntoa(ip)));
1434   } else {
1435     DEBUG(3,("Failed to find workgroup %s on broadcast %s\n",name,inet_ntoa(ip)));
1436   }
1437   return(name[0] != '*');
1438 }
1439
1440
1441 /****************************************************************************
1442   a hook for announce handling - called every minute
1443   **************************************************************************/
1444 static void do_announcements(void)
1445 {
1446   struct domain_record *d;
1447
1448   for (d = domainlist; d; d = d->next) {
1449     /* if the ip address is 0 then set to the broadcast */
1450     if (zero_ip(d->bcast_ip)) d->bcast_ip = bcast_ip;
1451
1452     /* if the workgroup is '*' then find a workgroup to be part of */
1453     if (d->name[0] == '*') {
1454       if (!find_workgroup(d->name,d->bcast_ip)) continue;
1455       add_host_entry(d->name,0x1e,False,0,SELF,
1456                      *interpret_addr2("255.255.255.255"));
1457       if (!PrimaryGroup[0] && ip_equal(bcast_ip,d->bcast_ip)) {
1458         strcpy(PrimaryGroup,d->name);
1459         strupper(PrimaryGroup);
1460       }
1461     }
1462
1463     announce_host(d,myname,ServerComment);
1464   }
1465
1466   /* if I have a domain controller then announce to it */
1467   if (AM_MASTER)
1468     announce_master(PrimaryGroup);
1469
1470   needannounce=False;
1471 }
1472
1473 /*******************************************************************
1474   check if someone still owns a name
1475   ******************************************************************/
1476 static BOOL confirm_name(struct name_record *n)
1477 {
1478   struct in_addr ipout;
1479   BOOL ret = name_query(ClientNMB,n->name.name,
1480                         n->name.name_type,False,
1481                         False,n->ip,&ipout,queue_packet);
1482   return(ret && ip_equal(ipout,n->ip));
1483 }
1484
1485 /****************************************************************************
1486 reply to a name release
1487 ****************************************************************************/
1488 static void reply_name_release(struct packet_struct *p)
1489 {
1490   struct nmb_packet *nmb = &p->packet.nmb;
1491   struct packet_struct p2;
1492   struct nmb_packet *nmb2;
1493   struct res_rec answer_rec;
1494   struct in_addr ip;
1495   int rcode=0;
1496   int nb_flags = nmb->additional->rdata[0];
1497   BOOL bcast = nmb->header.nm_flags.bcast;
1498   
1499
1500   putip((char *)&ip,&nmb->additional->rdata[2]);  
1501
1502   {
1503     struct name_record *n = find_name(&nmb->question.question_name);
1504     if (n && n->unique && n->source == REGISTER &&
1505         ip_equal(ip,n->ip)) {
1506       remove_name(n); n = NULL;
1507     }
1508
1509     /* XXXX under what conditions should we reject the removal?? */
1510   }
1511
1512   DEBUG(3,("Name release on name %s rcode=%d\n",
1513            namestr(&nmb->question.question_name),rcode));
1514
1515   if (bcast) return;
1516
1517   /* Send a NAME RELEASE RESPONSE */
1518   p2 = *p;
1519   nmb2 = &p2.packet.nmb;
1520
1521   nmb2->header.response = True;
1522   nmb2->header.nm_flags.bcast = False;
1523   nmb2->header.nm_flags.recursion_available = CanRecurse;
1524   nmb2->header.nm_flags.trunc = False;
1525   nmb2->header.nm_flags.authoritative = True; 
1526   nmb2->header.qdcount = 0;
1527   nmb2->header.ancount = 1;
1528   nmb2->header.nscount = 0;
1529   nmb2->header.arcount = 0;
1530   nmb2->header.rcode = rcode;
1531
1532   nmb2->answers = &answer_rec;
1533   bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
1534   
1535   nmb2->answers->rr_name = nmb->question.question_name;
1536   nmb2->answers->rr_type = nmb->question.question_type;
1537   nmb2->answers->rr_class = nmb->question.question_class;
1538   nmb2->answers->ttl = 0; 
1539   nmb2->answers->rdlength = 6;
1540   nmb2->answers->rdata[0] = nb_flags;
1541   putip(&nmb2->answers->rdata[2],(char *)&ip);
1542
1543   send_packet(&p2);
1544 }
1545
1546 /****************************************************************************
1547   reply to a reg request
1548   **************************************************************************/
1549 static void reply_name_reg(struct packet_struct *p)
1550 {
1551   struct nmb_packet *nmb = &p->packet.nmb;
1552   char *qname = nmb->question.question_name.name;
1553   BOOL wildcard = (qname[0] == '*'); 
1554   BOOL bcast = nmb->header.nm_flags.bcast;
1555   int ttl = GET_TTL(nmb->additional->ttl);
1556   int name_type = nmb->question.question_name.name_type;
1557   int nb_flags = nmb->additional->rdata[0];
1558   struct packet_struct p2;
1559   struct nmb_packet *nmb2;
1560   struct res_rec answer_rec;
1561   struct in_addr ip;
1562   BOOL group = (nb_flags&0x80)?True:False;
1563   int rcode = 0;  
1564
1565   if (wildcard) return;
1566
1567   putip((char *)&ip,&nmb->additional->rdata[2]);
1568
1569   if (group) {
1570     /* apparently we should return 255.255.255.255 for group queries (email from MS) */
1571     ip = *interpret_addr2("255.255.255.255");
1572   }
1573
1574   {
1575     struct name_record *n = find_name(&nmb->question.question_name);
1576
1577     if (n) {
1578       if (!group && !ip_equal(ip,n->ip)) {
1579         /* check if the previous owner still wants it, 
1580            if so reject the registration, otherwise change the owner 
1581            and refresh */
1582         if (n->source != REGISTER || confirm_name(n)) {
1583           rcode = 6;
1584         } else {
1585           n->ip = ip;
1586           n->death_time = ttl?p->timestamp+ttl*3:0;
1587           DEBUG(3,("%s changed owner to %s\n",
1588                    namestr(&n->name),inet_ntoa(n->ip)));
1589         }
1590       } else {
1591         /* refresh the name */
1592         if (n->source != SELF)
1593           n->death_time = ttl?p->timestamp + ttl*3:0;
1594       }
1595     } else {
1596       /* add the name to our database */
1597       n = add_host_entry(qname,name_type,!group,ttl,REGISTER,ip);
1598     }
1599   }
1600
1601   if (bcast) return;
1602
1603   DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
1604            namestr(&nmb->question.question_name),
1605            inet_ntoa(ip),rcode));
1606
1607   /* Send a NAME REGISTRATION RESPONSE */
1608   /* a lot of fields get copied from the query. This gives us the IP
1609      and port the reply will be sent to etc */
1610   p2 = *p;
1611   nmb2 = &p2.packet.nmb;
1612
1613   nmb2->header.opcode = 5; 
1614   nmb2->header.response = True;
1615   nmb2->header.nm_flags.bcast = False;
1616   nmb2->header.nm_flags.recursion_available = CanRecurse;
1617   nmb2->header.nm_flags.trunc = False;
1618   nmb2->header.nm_flags.authoritative = True; 
1619   nmb2->header.qdcount = 0;
1620   nmb2->header.ancount = 1;
1621   nmb2->header.nscount = 0;
1622   nmb2->header.arcount = 0;
1623   nmb2->header.rcode = rcode;
1624
1625   nmb2->answers = &answer_rec;
1626   bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
1627   
1628   nmb2->answers->rr_name = nmb->question.question_name;
1629   nmb2->answers->rr_type = nmb->question.question_type;
1630   nmb2->answers->rr_class = nmb->question.question_class;
1631
1632   nmb2->answers->ttl = ttl; 
1633   nmb2->answers->rdlength = 6;
1634   nmb2->answers->rdata[0] = nb_flags;
1635   putip(&nmb2->answers->rdata[2],(char *)&ip);
1636
1637   send_packet(&p2);  
1638 }
1639
1640
1641 /****************************************************************************
1642 reply to a name status query
1643 ****************************************************************************/
1644 static void reply_name_status(struct packet_struct *p)
1645 {
1646   struct nmb_packet *nmb = &p->packet.nmb;
1647   char *qname = nmb->question.question_name.name;
1648   BOOL wildcard = (qname[0] == '*'); 
1649   struct packet_struct p2;
1650   struct nmb_packet *nmb2;
1651   struct res_rec answer_rec;
1652   char *buf;
1653   int count;
1654   int rcode = 0;
1655   struct name_record *n = find_name(&nmb->question.question_name);
1656
1657   DEBUG(3,("Name status for name %s\n",
1658            namestr(&nmb->question.question_name)));
1659
1660   if (!wildcard && (!n || n->source != SELF)) 
1661     return;
1662
1663   /* Send a POSITIVE NAME STATUS RESPONSE */
1664   /* a lot of fields get copied from the query. This gives us the IP
1665      and port the reply will be sent to etc */
1666   p2 = *p;
1667   nmb2 = &p2.packet.nmb;
1668
1669   nmb2->header.response = True;
1670   nmb2->header.nm_flags.bcast = False;
1671   nmb2->header.nm_flags.recursion_available = CanRecurse;
1672   nmb2->header.nm_flags.trunc = False;
1673   nmb2->header.nm_flags.authoritative = True; /* WfWg ignores 
1674                                                  non-authoritative answers */
1675   nmb2->header.qdcount = 0;
1676   nmb2->header.ancount = 1;
1677   nmb2->header.nscount = 0;
1678   nmb2->header.arcount = 0;
1679   nmb2->header.rcode = rcode;
1680
1681   nmb2->answers = &answer_rec;
1682   bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
1683   
1684
1685   nmb2->answers->rr_name = nmb->question.question_name;
1686   nmb2->answers->rr_type = nmb->question.question_type;
1687   nmb2->answers->rr_class = nmb->question.question_class;
1688   nmb2->answers->ttl = 0; 
1689
1690   for (count=0, n = namelist ; n; n = n->next) {
1691     if (n->source != SELF) continue;
1692     count++;
1693   }
1694
1695   count = MIN(count,400/18); /* XXXX hack, we should calculate exactly
1696                                 how many will fit */
1697
1698   
1699   buf = &nmb2->answers->rdata[0];
1700   SCVAL(buf,0,count);
1701   buf += 1;
1702
1703   for (n = namelist ; n; n = n->next) 
1704     {
1705       if (n->source != SELF) continue;
1706
1707       bzero(buf,18);
1708       strcpy(buf,n->name.name);
1709       strupper(buf);
1710       buf[15] = n->name.name_type;
1711       buf += 16;
1712       buf[0] = 0x4; /* active */
1713       if (!n->unique) buf[0] |= 0x80; /* group */
1714       buf += 2;
1715       count--;
1716     }
1717
1718   /* XXXXXXX we should fill in more fields of the statistics structure */
1719   bzero(buf,64);
1720   {
1721     extern int num_good_sends,num_good_receives;
1722     SIVAL(buf,20,num_good_sends);
1723     SIVAL(buf,24,num_good_receives);
1724   }
1725   SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
1726
1727   buf += 64;
1728
1729   nmb2->answers->rdlength = PTR_DIFF(buf,&nmb2->answers->rdata[0]);
1730
1731   send_packet(&p2);
1732 }
1733
1734
1735
1736 /****************************************************************************
1737 reply to a name query
1738 ****************************************************************************/
1739 static void reply_name_query(struct packet_struct *p)
1740 {
1741   struct nmb_packet *nmb = &p->packet.nmb;
1742   char *qname = nmb->question.question_name.name;
1743   BOOL wildcard = (qname[0] == '*'); 
1744   BOOL bcast = nmb->header.nm_flags.bcast;
1745   struct in_addr retip;
1746   int name_type = nmb->question.question_name.name_type;
1747   struct packet_struct p2;
1748   struct nmb_packet *nmb2;
1749   struct res_rec answer_rec;
1750   int ttl=0;
1751   int rcode=0;
1752   BOOL unique = True;
1753
1754   DEBUG(3,("Name query for %s from %s (bcast=%s) - ",
1755            namestr(&nmb->question.question_name),
1756            inet_ntoa(p->ip),
1757            BOOLSTR(bcast)));
1758
1759   if (wildcard)
1760     retip = myip;
1761
1762   if (!wildcard) {
1763     struct name_record *n = find_name(&nmb->question.question_name);
1764
1765     if (!n) {
1766       struct in_addr ip;
1767       unsigned long a;
1768
1769       /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
1770       if (name_type != 0x20 && name_type != 0) {
1771         DEBUG(3,("not found\n"));
1772         return;
1773       }
1774
1775       /* look it up with DNS */      
1776       a = interpret_addr(qname);
1777
1778       putip((char *)&ip,(char *)&a);
1779
1780       if (!a) {
1781         /* no luck with DNS. We could possibly recurse here XXXX */
1782         /* if this isn't a bcast then we should send a negative reply XXXX */
1783         DEBUG(3,("no recursion\n"));
1784         add_host_entry(qname,name_type,True,60*60,DNSFAIL,ip);
1785         return;
1786       }
1787
1788       /* add it to our cache of names. give it 2 hours in the cache */
1789       n = add_host_entry(qname,name_type,True,2*60*60,DNS,ip);
1790
1791       /* failed to add it? yikes! */
1792       if (!n) return;
1793     }
1794
1795     /* don't respond to bcast queries for group names unless we own them */
1796     if (bcast && !n->unique && !n->source == SELF) {
1797       DEBUG(3,("no bcast replies\n"));
1798       return;
1799     }
1800
1801     /* don't respond to bcast queries for addresses on the same net as the 
1802        machine doing the querying unless its our IP */
1803     if (bcast && 
1804         n->source != SELF && 
1805         same_net(n->ip,p->ip)) {
1806       DEBUG(3,("same net\n"));      
1807       return;
1808     }
1809
1810     /* is our entry already dead? */
1811     if (n->death_time) {
1812       if (n->death_time < p->timestamp) return;
1813       ttl = n->death_time - p->timestamp;
1814     }
1815
1816     retip = n->ip;
1817     unique = n->unique;
1818
1819     /* it may have been an earlier failure */
1820     if (n->source == DNSFAIL) {
1821       DEBUG(3,("DNSFAIL\n"));
1822       return;
1823     }
1824   }
1825
1826   /* if the IP is 0 then substitute my IP - we should see which one is on the 
1827      right interface for the caller to do this right XXX */
1828   if (zero_ip(retip)) retip = myip;
1829   
1830   DEBUG(3,("OK %s rcode=%d\n",inet_ntoa(retip),rcode));      
1831
1832   /* a lot of fields get copied from the query. This gives us the IP
1833      and port the reply will be sent to etc */
1834   p2 = *p;
1835   nmb2 = &p2.packet.nmb;
1836
1837   nmb2->header.response = True;
1838   nmb2->header.nm_flags.bcast = False;
1839   nmb2->header.nm_flags.recursion_available = CanRecurse;
1840   nmb2->header.nm_flags.trunc = False;
1841   nmb2->header.nm_flags.authoritative = True; /* WfWg ignores 
1842                                                  non-authoritative answers */
1843   nmb2->header.qdcount = 0;
1844   nmb2->header.ancount = 1;
1845   nmb2->header.nscount = 0;
1846   nmb2->header.arcount = 0;
1847   nmb2->header.rcode = rcode;
1848
1849   nmb2->answers = &answer_rec;
1850   bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
1851
1852   nmb2->answers->rr_name = nmb->question.question_name;
1853   nmb2->answers->rr_type = nmb->question.question_type;
1854   nmb2->answers->rr_class = nmb->question.question_class;
1855   nmb2->answers->ttl = ttl;
1856   nmb2->answers->rdlength = 6;
1857   nmb2->answers->rdata[0] = unique?0:0x80; 
1858   nmb2->answers->rdata[1] = 0; 
1859   putip(&nmb2->answers->rdata[2],(char *)&retip);
1860
1861   send_packet(&p2);
1862 }
1863
1864
1865
1866 /* the global packet linked-list. incoming entries are added to the
1867    end of this list.  it is supposed to remain fairly short so we
1868    won't bother with an end pointer. */
1869 static struct packet_struct *packet_queue = NULL;
1870
1871
1872 /*******************************************************************
1873   queue a packet into the packet queue
1874   ******************************************************************/
1875 static void queue_packet(struct packet_struct *packet)
1876 {
1877   struct packet_struct *p;
1878   if (!packet_queue) {
1879     packet->prev = NULL;
1880     packet->next = NULL;
1881     packet_queue = packet;
1882     return;
1883   }
1884   
1885   /* find the bottom */
1886   for (p=packet_queue;p->next;p=p->next) ;
1887
1888   p->next = packet;
1889   packet->next = NULL;
1890   packet->prev = p;
1891 }
1892
1893 /****************************************************************************
1894   process a nmb packet
1895   ****************************************************************************/
1896 static void process_nmb(struct packet_struct *p)
1897 {
1898   struct nmb_packet *nmb = &p->packet.nmb;
1899
1900   /* if this is a response then ignore it */
1901   if (nmb->header.response) return;
1902
1903   switch (nmb->header.opcode) 
1904     {
1905     case 5:
1906     case 8:
1907     case 9:
1908       if (nmb->header.qdcount>0 && 
1909           nmb->header.arcount>0) {
1910         reply_name_reg(p);
1911         return;
1912       }
1913       break;
1914
1915     case 0:
1916       if (nmb->header.qdcount>0) 
1917         {
1918           switch (nmb->question.question_type)
1919             {
1920             case 0x20:
1921               reply_name_query(p);
1922               break;
1923
1924             case 0x21:
1925               reply_name_status(p);
1926               break;
1927             }
1928           return;
1929         }
1930       break;
1931
1932     case 6:
1933       if (nmb->header.qdcount>0 && 
1934           nmb->header.arcount>0) {
1935         reply_name_release(p);
1936         return;
1937       }
1938       break;
1939     }
1940
1941 }
1942
1943
1944
1945 /*******************************************************************
1946   run elements off the packet queue till its empty
1947   ******************************************************************/
1948 static void run_packet_queue(void)
1949 {
1950   struct packet_struct *p;
1951
1952   while ((p=packet_queue)) {
1953     switch (p->packet_type)
1954       {
1955       case NMB_PACKET:
1956         process_nmb(p);
1957         break;
1958
1959       case DGRAM_PACKET:
1960         process_dgram(p);
1961         break;
1962       }
1963
1964     packet_queue = packet_queue->next;
1965     if (packet_queue) packet_queue->prev = NULL;
1966     free_packet(p);
1967   }
1968 }
1969
1970
1971 /****************************************************************************
1972   The main select loop, listen for packets and respond
1973   ***************************************************************************/
1974 void process(void)
1975 {
1976
1977   while (True)
1978     {
1979       fd_set fds;
1980       int selrtn;
1981       struct timeval timeout;
1982
1983       if (needelection && PrimaryGroup[0] && !RunningElection) {
1984         DEBUG(3,(">>> Starting election on %s <<<\n",PrimaryGroup));
1985         ElectionCount = 0;
1986         RunningElection = True;
1987         needelection = False;
1988       }
1989
1990       FD_ZERO(&fds);
1991       FD_SET(ClientNMB,&fds);
1992       FD_SET(ClientDGRAM,&fds);
1993       /* during elections we need to send election packets at one
1994          second intervals */
1995       timeout.tv_sec = RunningElection?1:NMBD_SELECT_LOOP;
1996       timeout.tv_usec = 0;
1997
1998       selrtn = sys_select(&fds,&timeout);
1999
2000       if (FD_ISSET(ClientNMB,&fds)) {
2001         struct packet_struct *packet = read_packet(ClientNMB,NMB_PACKET);
2002         if (packet) queue_packet(packet);
2003       }
2004
2005       if (FD_ISSET(ClientDGRAM,&fds)) {
2006         struct packet_struct *packet = read_packet(ClientDGRAM,DGRAM_PACKET);
2007         if (packet) queue_packet(packet);
2008       }
2009
2010       if (RunningElection) 
2011         run_election();
2012
2013       run_packet_queue();
2014
2015       do_announcements();
2016
2017       housekeeping();
2018     }
2019 }
2020
2021
2022 /****************************************************************************
2023   open the socket communication
2024 ****************************************************************************/
2025 static BOOL open_sockets(BOOL isdaemon,int port)
2026 {
2027   struct hostent *hp;
2028  
2029   /* get host info */
2030   if ((hp = Get_Hostbyname(myhostname)) == 0) 
2031     {
2032       DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
2033       return False;
2034     }   
2035
2036   if (isdaemon)
2037     ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
2038   else
2039     ClientNMB = 0;
2040
2041   ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
2042
2043   if (ClientNMB == -1)
2044     return(False);
2045
2046   signal(SIGPIPE, SIGNAL_CAST sig_pipe);
2047
2048   set_socket_options(ClientNMB,"SO_BROADCAST");
2049   set_socket_options(ClientDGRAM,"SO_BROADCAST");
2050
2051   DEBUG(3, ("Socket opened.\n"));
2052   return True;
2053 }
2054
2055
2056 /*******************************************************************
2057   check that a IP, bcast and netmask and consistent. Must be a 1s
2058   broadcast
2059   ******************************************************************/
2060 static BOOL ip_consistent(struct in_addr ip,struct in_addr bcast,
2061                           struct in_addr nmask)
2062 {
2063   unsigned long a_ip,a_bcast,a_nmask;
2064
2065   a_ip = ntohl(ip.s_addr);
2066   a_bcast = ntohl(bcast.s_addr);
2067   a_nmask = ntohl(nmask.s_addr);
2068
2069   /* check the netmask is sane */
2070   if (((a_nmask>>24)&0xFF) != 0xFF) {
2071     DEBUG(0,("Insane netmask %s\n",inet_ntoa(nmask)));
2072     return(False);
2073   }
2074
2075   /* check the IP and bcast are on the same net */
2076   if ((a_ip&a_nmask) != (a_bcast&a_nmask)) {
2077     DEBUG(0,("IP and broadcast are on different nets!\n"));
2078     return(False);
2079   }
2080
2081   /* check the IP and bcast are on the same net */
2082   if ((a_bcast|a_nmask) != 0xFFFFFFFF) {
2083     DEBUG(0,("Not a ones based broadcast %s\n",inet_ntoa(bcast)));
2084     return(False);
2085   }
2086
2087   return(True);
2088 }
2089
2090 /****************************************************************************
2091   initialise connect, service and file structs
2092 ****************************************************************************/
2093 static BOOL init_structs(void )
2094 {
2095   if (!get_myname(myhostname,got_myip?NULL:&myip))
2096     return(False);
2097
2098   /* Read the broadcast address from the interface */
2099   {
2100     struct in_addr ip0,ip1,ip2;
2101
2102     ip0 = myip;
2103
2104     if (!(got_bcast && got_nmask))
2105       {
2106         get_broadcast(&ip0,&ip1,&ip2);
2107
2108         if (!got_myip)
2109           myip = ip0;
2110     
2111         if (!got_bcast)
2112           bcast_ip = ip1;
2113     
2114         if (!got_nmask)
2115           Netmask = ip2;   
2116       } 
2117
2118     DEBUG(1,("Using IP %s  ",inet_ntoa(myip))); 
2119     DEBUG(1,("broadcast %s  ",inet_ntoa(bcast_ip)));
2120     DEBUG(1,("netmask %s\n",inet_ntoa(Netmask)));    
2121
2122     if (!ip_consistent(myip,bcast_ip,Netmask)) {
2123       DEBUG(0,("WARNING: The IP address, broadcast and Netmask are not consistent\n"));
2124       DEBUG(0,("You are likely to experience problems with this setup!\n"));
2125     }
2126   }
2127
2128   if (! *myname) {
2129     char *p;
2130     strcpy(myname,myhostname);
2131     p = strchr(myname,'.');
2132     if (p) *p = 0;
2133   }
2134
2135   {
2136     extern fstring local_machine;
2137     strcpy(local_machine,myname);
2138     strupper(local_machine);
2139   }
2140
2141   return True;
2142 }
2143
2144 /****************************************************************************
2145 usage on the program
2146 ****************************************************************************/
2147 static void usage(char *pname)
2148 {
2149   DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
2150
2151   printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
2152   printf("Version %s\n",VERSION);
2153   printf("\t-D                    become a daemon\n");
2154   printf("\t-p port               listen on the specified port\n");
2155   printf("\t-d debuglevel         set the debuglevel\n");
2156   printf("\t-l log basename.      Basename for log/debug files\n");
2157   printf("\t-n netbiosname.       the netbios name to advertise for this host\n");
2158   printf("\t-B broadcast address  the address to use for broadcasts\n");
2159   printf("\t-N netmask           the netmask to use for subnet determination\n");
2160   printf("\t-H hosts file        load a netbios hosts file\n");
2161   printf("\t-I ip-address        override the IP address\n");
2162   printf("\t-G group name        add a group name to be part of\n");
2163   printf("\t-C comment           sets the machine comment that appears in browse lists\n");
2164   printf("\n");
2165 }
2166
2167
2168 /****************************************************************************
2169   main program
2170   **************************************************************************/
2171 int main(int argc,char *argv[])
2172 {
2173   int port = NMB_PORT;
2174   int opt;
2175   extern FILE *dbf;
2176   extern char *optarg;
2177
2178   *host_file = 0;
2179
2180 #if 0
2181   sleep(10);
2182 #endif
2183
2184   StartupTime = time(NULL);
2185
2186   TimeInit();
2187
2188   strcpy(debugf,NMBLOGFILE);
2189
2190   setup_logging(argv[0],False);
2191
2192   charset_initialise();
2193
2194 #ifdef LMHOSTSFILE
2195   strcpy(host_file,LMHOSTSFILE);
2196 #endif
2197
2198   /* this is for people who can't start the program correctly */
2199   while (argc > 1 && (*argv[1] != '-'))
2200     {
2201       argv++;
2202       argc--;
2203     }
2204
2205   fault_setup(fault_continue);
2206
2207   signal(SIGHUP,SIGNAL_CAST sig_hup);
2208
2209   bcast_ip = *interpret_addr2("0.0.0.0");
2210   myip = *interpret_addr2("0.0.0.0");
2211
2212   while ((opt = getopt (argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
2213     switch (opt)
2214       {
2215       case 's':
2216         strcpy(servicesf,optarg);
2217         break;
2218       case 'C':
2219         strcpy(ServerComment,optarg);
2220         break;
2221       case 'G':
2222         add_domain_entry(optarg,bcast_ip);
2223         break;
2224       case 'H':
2225         strcpy(host_file,optarg);
2226         break;
2227       case 'I':
2228         myip = *interpret_addr2(optarg);
2229         got_myip = True;
2230         break;
2231       case 'B':
2232         bcast_ip = *interpret_addr2(optarg);
2233         got_bcast = True;
2234         break;
2235       case 'N':
2236         Netmask = *interpret_addr2(optarg);
2237         got_nmask = True;
2238         break;
2239       case 'n':
2240         strcpy(myname,optarg);
2241         break;
2242       case 'l':
2243         sprintf(debugf,"%s.nmb",optarg);
2244         break;
2245       case 'i':
2246         strcpy(scope,optarg);
2247         strupper(scope);
2248         break;
2249       case 'D':
2250         is_daemon = True;
2251         break;
2252       case 'd':
2253         DEBUGLEVEL = atoi(optarg);
2254         break;
2255       case 'p':
2256         port = atoi(optarg);
2257         break;
2258       case 'h':
2259         usage(argv[0]);
2260         exit(0);
2261         break;
2262       default:
2263         if (!is_a_socket(0))
2264           usage(argv[0]);
2265         break;
2266       }
2267   
2268   DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
2269   DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
2270
2271   init_structs();
2272
2273   if (!reload_services(False))
2274     return(-1); 
2275
2276   if (*host_file)
2277     {
2278       load_hosts_file(host_file);
2279       DEBUG(3,("Loaded hosts file\n"));
2280     }
2281
2282   if (!*ServerComment)
2283     strcpy(ServerComment,"Samba %v");
2284   string_sub(ServerComment,"%v",VERSION);
2285   string_sub(ServerComment,"%h",myhostname);
2286
2287   add_my_names();
2288
2289   DEBUG(3,("Checked names\n"));
2290   
2291   dump_names();
2292
2293   DEBUG(3,("Dumped names\n"));
2294
2295   if (!is_daemon && !is_a_socket(0)) {
2296     DEBUG(0,("standard input is not a socket, assuming -D option\n"));
2297     is_daemon = True;
2298   }
2299   
2300
2301   if (is_daemon) {
2302     DEBUG(2,("%s becoming a daemon\n",timestring()));
2303     become_daemon();
2304   }
2305
2306
2307   DEBUG(3,("Opening sockets\n"));
2308
2309   if (open_sockets(is_daemon,port))
2310     {
2311       process();
2312       close_sockets();
2313     }
2314
2315   if (dbf)
2316     fclose(dbf);
2317   return(0);
2318 }