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