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