loadparm: make the source3/ lp_ functions take an explicit TALLOC_CTX *.
[jlayton/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 /**************************************************************************** **
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                 char *fname = lp_configfile(talloc_tos());
386                 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
387                         set_dyn_CONFIGFILE(fname);
388                         test = False;
389                 }
390                 TALLOC_FREE(fname);
391         }
392
393         if ( test && !lp_file_list_changed() )
394                 return(True);
395
396         ret = lp_load_global(get_dyn_CONFIGFILE());
397
398         /* perhaps the config filename is now set */
399         if ( !test ) {
400                 DEBUG( 3, ( "services not loaded\n" ) );
401                 reload_nmbd_services( True );
402         }
403
404         return(ret);
405 }
406
407 /**************************************************************************** **
408  * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
409  **************************************************************************** */
410
411 static void msg_reload_nmbd_services(struct messaging_context *msg,
412                                      void *private_data,
413                                      uint32_t msg_type,
414                                      struct server_id server_id,
415                                      DATA_BLOB *data)
416 {
417         write_browse_list( 0, True );
418         dump_all_namelists();
419         reload_nmbd_services( True );
420         reopen_logs();
421         reload_interfaces(0);
422 }
423
424 static void msg_nmbd_send_packet(struct messaging_context *msg,
425                                  void *private_data,
426                                  uint32_t msg_type,
427                                  struct server_id src,
428                                  DATA_BLOB *data)
429 {
430         struct packet_struct *p = (struct packet_struct *)data->data;
431         struct subnet_record *subrec;
432         struct sockaddr_storage ss;
433         const struct sockaddr_storage *pss;
434         const struct in_addr *local_ip;
435
436         DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src)));
437
438         if (data->length != sizeof(struct packet_struct)) {
439                 DEBUG(2, ("Discarding invalid packet length from %u\n",
440                           (unsigned int)procid_to_pid(&src)));
441                 return;
442         }
443
444         if ((p->packet_type != NMB_PACKET) &&
445             (p->packet_type != DGRAM_PACKET)) {
446                 DEBUG(2, ("Discarding invalid packet type from %u: %d\n",
447                           (unsigned int)procid_to_pid(&src), p->packet_type));
448                 return;
449         }
450
451         in_addr_to_sockaddr_storage(&ss, p->ip);
452         pss = iface_ip((struct sockaddr *)(void *)&ss);
453
454         if (pss == NULL) {
455                 DEBUG(2, ("Could not find ip for packet from %u\n",
456                           (unsigned int)procid_to_pid(&src)));
457                 return;
458         }
459
460         local_ip = &((const struct sockaddr_in *)pss)->sin_addr;
461         subrec = FIRST_SUBNET;
462
463         p->recv_fd = -1;
464         p->send_fd = (p->packet_type == NMB_PACKET) ?
465                 subrec->nmb_sock : subrec->dgram_sock;
466
467         for (subrec = FIRST_SUBNET; subrec != NULL;
468              subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
469                 if (ip_equal_v4(*local_ip, subrec->myip)) {
470                         p->send_fd = (p->packet_type == NMB_PACKET) ?
471                                 subrec->nmb_sock : subrec->dgram_sock;
472                         break;
473                 }
474         }
475
476         if (p->packet_type == DGRAM_PACKET) {
477                 p->port = 138;
478                 p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
479                 p->packet.dgram.header.source_port = 138;
480         }
481
482         send_packet(p);
483 }
484
485 /**************************************************************************** **
486  The main select loop.
487  **************************************************************************** */
488
489 static void process(struct messaging_context *msg)
490 {
491         bool run_election;
492
493         while( True ) {
494                 time_t t = time(NULL);
495                 TALLOC_CTX *frame = talloc_stackframe();
496
497                 /*
498                  * Check all broadcast subnets to see if
499                  * we need to run an election on any of them.
500                  * (nmbd_elections.c)
501                  */
502
503                 run_election = check_elections();
504
505                 /*
506                  * Read incoming UDP packets.
507                  * (nmbd_packets.c)
508                  */
509
510                 if (listen_for_packets(msg, run_election)) {
511                         TALLOC_FREE(frame);
512                         return;
513                 }
514
515                 /*
516                  * Process all incoming packets
517                  * read above. This calls the success and
518                  * failure functions registered when response
519                  * packets arrrive, and also deals with request
520                  * packets from other sources.
521                  * (nmbd_packets.c)
522                  */
523
524                 run_packet_queue();
525
526                 /*
527                  * Run any elections - initiate becoming
528                  * a local master browser if we have won.
529                  * (nmbd_elections.c)
530                  */
531
532                 run_elections(t);
533
534                 /*
535                  * Send out any broadcast announcements
536                  * of our server names. This also announces
537                  * the workgroup name if we are a local
538                  * master browser.
539                  * (nmbd_sendannounce.c)
540                  */
541
542                 announce_my_server_names(t);
543
544                 /*
545                  * Send out any LanMan broadcast announcements
546                  * of our server names.
547                  * (nmbd_sendannounce.c)
548                  */
549
550                 announce_my_lm_server_names(t);
551
552                 /*
553                  * If we are a local master browser, periodically
554                  * announce ourselves to the domain master browser.
555                  * This also deals with syncronising the domain master
556                  * browser server lists with ourselves as a local
557                  * master browser.
558                  * (nmbd_sendannounce.c)
559                  */
560
561                 announce_myself_to_domain_master_browser(t);
562
563                 /*
564                  * Fullfill any remote announce requests.
565                  * (nmbd_sendannounce.c)
566                  */
567
568                 announce_remote(t);
569
570                 /*
571                  * Fullfill any remote browse sync announce requests.
572                  * (nmbd_sendannounce.c)
573                  */
574
575                 browse_sync_remote(t);
576
577                 /*
578                  * Scan the broadcast subnets, and WINS client
579                  * namelists and refresh any that need refreshing.
580                  * (nmbd_mynames.c)
581                  */
582
583                 refresh_my_names(t);
584
585                 /*
586                  * Scan the subnet namelists and server lists and
587                  * expire thos that have timed out.
588                  * (nmbd.c)
589                  */
590
591                 expire_names_and_servers(t);
592
593                 /*
594                  * Write out a snapshot of our current browse list into
595                  * the browse.dat file. This is used by smbd to service
596                  * incoming NetServerEnum calls - used to synchronise
597                  * browse lists over subnets.
598                  * (nmbd_serverlistdb.c)
599                  */
600
601                 write_browse_list(t, False);
602
603                 /*
604                  * If we are a domain master browser, we have a list of
605                  * local master browsers we should synchronise browse
606                  * lists with (these are added by an incoming local
607                  * master browser announcement packet). Expire any of
608                  * these that are no longer current, and pull the server
609                  * lists from each of these known local master browsers.
610                  * (nmbd_browsesync.c)
611                  */
612
613                 dmb_expire_and_sync_browser_lists(t);
614
615                 /*
616                  * Check that there is a local master browser for our
617                  * workgroup for all our broadcast subnets. If one
618                  * is not found, start an election (which we ourselves
619                  * may or may not participate in, depending on the
620                  * setting of the 'local master' parameter.
621                  * (nmbd_elections.c)
622                  */
623
624                 check_master_browser_exists(t);
625
626                 /*
627                  * If we are configured as a logon server, attempt to
628                  * register the special NetBIOS names to become such
629                  * (WORKGROUP<1c> name) on all broadcast subnets and
630                  * with the WINS server (if used). If we are configured
631                  * to become a domain master browser, attempt to register
632                  * the special NetBIOS name (WORKGROUP<1b> name) to
633                  * become such.
634                  * (nmbd_become_dmb.c)
635                  */
636
637                 add_domain_names(t);
638
639                 /*
640                  * If we are a WINS server, do any timer dependent
641                  * processing required.
642                  * (nmbd_winsserver.c)
643                  */
644
645                 initiate_wins_processing(t);
646
647                 /*
648                  * If we are a domain master browser, attempt to contact the
649                  * WINS server to get a list of all known WORKGROUPS/DOMAINS.
650                  * This will only work to a Samba WINS server.
651                  * (nmbd_browsesync.c)
652                  */
653
654                 if (lp_enhanced_browsing())
655                         collect_all_workgroup_names_from_wins_server(t);
656
657                 /*
658                  * Go through the response record queue and time out or re-transmit
659                  * and expired entries.
660                  * (nmbd_packets.c)
661                  */
662
663                 retransmit_or_expire_response_records(t);
664
665                 /*
666                  * check to see if any remote browse sync child processes have completed
667                  */
668
669                 sync_check_completion();
670
671                 /*
672                  * regularly sync with any other DMBs we know about 
673                  */
674
675                 if (lp_enhanced_browsing())
676                         sync_all_dmbs(t);
677
678                 /* check for new network interfaces */
679
680                 reload_interfaces(t);
681
682                 /* free up temp memory */
683                 TALLOC_FREE(frame);
684         }
685 }
686
687 /**************************************************************************** **
688  Open the socket communication.
689  **************************************************************************** */
690
691 static bool open_sockets(bool isdaemon, int port)
692 {
693         struct sockaddr_storage ss;
694         const char *sock_addr = lp_socket_address();
695
696         /*
697          * The sockets opened here will be used to receive broadcast
698          * packets *only*. Interface specific sockets are opened in
699          * make_subnet() in namedbsubnet.c. Thus we bind to the
700          * address "0.0.0.0". The parameter 'socket address' is
701          * now deprecated.
702          */
703
704         if (!interpret_string_addr(&ss, sock_addr,
705                                 AI_NUMERICHOST|AI_PASSIVE)) {
706                 DEBUG(0,("open_sockets: unable to get socket address "
707                         "from string %s", sock_addr));
708                 return false;
709         }
710         if (ss.ss_family != AF_INET) {
711                 DEBUG(0,("open_sockets: unable to use IPv6 socket"
712                         "%s in nmbd\n",
713                         sock_addr));
714                 return false;
715         }
716
717         if (isdaemon) {
718                 ClientNMB = open_socket_in(SOCK_DGRAM, port,
719                                            0, &ss,
720                                            true);
721         } else {
722                 ClientNMB = 0;
723         }
724
725         if (ClientNMB == -1) {
726                 return false;
727         }
728
729         ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
730                                            3, &ss,
731                                            true);
732
733         if (ClientDGRAM == -1) {
734                 if (ClientNMB != 0) {
735                         close(ClientNMB);
736                 }
737                 return false;
738         }
739
740         /* we are never interested in SIGPIPE */
741         BlockSignals(True,SIGPIPE);
742
743         set_socket_options( ClientNMB,   "SO_BROADCAST" );
744         set_socket_options( ClientDGRAM, "SO_BROADCAST" );
745
746         /* Ensure we're non-blocking. */
747         set_blocking( ClientNMB, False);
748         set_blocking( ClientDGRAM, False);
749
750         DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
751         return( True );
752 }
753
754 /**************************************************************************** **
755  main program
756  **************************************************************************** */
757
758  int main(int argc, const char *argv[])
759 {
760         bool is_daemon = false;
761         bool opt_interactive = false;
762         bool Fork = true;
763         bool no_process_group = false;
764         bool log_stdout = false;
765         poptContext pc;
766         char *p_lmhosts = NULL;
767         int opt;
768         struct messaging_context *msg;
769         enum {
770                 OPT_DAEMON = 1000,
771                 OPT_INTERACTIVE,
772                 OPT_FORK,
773                 OPT_NO_PROCESS_GROUP,
774                 OPT_LOG_STDOUT
775         };
776         struct poptOption long_options[] = {
777         POPT_AUTOHELP
778         {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon(default)" },
779         {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)" },
780         {"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools & etc)" },
781         {"no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
782         {"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
783         {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 0, "Load a netbios hosts file"},
784         {"port", 'p', POPT_ARG_INT, &global_nmb_port, 0, "Listen on the specified port" },
785         POPT_COMMON_SAMBA
786         { NULL }
787         };
788         TALLOC_CTX *frame;
789         NTSTATUS status;
790
791         /*
792          * Do this before any other talloc operation
793          */
794         talloc_enable_null_tracking();
795         frame = talloc_stackframe();
796
797         setup_logging(argv[0], DEBUG_DEFAULT_STDOUT);
798
799         load_case_tables();
800
801         global_nmb_port = NMB_PORT;
802
803         pc = poptGetContext("nmbd", argc, argv, long_options, 0);
804         while ((opt = poptGetNextOpt(pc)) != -1) {
805                 switch (opt) {
806                 case OPT_DAEMON:
807                         is_daemon = true;
808                         break;
809                 case OPT_INTERACTIVE:
810                         opt_interactive = true;
811                         break;
812                 case OPT_FORK:
813                         Fork = false;
814                         break;
815                 case OPT_NO_PROCESS_GROUP:
816                         no_process_group = true;
817                         break;
818                 case OPT_LOG_STDOUT:
819                         log_stdout = true;
820                         break;
821                 default:
822                         d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
823                                   poptBadOption(pc, 0), poptStrerror(opt));
824                         poptPrintUsage(pc, stderr, 0);
825                         exit(1);
826                 }
827         };
828         poptFreeContext(pc);
829
830         global_in_nmbd = true;
831
832         StartupTime = time(NULL);
833
834         sys_srandom(time(NULL) ^ getpid());
835
836         if (!override_logfile) {
837                 char *lfile = NULL;
838                 if (asprintf(&lfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) {
839                         exit(1);
840                 }
841                 lp_set_logfile(lfile);
842                 SAFE_FREE(lfile);
843         }
844
845         fault_setup();
846         dump_core_setup("nmbd", lp_logfile(talloc_tos()));
847
848         /* POSIX demands that signals are inherited. If the invoking process has
849          * these signals masked, we will have problems, as we won't receive them. */
850         BlockSignals(False, SIGHUP);
851         BlockSignals(False, SIGUSR1);
852         BlockSignals(False, SIGTERM);
853
854 #if defined(SIGFPE)
855         /* we are never interested in SIGFPE */
856         BlockSignals(True,SIGFPE);
857 #endif
858
859         /* We no longer use USR2... */
860 #if defined(SIGUSR2)
861         BlockSignals(True, SIGUSR2);
862 #endif
863
864         if ( opt_interactive ) {
865                 Fork = False;
866                 log_stdout = True;
867         }
868
869         if ( log_stdout && Fork ) {
870                 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
871                 exit(1);
872         }
873
874         if (log_stdout) {
875                 setup_logging(argv[0], DEBUG_STDOUT);
876         } else {
877                 setup_logging( argv[0], DEBUG_FILE);
878         }
879
880         reopen_logs();
881
882         DEBUG(0,("nmbd version %s started.\n", samba_version_string()));
883         DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
884
885         if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
886                 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
887                 exit(1);
888         }
889
890         msg = messaging_init(NULL, server_event_context());
891         if (msg == NULL) {
892                 return 1;
893         }
894
895         if ( !reload_nmbd_services(False) )
896                 return(-1);
897
898         if(!init_names())
899                 return -1;
900
901         reload_nmbd_services( True );
902
903         if (strequal(lp_workgroup(),"*")) {
904                 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
905                 exit(1);
906         }
907
908         set_samba_nb_type();
909
910         if (!is_daemon && !is_a_socket(0)) {
911                 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
912                 is_daemon = True;
913         }
914
915         if (is_daemon && !opt_interactive) {
916                 DEBUG( 2, ( "Becoming a daemon.\n" ) );
917                 become_daemon(Fork, no_process_group, log_stdout);
918         }
919
920 #if HAVE_SETPGID
921         /*
922          * If we're interactive we want to set our own process group for 
923          * signal management.
924          */
925         if (opt_interactive && !no_process_group)
926                 setpgid( (pid_t)0, (pid_t)0 );
927 #endif
928
929 #ifndef SYNC_DNS
930         /* Setup the async dns. We do it here so it doesn't have all the other
931                 stuff initialised and thus chewing memory and sockets */
932         if(lp_we_are_a_wins_server() && lp_wins_dns_proxy()) {
933                 start_async_dns(msg);
934         }
935 #endif
936
937         if (!directory_exist(lp_lockdir())) {
938                 mkdir(lp_lockdir(), 0755);
939         }
940
941         if (!directory_exist(lp_piddir())) {
942                 mkdir(lp_piddir(), 0755);
943         }
944
945         pidfile_create("nmbd");
946
947         status = reinit_after_fork(msg, nmbd_event_context(),
948                                    false);
949
950         if (!NT_STATUS_IS_OK(status)) {
951                 DEBUG(0,("reinit_after_fork() failed\n"));
952                 exit(1);
953         }
954
955         /*
956          * Do not initialize the parent-child-pipe before becoming
957          * a daemon: this is used to detect a died parent in the child
958          * process.
959          */
960         status = init_before_fork();
961         if (!NT_STATUS_IS_OK(status)) {
962                 DEBUG(0, ("init_before_fork failed: %s\n", nt_errstr(status)));
963                 exit(1);
964         }
965
966         if (!nmbd_setup_sig_term_handler(msg))
967                 exit(1);
968         if (!nmbd_setup_stdin_handler(msg, !Fork))
969                 exit(1);
970         if (!nmbd_setup_sig_hup_handler(msg))
971                 exit(1);
972
973         /* get broadcast messages */
974
975         if (!serverid_register(messaging_server_id(msg),
976                                 FLAG_MSG_GENERAL |
977                                 FLAG_MSG_NMBD |
978                                 FLAG_MSG_DBWRAP)) {
979                 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
980                 exit(1);
981         }
982
983         messaging_register(msg, NULL, MSG_FORCE_ELECTION,
984                            nmbd_message_election);
985 #if 0
986         /* Until winsrepl is done. */
987         messaging_register(msg, NULL, MSG_WINS_NEW_ENTRY,
988                            nmbd_wins_new_entry);
989 #endif
990         messaging_register(msg, NULL, MSG_SHUTDOWN,
991                            nmbd_terminate);
992         messaging_register(msg, NULL, MSG_SMB_CONF_UPDATED,
993                            msg_reload_nmbd_services);
994         messaging_register(msg, NULL, MSG_SEND_PACKET,
995                            msg_nmbd_send_packet);
996
997         TimeInit();
998
999         DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
1000
1001         if ( !open_sockets( is_daemon, global_nmb_port ) ) {
1002                 kill_async_dns_child();
1003                 return 1;
1004         }
1005
1006         /* Determine all the IP addresses we have. */
1007         load_interfaces();
1008
1009         /* Create an nmbd subnet record for each of the above. */
1010         if( False == create_subnets() ) {
1011                 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
1012                 kill_async_dns_child();
1013                 exit(1);
1014         }
1015
1016         /* Load in any static local names. */ 
1017         if (p_lmhosts) {
1018                 set_dyn_LMHOSTSFILE(p_lmhosts);
1019         }
1020         load_lmhosts_file(get_dyn_LMHOSTSFILE());
1021         DEBUG(3,("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE()));
1022
1023         /* If we are acting as a WINS server, initialise data structures. */
1024         if( !initialise_wins() ) {
1025                 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
1026                 kill_async_dns_child();
1027                 exit(1);
1028         }
1029
1030         /* 
1031          * Register nmbd primary workgroup and nmbd names on all
1032          * the broadcast subnets, and on the WINS server (if specified).
1033          * Also initiate the startup of our primary workgroup (start
1034          * elections if we are setup as being able to be a local
1035          * master browser.
1036          */
1037
1038         if( False == register_my_workgroup_and_names() ) {
1039                 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
1040                 kill_async_dns_child();
1041                 exit(1);
1042         }
1043
1044         if (!initialize_nmbd_proxy_logon()) {
1045                 DEBUG(0,("ERROR: Failed setup nmbd_proxy_logon.\n"));
1046                 kill_async_dns_child();
1047                 exit(1);
1048         }
1049
1050         if (!nmbd_init_packet_server()) {
1051                 kill_async_dns_child();
1052                 exit(1);
1053         }
1054
1055         TALLOC_FREE(frame);
1056         process(msg);
1057
1058         kill_async_dns_child();
1059         return(0);
1060 }