r14618: add --no-process-group to all server programms
[tprouty/samba.git] / source / nmbd / nmbd.c
1 /*
2    Unix SMB/CIFS implementation.
3    NBT netbios routines and daemon - version 2
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Jeremy Allison 1997-2002
6    Copyright (C) Jelmer Vernooij 2002,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(0,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, True);
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,
636                                            3, interpret_addr(lp_socket_address()),
637                                            True);
638
639         if ( ClientNMB == -1 )
640                 return( False );
641
642         /* we are never interested in SIGPIPE */
643         BlockSignals(True,SIGPIPE);
644
645         set_socket_options( ClientNMB,   "SO_BROADCAST" );
646         set_socket_options( ClientDGRAM, "SO_BROADCAST" );
647
648         DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
649         return( True );
650 }
651
652 /**************************************************************************** **
653  main program
654  **************************************************************************** */
655  int main(int argc, const char *argv[])
656 {
657         pstring logfile;
658         static BOOL opt_interactive;
659         poptContext pc;
660         static char *p_lmhosts = dyn_LMHOSTSFILE;
661         static BOOL no_process_group = False;
662         struct poptOption long_options[] = {
663         POPT_AUTOHELP
664         {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" },
665         {"interactive", 'i', POPT_ARG_VAL, &opt_interactive, True, "Run interactive (not a daemon)" },
666         {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
667         {"no-process-group", 0, POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
668         {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
669         {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 'H', "Load a netbios hosts file"},
670         {"port", 'p', POPT_ARG_INT, &global_nmb_port, NMB_PORT, "Listen on the specified port" },
671         POPT_COMMON_SAMBA
672         { NULL }
673         };
674
675         load_case_tables();
676
677         global_nmb_port = NMB_PORT;
678
679         pc = poptGetContext("nmbd", argc, argv, long_options, 0);
680         while (poptGetNextOpt(pc) != -1) {};
681         poptFreeContext(pc);
682
683         global_in_nmbd = True;
684         
685         StartupTime = time(NULL);
686         
687         sys_srandom(time(NULL) ^ sys_getpid());
688         
689         if (!override_logfile) {
690                 slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
691                 lp_set_logfile(logfile);
692         }
693         
694         fault_setup((void (*)(void *))fault_continue );
695         
696         /* POSIX demands that signals are inherited. If the invoking process has
697          * these signals masked, we will have problems, as we won't receive them. */
698         BlockSignals(False, SIGHUP);
699         BlockSignals(False, SIGUSR1);
700         BlockSignals(False, SIGTERM);
701         
702         CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
703         CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
704         
705 #if defined(SIGFPE)
706         /* we are never interested in SIGFPE */
707         BlockSignals(True,SIGFPE);
708 #endif
709
710         /* We no longer use USR2... */
711 #if defined(SIGUSR2)
712         BlockSignals(True, SIGUSR2);
713 #endif
714
715         if ( opt_interactive ) {
716                 Fork = False;
717                 log_stdout = True;
718         }
719
720         if ( log_stdout && Fork ) {
721                 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
722                 exit(1);
723         }
724
725         setup_logging( argv[0], log_stdout );
726
727         reopen_logs();
728
729         DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) );
730         DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) );
731
732         if ( !reload_nmbd_services(False) )
733                 return(-1);
734
735         if(!init_names())
736                 return -1;
737
738         reload_nmbd_services( True );
739
740         if (strequal(lp_workgroup(),"*")) {
741                 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
742                 exit(1);
743         }
744
745         set_samba_nb_type();
746
747         if (!is_daemon && !is_a_socket(0)) {
748                 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
749                 is_daemon = True;
750         }
751   
752         if (is_daemon && !opt_interactive) {
753                 DEBUG( 2, ( "Becoming a daemon.\n" ) );
754                 become_daemon(Fork, no_process_group);
755         }
756
757 #if HAVE_SETPGID
758         /*
759          * If we're interactive we want to set our own process group for 
760          * signal management.
761          */
762         if (opt_interactive && !no_process_group)
763                 setpgid( (pid_t)0, (pid_t)0 );
764 #endif
765
766 #ifndef SYNC_DNS
767         /* Setup the async dns. We do it here so it doesn't have all the other
768                 stuff initialised and thus chewing memory and sockets */
769         if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
770                 start_async_dns();
771         }
772 #endif
773
774         if (!directory_exist(lp_lockdir(), NULL)) {
775                 mkdir(lp_lockdir(), 0755);
776         }
777
778         pidfile_create("nmbd");
779         message_init();
780         message_register(MSG_FORCE_ELECTION, nmbd_message_election);
781 #if 0
782         /* Until winsrepl is done. */
783         message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
784 #endif
785         message_register(MSG_SHUTDOWN, nmbd_terminate);
786         message_register(MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
787         message_register(MSG_SEND_PACKET, msg_nmbd_send_packet);
788
789         TimeInit();
790
791         DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
792
793         if ( !open_sockets( is_daemon, global_nmb_port ) ) {
794                 kill_async_dns_child();
795                 return 1;
796         }
797
798         /* Determine all the IP addresses we have. */
799         load_interfaces();
800
801         /* Create an nmbd subnet record for each of the above. */
802         if( False == create_subnets() ) {
803                 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
804                 kill_async_dns_child();
805                 exit(1);
806         }
807
808         /* Load in any static local names. */ 
809         load_lmhosts_file(p_lmhosts);
810         DEBUG(3,("Loaded hosts file %s\n", p_lmhosts));
811
812         /* If we are acting as a WINS server, initialise data structures. */
813         if( !initialise_wins() ) {
814                 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
815                 kill_async_dns_child();
816                 exit(1);
817         }
818
819         /* 
820          * Register nmbd primary workgroup and nmbd names on all
821          * the broadcast subnets, and on the WINS server (if specified).
822          * Also initiate the startup of our primary workgroup (start
823          * elections if we are setup as being able to be a local
824          * master browser.
825          */
826
827         if( False == register_my_workgroup_and_names() ) {
828                 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
829                 kill_async_dns_child();
830                 exit(1);
831         }
832
833         /* We can only take signals in the select. */
834         BlockSignals( True, SIGTERM );
835
836         process();
837
838         if (dbf)
839                 x_fclose(dbf);
840         kill_async_dns_child();
841         return(0);
842 }