make sure async dns nmbd child dies
[tprouty/samba.git] / source / nmbd / nmbd.c
1 /*
2    Unix SMB/CIFS implementation.
3    NBT netbios routines and daemon - version 2
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Jeremy Allison 1997-2002
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
25 int ClientNMB       = -1;
26 int ClientDGRAM     = -1;
27 int global_nmb_port = -1;
28
29 extern pstring global_myname;
30 extern fstring global_myworkgroup;
31 extern char **my_netbios_names;
32
33 extern BOOL global_in_nmbd;
34
35 /* are we running as a daemon ? */
36 static BOOL is_daemon = False;
37
38 /* have we found LanMan clients yet? */
39 BOOL found_lm_clients = False;
40
41 /* what server type are we currently */
42
43 time_t StartupTime = 0;
44
45 /**************************************************************************** **
46  Handle a SIGTERM in band.
47  **************************************************************************** */
48
49 static void terminate(void)
50 {
51         DEBUG(0,("Got SIGTERM: going down...\n"));
52   
53         /* Write out wins.dat file if samba is a WINS server */
54         wins_write_database(False);
55   
56         /* Remove all SELF registered names from WINS */
57         release_wins_names();
58   
59         /* Announce all server entries as 0 time-to-live, 0 type. */
60         announce_my_servers_removed();
61
62         /* If there was an async dns child - kill it. */
63         kill_async_dns_child();
64
65         exit(0);
66 }
67
68 /**************************************************************************** **
69  Handle a SHUTDOWN message from smbcontrol.
70  **************************************************************************** */
71
72 static void nmbd_terminate(int msg_type, pid_t src, void *buf, size_t len)
73 {
74         terminate();
75 }
76
77 /**************************************************************************** **
78  Catch a SIGTERM signal.
79  **************************************************************************** */
80
81 static SIG_ATOMIC_T got_sig_term;
82
83 static void sig_term(int sig)
84 {
85         got_sig_term = 1;
86         sys_select_signal();
87 }
88
89 /**************************************************************************** **
90  Catch a SIGHUP signal.
91  **************************************************************************** */
92
93 static SIG_ATOMIC_T reload_after_sighup;
94
95 static void sig_hup(int sig)
96 {
97         reload_after_sighup = 1;
98         sys_select_signal();
99 }
100
101 #if DUMP_CORE
102 /**************************************************************************** **
103  Prepare to dump a core file - carefully!
104  **************************************************************************** */
105
106 static BOOL dump_core(void)
107 {
108         char *p;
109         pstring dname;
110         pstrcpy( dname, lp_logfile() );
111         if ((p=strrchr_m(dname,'/')))
112                 *p=0;
113         pstrcat( dname, "/corefiles" );
114         mkdir( dname, 0700 );
115         sys_chown( dname, getuid(), getgid() );
116         chmod( dname, 0700 );
117         if ( chdir(dname) )
118                 return( False );
119         umask( ~(0700) );
120
121 #ifdef HAVE_GETRLIMIT
122 #ifdef RLIMIT_CORE
123         {
124                 struct rlimit rlp;
125                 getrlimit( RLIMIT_CORE, &rlp );
126                 rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
127                 setrlimit( RLIMIT_CORE, &rlp );
128                 getrlimit( RLIMIT_CORE, &rlp );
129                 DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
130         }
131 #endif
132 #endif
133
134
135         DEBUG(0,("Dumping core in %s\n",dname));
136         abort();
137         return( True );
138 }
139 #endif
140
141 /**************************************************************************** **
142  Possibly continue after a fault.
143  **************************************************************************** */
144
145 static void fault_continue(void)
146 {
147 #if DUMP_CORE
148         dump_core();
149 #endif
150 }
151
152 /**************************************************************************** **
153  Expire old names from the namelist and server list.
154  **************************************************************************** */
155
156 static void expire_names_and_servers(time_t t)
157 {
158         static time_t lastrun = 0;
159   
160         if ( !lastrun )
161                 lastrun = t;
162         if ( t < (lastrun + 5) )
163                 return;
164         lastrun = t;
165
166         /*
167          * Expire any timed out names on all the broadcast
168          * subnets and those registered with the WINS server.
169          * (nmbd_namelistdb.c)
170          */
171
172         expire_names(t);
173
174         /*
175          * Go through all the broadcast subnets and for each
176          * workgroup known on that subnet remove any expired
177          * server names. If a workgroup has an empty serverlist
178          * and has itself timed out then remove the workgroup.
179          * (nmbd_workgroupdb.c)
180          */
181
182         expire_workgroups_and_servers(t);
183 }
184
185 /************************************************************************** **
186  Reload the list of network interfaces.
187  ************************************************************************** */
188
189 static BOOL reload_interfaces(time_t t)
190 {
191         static time_t lastt;
192         int n;
193         struct subnet_record *subrec;
194         extern BOOL rescan_listen_set;
195         extern struct in_addr loopback_ip;
196
197         if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False;
198         lastt = t;
199
200         if (!interfaces_changed()) return False;
201
202         /* the list of probed interfaces has changed, we may need to add/remove
203            some subnets */
204         load_interfaces();
205
206         /* find any interfaces that need adding */
207         for (n=iface_count() - 1; n >= 0; n--) {
208                 struct interface *iface = get_interface(n);
209
210                 /*
211                  * We don't want to add a loopback interface, in case
212                  * someone has added 127.0.0.1 for smbd, nmbd needs to
213                  * ignore it here. JRA.
214                  */
215
216                 if (ip_equal(iface->ip, loopback_ip)) {
217                         DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
218                         continue;
219                 }
220
221                 for (subrec=subnetlist; subrec; subrec=subrec->next) {
222                         if (ip_equal(iface->ip, subrec->myip) &&
223                             ip_equal(iface->nmask, subrec->mask_ip)) break;
224                 }
225
226                 if (!subrec) {
227                         /* it wasn't found! add it */
228                         DEBUG(2,("Found new interface %s\n", 
229                                  inet_ntoa(iface->ip)));
230                         subrec = make_normal_subnet(iface);
231                         if (subrec) register_my_workgroup_one_subnet(subrec);
232                 }
233         }
234
235         /* find any interfaces that need deleting */
236         for (subrec=subnetlist; subrec; subrec=subrec->next) {
237                 for (n=iface_count() - 1; n >= 0; n--) {
238                         struct interface *iface = get_interface(n);
239                         if (ip_equal(iface->ip, subrec->myip) &&
240                             ip_equal(iface->nmask, subrec->mask_ip)) break;
241                 }
242                 if (n == -1) {
243                         /* oops, an interface has disapeared. This is
244                          tricky, we don't dare actually free the
245                          interface as it could be being used, so
246                          instead we just wear the memory leak and
247                          remove it from the list of interfaces without
248                          freeing it */
249                         DEBUG(2,("Deleting dead interface %s\n", 
250                                  inet_ntoa(subrec->myip)));
251                         close_subnet(subrec);
252                 }
253         }
254         
255         rescan_listen_set = True;
256
257         /* We need to shutdown if there are no subnets... */
258         if (FIRST_SUBNET == NULL) {
259                 DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n"));
260                 return True;
261         }
262         return False;
263 }
264
265 /**************************************************************************** **
266  Reload the services file.
267  **************************************************************************** */
268
269 static BOOL reload_nmbd_services(BOOL test)
270 {
271         BOOL ret;
272         extern fstring remote_machine;
273
274         fstrcpy( remote_machine, "nmbd" );
275
276         if ( lp_loaded() ) {
277                 pstring fname;
278                 pstrcpy( fname,lp_configfile());
279                 if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
280                         pstrcpy(dyn_CONFIGFILE,fname);
281                         test = False;
282                 }
283         }
284
285         if ( test && !lp_file_list_changed() )
286                 return(True);
287
288         ret = lp_load( dyn_CONFIGFILE, True , False, False);
289
290         /* perhaps the config filename is now set */
291         if ( !test ) {
292                 DEBUG( 3, ( "services not loaded\n" ) );
293                 reload_nmbd_services( True );
294         }
295
296         return(ret);
297 }
298
299 /**************************************************************************** **
300  The main select loop.
301  **************************************************************************** */
302
303 static void process(void)
304 {
305         BOOL run_election;
306
307         while( True ) {
308                 time_t t = time(NULL);
309
310                 /* Check for internal messages */
311
312                 message_dispatch();
313
314                 /*
315                  * Check all broadcast subnets to see if
316                  * we need to run an election on any of them.
317                  * (nmbd_elections.c)
318                  */
319
320                 run_election = check_elections();
321
322                 /*
323                  * Read incoming UDP packets.
324                  * (nmbd_packets.c)
325                  */
326
327                 if(listen_for_packets(run_election))
328                         return;
329
330                 /*
331                  * Handle termination inband.
332                  */
333
334                 if (got_sig_term) {
335                         got_sig_term = 0;
336                         terminate();
337                 }
338
339                 /*
340                  * Process all incoming packets
341                  * read above. This calls the success and
342                  * failure functions registered when response
343                  * packets arrrive, and also deals with request
344                  * packets from other sources.
345                  * (nmbd_packets.c)
346                  */
347
348                 run_packet_queue();
349
350                 /*
351                  * Run any elections - initiate becoming
352                  * a local master browser if we have won.
353                  * (nmbd_elections.c)
354                  */
355
356                 run_elections(t);
357
358                 /*
359                  * Send out any broadcast announcements
360                  * of our server names. This also announces
361                  * the workgroup name if we are a local
362                  * master browser.
363                  * (nmbd_sendannounce.c)
364                  */
365
366                 announce_my_server_names(t);
367
368                 /*
369                  * Send out any LanMan broadcast announcements
370                  * of our server names.
371                  * (nmbd_sendannounce.c)
372                  */
373
374                 announce_my_lm_server_names(t);
375
376                 /*
377                  * If we are a local master browser, periodically
378                  * announce ourselves to the domain master browser.
379                  * This also deals with syncronising the domain master
380                  * browser server lists with ourselves as a local
381                  * master browser.
382                  * (nmbd_sendannounce.c)
383                  */
384
385                 announce_myself_to_domain_master_browser(t);
386
387                 /*
388                  * Fullfill any remote announce requests.
389                  * (nmbd_sendannounce.c)
390                  */
391
392                 announce_remote(t);
393
394                 /*
395                  * Fullfill any remote browse sync announce requests.
396                  * (nmbd_sendannounce.c)
397                  */
398
399                 browse_sync_remote(t);
400
401                 /*
402                  * Scan the broadcast subnets, and WINS client
403                  * namelists and refresh any that need refreshing.
404                  * (nmbd_mynames.c)
405                  */
406
407                 refresh_my_names(t);
408
409                 /*
410                  * Scan the subnet namelists and server lists and
411                  * expire thos that have timed out.
412                  * (nmbd.c)
413                  */
414
415                 expire_names_and_servers(t);
416
417                 /*
418                  * Write out a snapshot of our current browse list into
419                  * the browse.dat file. This is used by smbd to service
420                  * incoming NetServerEnum calls - used to synchronise
421                  * browse lists over subnets.
422                  * (nmbd_serverlistdb.c)
423                  */
424
425                 write_browse_list(t, False);
426
427                 /*
428                  * If we are a domain master browser, we have a list of
429                  * local master browsers we should synchronise browse
430                  * lists with (these are added by an incoming local
431                  * master browser announcement packet). Expire any of
432                  * these that are no longer current, and pull the server
433                  * lists from each of these known local master browsers.
434                  * (nmbd_browsesync.c)
435                  */
436
437                 dmb_expire_and_sync_browser_lists(t);
438
439                 /*
440                  * Check that there is a local master browser for our
441                  * workgroup for all our broadcast subnets. If one
442                  * is not found, start an election (which we ourselves
443                  * may or may not participate in, depending on the
444                  * setting of the 'local master' parameter.
445                  * (nmbd_elections.c)
446                  */
447
448                 check_master_browser_exists(t);
449
450                 /*
451                  * If we are configured as a logon server, attempt to
452                  * register the special NetBIOS names to become such
453                  * (WORKGROUP<1c> name) on all broadcast subnets and
454                  * with the WINS server (if used). If we are configured
455                  * to become a domain master browser, attempt to register
456                  * the special NetBIOS name (WORKGROUP<1b> name) to
457                  * become such.
458                  * (nmbd_become_dmb.c)
459                  */
460
461                 add_domain_names(t);
462
463                 /*
464                  * If we are a WINS server, do any timer dependent
465                  * processing required.
466                  * (nmbd_winsserver.c)
467                  */
468
469                 initiate_wins_processing(t);
470
471                 /*
472                  * If we are a domain master browser, attempt to contact the
473                  * WINS server to get a list of all known WORKGROUPS/DOMAINS.
474                  * This will only work to a Samba WINS server.
475                  * (nmbd_browsesync.c)
476                  */
477
478                 if (lp_enhanced_browsing())
479                         collect_all_workgroup_names_from_wins_server(t);
480
481                 /*
482                  * Go through the response record queue and time out or re-transmit
483                  * and expired entries.
484                  * (nmbd_packets.c)
485                  */
486
487                 retransmit_or_expire_response_records(t);
488
489                 /*
490                  * check to see if any remote browse sync child processes have completed
491                  */
492
493                 sync_check_completion();
494
495                 /*
496                  * regularly sync with any other DMBs we know about 
497                  */
498
499                 if (lp_enhanced_browsing())
500                         sync_all_dmbs(t);
501
502                 /*
503                  * clear the unexpected packet queue 
504                  */
505
506                 clear_unexpected(t);
507
508                 /*
509                  * Reload the services file if we got a sighup.
510                  */
511
512                 if(reload_after_sighup) {
513                         DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
514                         write_browse_list( 0, True );
515                         dump_all_namelists();
516                         reload_nmbd_services( True );
517                         reopen_logs();
518                         if(reload_interfaces(0))
519                                 return;
520                         reload_after_sighup = 0;
521                 }
522
523                 /* check for new network interfaces */
524
525                 if(reload_interfaces(t))
526                         return;
527
528                 /* free up temp memory */
529                         lp_talloc_free();
530         }
531 }
532
533 /**************************************************************************** **
534  Open the socket communication.
535  **************************************************************************** */
536
537 static BOOL open_sockets(BOOL isdaemon, int port)
538 {
539         /*
540          * The sockets opened here will be used to receive broadcast
541          * packets *only*. Interface specific sockets are opened in
542          * make_subnet() in namedbsubnet.c. Thus we bind to the
543          * address "0.0.0.0". The parameter 'socket address' is
544          * now deprecated.
545          */
546
547         if ( isdaemon )
548                 ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0,True);
549         else
550                 ClientNMB = 0;
551   
552         ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0,True);
553
554         if ( ClientNMB == -1 )
555                 return( False );
556
557         /* we are never interested in SIGPIPE */
558         BlockSignals(True,SIGPIPE);
559
560         set_socket_options( ClientNMB,   "SO_BROADCAST" );
561         set_socket_options( ClientDGRAM, "SO_BROADCAST" );
562
563         DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
564         return( True );
565 }
566
567 /**************************************************************************** **
568  Initialise connect, service and file structs.
569  **************************************************************************** */
570
571 static BOOL init_structs(void)
572 {
573   extern fstring local_machine;
574   char *p, **ptr;
575   int namecount;
576   int n;
577   int nodup;
578   char *nbname;
579
580   if (! *global_myname)
581   {
582     fstrcpy( global_myname, myhostname() );
583     p = strchr_m( global_myname, '.' );
584     if (p)
585       *p = 0;
586   }
587   strupper( global_myname );
588
589   /* Add any NETBIOS name aliases. Ensure that the first entry
590      is equal to global_myname.
591    */
592   /* Work out the max number of netbios aliases that we have */
593   ptr = lp_netbios_aliases();
594   namecount = 0;
595   if (ptr)
596     for( ; *ptr; namecount++,ptr++ )
597       ;
598   if ( *global_myname )
599     namecount++;
600
601   /* Allocate space for the netbios aliases */
602   my_netbios_names = (char **)malloc( sizeof(char *) * (namecount+1) );
603   if( NULL == my_netbios_names )
604   {
605      DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
606      return( False );
607   }
608  
609   /* Use the global_myname string first */
610   namecount=0;
611   if ( *global_myname )
612     my_netbios_names[namecount++] = global_myname;
613   
614   ptr = lp_netbios_aliases();
615   if (ptr)
616   {
617     while ( *ptr )
618     {
619       nbname = strdup(*ptr);
620       if (nbname == NULL)
621       {
622         DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
623         return False;
624       }
625       strupper( nbname );
626       /* Look for duplicates */
627       nodup=1;
628       for( n=0; n<namecount; n++ )
629       {
630         if( 0 == strcmp( nbname, my_netbios_names[n] ) )
631           nodup=0;
632       }
633       if (nodup)
634         my_netbios_names[namecount++] = nbname;
635       else
636         SAFE_FREE(nbname);
637
638       ptr++;
639     }
640   }
641   
642   /* Terminate name list */
643   my_netbios_names[namecount++] = NULL;
644   
645   fstrcpy( local_machine, global_myname );
646   trim_string( local_machine, " ", " " );
647   p = strchr_m( local_machine, ' ' );
648   if (p)
649     *p = 0;
650   strlower( local_machine );
651
652   DEBUG( 5, ("Netbios name list:-\n") );
653   for( n=0; my_netbios_names[n]; n++ )
654     DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) );
655
656   return( True );
657 }
658
659 /**************************************************************************** **
660  Usage on the program.
661  **************************************************************************** */
662
663 static void usage(char *pname)
664 {
665
666   printf( "Usage: %s [-DaiohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
667   printf( "       [-n name] [-p port] [-s configuration file]\n" );
668   printf( "\t-D                    Become a daemon (default)\n" );
669   printf( "\t-a                    Append to log file (default)\n" );
670   printf( "\t-i                    Run interactive (not a daemon)\n" );
671   printf( "\t-o                    Overwrite log file, don't append\n" );
672   printf( "\t-h                    Print usage\n" );
673   printf( "\t-V                    Print version\n" );
674   printf( "\t-H hosts file         Load a netbios hosts file\n" );
675   printf( "\t-d debuglevel         Set the debuglevel\n" );
676   printf( "\t-l log basename.      Basename for log/debug files\n" );
677   printf( "\t-n netbiosname.       Primary netbios name\n" );
678   printf( "\t-p port               Listen on the specified port\n" );
679   printf( "\t-s configuration file Configuration file name\n" );
680   printf( "\n");
681 }
682
683
684 /**************************************************************************** **
685  main program
686  **************************************************************************** */
687  int main(int argc,char *argv[])
688 {
689   int opt;
690   extern char *optarg;
691   extern BOOL  append_log;
692   BOOL opt_interactive = False;
693   pstring logfile;
694
695   append_log = True;  /* Default, override with '-o' option. */
696
697   global_nmb_port = NMB_PORT;
698   global_in_nmbd = True;
699
700   StartupTime = time(NULL);
701
702   sys_srandom(time(NULL) ^ sys_getpid());
703
704   slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
705   lp_set_logfile(logfile);
706
707   /* this is for people who can't start the program correctly */
708   while (argc > 1 && (*argv[1] != '-'))
709   {
710     argv++;
711     argc--;
712   }
713
714   fault_setup((void (*)(void *))fault_continue );
715
716   /* POSIX demands that signals are inherited. If the invoking process has
717    * these signals masked, we will have problems, as we won't recieve them. */
718   BlockSignals(False, SIGHUP);
719   BlockSignals(False, SIGUSR1);
720   BlockSignals(False, SIGTERM);
721
722   CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
723   CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
724
725 #if defined(SIGFPE)
726   /* we are never interested in SIGFPE */
727   BlockSignals(True,SIGFPE);
728 #endif
729
730   /* We no longer use USR2... */
731 #if defined(SIGUSR2)
732   BlockSignals(True, SIGUSR2);
733 #endif
734
735   while( EOF != 
736          (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dp:hSH:G:f:i" )) )
737     {
738       switch (opt)
739         {
740         case 's':
741           pstrcpy(dyn_CONFIGFILE, optarg);
742           break;          
743         case 'N':
744         case 'B':
745         case 'I':
746         case 'C':
747         case 'G':
748           DEBUG(0,("Obsolete option '%c' used\n",opt));
749           break;
750         case 'i':
751           opt_interactive = True;
752           break;
753         case 'H':
754           pstrcpy(dyn_LMHOSTSFILE, optarg);
755           break;
756         case 'n':
757           pstrcpy(global_myname,optarg);
758           strupper(global_myname);
759           break;
760         case 'l':
761           slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", optarg);
762           lp_set_logfile(logfile);
763           break;
764         case 'a':
765           append_log = True;
766           break;
767         case 'o':
768           append_log = False;
769           break;
770         case 'D':
771           is_daemon = True;
772           break;
773         case 'd':
774           DEBUGLEVEL = atoi(optarg);
775           break;
776         case 'p':
777           global_nmb_port = atoi(optarg);
778           break;
779         case 'h':
780           usage(argv[0]);
781           exit(0);
782           break;
783         case 'V':
784           printf( "Version %s\n", VERSION );
785           exit(0);
786           break;
787         default:
788           if( !is_a_socket(0) )
789           {
790             DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
791             usage(argv[0]);
792             exit(0);
793           }
794           break;
795         }
796     }
797
798   setup_logging( argv[0], opt_interactive );
799
800   reopen_logs();
801
802   DEBUG( 0, ( "Netbios nameserver version %s started.\n", VERSION ) );
803   DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2002\n" ) );
804
805   if ( !reload_nmbd_services(False) )
806     return(-1);
807
808   if(!init_structs())
809     return -1;
810
811   reload_nmbd_services( True );
812
813   fstrcpy( global_myworkgroup, lp_workgroup() );
814
815   if (strequal(global_myworkgroup,"*"))
816   {
817     DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
818     exit(1);
819   }
820
821   set_samba_nb_type();
822
823   if (!is_daemon && !is_a_socket(0))
824   {
825     DEBUG(0,("standard input is not a socket, assuming -D option\n"));
826     is_daemon = True;
827   }
828   
829   if (is_daemon && !opt_interactive)
830   {
831     DEBUG( 2, ( "Becoming a daemon.\n" ) );
832     become_daemon();
833   }
834
835 #if HAVE_SETPGID
836   /*
837    * If we're interactive we want to set our own process group for 
838    * signal management.
839    */
840   if (opt_interactive)
841     setpgid( (pid_t)0, (pid_t)0 );
842 #endif
843
844 #ifndef SYNC_DNS
845   /* Setup the async dns. We do it here so it doesn't have all the other
846      stuff initialised and thus chewing memory and sockets */
847   if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
848           start_async_dns();
849   }
850 #endif
851
852   if (!directory_exist(lp_lockdir(), NULL)) {
853           mkdir(lp_lockdir(), 0755);
854   }
855
856   pidfile_create("nmbd");
857   message_init();
858   message_register(MSG_FORCE_ELECTION, nmbd_message_election);
859   message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
860   message_register(MSG_SHUTDOWN, nmbd_terminate);
861
862   DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
863
864   if ( !open_sockets( is_daemon, global_nmb_port ) ) {
865     kill_async_dns_child();
866     return 1;
867   }
868
869   /* Determine all the IP addresses we have. */
870   load_interfaces();
871
872   /* Create an nmbd subnet record for each of the above. */
873   if( False == create_subnets() )
874   {
875     DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
876     kill_async_dns_child();
877     exit(1);
878   }
879
880   /* Load in any static local names. */ 
881   load_lmhosts_file(dyn_LMHOSTSFILE);
882   DEBUG(3,("Loaded hosts file %s\n", dyn_LMHOSTSFILE));
883
884   /* If we are acting as a WINS server, initialise data structures. */
885   if( !initialise_wins() )
886   {
887     DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
888     kill_async_dns_child();
889     exit(1);
890   }
891
892   /* 
893    * Register nmbd primary workgroup and nmbd names on all
894    * the broadcast subnets, and on the WINS server (if specified).
895    * Also initiate the startup of our primary workgroup (start
896    * elections if we are setup as being able to be a local
897    * master browser.
898    */
899
900   if( False == register_my_workgroup_and_names() )
901   {
902     DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
903     kill_async_dns_child();
904     exit(1);
905   }
906
907   /* We can only take signals in the select. */
908   BlockSignals( True, SIGTERM );
909
910   process();
911
912   if (dbf)
913     x_fclose(dbf);
914   kill_async_dns_child();
915   return(0);
916 }