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