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