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