5e8e7e1ec661019c0b15e3083e77b84961d1108f
[samba.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(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() && *lp_wins_server() )
302   {
303     DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
304 cannot be set in the smb.conf file. nmbd aborting.\n"));
305     exit(10);
306   }
307
308   return(ret);
309 } /* reload_nmbd_services */
310
311 /**************************************************************************** **
312  The main select loop.
313  **************************************************************************** */
314 static void process(void)
315 {
316   BOOL run_election;
317
318   while( True )
319   {
320     time_t t = time(NULL);
321
322     /* check for internal messages */
323     message_dispatch();
324
325     /*
326      * Check all broadcast subnets to see if
327      * we need to run an election on any of them.
328      * (nmbd_elections.c)
329      */
330     run_election = check_elections();
331
332     /*
333      * Read incoming UDP packets.
334      * (nmbd_packets.c)
335      */
336     if(listen_for_packets(run_election))
337       return;
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     run_packet_queue();
348
349     /*
350      * Run any elections - initiate becoming
351      * a local master browser if we have won.
352      * (nmbd_elections.c)
353      */
354     run_elections(t);
355
356     /*
357      * Send out any broadcast announcements
358      * of our server names. This also announces
359      * the workgroup name if we are a local
360      * master browser.
361      * (nmbd_sendannounce.c)
362      */
363     announce_my_server_names(t);
364
365     /*
366      * Send out any LanMan broadcast announcements
367      * of our server names.
368      * (nmbd_sendannounce.c)
369      */
370     announce_my_lm_server_names(t);
371
372     /*
373      * If we are a local master browser, periodically
374      * announce ourselves to the domain master browser.
375      * This also deals with syncronising the domain master
376      * browser server lists with ourselves as a local
377      * master browser.
378      * (nmbd_sendannounce.c)
379      */
380     announce_myself_to_domain_master_browser(t);
381
382     /*
383      * Fullfill any remote announce requests.
384      * (nmbd_sendannounce.c)
385      */
386     announce_remote(t);
387
388     /*
389      * Fullfill any remote browse sync announce requests.
390      * (nmbd_sendannounce.c)
391      */
392     browse_sync_remote(t);
393
394     /*
395      * Scan the broadcast subnets, and WINS client
396      * namelists and refresh any that need refreshing.
397      * (nmbd_mynames.c)
398      */
399     refresh_my_names(t);
400
401     /*
402      * Scan the subnet namelists and server lists and
403      * expire thos that have timed out.
404      * (nmbd.c)
405      */
406     expire_names_and_servers(t);
407
408     /*
409      * Write out a snapshot of our current browse list into
410      * the browse.dat file. This is used by smbd to service
411      * incoming NetServerEnum calls - used to synchronise
412      * browse lists over subnets.
413      * (nmbd_serverlistdb.c)
414      */
415     write_browse_list(t, False);
416
417     /*
418      * If we are a domain master browser, we have a list of
419      * local master browsers we should synchronise browse
420      * lists with (these are added by an incoming local
421      * master browser announcement packet). Expire any of
422      * these that are no longer current, and pull the server
423      * lists from each of these known local master browsers.
424      * (nmbd_browsesync.c)
425      */
426     dmb_expire_and_sync_browser_lists(t);
427
428     /*
429      * Check that there is a local master browser for our
430      * workgroup for all our broadcast subnets. If one
431      * is not found, start an election (which we ourselves
432      * may or may not participate in, depending on the
433      * setting of the 'local master' parameter.
434      * (nmbd_elections.c)
435      */
436     check_master_browser_exists(t);
437
438     /*
439      * If we are configured as a logon server, attempt to
440      * register the special NetBIOS names to become such
441      * (WORKGROUP<1c> name) on all broadcast subnets and
442      * with the WINS server (if used). If we are configured
443      * to become a domain master browser, attempt to register
444      * the special NetBIOS name (WORKGROUP<1b> name) to
445      * become such.
446      * (nmbd_become_dmb.c)
447      */
448     add_domain_names(t);
449
450     /*
451      * If we are a WINS server, do any timer dependent
452      * processing required.
453      * (nmbd_winsserver.c)
454      */
455     initiate_wins_processing(t);
456
457     /*
458      * If we are a domain master browser, attempt to contact the
459      * WINS server to get a list of all known WORKGROUPS/DOMAINS.
460      * This will only work to a Samba WINS server.
461      * (nmbd_browsesync.c)
462      */
463     if (lp_enhanced_browsing()) {
464             collect_all_workgroup_names_from_wins_server(t);
465     }
466
467     /*
468      * Go through the response record queue and time out or re-transmit
469      * and expired entries.
470      * (nmbd_packets.c)
471      */
472     retransmit_or_expire_response_records(t);
473
474     /*
475      * check to see if any remote browse sync child processes have completed
476      */
477     sync_check_completion();
478
479     /*
480      * regularly sync with any other DMBs we know about 
481      */
482     if (lp_enhanced_browsing()) {
483             sync_all_dmbs(t);
484     }
485
486     /*
487      * clear the unexpected packet queue 
488      */
489     clear_unexpected(t);
490
491     /*
492      * Reload the services file if we got a sighup.
493      */
494
495     if(reload_after_sighup) {
496             reload_nmbd_services( True );
497             reopen_logs();
498             if(reload_interfaces(0))
499                         return;
500             reload_after_sighup = False;
501     }
502
503     /* check for new network interfaces */
504     if(reload_interfaces(t))
505                 return;
506
507     /* free up temp memory */
508     lp_talloc_free();
509   }
510 } /* process */
511
512
513 /**************************************************************************** **
514  open the socket communication
515  **************************************************************************** */
516 static BOOL open_sockets(BOOL isdaemon, int port)
517 {
518   /* The sockets opened here will be used to receive broadcast
519      packets *only*. Interface specific sockets are opened in
520      make_subnet() in namedbsubnet.c. Thus we bind to the
521      address "0.0.0.0". The parameter 'socket address' is
522      now deprecated.
523    */
524
525   if ( isdaemon )
526     ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0,True);
527   else
528     ClientNMB = 0;
529   
530   ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0,True);
531
532   if ( ClientNMB == -1 )
533     return( False );
534
535   /* we are never interested in SIGPIPE */
536   BlockSignals(True,SIGPIPE);
537
538   set_socket_options( ClientNMB,   "SO_BROADCAST" );
539   set_socket_options( ClientDGRAM, "SO_BROADCAST" );
540
541   DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
542   return( True );
543 } /* open_sockets */
544
545
546 /**************************************************************************** **
547  initialise connect, service and file structs
548  **************************************************************************** */
549 static BOOL init_structs(void)
550 {
551   extern fstring local_machine;
552   char *p, *ptr;
553   int namecount;
554   int n;
555   int nodup;
556   pstring nbname;
557
558   if (! *global_myname)
559   {
560     fstrcpy( global_myname, myhostname() );
561     p = strchr( global_myname, '.' );
562     if (p)
563       *p = 0;
564   }
565   strupper( global_myname );
566
567   /* Add any NETBIOS name aliases. Ensure that the first entry
568      is equal to global_myname.
569    */
570   /* Work out the max number of netbios aliases that we have */
571   ptr = lp_netbios_aliases();
572   for( namecount=0; next_token(&ptr,nbname,NULL, sizeof(nbname)); namecount++ )
573     ;
574   if ( *global_myname )
575     namecount++;
576
577   /* Allocate space for the netbios aliases */
578   my_netbios_names = (char **)malloc( sizeof(char *) * (namecount+1) );
579   if( NULL == my_netbios_names )
580   {
581      DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
582      return( False );
583   }
584  
585   /* Use the global_myname string first */
586   namecount=0;
587   if ( *global_myname )
588     my_netbios_names[namecount++] = global_myname;
589   
590   ptr = lp_netbios_aliases();
591   while ( next_token( &ptr, nbname, NULL, sizeof(nbname) ) )
592   {
593     strupper( nbname );
594     /* Look for duplicates */
595     nodup=1;
596     for( n=0; n<namecount; n++ )
597     {
598       if( 0 == strcmp( nbname, my_netbios_names[n] ) )
599         nodup=0;
600     }
601     if (nodup)
602       my_netbios_names[namecount++] = strdup( nbname );
603   }
604   
605   /* Check the strdups succeeded. */
606   for( n = 0; n < namecount; n++ )
607     if( NULL == my_netbios_names[n] )
608     {
609       DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
610       return False;
611     }
612   
613   /* Terminate name list */
614   my_netbios_names[namecount++] = NULL;
615   
616   fstrcpy( local_machine, global_myname );
617   trim_string( local_machine, " ", " " );
618   p = strchr( local_machine, ' ' );
619   if (p)
620     *p = 0;
621   strlower( local_machine );
622
623   DEBUG( 5, ("Netbios name list:-\n") );
624   for( n=0; my_netbios_names[n]; n++ )
625     DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) );
626
627   return( True );
628 } /* init_structs */
629
630 /**************************************************************************** **
631  usage on the program
632  **************************************************************************** */
633 static void usage(char *pname)
634 {
635
636   printf( "Usage: %s [-DaohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
637   printf( "       [-n name] [-p port] [-s configuration file]\n" );
638   printf( "\t-D                    Become a daemon\n" );
639   printf( "\t-a                    Append to log file (default)\n" );
640   printf( "\t-o                    Overwrite log file, don't append\n" );
641   printf( "\t-h                    Print usage\n" );
642   printf( "\t-V                    Print version\n" );
643   printf( "\t-H hosts file         Load a netbios hosts file\n" );
644   printf( "\t-d debuglevel         Set the debuglevel\n" );
645   printf( "\t-l log basename.      Basename for log/debug files\n" );
646   printf( "\t-n netbiosname.       Primary netbios name\n" );
647   printf( "\t-p port               Listen on the specified port\n" );
648   printf( "\t-s configuration file Configuration file name\n" );
649   printf( "\n");
650 } /* usage */
651
652
653 /**************************************************************************** **
654  main program
655  **************************************************************************** */
656  int main(int argc,char *argv[])
657 {
658   int opt;
659   extern FILE *dbf;
660   extern char *optarg;
661   extern BOOL  append_log;
662
663   append_log = True;  /* Default, override with '-o' option. */
664
665   global_nmb_port = NMB_PORT;
666   *host_file = 0;
667   global_in_nmbd = True;
668
669   StartupTime = time(NULL);
670
671   sys_srandom(time(NULL) ^ sys_getpid());
672
673   TimeInit();
674
675   slprintf(debugf, sizeof(debugf), "%s/log.nmbd", LOGFILEBASE);
676   setup_logging( argv[0], False );
677
678   charset_initialise();
679
680 #ifdef LMHOSTSFILE
681   pstrcpy( host_file, LMHOSTSFILE );
682 #endif
683
684   /* this is for people who can't start the program correctly */
685   while (argc > 1 && (*argv[1] != '-'))
686   {
687     argv++;
688     argc--;
689   }
690
691   fault_setup((void (*)(void *))fault_continue );
692
693   /* POSIX demands that signals are inherited. If the invoking process has
694    * these signals masked, we will have problems, as we won't recieve them. */
695   BlockSignals(False, SIGHUP);
696   BlockSignals(False, SIGUSR1);
697   BlockSignals(False, SIGTERM);
698
699   CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
700   CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
701
702 #if defined(SIGFPE)
703   /* we are never interested in SIGFPE */
704   BlockSignals(True,SIGFPE);
705 #endif
706
707   /* We no longer use USR2... */
708 #if defined(SIGUSR2)
709   BlockSignals(True, SIGUSR2);
710 #endif
711
712   while( EOF != 
713          (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dp:hSH:G:f:" )) )
714     {
715       switch (opt)
716         {
717         case 's':
718           pstrcpy(servicesf,optarg);
719           break;          
720         case 'N':
721         case 'B':
722         case 'I':
723         case 'C':
724         case 'G':
725           DEBUG(0,("Obsolete option '%c' used\n",opt));
726           break;
727         case 'H':
728           pstrcpy(host_file,optarg);
729           break;
730         case 'n':
731           pstrcpy(global_myname,optarg);
732           strupper(global_myname);
733           break;
734         case 'l':
735           slprintf(debugf,sizeof(debugf)-1, "%s.nmb",optarg);
736           break;
737         case 'a':
738           append_log = True;
739           break;
740         case 'o':
741           append_log = False;
742           break;
743         case 'D':
744           is_daemon = True;
745           break;
746         case 'd':
747           DEBUGLEVEL = atoi(optarg);
748           break;
749         case 'p':
750           global_nmb_port = atoi(optarg);
751           break;
752         case 'h':
753           usage(argv[0]);
754           exit(0);
755           break;
756         case 'V':
757           printf( "Version %s\n", VERSION );
758           exit(0);
759           break;
760         default:
761           if( !is_a_socket(0) )
762           {
763             DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
764             usage(argv[0]);
765             exit(0);
766           }
767           break;
768         }
769     }
770
771   reopen_logs();
772
773   DEBUG( 1, ( "Netbios nameserver version %s started.\n", VERSION ) );
774   DEBUGADD( 1, ( "Copyright Andrew Tridgell 1994-1998\n" ) );
775
776   if ( !reload_nmbd_services(False) )
777     return(-1);
778
779   codepage_initialise(lp_client_code_page());
780
781   if(!init_structs())
782     return -1;
783
784   reload_nmbd_services( True );
785
786   fstrcpy( global_myworkgroup, lp_workgroup() );
787
788   if (strequal(global_myworkgroup,"*"))
789   {
790     DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
791     exit(1);
792   }
793
794   set_samba_nb_type();
795
796   if (!is_daemon && !is_a_socket(0))
797   {
798     DEBUG(0,("standard input is not a socket, assuming -D option\n"));
799     is_daemon = True;
800   }
801   
802   if (is_daemon)
803   {
804     DEBUG( 2, ( "Becoming a daemon.\n" ) );
805     become_daemon();
806   }
807
808 #ifndef SYNC_DNS
809   /* Setup the async dns. We do it here so it doesn't have all the other
810      stuff initialised and thus chewing memory and sockets */
811   if(lp_we_are_a_wins_server()) {
812           start_async_dns();
813   }
814 #endif
815
816   if (!directory_exist(lp_lockdir(), NULL)) {
817           mkdir(lp_lockdir(), 0755);
818   }
819
820   pidfile_create("nmbd");
821   message_init();
822   message_register(MSG_FORCE_ELECTION, nmbd_message_election);
823
824   DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
825
826   if ( !open_sockets( is_daemon, global_nmb_port ) )
827     return 1;
828
829   /* Determine all the IP addresses we have. */
830   load_interfaces();
831
832   /* Create an nmbd subnet record for each of the above. */
833   if( False == create_subnets() )
834   {
835     DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
836     exit(1);
837   }
838
839   /* Load in any static local names. */ 
840   if ( *host_file )
841   {
842     load_lmhosts_file(host_file);
843     DEBUG(3,("Loaded hosts file\n"));
844   }
845
846   /* If we are acting as a WINS server, initialise data structures. */
847   if( !initialise_wins() )
848   {
849     DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
850     exit(1);
851   }
852
853   /* 
854    * Register nmbd primary workgroup and nmbd names on all
855    * the broadcast subnets, and on the WINS server (if specified).
856    * Also initiate the startup of our primary workgroup (start
857    * elections if we are setup as being able to be a local
858    * master browser.
859    */
860
861   if( False == register_my_workgroup_and_names() )
862   {
863     DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
864     exit(1);
865   }
866
867   /* We can only take signals in the select. */
868   BlockSignals( True, SIGTERM );
869
870   process();
871
872   if (dbf)
873     fclose(dbf);
874   return(0);
875 } /* main */
876