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