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