Sync with HEAD
[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    Copyright (C) Jelmer Vernooij 2002 (Conversion to popt)
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21    
22 */
23
24 #include "includes.h"
25
26 int ClientNMB       = -1;
27 int ClientDGRAM     = -1;
28 int global_nmb_port = -1;
29
30 extern pstring global_myname;
31 extern fstring global_myworkgroup;
32 extern char **my_netbios_names;
33
34 extern BOOL global_in_nmbd;
35
36 /* are we running as a daemon ? */
37 static BOOL is_daemon = False;
38
39 /* have we found LanMan clients yet? */
40 BOOL found_lm_clients = False;
41
42 /* what server type are we currently */
43
44 time_t StartupTime = 0;
45
46 /**************************************************************************** **
47  Handle a SIGTERM in band.
48  **************************************************************************** */
49
50 static void terminate(void)
51 {
52         DEBUG(0,("Got SIGTERM: going down...\n"));
53   
54         /* Write out wins.dat file if samba is a WINS server */
55         wins_write_database(False);
56   
57         /* Remove all SELF registered names from WINS */
58         release_wins_names();
59   
60         /* Announce all server entries as 0 time-to-live, 0 type. */
61         announce_my_servers_removed();
62
63         /* If there was an async dns child - kill it. */
64         kill_async_dns_child();
65
66         exit(0);
67 }
68
69 /**************************************************************************** **
70  Handle a SHUTDOWN message from smbcontrol.
71  **************************************************************************** */
72
73 static void nmbd_terminate(int msg_type, pid_t src, void *buf, size_t len)
74 {
75         terminate();
76 }
77
78 /**************************************************************************** **
79  Catch a SIGTERM signal.
80  **************************************************************************** */
81
82 static SIG_ATOMIC_T got_sig_term;
83
84 static void sig_term(int sig)
85 {
86         got_sig_term = 1;
87         sys_select_signal();
88 }
89
90 /**************************************************************************** **
91  Catch a SIGHUP signal.
92  **************************************************************************** */
93
94 static SIG_ATOMIC_T reload_after_sighup;
95
96 static void sig_hup(int sig)
97 {
98         reload_after_sighup = 1;
99         sys_select_signal();
100 }
101
102 #if DUMP_CORE
103 /**************************************************************************** **
104  Prepare to dump a core file - carefully!
105  **************************************************************************** */
106
107 static BOOL dump_core(void)
108 {
109         char *p;
110         pstring dname;
111         pstrcpy( dname, lp_logfile() );
112         if ((p=strrchr_m(dname,'/')))
113                 *p=0;
114         pstrcat( dname, "/corefiles" );
115         mkdir( dname, 0700 );
116         sys_chown( dname, getuid(), getgid() );
117         chmod( dname, 0700 );
118         if ( chdir(dname) )
119                 return( False );
120         umask( ~(0700) );
121
122 #ifdef HAVE_GETRLIMIT
123 #ifdef RLIMIT_CORE
124         {
125                 struct rlimit rlp;
126                 getrlimit( RLIMIT_CORE, &rlp );
127                 rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
128                 setrlimit( RLIMIT_CORE, &rlp );
129                 getrlimit( RLIMIT_CORE, &rlp );
130                 DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
131         }
132 #endif
133 #endif
134
135
136         DEBUG(0,("Dumping core in %s\n",dname));
137         abort();
138         return( True );
139 }
140 #endif
141
142 /**************************************************************************** **
143  Possibly continue after a fault.
144  **************************************************************************** */
145
146 static void fault_continue(void)
147 {
148 #if DUMP_CORE
149         dump_core();
150 #endif
151 }
152
153 /**************************************************************************** **
154  Expire old names from the namelist and server list.
155  **************************************************************************** */
156
157 static void expire_names_and_servers(time_t t)
158 {
159         static time_t lastrun = 0;
160   
161         if ( !lastrun )
162                 lastrun = t;
163         if ( t < (lastrun + 5) )
164                 return;
165         lastrun = t;
166
167         /*
168          * Expire any timed out names on all the broadcast
169          * subnets and those registered with the WINS server.
170          * (nmbd_namelistdb.c)
171          */
172
173         expire_names(t);
174
175         /*
176          * Go through all the broadcast subnets and for each
177          * workgroup known on that subnet remove any expired
178          * server names. If a workgroup has an empty serverlist
179          * and has itself timed out then remove the workgroup.
180          * (nmbd_workgroupdb.c)
181          */
182
183         expire_workgroups_and_servers(t);
184 }
185
186 /************************************************************************** **
187  Reload the list of network interfaces.
188  ************************************************************************** */
189
190 static BOOL reload_interfaces(time_t t)
191 {
192         static time_t lastt;
193         int n;
194         struct subnet_record *subrec;
195         extern BOOL rescan_listen_set;
196         extern struct in_addr loopback_ip;
197
198         if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False;
199         lastt = t;
200
201         if (!interfaces_changed()) return False;
202
203         /* the list of probed interfaces has changed, we may need to add/remove
204            some subnets */
205         load_interfaces();
206
207         /* find any interfaces that need adding */
208         for (n=iface_count() - 1; n >= 0; n--) {
209                 struct interface *iface = get_interface(n);
210
211                 /*
212                  * We don't want to add a loopback interface, in case
213                  * someone has added 127.0.0.1 for smbd, nmbd needs to
214                  * ignore it here. JRA.
215                  */
216
217                 if (ip_equal(iface->ip, loopback_ip)) {
218                         DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
219                         continue;
220                 }
221
222                 for (subrec=subnetlist; subrec; subrec=subrec->next) {
223                         if (ip_equal(iface->ip, subrec->myip) &&
224                             ip_equal(iface->nmask, subrec->mask_ip)) break;
225                 }
226
227                 if (!subrec) {
228                         /* it wasn't found! add it */
229                         DEBUG(2,("Found new interface %s\n", 
230                                  inet_ntoa(iface->ip)));
231                         subrec = make_normal_subnet(iface);
232                         if (subrec) register_my_workgroup_one_subnet(subrec);
233                 }
234         }
235
236         /* find any interfaces that need deleting */
237         for (subrec=subnetlist; subrec; subrec=subrec->next) {
238                 for (n=iface_count() - 1; n >= 0; n--) {
239                         struct interface *iface = get_interface(n);
240                         if (ip_equal(iface->ip, subrec->myip) &&
241                             ip_equal(iface->nmask, subrec->mask_ip)) break;
242                 }
243                 if (n == -1) {
244                         /* oops, an interface has disapeared. This is
245                          tricky, we don't dare actually free the
246                          interface as it could be being used, so
247                          instead we just wear the memory leak and
248                          remove it from the list of interfaces without
249                          freeing it */
250                         DEBUG(2,("Deleting dead interface %s\n", 
251                                  inet_ntoa(subrec->myip)));
252                         close_subnet(subrec);
253                 }
254         }
255         
256         rescan_listen_set = True;
257
258         /* We need to shutdown if there are no subnets... */
259         if (FIRST_SUBNET == NULL) {
260                 DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n"));
261                 return True;
262         }
263         return False;
264 }
265
266 /**************************************************************************** **
267  Reload the services file.
268  **************************************************************************** */
269
270 static BOOL reload_nmbd_services(BOOL test)
271 {
272         BOOL ret;
273
274         set_remote_machine_name("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  main program
661  **************************************************************************** */
662  int main(int argc, const char *argv[])
663 {
664         extern BOOL append_log;
665         static BOOL opt_interactive = False;
666         poptContext pc;
667         struct poptOption long_options[] = {
668         POPT_AUTOHELP
669         {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" },
670         {"log-append", 'a', POPT_ARG_VAL, &append_log, True, "Append to log file" },
671         {"interactive", 'i', POPT_ARG_VAL, &opt_interactive, True, "Run interactive (not a daemon)" },
672         {"log-overwrite", 'o', POPT_ARG_VAL, &append_log, False, "Overwrite log file, don't append" },
673         {"hosts", 'H', POPT_ARG_STRING, dyn_LMHOSTSFILE, 'H', "Load a netbios hosts file"},
674         {"port", 'p', POPT_ARG_INT, &global_nmb_port, NMB_PORT, "Listen on the specified port" },
675         {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug },
676         {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_configfile },
677         {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_socket_options },
678         {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version },
679         {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_netbios_name },
680         {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_log_base },
681         { NULL }
682         };
683         int opt;
684         pstring logfile;
685
686   append_log = True;  /* Default, override with '-o' option. */
687
688   global_nmb_port = NMB_PORT;
689   global_in_nmbd = True;
690
691   StartupTime = time(NULL);
692
693   sys_srandom(time(NULL) ^ sys_getpid());
694
695   slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
696   lp_set_logfile(logfile);
697
698   fault_setup((void (*)(void *))fault_continue );
699
700   /* POSIX demands that signals are inherited. If the invoking process has
701    * these signals masked, we will have problems, as we won't recieve them. */
702   BlockSignals(False, SIGHUP);
703   BlockSignals(False, SIGUSR1);
704   BlockSignals(False, SIGTERM);
705
706   CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
707   CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
708
709 #if defined(SIGFPE)
710   /* we are never interested in SIGFPE */
711   BlockSignals(True,SIGFPE);
712 #endif
713
714   /* We no longer use USR2... */
715 #if defined(SIGUSR2)
716   BlockSignals(True, SIGUSR2);
717 #endif
718   pc = poptGetContext("nmbd", argc, argv, long_options, 0);
719   
720   while((opt = poptGetNextOpt(pc)) != -1)
721     { }
722
723   poptFreeContext(pc);
724   
725   setup_logging( argv[0], opt_interactive );
726
727   reopen_logs();
728
729   DEBUG( 0, ( "Netbios nameserver version %s started.\n", VERSION ) );
730   DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2002\n" ) );
731
732   if ( !reload_nmbd_services(False) )
733     return(-1);
734
735   if(!init_structs())
736     return -1;
737
738   reload_nmbd_services( True );
739
740   fstrcpy( global_myworkgroup, lp_workgroup() );
741
742   if (strequal(global_myworkgroup,"*"))
743   {
744     DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
745     exit(1);
746   }
747
748   set_samba_nb_type();
749
750   if (!is_daemon && !is_a_socket(0))
751   {
752     DEBUG(0,("standard input is not a socket, assuming -D option\n"));
753     is_daemon = True;
754   }
755   
756   if (is_daemon && !opt_interactive)
757   {
758     DEBUG( 2, ( "Becoming a daemon.\n" ) );
759     become_daemon();
760   }
761
762 #if HAVE_SETPGID
763   /*
764    * If we're interactive we want to set our own process group for 
765    * signal management.
766    */
767   if (opt_interactive)
768     setpgid( (pid_t)0, (pid_t)0 );
769 #endif
770
771 #ifndef SYNC_DNS
772   /* Setup the async dns. We do it here so it doesn't have all the other
773      stuff initialised and thus chewing memory and sockets */
774   if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
775           start_async_dns();
776   }
777 #endif
778
779   if (!directory_exist(lp_lockdir(), NULL)) {
780           mkdir(lp_lockdir(), 0755);
781   }
782
783   pidfile_create("nmbd");
784   message_init();
785   message_register(MSG_FORCE_ELECTION, nmbd_message_election);
786   message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
787   message_register(MSG_SHUTDOWN, nmbd_terminate);
788
789   DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
790
791   if ( !open_sockets( is_daemon, global_nmb_port ) ) {
792     kill_async_dns_child();
793     return 1;
794   }
795
796   /* Determine all the IP addresses we have. */
797   load_interfaces();
798
799   /* Create an nmbd subnet record for each of the above. */
800   if( False == create_subnets() )
801   {
802     DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
803     kill_async_dns_child();
804     exit(1);
805   }
806
807   /* Load in any static local names. */ 
808   load_lmhosts_file(dyn_LMHOSTSFILE);
809   DEBUG(3,("Loaded hosts file %s\n", dyn_LMHOSTSFILE));
810
811   /* If we are acting as a WINS server, initialise data structures. */
812   if( !initialise_wins() )
813   {
814     DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
815     kill_async_dns_child();
816     exit(1);
817   }
818
819   /* 
820    * Register nmbd primary workgroup and nmbd names on all
821    * the broadcast subnets, and on the WINS server (if specified).
822    * Also initiate the startup of our primary workgroup (start
823    * elections if we are setup as being able to be a local
824    * master browser.
825    */
826
827   if( False == register_my_workgroup_and_names() )
828   {
829     DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
830     kill_async_dns_child();
831     exit(1);
832   }
833
834   /* We can only take signals in the select. */
835   BlockSignals( True, SIGTERM );
836
837   process();
838
839   if (dbf)
840     x_fclose(dbf);
841   kill_async_dns_child();
842   return(0);
843 }