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