r24599: patch from Karolin Seeger <ks@sernet.de>:
[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 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         int opt;
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 ((opt = poptGetNextOpt(pc)) != -1) {
679                 switch (opt) {
680                 default:
681                         d_fprintf(stderr, "\nInvalid option %s: %s\n",
682                                   poptBadOption(pc, 0), poptStrerror(opt));
683                         exit(1);
684                 }
685         };
686         poptFreeContext(pc);
687
688         global_in_nmbd = True;
689         
690         StartupTime = time(NULL);
691         
692         sys_srandom(time(NULL) ^ sys_getpid());
693         
694         if (!override_logfile) {
695                 slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
696                 lp_set_logfile(logfile);
697         }
698         
699         fault_setup((void (*)(void *))fault_continue );
700         dump_core_setup("nmbd");
701         
702         /* POSIX demands that signals are inherited. If the invoking process has
703          * these signals masked, we will have problems, as we won't receive them. */
704         BlockSignals(False, SIGHUP);
705         BlockSignals(False, SIGUSR1);
706         BlockSignals(False, SIGTERM);
707         
708         CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
709         CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
710         
711 #if defined(SIGFPE)
712         /* we are never interested in SIGFPE */
713         BlockSignals(True,SIGFPE);
714 #endif
715
716         /* We no longer use USR2... */
717 #if defined(SIGUSR2)
718         BlockSignals(True, SIGUSR2);
719 #endif
720
721         if (server_mode == SERVER_MODE_INTERACTIVE) {
722                 log_stdout = True;
723         }
724
725         if (log_stdout && server_mode == SERVER_MODE_DAEMON) {
726                 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
727                 exit(1);
728         }
729
730         setup_logging( argv[0], log_stdout );
731
732         reopen_logs();
733
734         DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) );
735         DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) );
736
737         if ( !reload_nmbd_services(False) )
738                 return(-1);
739
740         if(!init_names())
741                 return -1;
742
743         reload_nmbd_services( True );
744
745         if (strequal(lp_workgroup(),"*")) {
746                 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
747                 exit(1);
748         }
749
750         set_samba_nb_type();
751
752         if (is_a_socket(0)) {
753                 if (server_mode == SERVER_MODE_DAEMON) {
754                         DEBUG(0,("standard input is a socket, "
755                                     "assuming -F option\n"));
756                 }
757                 server_mode = SERVER_MODE_INETD;
758         }
759
760         if (server_mode == SERVER_MODE_DAEMON) {
761                 DEBUG( 2, ( "Becoming a daemon.\n" ) );
762                 become_daemon(True, no_process_group);
763         } else if (server_mode == SERVER_MODE_FOREGROUND) {
764                 become_daemon(False, no_process_group);
765         }
766
767 #if HAVE_SETPGID
768         /*
769          * If we're interactive we want to set our own process group for 
770          * signal management.
771          */
772         if (server_mode == SERVER_MODE_INTERACTIVE && !no_process_group)
773                 setpgid( (pid_t)0, (pid_t)0 );
774 #endif
775
776         if (nmbd_messaging_context() == NULL) {
777                 return 1;
778         }
779
780 #ifndef SYNC_DNS
781         /* Setup the async dns. We do it here so it doesn't have all the other
782                 stuff initialised and thus chewing memory and sockets */
783         if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
784                 start_async_dns();
785         }
786 #endif
787
788         if (!directory_exist(lp_lockdir(), NULL)) {
789                 mkdir(lp_lockdir(), 0755);
790         }
791
792         pidfile_create("nmbd");
793         messaging_register(nmbd_messaging_context(), NULL,
794                            MSG_FORCE_ELECTION, nmbd_message_election);
795 #if 0
796         /* Until winsrepl is done. */
797         messaging_register(nmbd_messaging_context(), NULL,
798                            MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
799 #endif
800         messaging_register(nmbd_messaging_context(), NULL,
801                            MSG_SHUTDOWN, nmbd_terminate);
802         messaging_register(nmbd_messaging_context(), NULL,
803                            MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
804         messaging_register(nmbd_messaging_context(), NULL,
805                            MSG_SEND_PACKET, msg_nmbd_send_packet);
806
807         TimeInit();
808
809         DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
810
811         if ( !open_sockets( server_mode, global_nmb_port ) ) {
812                 kill_async_dns_child();
813                 return 1;
814         }
815
816         /* Determine all the IP addresses we have. */
817         load_interfaces();
818
819         /* Create an nmbd subnet record for each of the above. */
820         if( False == create_subnets() ) {
821                 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
822                 kill_async_dns_child();
823                 exit(1);
824         }
825
826         /* Load in any static local names. */ 
827         load_lmhosts_file(p_lmhosts);
828         DEBUG(3,("Loaded hosts file %s\n", p_lmhosts));
829
830         /* If we are acting as a WINS server, initialise data structures. */
831         if( !initialise_wins() ) {
832                 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
833                 kill_async_dns_child();
834                 exit(1);
835         }
836
837         /* 
838          * Register nmbd primary workgroup and nmbd names on all
839          * the broadcast subnets, and on the WINS server (if specified).
840          * Also initiate the startup of our primary workgroup (start
841          * elections if we are setup as being able to be a local
842          * master browser.
843          */
844
845         if( False == register_my_workgroup_and_names() ) {
846                 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
847                 kill_async_dns_child();
848                 exit(1);
849         }
850
851         /* We can only take signals in the select. */
852         BlockSignals( True, SIGTERM );
853
854         process();
855
856         if (dbf)
857                 x_fclose(dbf);
858         kill_async_dns_child();
859         return(0);
860 }