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