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