compile warngin fixes merged from 2.2
[Samba.git] / source / nmbd / nmbd.c
blobf698b396b26688fa5838456a377f20a867f62ea1
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
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
25 int ClientNMB = -1;
26 int ClientDGRAM = -1;
27 int global_nmb_port = -1;
29 extern pstring global_myname;
30 extern fstring global_myworkgroup;
31 extern char **my_netbios_names;
33 extern BOOL global_in_nmbd;
35 /* are we running as a daemon ? */
36 static BOOL is_daemon = False;
38 /* have we found LanMan clients yet? */
39 BOOL found_lm_clients = False;
41 /* what server type are we currently */
43 time_t StartupTime = 0;
45 /**************************************************************************** **
46 Handle a SIGTERM in band.
47 **************************************************************************** */
49 static void terminate(void)
51 DEBUG(0,("Got SIGTERM: going down...\n"));
53 /* Write out wins.dat file if samba is a WINS server */
54 wins_write_database(False);
56 /* Remove all SELF registered names. */
57 release_my_names();
59 /* Announce all server entries as 0 time-to-live, 0 type. */
60 announce_my_servers_removed();
62 /* If there was an async dns child - kill it. */
63 kill_async_dns_child();
65 exit(0);
68 /**************************************************************************** **
69 Handle a SHUTDOWN message from smbcontrol.
70 **************************************************************************** */
72 static void nmbd_terminate(int msg_type, pid_t src, void *buf, size_t len)
74 terminate();
77 /**************************************************************************** **
78 Catch a SIGTERM signal.
79 **************************************************************************** */
81 static SIG_ATOMIC_T got_sig_term;
83 static void sig_term(int sig)
85 got_sig_term = 1;
86 sys_select_signal();
89 /**************************************************************************** **
90 Catch a SIGHUP signal.
91 **************************************************************************** */
93 static SIG_ATOMIC_T reload_after_sighup;
95 static void sig_hup(int sig)
97 reload_after_sighup = 1;
98 sys_select_signal();
101 #if DUMP_CORE
102 /**************************************************************************** **
103 Prepare to dump a core file - carefully!
104 **************************************************************************** */
106 static BOOL dump_core(void)
108 char *p;
109 pstring dname;
110 pstrcpy( dname, lp_logfile() );
111 if ((p=strrchr_m(dname,'/')))
112 *p=0;
113 pstrcat( dname, "/corefiles" );
114 mkdir( dname, 0700 );
115 sys_chown( dname, getuid(), getgid() );
116 chmod( dname, 0700 );
117 if ( chdir(dname) )
118 return( False );
119 umask( ~(0700) );
121 #ifdef HAVE_GETRLIMIT
122 #ifdef RLIMIT_CORE
124 struct rlimit rlp;
125 getrlimit( RLIMIT_CORE, &rlp );
126 rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
127 setrlimit( RLIMIT_CORE, &rlp );
128 getrlimit( RLIMIT_CORE, &rlp );
129 DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
131 #endif
132 #endif
135 DEBUG(0,("Dumping core in %s\n",dname));
136 abort();
137 return( True );
139 #endif
141 /**************************************************************************** **
142 Possibly continue after a fault.
143 **************************************************************************** */
145 static void fault_continue(void)
147 #if DUMP_CORE
148 dump_core();
149 #endif
152 /**************************************************************************** **
153 Expire old names from the namelist and server list.
154 **************************************************************************** */
156 static void expire_names_and_servers(time_t t)
158 static time_t lastrun = 0;
160 if ( !lastrun )
161 lastrun = t;
162 if ( t < (lastrun + 5) )
163 return;
164 lastrun = t;
167 * Expire any timed out names on all the broadcast
168 * subnets and those registered with the WINS server.
169 * (nmbd_namelistdb.c)
172 expire_names(t);
175 * Go through all the broadcast subnets and for each
176 * workgroup known on that subnet remove any expired
177 * server names. If a workgroup has an empty serverlist
178 * and has itself timed out then remove the workgroup.
179 * (nmbd_workgroupdb.c)
182 expire_workgroups_and_servers(t);
185 /************************************************************************** **
186 Reload the list of network interfaces.
187 ************************************************************************** */
189 static BOOL reload_interfaces(time_t t)
191 static time_t lastt;
192 int n;
193 struct subnet_record *subrec;
194 extern BOOL rescan_listen_set;
195 extern struct in_addr loopback_ip;
197 if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False;
198 lastt = t;
200 if (!interfaces_changed()) return False;
202 /* the list of probed interfaces has changed, we may need to add/remove
203 some subnets */
204 load_interfaces();
206 /* find any interfaces that need adding */
207 for (n=iface_count() - 1; n >= 0; n--) {
208 struct interface *iface = get_interface(n);
211 * We don't want to add a loopback interface, in case
212 * someone has added 127.0.0.1 for smbd, nmbd needs to
213 * ignore it here. JRA.
216 if (ip_equal(iface->ip, loopback_ip)) {
217 DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
218 continue;
221 for (subrec=subnetlist; subrec; subrec=subrec->next) {
222 if (ip_equal(iface->ip, subrec->myip) &&
223 ip_equal(iface->nmask, subrec->mask_ip)) break;
226 if (!subrec) {
227 /* it wasn't found! add it */
228 DEBUG(2,("Found new interface %s\n",
229 inet_ntoa(iface->ip)));
230 subrec = make_normal_subnet(iface);
231 if (subrec) register_my_workgroup_one_subnet(subrec);
235 /* find any interfaces that need deleting */
236 for (subrec=subnetlist; subrec; subrec=subrec->next) {
237 for (n=iface_count() - 1; n >= 0; n--) {
238 struct interface *iface = get_interface(n);
239 if (ip_equal(iface->ip, subrec->myip) &&
240 ip_equal(iface->nmask, subrec->mask_ip)) break;
242 if (n == -1) {
243 /* oops, an interface has disapeared. This is
244 tricky, we don't dare actually free the
245 interface as it could be being used, so
246 instead we just wear the memory leak and
247 remove it from the list of interfaces without
248 freeing it */
249 DEBUG(2,("Deleting dead interface %s\n",
250 inet_ntoa(subrec->myip)));
251 close_subnet(subrec);
255 rescan_listen_set = True;
257 /* We need to shutdown if there are no subnets... */
258 if (FIRST_SUBNET == NULL) {
259 DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n"));
260 return True;
262 return False;
265 /**************************************************************************** **
266 Reload the services file.
267 **************************************************************************** */
269 static BOOL reload_nmbd_services(BOOL test)
271 BOOL ret;
272 extern fstring remote_machine;
274 fstrcpy( remote_machine, "nmbd" );
276 if ( lp_loaded() ) {
277 pstring fname;
278 pstrcpy( fname,lp_configfile());
279 if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
280 pstrcpy(dyn_CONFIGFILE,fname);
281 test = False;
285 if ( test && !lp_file_list_changed() )
286 return(True);
288 ret = lp_load( dyn_CONFIGFILE, True , False, False);
290 /* perhaps the config filename is now set */
291 if ( !test ) {
292 DEBUG( 3, ( "services not loaded\n" ) );
293 reload_nmbd_services( True );
296 /* Do a sanity check for a misconfigured nmbd */
297 if( lp_wins_support() && wins_srv_count() ) {
298 if( DEBUGLVL(0) ) {
299 dbgtext( "ERROR: 'wins support = true' and 'wins server = <server>'\n" );
300 dbgtext( "are conflicting settings. nmbd aborting.\n" );
302 exit(10);
305 return(ret);
308 /**************************************************************************** **
309 The main select loop.
310 **************************************************************************** */
312 static void process(void)
314 BOOL run_election;
316 while( True ) {
317 time_t t = time(NULL);
319 /* Check for internal messages */
321 message_dispatch();
324 * Check all broadcast subnets to see if
325 * we need to run an election on any of them.
326 * (nmbd_elections.c)
329 run_election = check_elections();
332 * Read incoming UDP packets.
333 * (nmbd_packets.c)
336 if(listen_for_packets(run_election))
337 return;
340 * Handle termination inband.
343 if (got_sig_term) {
344 got_sig_term = 0;
345 terminate();
349 * Process all incoming packets
350 * read above. This calls the success and
351 * failure functions registered when response
352 * packets arrrive, and also deals with request
353 * packets from other sources.
354 * (nmbd_packets.c)
357 run_packet_queue();
360 * Run any elections - initiate becoming
361 * a local master browser if we have won.
362 * (nmbd_elections.c)
365 run_elections(t);
368 * Send out any broadcast announcements
369 * of our server names. This also announces
370 * the workgroup name if we are a local
371 * master browser.
372 * (nmbd_sendannounce.c)
375 announce_my_server_names(t);
378 * Send out any LanMan broadcast announcements
379 * of our server names.
380 * (nmbd_sendannounce.c)
383 announce_my_lm_server_names(t);
386 * If we are a local master browser, periodically
387 * announce ourselves to the domain master browser.
388 * This also deals with syncronising the domain master
389 * browser server lists with ourselves as a local
390 * master browser.
391 * (nmbd_sendannounce.c)
394 announce_myself_to_domain_master_browser(t);
397 * Fullfill any remote announce requests.
398 * (nmbd_sendannounce.c)
401 announce_remote(t);
404 * Fullfill any remote browse sync announce requests.
405 * (nmbd_sendannounce.c)
408 browse_sync_remote(t);
411 * Scan the broadcast subnets, and WINS client
412 * namelists and refresh any that need refreshing.
413 * (nmbd_mynames.c)
416 refresh_my_names(t);
419 * Scan the subnet namelists and server lists and
420 * expire thos that have timed out.
421 * (nmbd.c)
424 expire_names_and_servers(t);
427 * Write out a snapshot of our current browse list into
428 * the browse.dat file. This is used by smbd to service
429 * incoming NetServerEnum calls - used to synchronise
430 * browse lists over subnets.
431 * (nmbd_serverlistdb.c)
434 write_browse_list(t, False);
437 * If we are a domain master browser, we have a list of
438 * local master browsers we should synchronise browse
439 * lists with (these are added by an incoming local
440 * master browser announcement packet). Expire any of
441 * these that are no longer current, and pull the server
442 * lists from each of these known local master browsers.
443 * (nmbd_browsesync.c)
446 dmb_expire_and_sync_browser_lists(t);
449 * Check that there is a local master browser for our
450 * workgroup for all our broadcast subnets. If one
451 * is not found, start an election (which we ourselves
452 * may or may not participate in, depending on the
453 * setting of the 'local master' parameter.
454 * (nmbd_elections.c)
457 check_master_browser_exists(t);
460 * If we are configured as a logon server, attempt to
461 * register the special NetBIOS names to become such
462 * (WORKGROUP<1c> name) on all broadcast subnets and
463 * with the WINS server (if used). If we are configured
464 * to become a domain master browser, attempt to register
465 * the special NetBIOS name (WORKGROUP<1b> name) to
466 * become such.
467 * (nmbd_become_dmb.c)
470 add_domain_names(t);
473 * If we are a WINS server, do any timer dependent
474 * processing required.
475 * (nmbd_winsserver.c)
478 initiate_wins_processing(t);
481 * If we are a domain master browser, attempt to contact the
482 * WINS server to get a list of all known WORKGROUPS/DOMAINS.
483 * This will only work to a Samba WINS server.
484 * (nmbd_browsesync.c)
487 if (lp_enhanced_browsing())
488 collect_all_workgroup_names_from_wins_server(t);
491 * Go through the response record queue and time out or re-transmit
492 * and expired entries.
493 * (nmbd_packets.c)
496 retransmit_or_expire_response_records(t);
499 * check to see if any remote browse sync child processes have completed
502 sync_check_completion();
505 * regularly sync with any other DMBs we know about
508 if (lp_enhanced_browsing())
509 sync_all_dmbs(t);
512 * clear the unexpected packet queue
515 clear_unexpected(t);
518 * Reload the services file if we got a sighup.
521 if(reload_after_sighup) {
522 DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
523 write_browse_list( 0, True );
524 dump_all_namelists();
525 reload_nmbd_services( True );
526 reopen_logs();
527 if(reload_interfaces(0))
528 return;
529 reload_after_sighup = 0;
532 /* check for new network interfaces */
534 if(reload_interfaces(t))
535 return;
537 /* free up temp memory */
538 lp_talloc_free();
542 /**************************************************************************** **
543 Open the socket communication.
544 **************************************************************************** */
546 static BOOL open_sockets(BOOL isdaemon, int port)
549 * The sockets opened here will be used to receive broadcast
550 * packets *only*. Interface specific sockets are opened in
551 * make_subnet() in namedbsubnet.c. Thus we bind to the
552 * address "0.0.0.0". The parameter 'socket address' is
553 * now deprecated.
556 if ( isdaemon )
557 ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0,True);
558 else
559 ClientNMB = 0;
561 ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0,True);
563 if ( ClientNMB == -1 )
564 return( False );
566 /* we are never interested in SIGPIPE */
567 BlockSignals(True,SIGPIPE);
569 set_socket_options( ClientNMB, "SO_BROADCAST" );
570 set_socket_options( ClientDGRAM, "SO_BROADCAST" );
572 DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
573 return( True );
576 /**************************************************************************** **
577 Initialise connect, service and file structs.
578 **************************************************************************** */
580 static BOOL init_structs(void)
582 extern fstring local_machine;
583 char *p, **ptr;
584 int namecount;
585 int n;
586 int nodup;
587 char *nbname;
589 if (! *global_myname)
591 fstrcpy( global_myname, myhostname() );
592 p = strchr_m( global_myname, '.' );
593 if (p)
594 *p = 0;
596 strupper( global_myname );
598 /* Add any NETBIOS name aliases. Ensure that the first entry
599 is equal to global_myname.
601 /* Work out the max number of netbios aliases that we have */
602 ptr = lp_netbios_aliases();
603 namecount = 0;
604 if (ptr)
605 for( ; *ptr; namecount++,ptr++ )
607 if ( *global_myname )
608 namecount++;
610 /* Allocate space for the netbios aliases */
611 my_netbios_names = (char **)malloc( sizeof(char *) * (namecount+1) );
612 if( NULL == my_netbios_names )
614 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
615 return( False );
618 /* Use the global_myname string first */
619 namecount=0;
620 if ( *global_myname )
621 my_netbios_names[namecount++] = global_myname;
623 ptr = lp_netbios_aliases();
624 if (ptr)
626 while ( *ptr )
628 nbname = strdup(*ptr);
629 if (nbname == NULL)
631 DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
632 return False;
634 strupper( nbname );
635 /* Look for duplicates */
636 nodup=1;
637 for( n=0; n<namecount; n++ )
639 if( 0 == strcmp( nbname, my_netbios_names[n] ) )
640 nodup=0;
642 if (nodup)
643 my_netbios_names[namecount++] = nbname;
644 else
645 SAFE_FREE(nbname);
647 ptr++;
651 /* Terminate name list */
652 my_netbios_names[namecount++] = NULL;
654 fstrcpy( local_machine, global_myname );
655 trim_string( local_machine, " ", " " );
656 p = strchr_m( local_machine, ' ' );
657 if (p)
658 *p = 0;
659 strlower( local_machine );
661 DEBUG( 5, ("Netbios name list:-\n") );
662 for( n=0; my_netbios_names[n]; n++ )
663 DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) );
665 return( True );
668 /**************************************************************************** **
669 Usage on the program.
670 **************************************************************************** */
672 static void usage(char *pname)
675 printf( "Usage: %s [-DaiohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
676 printf( " [-n name] [-p port] [-s configuration file]\n" );
677 printf( "\t-D Become a daemon (default)\n" );
678 printf( "\t-a Append to log file (default)\n" );
679 printf( "\t-i Run interactive (not a daemon)\n" );
680 printf( "\t-o Overwrite log file, don't append\n" );
681 printf( "\t-h Print usage\n" );
682 printf( "\t-V Print version\n" );
683 printf( "\t-H hosts file Load a netbios hosts file\n" );
684 printf( "\t-d debuglevel Set the debuglevel\n" );
685 printf( "\t-l log basename. Basename for log/debug files\n" );
686 printf( "\t-n netbiosname. Primary netbios name\n" );
687 printf( "\t-p port Listen on the specified port\n" );
688 printf( "\t-s configuration file Configuration file name\n" );
689 printf( "\n");
693 /**************************************************************************** **
694 main program
695 **************************************************************************** */
696 int main(int argc,char *argv[])
698 int opt;
699 extern char *optarg;
700 extern BOOL append_log;
701 BOOL opt_interactive = False;
702 pstring logfile;
704 append_log = True; /* Default, override with '-o' option. */
706 global_nmb_port = NMB_PORT;
707 global_in_nmbd = True;
709 StartupTime = time(NULL);
711 sys_srandom(time(NULL) ^ sys_getpid());
713 slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
714 lp_set_logfile(logfile);
716 /* this is for people who can't start the program correctly */
717 while (argc > 1 && (*argv[1] != '-'))
719 argv++;
720 argc--;
723 fault_setup((void (*)(void *))fault_continue );
725 /* POSIX demands that signals are inherited. If the invoking process has
726 * these signals masked, we will have problems, as we won't recieve them. */
727 BlockSignals(False, SIGHUP);
728 BlockSignals(False, SIGUSR1);
729 BlockSignals(False, SIGTERM);
731 CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
732 CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
734 #if defined(SIGFPE)
735 /* we are never interested in SIGFPE */
736 BlockSignals(True,SIGFPE);
737 #endif
739 /* We no longer use USR2... */
740 #if defined(SIGUSR2)
741 BlockSignals(True, SIGUSR2);
742 #endif
744 while( EOF !=
745 (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dp:hSH:G:f:i" )) )
747 switch (opt)
749 case 's':
750 pstrcpy(dyn_CONFIGFILE, optarg);
751 break;
752 case 'N':
753 case 'B':
754 case 'I':
755 case 'C':
756 case 'G':
757 DEBUG(0,("Obsolete option '%c' used\n",opt));
758 break;
759 case 'i':
760 opt_interactive = True;
761 break;
762 case 'H':
763 pstrcpy(dyn_LMHOSTSFILE, optarg);
764 break;
765 case 'n':
766 pstrcpy(global_myname,optarg);
767 strupper(global_myname);
768 break;
769 case 'l':
770 slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", optarg);
771 lp_set_logfile(logfile);
772 break;
773 case 'a':
774 append_log = True;
775 break;
776 case 'o':
777 append_log = False;
778 break;
779 case 'D':
780 is_daemon = True;
781 break;
782 case 'd':
783 DEBUGLEVEL = atoi(optarg);
784 break;
785 case 'p':
786 global_nmb_port = atoi(optarg);
787 break;
788 case 'h':
789 usage(argv[0]);
790 exit(0);
791 break;
792 case 'V':
793 printf( "Version %s\n", VERSION );
794 exit(0);
795 break;
796 default:
797 if( !is_a_socket(0) )
799 DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
800 usage(argv[0]);
801 exit(0);
803 break;
807 setup_logging( argv[0], opt_interactive );
809 reopen_logs();
811 DEBUG( 0, ( "Netbios nameserver version %s started.\n", VERSION ) );
812 DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2002\n" ) );
814 if ( !reload_nmbd_services(False) )
815 return(-1);
817 if(!init_structs())
818 return -1;
820 reload_nmbd_services( True );
822 fstrcpy( global_myworkgroup, lp_workgroup() );
824 if (strequal(global_myworkgroup,"*"))
826 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
827 exit(1);
830 set_samba_nb_type();
832 if (!is_daemon && !is_a_socket(0))
834 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
835 is_daemon = True;
838 if (is_daemon && !opt_interactive)
840 DEBUG( 2, ( "Becoming a daemon.\n" ) );
841 become_daemon();
844 #if HAVE_SETPGID
846 * If we're interactive we want to set our own process group for
847 * signal management.
849 if (opt_interactive)
850 setpgid( (pid_t)0, (pid_t)0 );
851 #endif
853 #ifndef SYNC_DNS
854 /* Setup the async dns. We do it here so it doesn't have all the other
855 stuff initialised and thus chewing memory and sockets */
856 if(lp_we_are_a_wins_server()) {
857 start_async_dns();
859 #endif
861 if (!directory_exist(lp_lockdir(), NULL)) {
862 mkdir(lp_lockdir(), 0755);
865 pidfile_create("nmbd");
866 message_init();
867 message_register(MSG_FORCE_ELECTION, nmbd_message_election);
868 message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
869 message_register(MSG_SHUTDOWN, nmbd_terminate);
871 DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
873 if ( !open_sockets( is_daemon, global_nmb_port ) )
874 return 1;
876 /* Determine all the IP addresses we have. */
877 load_interfaces();
879 /* Create an nmbd subnet record for each of the above. */
880 if( False == create_subnets() )
882 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
883 exit(1);
886 /* Load in any static local names. */
887 load_lmhosts_file(dyn_LMHOSTSFILE);
888 DEBUG(3,("Loaded hosts file %s\n", dyn_LMHOSTSFILE));
890 /* If we are acting as a WINS server, initialise data structures. */
891 if( !initialise_wins() )
893 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
894 exit(1);
898 * Register nmbd primary workgroup and nmbd names on all
899 * the broadcast subnets, and on the WINS server (if specified).
900 * Also initiate the startup of our primary workgroup (start
901 * elections if we are setup as being able to be a local
902 * master browser.
905 if( False == register_my_workgroup_and_names() )
907 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
908 exit(1);
911 /* We can only take signals in the select. */
912 BlockSignals( True, SIGTERM );
914 process();
916 if (dbf)
917 x_fclose(dbf);
918 return(0);