2 Unix SMB/Netbios implementation.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1998
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 14 jan 96: lkcl@pires.co.uk
24 added multiple workgroup domain master support
30 pstring servicesf
= CONFIGFILE
;
34 int global_nmb_port
= -1;
36 static pstring host_file
;
37 extern pstring global_myname
;
38 extern fstring global_myworkgroup
;
39 extern char **my_netbios_names
;
41 extern BOOL global_in_nmbd
;
43 /* are we running as a daemon ? */
44 static BOOL is_daemon
= False
;
46 /* have we found LanMan clients yet? */
47 BOOL found_lm_clients
= False
;
49 /* what server type are we currently */
51 time_t StartupTime
= 0;
53 /**************************************************************************** **
54 Handle a SIGTERM in band.
55 **************************************************************************** */
57 static void terminate(void)
59 DEBUG(0,("Got SIGTERM: going down...\n"));
61 /* Write out wins.dat file if samba is a WINS server */
62 wins_write_database(False
);
64 /* Remove all SELF registered names. */
67 /* Announce all server entries as 0 time-to-live, 0 type. */
68 announce_my_servers_removed();
70 /* If there was an async dns child - kill it. */
71 kill_async_dns_child();
76 /**************************************************************************** **
77 Catch a SIGTERM signal.
78 **************************************************************************** */
80 static SIG_ATOMIC_T got_sig_term
;
82 static void sig_term(int sig
)
88 /**************************************************************************** **
89 Catch a SIGHUP signal.
90 **************************************************************************** */
92 static SIG_ATOMIC_T reload_after_sighup
;
94 static void sig_hup(int sig
)
96 reload_after_sighup
= 1;
101 /**************************************************************************** **
102 Prepare to dump a core file - carefully!
103 **************************************************************************** */
105 static BOOL
dump_core(void)
109 pstrcpy( dname
, lp_logfile() );
110 if ((p
=strrchr(dname
,'/')))
112 pstrcat( dname
, "/corefiles" );
113 mkdir( dname
, 0700 );
114 sys_chown( dname
, getuid(), getgid() );
115 chmod( dname
, 0700 );
120 #ifdef HAVE_GETRLIMIT
124 getrlimit( RLIMIT_CORE
, &rlp
);
125 rlp
.rlim_cur
= MAX( 4*1024*1024, rlp
.rlim_cur
);
126 setrlimit( RLIMIT_CORE
, &rlp
);
127 getrlimit( RLIMIT_CORE
, &rlp
);
128 DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp
.rlim_cur
, (int)rlp
.rlim_max
) );
134 DEBUG(0,("Dumping core in %s\n",dname
));
140 /**************************************************************************** **
141 Possibly continue after a fault.
142 **************************************************************************** */
144 static void fault_continue(void)
149 } /* fault_continue */
151 /**************************************************************************** **
152 Expire old names from the namelist and server list.
153 **************************************************************************** */
155 static void expire_names_and_servers(time_t t
)
157 static time_t lastrun
= 0;
161 if ( t
< (lastrun
+ 5) )
166 * Expire any timed out names on all the broadcast
167 * subnets and those registered with the WINS server.
168 * (nmbd_namelistdb.c)
173 * Go through all the broadcast subnets and for each
174 * workgroup known on that subnet remove any expired
175 * server names. If a workgroup has an empty serverlist
176 * and has itself timed out then remove the workgroup.
177 * (nmbd_workgroupdb.c)
179 expire_workgroups_and_servers(t
);
180 } /* expire_names_and_servers */
182 /************************************************************************** **
183 Reload the list of network interfaces.
184 ************************************************************************** */
186 static BOOL
reload_interfaces(time_t t
)
190 struct subnet_record
*subrec
;
191 extern BOOL rescan_listen_set
;
192 extern struct in_addr loopback_ip
;
194 if (t
&& ((t
- lastt
) < NMBD_INTERFACES_RELOAD
)) return False
;
197 if (!interfaces_changed()) return False
;
199 /* the list of probed interfaces has changed, we may need to add/remove
203 /* find any interfaces that need adding */
204 for (n
=iface_count() - 1; n
>= 0; n
--) {
205 struct interface
*iface
= get_interface(n
);
208 * We don't want to add a loopback interface, in case
209 * someone has added 127.0.0.1 for smbd, nmbd needs to
210 * ignore it here. JRA.
213 if (ip_equal(iface
->ip
, loopback_ip
)) {
214 DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface
->ip
)));
218 for (subrec
=subnetlist
; subrec
; subrec
=subrec
->next
) {
219 if (ip_equal(iface
->ip
, subrec
->myip
) &&
220 ip_equal(iface
->nmask
, subrec
->mask_ip
)) break;
224 /* it wasn't found! add it */
225 DEBUG(2,("Found new interface %s\n",
226 inet_ntoa(iface
->ip
)));
227 subrec
= make_normal_subnet(iface
);
228 if (subrec
) register_my_workgroup_one_subnet(subrec
);
232 /* find any interfaces that need deleting */
233 for (subrec
=subnetlist
; subrec
; subrec
=subrec
->next
) {
234 for (n
=iface_count() - 1; n
>= 0; n
--) {
235 struct interface
*iface
= get_interface(n
);
236 if (ip_equal(iface
->ip
, subrec
->myip
) &&
237 ip_equal(iface
->nmask
, subrec
->mask_ip
)) break;
240 /* oops, an interface has disapeared. This is
241 tricky, we don't dare actually free the
242 interface as it could be being used, so
243 instead we just wear the memory leak and
244 remove it from the list of interfaces without
246 DEBUG(2,("Deleting dead interface %s\n",
247 inet_ntoa(subrec
->myip
)));
248 close_subnet(subrec
);
252 rescan_listen_set
= True
;
254 /* We need to shutdown if there are no subnets... */
255 if (FIRST_SUBNET
== NULL
) {
256 DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n"));
262 /**************************************************************************** **
263 Reload the services file.
264 **************************************************************************** */
266 static BOOL
reload_nmbd_services(BOOL test
)
269 extern fstring remote_machine
;
271 fstrcpy( remote_machine
, "nmbd" );
276 pstrcpy( fname
,lp_configfile());
277 if (file_exist(fname
,NULL
) && !strcsequal(fname
,servicesf
))
279 pstrcpy(servicesf
,fname
);
284 if ( test
&& !lp_file_list_changed() )
287 ret
= lp_load( servicesf
, True
, False
, False
);
289 /* perhaps the config filename is now set */
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() && *lp_wins_server() )
299 DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
300 cannot be set in the smb.conf file. nmbd aborting.\n"));
305 } /* reload_nmbd_services */
307 /**************************************************************************** **
308 The main select loop.
309 **************************************************************************** */
311 static void process(void)
317 time_t t
= time(NULL
);
319 /* check for internal messages */
323 * Check all broadcast subnets to see if
324 * we need to run an election on any of them.
327 run_election
= check_elections();
330 * Read incoming UDP packets.
333 if(listen_for_packets(run_election
))
337 * Handle termination inband.
346 * Process all incoming packets
347 * read above. This calls the success and
348 * failure functions registered when response
349 * packets arrrive, and also deals with request
350 * packets from other sources.
356 * Run any elections - initiate becoming
357 * a local master browser if we have won.
363 * Send out any broadcast announcements
364 * of our server names. This also announces
365 * the workgroup name if we are a local
367 * (nmbd_sendannounce.c)
369 announce_my_server_names(t
);
372 * Send out any LanMan broadcast announcements
373 * of our server names.
374 * (nmbd_sendannounce.c)
376 announce_my_lm_server_names(t
);
379 * If we are a local master browser, periodically
380 * announce ourselves to the domain master browser.
381 * This also deals with syncronising the domain master
382 * browser server lists with ourselves as a local
384 * (nmbd_sendannounce.c)
386 announce_myself_to_domain_master_browser(t
);
389 * Fullfill any remote announce requests.
390 * (nmbd_sendannounce.c)
395 * Fullfill any remote browse sync announce requests.
396 * (nmbd_sendannounce.c)
398 browse_sync_remote(t
);
401 * Scan the broadcast subnets, and WINS client
402 * namelists and refresh any that need refreshing.
408 * Scan the subnet namelists and server lists and
409 * expire thos that have timed out.
412 expire_names_and_servers(t
);
415 * Write out a snapshot of our current browse list into
416 * the browse.dat file. This is used by smbd to service
417 * incoming NetServerEnum calls - used to synchronise
418 * browse lists over subnets.
419 * (nmbd_serverlistdb.c)
421 write_browse_list(t
, False
);
424 * If we are a domain master browser, we have a list of
425 * local master browsers we should synchronise browse
426 * lists with (these are added by an incoming local
427 * master browser announcement packet). Expire any of
428 * these that are no longer current, and pull the server
429 * lists from each of these known local master browsers.
430 * (nmbd_browsesync.c)
432 dmb_expire_and_sync_browser_lists(t
);
435 * Check that there is a local master browser for our
436 * workgroup for all our broadcast subnets. If one
437 * is not found, start an election (which we ourselves
438 * may or may not participate in, depending on the
439 * setting of the 'local master' parameter.
442 check_master_browser_exists(t
);
445 * If we are configured as a logon server, attempt to
446 * register the special NetBIOS names to become such
447 * (WORKGROUP<1c> name) on all broadcast subnets and
448 * with the WINS server (if used). If we are configured
449 * to become a domain master browser, attempt to register
450 * the special NetBIOS name (WORKGROUP<1b> name) to
452 * (nmbd_become_dmb.c)
457 * If we are a WINS server, do any timer dependent
458 * processing required.
459 * (nmbd_winsserver.c)
461 initiate_wins_processing(t
);
464 * If we are a domain master browser, attempt to contact the
465 * WINS server to get a list of all known WORKGROUPS/DOMAINS.
466 * This will only work to a Samba WINS server.
467 * (nmbd_browsesync.c)
469 if (lp_enhanced_browsing()) {
470 collect_all_workgroup_names_from_wins_server(t
);
474 * Go through the response record queue and time out or re-transmit
475 * and expired entries.
478 retransmit_or_expire_response_records(t
);
481 * check to see if any remote browse sync child processes have completed
483 sync_check_completion();
486 * regularly sync with any other DMBs we know about
488 if (lp_enhanced_browsing()) {
493 * clear the unexpected packet queue
498 * Reload the services file if we got a sighup.
501 if(reload_after_sighup
) {
502 DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
503 write_browse_list( 0, True
);
504 dump_all_namelists();
505 reload_nmbd_services( True
);
507 if(reload_interfaces(0))
509 reload_after_sighup
= 0;
512 /* check for new network interfaces */
513 if(reload_interfaces(t
))
516 /* free up temp memory */
521 /**************************************************************************** **
522 Open the socket communication.
523 **************************************************************************** */
525 static BOOL
open_sockets(BOOL isdaemon
, int port
)
527 /* The sockets opened here will be used to receive broadcast
528 packets *only*. Interface specific sockets are opened in
529 make_subnet() in namedbsubnet.c. Thus we bind to the
530 address "0.0.0.0". The parameter 'socket address' is
535 ClientNMB
= open_socket_in(SOCK_DGRAM
, port
,0,0,True
);
539 ClientDGRAM
= open_socket_in(SOCK_DGRAM
,DGRAM_PORT
,3,0,True
);
541 if ( ClientNMB
== -1 )
544 /* we are never interested in SIGPIPE */
545 BlockSignals(True
,SIGPIPE
);
547 set_socket_options( ClientNMB
, "SO_BROADCAST" );
548 set_socket_options( ClientDGRAM
, "SO_BROADCAST" );
550 DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
554 /**************************************************************************** **
555 Initialise connect, service and file structs.
556 **************************************************************************** */
558 static BOOL
init_structs(void)
560 extern fstring local_machine
;
567 if (! *global_myname
)
569 fstrcpy( global_myname
, myhostname() );
570 p
= strchr( global_myname
, '.' );
574 strupper( global_myname
);
576 /* Add any NETBIOS name aliases. Ensure that the first entry
577 is equal to global_myname.
579 /* Work out the max number of netbios aliases that we have */
580 ptr
= lp_netbios_aliases();
581 for( namecount
=0; next_token(&ptr
,nbname
,NULL
, sizeof(nbname
)); namecount
++ )
583 if ( *global_myname
)
586 /* Allocate space for the netbios aliases */
587 my_netbios_names
= (char **)malloc( sizeof(char *) * (namecount
+1) );
588 if( NULL
== my_netbios_names
)
590 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
594 /* Use the global_myname string first */
596 if ( *global_myname
)
597 my_netbios_names
[namecount
++] = global_myname
;
599 ptr
= lp_netbios_aliases();
600 while ( next_token( &ptr
, nbname
, NULL
, sizeof(nbname
) ) )
603 /* Look for duplicates */
605 for( n
=0; n
<namecount
; n
++ )
607 if( 0 == strcmp( nbname
, my_netbios_names
[n
] ) )
611 my_netbios_names
[namecount
++] = strdup( nbname
);
614 /* Check the strdups succeeded. */
615 for( n
= 0; n
< namecount
; n
++ )
616 if( NULL
== my_netbios_names
[n
] )
618 DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
622 /* Terminate name list */
623 my_netbios_names
[namecount
++] = NULL
;
625 fstrcpy( local_machine
, global_myname
);
626 trim_string( local_machine
, " ", " " );
627 p
= strchr( local_machine
, ' ' );
630 strlower( local_machine
);
632 DEBUG( 5, ("Netbios name list:-\n") );
633 for( n
=0; my_netbios_names
[n
]; n
++ )
634 DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n
, my_netbios_names
[n
] ) );
639 /**************************************************************************** **
640 Usage on the program.
641 **************************************************************************** */
643 static void usage(char *pname
)
646 printf( "Usage: %s [-DaiohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname
);
647 printf( " [-n name] [-p port] [-s configuration file]\n" );
648 printf( "\t-D Become a daemon (default)\n" );
649 printf( "\t-a Append to log file (default)\n" );
650 printf( "\t-i Run interactive (not a daemon)\n" );
651 printf( "\t-o Overwrite log file, don't append\n" );
652 printf( "\t-h Print usage\n" );
653 printf( "\t-V Print version\n" );
654 printf( "\t-H hosts file Load a netbios hosts file\n" );
655 printf( "\t-d debuglevel Set the debuglevel\n" );
656 printf( "\t-l log basename. Basename for log/debug files\n" );
657 printf( "\t-n netbiosname. Primary netbios name\n" );
658 printf( "\t-p port Listen on the specified port\n" );
659 printf( "\t-s configuration file Configuration file name\n" );
664 /**************************************************************************** **
666 **************************************************************************** */
668 int main(int argc
,char *argv
[])
673 extern BOOL append_log
;
674 extern BOOL AllowDebugChange
;
675 BOOL opt_interactive
= False
;
678 append_log
= True
; /* Default, override with '-o' option. */
680 global_nmb_port
= NMB_PORT
;
682 global_in_nmbd
= True
;
684 StartupTime
= time(NULL
);
686 sys_srandom(time(NULL
) ^ sys_getpid());
690 slprintf(logfile
, sizeof(logfile
)-1, "%s/log.nmbd", LOGFILEBASE
);
691 lp_set_logfile(logfile
);
693 charset_initialise();
696 pstrcpy( host_file
, LMHOSTSFILE
);
699 /* this is for people who can't start the program correctly */
700 while (argc
> 1 && (*argv
[1] != '-'))
706 fault_setup((void (*)(void *))fault_continue
);
708 /* POSIX demands that signals are inherited. If the invoking process has
709 * these signals masked, we will have problems, as we won't recieve them. */
710 BlockSignals(False
, SIGHUP
);
711 BlockSignals(False
, SIGUSR1
);
712 BlockSignals(False
, SIGTERM
);
714 CatchSignal( SIGHUP
, SIGNAL_CAST sig_hup
);
715 CatchSignal( SIGTERM
, SIGNAL_CAST sig_term
);
718 /* we are never interested in SIGFPE */
719 BlockSignals(True
,SIGFPE
);
722 /* We no longer use USR2... */
724 BlockSignals(True
, SIGUSR2
);
728 (opt
= getopt( argc
, argv
, "Vaos:T:I:C:bAB:N:Rn:l:d:Dip:hSH:G:f:" )) )
733 pstrcpy(servicesf
,optarg
);
740 DEBUG(0,("Obsolete option '%c' used\n",opt
));
743 pstrcpy(host_file
,optarg
);
746 pstrcpy(global_myname
,optarg
);
747 strupper(global_myname
);
750 slprintf(logfile
, sizeof(logfile
)-1, "%s/log.nmbd", optarg
);
751 lp_set_logfile(logfile
);
760 opt_interactive
= True
;
766 DEBUGLEVEL
= atoi(optarg
);
767 AllowDebugChange
= False
;
770 global_nmb_port
= atoi(optarg
);
777 printf( "Version %s\n", VERSION
);
781 if( !is_a_socket(0) )
783 DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
791 setup_logging( argv
[0], opt_interactive
);
794 DEBUG( 0, ( "Netbios nameserver version %s started.\n", VERSION
) );
795 DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2002\n" ) );
797 if ( !reload_nmbd_services(False
) )
801 if (!profile_setup(False
)) {
802 DEBUG(0,("ERROR: failed to setup profiling shared memory\n"));
805 #endif /* WITH_PROFILE */
807 codepage_initialise(lp_client_code_page());
812 reload_nmbd_services( True
);
814 fstrcpy( global_myworkgroup
, lp_workgroup() );
816 if (strequal(global_myworkgroup
,"*"))
818 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
824 if (!is_daemon
&& !is_a_socket(0))
826 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
830 if (is_daemon
&& !opt_interactive
)
832 DEBUG( 2, ( "Becoming a daemon.\n" ) );
838 * If we're interactive we want to set our own process group for
842 setpgid( (pid_t
)0, (pid_t
)0 );
846 /* Setup the async dns. We do it here so it doesn't have all the other
847 stuff initialised and thus chewing memory and sockets */
848 if(lp_we_are_a_wins_server()) {
853 if (!directory_exist(lp_lockdir(), NULL
)) {
854 mkdir(lp_lockdir(), 0755);
857 pidfile_create("nmbd");
859 message_register(MSG_FORCE_ELECTION
, nmbd_message_election
);
861 DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port
) );
863 if ( !open_sockets( is_daemon
, global_nmb_port
) )
866 /* Determine all the IP addresses we have. */
869 /* Create an nmbd subnet record for each of the above. */
870 if( False
== create_subnets() )
872 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
876 /* Load in any static local names. */
879 load_lmhosts_file(host_file
);
880 DEBUG(3,("Loaded hosts file\n"));
883 /* If we are acting as a WINS server, initialise data structures. */
884 if( !initialise_wins() )
886 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
891 * Register nmbd primary workgroup and nmbd names on all
892 * the broadcast subnets, and on the WINS server (if specified).
893 * Also initiate the startup of our primary workgroup (start
894 * elections if we are setup as being able to be a local
898 if( False
== register_my_workgroup_and_names() )
900 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
904 /* We can only take signals in the select. */
905 BlockSignals( True
, SIGTERM
);