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