6fead637ebbff644c23bedef53c21f3ba45b81d6
[nivanova/samba-autobuild/.git] / source3 / nmbd / nmbd.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-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21    Revision History:
22
23    14 jan 96: lkcl@pires.co.uk
24    added multiple workgroup domain master support
25
26 */
27
28 #include "includes.h"
29
30 extern int DEBUGLEVEL;
31
32 extern pstring debugf;
33 pstring servicesf = CONFIGFILE;
34
35 int ClientNMB       = -1;
36 int ClientDGRAM     = -1;
37 int global_nmb_port = -1;
38
39 static pstring host_file;
40 extern pstring global_myname;
41 extern fstring global_myworkgroup;
42 extern char **my_netbios_names;
43
44 extern BOOL global_in_nmbd;
45
46 /* are we running as a daemon ? */
47 static BOOL is_daemon = False;
48
49 /* have we found LanMan clients yet? */
50 BOOL found_lm_clients = False;
51
52 /* what server type are we currently */
53
54 time_t StartupTime = 0;
55
56 extern struct in_addr ipzero;
57
58 /**************************************************************************** **
59   catch a sigterm
60  **************************************************************************** */
61 static void sig_term(int sig)
62 {
63   BlockSignals(True,SIGTERM);
64   
65   DEBUG(0,("Got SIGTERM: going down...\n"));
66   
67   /* Write out wins.dat file if samba is a WINS server */
68   wins_write_database(False);
69   
70   /* Remove all SELF registered names. */
71   release_my_names();
72   
73   /* Announce all server entries as 0 time-to-live, 0 type. */
74   announce_my_servers_removed();
75
76   /* If there was an async dns child - kill it. */
77   kill_async_dns_child();
78
79   exit(0);
80
81 } /* sig_term */
82
83 /**************************************************************************** **
84  catch a sighup
85  **************************************************************************** */
86 static VOLATILE sig_atomic_t reload_after_sighup = False;
87
88 static void sig_hup(int sig)
89 {
90   BlockSignals( True, SIGHUP );
91
92   DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
93
94   write_browse_list( 0, True );
95
96   dump_all_namelists();
97
98   reload_after_sighup = True;
99
100   BlockSignals(False,SIGHUP);
101
102 } /* sig_hup */
103
104
105 #if DUMP_CORE
106 /**************************************************************************** **
107  prepare to dump a core file - carefully!
108  **************************************************************************** */
109 static BOOL dump_core(void)
110 {
111   char *p;
112   pstring dname;
113   pstrcpy( dname, debugf );
114   if ((p=strrchr_m(dname,'/')))
115     *p=0;
116   pstrcat( dname, "/corefiles" );
117   mkdir( dname, 0700 );
118   sys_chown( dname, getuid(), getgid() );
119   chmod( dname, 0700 );
120   if ( chdir(dname) )
121     return( False );
122   umask( ~(0700) );
123
124 #ifdef HAVE_GETRLIMIT
125 #ifdef RLIMIT_CORE
126   {
127     struct rlimit rlp;
128     getrlimit( RLIMIT_CORE, &rlp );
129     rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
130     setrlimit( RLIMIT_CORE, &rlp );
131     getrlimit( RLIMIT_CORE, &rlp );
132     DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
133   }
134 #endif
135 #endif
136
137
138   DEBUG(0,("Dumping core in %s\n",dname));
139   abort();
140   return( True );
141 } /* dump_core */
142 #endif
143
144
145 /**************************************************************************** **
146  possibly continue after a fault
147  **************************************************************************** */
148 static void fault_continue(void)
149 {
150 #if DUMP_CORE
151   dump_core();
152 #endif
153 } /* fault_continue */
154
155 /**************************************************************************** **
156  expire old names from the namelist and server list
157  **************************************************************************** */
158 static void expire_names_and_servers(time_t t)
159 {
160   static time_t lastrun = 0;
161   
162   if ( !lastrun )
163     lastrun = t;
164   if ( t < (lastrun + 5) )
165     return;
166   lastrun = t;
167
168   /*
169    * Expire any timed out names on all the broadcast
170    * subnets and those registered with the WINS server.
171    * (nmbd_namelistdb.c)
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   expire_workgroups_and_servers(t);
183 } /* expire_names_and_servers */
184
185
186 /************************************************************************** **
187 reload the list of network interfaces
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
267 /**************************************************************************** **
268   reload the services file
269  **************************************************************************** */
270 static BOOL reload_nmbd_services(BOOL test)
271 {
272   BOOL ret;
273   extern fstring remote_machine;
274
275   fstrcpy( remote_machine, "nmbd" );
276
277   if ( lp_loaded() )
278   {
279     pstring fname;
280     pstrcpy( fname,lp_configfile());
281     if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
282     {
283       pstrcpy(servicesf,fname);
284       test = False;
285     }
286   }
287
288   if ( test && !lp_file_list_changed() )
289     return(True);
290
291   ret = lp_load( servicesf, True , False, False);
292
293   /* perhaps the config filename is now set */
294   if ( !test )
295   {
296     DEBUG( 3, ( "services not loaded\n" ) );
297     reload_nmbd_services( True );
298   }
299
300   /* Do a sanity check for a misconfigured nmbd */
301   if( lp_wins_support() && wins_srv_count() )
302     {
303     if( DEBUGLVL(0) )
304       {
305       dbgtext( "ERROR: 'wins support = true' and 'wins server = <server>'\n" );
306       dbgtext( "are conflicting settings.  nmbd aborting.\n" );
307       }
308     exit(10);
309     }
310
311   return(ret);
312 } /* reload_nmbd_services */
313
314 /**************************************************************************** **
315  The main select loop.
316  **************************************************************************** */
317 static void process(void)
318 {
319   BOOL run_election;
320
321   while( True )
322   {
323     time_t t = time(NULL);
324
325     /* check for internal messages */
326     message_dispatch();
327
328     /*
329      * Check all broadcast subnets to see if
330      * we need to run an election on any of them.
331      * (nmbd_elections.c)
332      */
333     run_election = check_elections();
334
335     /*
336      * Read incoming UDP packets.
337      * (nmbd_packets.c)
338      */
339     if(listen_for_packets(run_election))
340       return;
341
342     /*
343      * Process all incoming packets
344      * read above. This calls the success and
345      * failure functions registered when response
346      * packets arrrive, and also deals with request
347      * packets from other sources.
348      * (nmbd_packets.c)
349      */
350     run_packet_queue();
351
352     /*
353      * Run any elections - initiate becoming
354      * a local master browser if we have won.
355      * (nmbd_elections.c)
356      */
357     run_elections(t);
358
359     /*
360      * Send out any broadcast announcements
361      * of our server names. This also announces
362      * the workgroup name if we are a local
363      * master browser.
364      * (nmbd_sendannounce.c)
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     announce_my_lm_server_names(t);
374
375     /*
376      * If we are a local master browser, periodically
377      * announce ourselves to the domain master browser.
378      * This also deals with syncronising the domain master
379      * browser server lists with ourselves as a local
380      * master browser.
381      * (nmbd_sendannounce.c)
382      */
383     announce_myself_to_domain_master_browser(t);
384
385     /*
386      * Fullfill any remote announce requests.
387      * (nmbd_sendannounce.c)
388      */
389     announce_remote(t);
390
391     /*
392      * Fullfill any remote browse sync announce requests.
393      * (nmbd_sendannounce.c)
394      */
395     browse_sync_remote(t);
396
397     /*
398      * Scan the broadcast subnets, and WINS client
399      * namelists and refresh any that need refreshing.
400      * (nmbd_mynames.c)
401      */
402     refresh_my_names(t);
403
404     /*
405      * Scan the subnet namelists and server lists and
406      * expire thos that have timed out.
407      * (nmbd.c)
408      */
409     expire_names_and_servers(t);
410
411     /*
412      * Write out a snapshot of our current browse list into
413      * the browse.dat file. This is used by smbd to service
414      * incoming NetServerEnum calls - used to synchronise
415      * browse lists over subnets.
416      * (nmbd_serverlistdb.c)
417      */
418     write_browse_list(t, False);
419
420     /*
421      * If we are a domain master browser, we have a list of
422      * local master browsers we should synchronise browse
423      * lists with (these are added by an incoming local
424      * master browser announcement packet). Expire any of
425      * these that are no longer current, and pull the server
426      * lists from each of these known local master browsers.
427      * (nmbd_browsesync.c)
428      */
429     dmb_expire_and_sync_browser_lists(t);
430
431     /*
432      * Check that there is a local master browser for our
433      * workgroup for all our broadcast subnets. If one
434      * is not found, start an election (which we ourselves
435      * may or may not participate in, depending on the
436      * setting of the 'local master' parameter.
437      * (nmbd_elections.c)
438      */
439     check_master_browser_exists(t);
440
441     /*
442      * If we are configured as a logon server, attempt to
443      * register the special NetBIOS names to become such
444      * (WORKGROUP<1c> name) on all broadcast subnets and
445      * with the WINS server (if used). If we are configured
446      * to become a domain master browser, attempt to register
447      * the special NetBIOS name (WORKGROUP<1b> name) to
448      * become such.
449      * (nmbd_become_dmb.c)
450      */
451     add_domain_names(t);
452
453     /*
454      * If we are a WINS server, do any timer dependent
455      * processing required.
456      * (nmbd_winsserver.c)
457      */
458     initiate_wins_processing(t);
459
460     /*
461      * If we are a domain master browser, attempt to contact the
462      * WINS server to get a list of all known WORKGROUPS/DOMAINS.
463      * This will only work to a Samba WINS server.
464      * (nmbd_browsesync.c)
465      */
466     if (lp_enhanced_browsing()) {
467             collect_all_workgroup_names_from_wins_server(t);
468     }
469
470     /*
471      * Go through the response record queue and time out or re-transmit
472      * and expired entries.
473      * (nmbd_packets.c)
474      */
475     retransmit_or_expire_response_records(t);
476
477     /*
478      * check to see if any remote browse sync child processes have completed
479      */
480     sync_check_completion();
481
482     /*
483      * regularly sync with any other DMBs we know about 
484      */
485     if (lp_enhanced_browsing()) {
486             sync_all_dmbs(t);
487     }
488
489     /*
490      * clear the unexpected packet queue 
491      */
492     clear_unexpected(t);
493
494     /*
495      * Reload the services file if we got a sighup.
496      */
497
498     if(reload_after_sighup) {
499             reload_nmbd_services( True );
500             reopen_logs();
501             if(reload_interfaces(0))
502                         return;
503             reload_after_sighup = False;
504     }
505
506     /* check for new network interfaces */
507     if(reload_interfaces(t))
508                 return;
509
510     /* free up temp memory */
511     lp_talloc_free();
512   }
513 } /* process */
514
515
516 /**************************************************************************** **
517  open the socket communication
518  **************************************************************************** */
519 static BOOL open_sockets(BOOL isdaemon, int port)
520 {
521   /* The sockets opened here will be used to receive broadcast
522      packets *only*. Interface specific sockets are opened in
523      make_subnet() in namedbsubnet.c. Thus we bind to the
524      address "0.0.0.0". The parameter 'socket address' is
525      now deprecated.
526    */
527
528   if ( isdaemon )
529     ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0,True);
530   else
531     ClientNMB = 0;
532   
533   ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0,True);
534
535   if ( ClientNMB == -1 )
536     return( False );
537
538   /* we are never interested in SIGPIPE */
539   BlockSignals(True,SIGPIPE);
540
541   set_socket_options( ClientNMB,   "SO_BROADCAST" );
542   set_socket_options( ClientDGRAM, "SO_BROADCAST" );
543
544   DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
545   return( True );
546 } /* open_sockets */
547
548
549 /**************************************************************************** **
550  initialise connect, service and file structs
551  **************************************************************************** */
552 static BOOL init_structs(void)
553 {
554   extern fstring local_machine;
555   char *p, **ptr;
556   int namecount;
557   int n;
558   int nodup;
559   char *nbname;
560
561   if (! *global_myname)
562   {
563     fstrcpy( global_myname, myhostname() );
564     p = strchr_m( global_myname, '.' );
565     if (p)
566       *p = 0;
567   }
568   strupper( global_myname );
569
570   /* Add any NETBIOS name aliases. Ensure that the first entry
571      is equal to global_myname.
572    */
573   /* Work out the max number of netbios aliases that we have */
574   ptr = lp_netbios_aliases();
575   namecount = 0;
576   if (ptr)
577     for( ; *ptr; namecount++,ptr++ )
578       ;
579   if ( *global_myname )
580     namecount++;
581
582   /* Allocate space for the netbios aliases */
583   my_netbios_names = (char **)malloc( sizeof(char *) * (namecount+1) );
584   if( NULL == my_netbios_names )
585   {
586      DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
587      return( False );
588   }
589  
590   /* Use the global_myname string first */
591   namecount=0;
592   if ( *global_myname )
593     my_netbios_names[namecount++] = global_myname;
594   
595   ptr = lp_netbios_aliases();
596   if (ptr)
597   {
598     while ( *ptr )
599     {
600       nbname = strdup(*ptr);
601       if (nbname == NULL)
602       {
603         DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
604         return False;
605       }
606       strupper( nbname );
607       /* Look for duplicates */
608       nodup=1;
609       for( n=0; n<namecount; n++ )
610       {
611         if( 0 == strcmp( nbname, my_netbios_names[n] ) )
612           nodup=0;
613       }
614       if (nodup)
615         my_netbios_names[namecount++] = nbname;
616       else
617         SAFE_FREE(nbname);
618
619       ptr++;
620     }
621   }
622   
623   /* Terminate name list */
624   my_netbios_names[namecount++] = NULL;
625   
626   fstrcpy( local_machine, global_myname );
627   trim_string( local_machine, " ", " " );
628   p = strchr_m( local_machine, ' ' );
629   if (p)
630     *p = 0;
631   strlower( local_machine );
632
633   DEBUG( 5, ("Netbios name list:-\n") );
634   for( n=0; my_netbios_names[n]; n++ )
635     DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) );
636
637   return( True );
638 } /* init_structs */
639
640 /**************************************************************************** **
641  usage on the program
642  **************************************************************************** */
643 static void usage(char *pname)
644 {
645
646   printf( "Usage: %s [-DaohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
647   printf( "       [-n name] [-p port] [-s configuration file]\n" );
648   printf( "\t-D                    Become a daemon\n" );
649   printf( "\t-a                    Append to log file (default)\n" );
650   printf( "\t-o                    Overwrite log file, don't append\n" );
651   printf( "\t-h                    Print usage\n" );
652   printf( "\t-V                    Print version\n" );
653   printf( "\t-H hosts file         Load a netbios hosts file\n" );
654   printf( "\t-d debuglevel         Set the debuglevel\n" );
655   printf( "\t-l log basename.      Basename for log/debug files\n" );
656   printf( "\t-n netbiosname.       Primary netbios name\n" );
657   printf( "\t-p port               Listen on the specified port\n" );
658   printf( "\t-s configuration file Configuration file name\n" );
659   printf( "\n");
660 } /* usage */
661
662
663 /**************************************************************************** **
664  main program
665  **************************************************************************** */
666  int main(int argc,char *argv[])
667 {
668   int opt;
669   extern char *optarg;
670   extern BOOL  append_log;
671
672   append_log = True;  /* Default, override with '-o' option. */
673
674   global_nmb_port = NMB_PORT;
675   *host_file = 0;
676   global_in_nmbd = True;
677
678   StartupTime = time(NULL);
679
680   sys_srandom(time(NULL) ^ sys_getpid());
681
682   TimeInit();
683
684   slprintf(debugf, sizeof(debugf)-1, "%s/log.nmbd", LOGFILEBASE);
685   setup_logging( argv[0], False );
686
687 #ifdef LMHOSTSFILE
688   pstrcpy( host_file, LMHOSTSFILE );
689 #endif
690
691   /* this is for people who can't start the program correctly */
692   while (argc > 1 && (*argv[1] != '-'))
693   {
694     argv++;
695     argc--;
696   }
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
719   while( EOF != 
720          (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dp:hSH:G:f:" )) )
721     {
722       switch (opt)
723         {
724         case 's':
725           pstrcpy(servicesf,optarg);
726           break;          
727         case 'N':
728         case 'B':
729         case 'I':
730         case 'C':
731         case 'G':
732           DEBUG(0,("Obsolete option '%c' used\n",opt));
733           break;
734         case 'H':
735           pstrcpy(host_file,optarg);
736           break;
737         case 'n':
738           pstrcpy(global_myname,optarg);
739           strupper(global_myname);
740           break;
741         case 'l':
742           slprintf(debugf, sizeof(debugf)-1, "%s/log.nmbd", optarg);
743           break;
744         case 'a':
745           append_log = True;
746           break;
747         case 'o':
748           append_log = False;
749           break;
750         case 'D':
751           is_daemon = True;
752           break;
753         case 'd':
754           DEBUGLEVEL = atoi(optarg);
755           break;
756         case 'p':
757           global_nmb_port = atoi(optarg);
758           break;
759         case 'h':
760           usage(argv[0]);
761           exit(0);
762           break;
763         case 'V':
764           printf( "Version %s\n", VERSION );
765           exit(0);
766           break;
767         default:
768           if( !is_a_socket(0) )
769           {
770             DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
771             usage(argv[0]);
772             exit(0);
773           }
774           break;
775         }
776     }
777
778   reopen_logs();
779
780   DEBUG( 1, ( "Netbios nameserver version %s started.\n", VERSION ) );
781   DEBUGADD( 1, ( "Copyright Andrew Tridgell 1994-1998\n" ) );
782
783   if ( !reload_nmbd_services(False) )
784     return(-1);
785
786   if(!init_structs())
787     return -1;
788
789   reload_nmbd_services( True );
790
791   fstrcpy( global_myworkgroup, lp_workgroup() );
792
793   if (strequal(global_myworkgroup,"*"))
794   {
795     DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
796     exit(1);
797   }
798
799   set_samba_nb_type();
800
801   if (!is_daemon && !is_a_socket(0))
802   {
803     DEBUG(0,("standard input is not a socket, assuming -D option\n"));
804     is_daemon = True;
805   }
806   
807   if (is_daemon)
808   {
809     DEBUG( 2, ( "Becoming a daemon.\n" ) );
810     become_daemon();
811   }
812
813 #ifndef SYNC_DNS
814   /* Setup the async dns. We do it here so it doesn't have all the other
815      stuff initialised and thus chewing memory and sockets */
816   if(lp_we_are_a_wins_server()) {
817           start_async_dns();
818   }
819 #endif
820
821   if (!directory_exist(lp_lockdir(), NULL)) {
822           mkdir(lp_lockdir(), 0755);
823   }
824
825   pidfile_create("nmbd");
826   message_init();
827   message_register(MSG_FORCE_ELECTION, nmbd_message_election);
828
829   DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
830
831   if ( !open_sockets( is_daemon, global_nmb_port ) )
832     return 1;
833
834   /* Determine all the IP addresses we have. */
835   load_interfaces();
836
837   /* Create an nmbd subnet record for each of the above. */
838   if( False == create_subnets() )
839   {
840     DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
841     exit(1);
842   }
843
844   /* Load in any static local names. */ 
845   if ( *host_file )
846   {
847     load_lmhosts_file(host_file);
848     DEBUG(3,("Loaded hosts file\n"));
849   }
850
851   /* If we are acting as a WINS server, initialise data structures. */
852   if( !initialise_wins() )
853   {
854     DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
855     exit(1);
856   }
857
858   /* 
859    * Register nmbd primary workgroup and nmbd names on all
860    * the broadcast subnets, and on the WINS server (if specified).
861    * Also initiate the startup of our primary workgroup (start
862    * elections if we are setup as being able to be a local
863    * master browser.
864    */
865
866   if( False == register_my_workgroup_and_names() )
867   {
868     DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
869     exit(1);
870   }
871
872   /* We can only take signals in the select. */
873   BlockSignals( True, SIGTERM );
874
875   process();
876
877   if (dbf)
878     x_fclose(dbf);
879   return(0);
880 } /* main */
881