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