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