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