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)
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.
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.
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.
28 int global_nmb_port
= -1;
30 extern BOOL rescan_listen_set
;
31 extern struct in_addr loopback_ip
;
32 extern BOOL global_in_nmbd
;
34 extern BOOL override_logfile
;
36 /* are we running as a daemon ? */
37 static BOOL is_daemon
;
39 /* fork or run in foreground ? */
40 static BOOL Fork
= True
;
42 /* log to standard output ? */
43 static BOOL log_stdout
;
45 /* have we found LanMan clients yet? */
46 BOOL found_lm_clients
= False
;
48 /* what server type are we currently */
50 time_t StartupTime
= 0;
52 /**************************************************************************** **
53 Handle a SIGTERM in band.
54 **************************************************************************** */
56 static void terminate(void)
58 DEBUG(0,("Got SIGTERM: going down...\n"));
60 /* Write out wins.dat file if samba is a WINS server */
61 wins_write_database(0,False
);
63 /* Remove all SELF registered names from WINS */
66 /* Announce all server entries as 0 time-to-live, 0 type. */
67 announce_my_servers_removed();
69 /* If there was an async dns child - kill it. */
70 kill_async_dns_child();
75 /**************************************************************************** **
76 Handle a SHUTDOWN message from smbcontrol.
77 **************************************************************************** */
79 static void nmbd_terminate(int msg_type
, struct process_id src
,
80 void *buf
, size_t len
)
85 /**************************************************************************** **
86 Catch a SIGTERM signal.
87 **************************************************************************** */
89 static SIG_ATOMIC_T got_sig_term
;
91 static void sig_term(int sig
)
94 sys_select_signal(SIGTERM
);
97 /**************************************************************************** **
98 Catch a SIGHUP signal.
99 **************************************************************************** */
101 static SIG_ATOMIC_T reload_after_sighup
;
103 static void sig_hup(int sig
)
105 reload_after_sighup
= 1;
106 sys_select_signal(SIGHUP
);
109 /**************************************************************************** **
110 Possibly continue after a fault.
111 **************************************************************************** */
113 static void fault_continue(void)
120 /**************************************************************************** **
121 Expire old names from the namelist and server list.
122 **************************************************************************** */
124 static void expire_names_and_servers(time_t t
)
126 static time_t lastrun
= 0;
130 if ( t
< (lastrun
+ 5) )
135 * Expire any timed out names on all the broadcast
136 * subnets and those registered with the WINS server.
137 * (nmbd_namelistdb.c)
143 * Go through all the broadcast subnets and for each
144 * workgroup known on that subnet remove any expired
145 * server names. If a workgroup has an empty serverlist
146 * and has itself timed out then remove the workgroup.
147 * (nmbd_workgroupdb.c)
150 expire_workgroups_and_servers(t
);
153 /************************************************************************** **
154 Reload the list of network interfaces.
155 ************************************************************************** */
157 static BOOL
reload_interfaces(time_t t
)
161 struct subnet_record
*subrec
;
163 if (t
&& ((t
- lastt
) < NMBD_INTERFACES_RELOAD
)) return False
;
166 if (!interfaces_changed()) return False
;
168 /* the list of probed interfaces has changed, we may need to add/remove
172 /* find any interfaces that need adding */
173 for (n
=iface_count() - 1; n
>= 0; n
--) {
174 struct interface
*iface
= get_interface(n
);
177 DEBUG(2,("reload_interfaces: failed to get interface %d\n", n
));
182 * We don't want to add a loopback interface, in case
183 * someone has added 127.0.0.1 for smbd, nmbd needs to
184 * ignore it here. JRA.
187 if (ip_equal(iface
->ip
, loopback_ip
)) {
188 DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface
->ip
)));
192 for (subrec
=subnetlist
; subrec
; subrec
=subrec
->next
) {
193 if (ip_equal(iface
->ip
, subrec
->myip
) &&
194 ip_equal(iface
->nmask
, subrec
->mask_ip
)) break;
198 /* it wasn't found! add it */
199 DEBUG(2,("Found new interface %s\n",
200 inet_ntoa(iface
->ip
)));
201 subrec
= make_normal_subnet(iface
);
203 register_my_workgroup_one_subnet(subrec
);
207 /* find any interfaces that need deleting */
208 for (subrec
=subnetlist
; subrec
; subrec
=subrec
->next
) {
209 for (n
=iface_count() - 1; n
>= 0; n
--) {
210 struct interface
*iface
= get_interface(n
);
211 if (ip_equal(iface
->ip
, subrec
->myip
) &&
212 ip_equal(iface
->nmask
, subrec
->mask_ip
)) break;
215 /* oops, an interface has disapeared. This is
216 tricky, we don't dare actually free the
217 interface as it could be being used, so
218 instead we just wear the memory leak and
219 remove it from the list of interfaces without
221 DEBUG(2,("Deleting dead interface %s\n",
222 inet_ntoa(subrec
->myip
)));
223 close_subnet(subrec
);
227 rescan_listen_set
= True
;
229 /* We need to shutdown if there are no subnets... */
230 if (FIRST_SUBNET
== NULL
) {
231 DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n"));
237 /**************************************************************************** **
238 Reload the services file.
239 **************************************************************************** */
241 static BOOL
reload_nmbd_services(BOOL test
)
245 set_remote_machine_name("nmbd", False
);
249 pstrcpy( fname
,lp_configfile());
250 if (file_exist(fname
,NULL
) && !strcsequal(fname
,dyn_CONFIGFILE
)) {
251 pstrcpy(dyn_CONFIGFILE
,fname
);
256 if ( test
&& !lp_file_list_changed() )
259 ret
= lp_load( dyn_CONFIGFILE
, True
, False
, False
, True
);
261 /* perhaps the config filename is now set */
263 DEBUG( 3, ( "services not loaded\n" ) );
264 reload_nmbd_services( True
);
270 /**************************************************************************** **
271 * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
272 * We use buf here to return BOOL result to process() when reload_interfaces()
273 * detects that there are no subnets.
274 **************************************************************************** */
276 static void msg_reload_nmbd_services(int msg_type
, struct process_id src
,
277 void *buf
, size_t len
)
279 write_browse_list( 0, True
);
280 dump_all_namelists();
281 reload_nmbd_services( True
);
285 /* We were called from process() */
286 /* If reload_interfaces() returned True */
287 /* we need to shutdown if there are no subnets... */
288 /* pass this info back to process() */
289 *((BOOL
*)buf
) = reload_interfaces(0);
293 static void msg_nmbd_send_packet(int msg_type
, struct process_id src
,
294 void *buf
, size_t len
)
296 struct packet_struct
*p
= (struct packet_struct
*)buf
;
297 struct subnet_record
*subrec
;
298 struct in_addr
*local_ip
;
300 DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src
)));
302 if (len
!= sizeof(struct packet_struct
)) {
303 DEBUG(2, ("Discarding invalid packet length from %d\n",
304 procid_to_pid(&src
)));
308 if ((p
->packet_type
!= NMB_PACKET
) &&
309 (p
->packet_type
!= DGRAM_PACKET
)) {
310 DEBUG(2, ("Discarding invalid packet type from %d: %d\n",
311 procid_to_pid(&src
), p
->packet_type
));
315 local_ip
= iface_ip(p
->ip
);
317 if (local_ip
== NULL
) {
318 DEBUG(2, ("Could not find ip for packet from %d\n",
319 procid_to_pid(&src
)));
323 subrec
= FIRST_SUBNET
;
325 p
->fd
= (p
->packet_type
== NMB_PACKET
) ?
326 subrec
->nmb_sock
: subrec
->dgram_sock
;
328 for (subrec
= FIRST_SUBNET
; subrec
!= NULL
;
329 subrec
= NEXT_SUBNET_EXCLUDING_UNICAST(subrec
)) {
330 if (ip_equal(*local_ip
, subrec
->myip
)) {
331 p
->fd
= (p
->packet_type
== NMB_PACKET
) ?
332 subrec
->nmb_sock
: subrec
->dgram_sock
;
337 if (p
->packet_type
== DGRAM_PACKET
) {
339 p
->packet
.dgram
.header
.source_ip
.s_addr
= local_ip
->s_addr
;
340 p
->packet
.dgram
.header
.source_port
= 138;
346 /**************************************************************************** **
347 The main select loop.
348 **************************************************************************** */
350 static void process(void)
356 time_t t
= time(NULL
);
358 /* Check for internal messages */
363 * Check all broadcast subnets to see if
364 * we need to run an election on any of them.
368 run_election
= check_elections();
371 * Read incoming UDP packets.
375 if(listen_for_packets(run_election
))
379 * Handle termination inband.
388 * Process all incoming packets
389 * read above. This calls the success and
390 * failure functions registered when response
391 * packets arrrive, and also deals with request
392 * packets from other sources.
399 * Run any elections - initiate becoming
400 * a local master browser if we have won.
407 * Send out any broadcast announcements
408 * of our server names. This also announces
409 * the workgroup name if we are a local
411 * (nmbd_sendannounce.c)
414 announce_my_server_names(t
);
417 * Send out any LanMan broadcast announcements
418 * of our server names.
419 * (nmbd_sendannounce.c)
422 announce_my_lm_server_names(t
);
425 * If we are a local master browser, periodically
426 * announce ourselves to the domain master browser.
427 * This also deals with syncronising the domain master
428 * browser server lists with ourselves as a local
430 * (nmbd_sendannounce.c)
433 announce_myself_to_domain_master_browser(t
);
436 * Fullfill any remote announce requests.
437 * (nmbd_sendannounce.c)
443 * Fullfill any remote browse sync announce requests.
444 * (nmbd_sendannounce.c)
447 browse_sync_remote(t
);
450 * Scan the broadcast subnets, and WINS client
451 * namelists and refresh any that need refreshing.
458 * Scan the subnet namelists and server lists and
459 * expire thos that have timed out.
463 expire_names_and_servers(t
);
466 * Write out a snapshot of our current browse list into
467 * the browse.dat file. This is used by smbd to service
468 * incoming NetServerEnum calls - used to synchronise
469 * browse lists over subnets.
470 * (nmbd_serverlistdb.c)
473 write_browse_list(t
, False
);
476 * If we are a domain master browser, we have a list of
477 * local master browsers we should synchronise browse
478 * lists with (these are added by an incoming local
479 * master browser announcement packet). Expire any of
480 * these that are no longer current, and pull the server
481 * lists from each of these known local master browsers.
482 * (nmbd_browsesync.c)
485 dmb_expire_and_sync_browser_lists(t
);
488 * Check that there is a local master browser for our
489 * workgroup for all our broadcast subnets. If one
490 * is not found, start an election (which we ourselves
491 * may or may not participate in, depending on the
492 * setting of the 'local master' parameter.
496 check_master_browser_exists(t
);
499 * If we are configured as a logon server, attempt to
500 * register the special NetBIOS names to become such
501 * (WORKGROUP<1c> name) on all broadcast subnets and
502 * with the WINS server (if used). If we are configured
503 * to become a domain master browser, attempt to register
504 * the special NetBIOS name (WORKGROUP<1b> name) to
506 * (nmbd_become_dmb.c)
512 * If we are a WINS server, do any timer dependent
513 * processing required.
514 * (nmbd_winsserver.c)
517 initiate_wins_processing(t
);
520 * If we are a domain master browser, attempt to contact the
521 * WINS server to get a list of all known WORKGROUPS/DOMAINS.
522 * This will only work to a Samba WINS server.
523 * (nmbd_browsesync.c)
526 if (lp_enhanced_browsing())
527 collect_all_workgroup_names_from_wins_server(t
);
530 * Go through the response record queue and time out or re-transmit
531 * and expired entries.
535 retransmit_or_expire_response_records(t
);
538 * check to see if any remote browse sync child processes have completed
541 sync_check_completion();
544 * regularly sync with any other DMBs we know about
547 if (lp_enhanced_browsing())
551 * clear the unexpected packet queue
557 * Reload the services file if we got a sighup.
560 if(reload_after_sighup
) {
561 DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
562 msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED
,
563 pid_to_procid(0), (void*) &no_subnets
, 0);
566 reload_after_sighup
= 0;
569 /* check for new network interfaces */
571 if(reload_interfaces(t
))
574 /* free up temp memory */
579 /**************************************************************************** **
580 Open the socket communication.
581 **************************************************************************** */
583 static BOOL
open_sockets(BOOL isdaemon
, int port
)
586 * The sockets opened here will be used to receive broadcast
587 * packets *only*. Interface specific sockets are opened in
588 * make_subnet() in namedbsubnet.c. Thus we bind to the
589 * address "0.0.0.0". The parameter 'socket address' is
594 ClientNMB
= open_socket_in(SOCK_DGRAM
, port
,
595 0, interpret_addr(lp_socket_address()),
600 ClientDGRAM
= open_socket_in(SOCK_DGRAM
, DGRAM_PORT
,
601 3, interpret_addr(lp_socket_address()),
604 if ( ClientNMB
== -1 )
607 /* we are never interested in SIGPIPE */
608 BlockSignals(True
,SIGPIPE
);
610 set_socket_options( ClientNMB
, "SO_BROADCAST" );
611 set_socket_options( ClientDGRAM
, "SO_BROADCAST" );
613 /* Ensure we're non-blocking. */
614 set_blocking( ClientNMB
, False
);
615 set_blocking( ClientDGRAM
, False
);
617 DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
621 /**************************************************************************** **
623 **************************************************************************** */
624 int main(int argc
, const char *argv
[])
627 static BOOL opt_interactive
;
629 static char *p_lmhosts
= dyn_LMHOSTSFILE
;
630 static BOOL no_process_group
= False
;
631 struct poptOption long_options
[] = {
633 {"daemon", 'D', POPT_ARG_VAL
, &is_daemon
, True
, "Become a daemon(default)" },
634 {"interactive", 'i', POPT_ARG_VAL
, &opt_interactive
, True
, "Run interactive (not a daemon)" },
635 {"foreground", 'F', POPT_ARG_VAL
, &Fork
, False
, "Run daemon in foreground (for daemontools & etc)" },
636 {"no-process-group", 0, POPT_ARG_VAL
, &no_process_group
, True
, "Don't create a new process group" },
637 {"log-stdout", 'S', POPT_ARG_VAL
, &log_stdout
, True
, "Log to stdout" },
638 {"hosts", 'H', POPT_ARG_STRING
, &p_lmhosts
, 'H', "Load a netbios hosts file"},
639 {"port", 'p', POPT_ARG_INT
, &global_nmb_port
, NMB_PORT
, "Listen on the specified port" },
646 global_nmb_port
= NMB_PORT
;
648 pc
= poptGetContext("nmbd", argc
, argv
, long_options
, 0);
649 while (poptGetNextOpt(pc
) != -1) {};
652 global_in_nmbd
= True
;
654 StartupTime
= time(NULL
);
656 sys_srandom(time(NULL
) ^ sys_getpid());
658 if (!override_logfile
) {
659 slprintf(logfile
, sizeof(logfile
)-1, "%s/log.nmbd", dyn_LOGFILEBASE
);
660 lp_set_logfile(logfile
);
663 fault_setup((void (*)(void *))fault_continue
);
664 dump_core_setup("nmbd");
666 /* POSIX demands that signals are inherited. If the invoking process has
667 * these signals masked, we will have problems, as we won't receive them. */
668 BlockSignals(False
, SIGHUP
);
669 BlockSignals(False
, SIGUSR1
);
670 BlockSignals(False
, SIGTERM
);
672 CatchSignal( SIGHUP
, SIGNAL_CAST sig_hup
);
673 CatchSignal( SIGTERM
, SIGNAL_CAST sig_term
);
676 /* we are never interested in SIGFPE */
677 BlockSignals(True
,SIGFPE
);
680 /* We no longer use USR2... */
682 BlockSignals(True
, SIGUSR2
);
685 if ( opt_interactive
) {
690 if ( log_stdout
&& Fork
) {
691 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
695 setup_logging( argv
[0], log_stdout
);
699 DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING
) );
700 DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE
) );
702 if ( !reload_nmbd_services(False
) )
708 reload_nmbd_services( True
);
710 if (strequal(lp_workgroup(),"*")) {
711 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
717 if (!is_daemon
&& !is_a_socket(0)) {
718 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
722 if (is_daemon
&& !opt_interactive
) {
723 DEBUG( 2, ( "Becoming a daemon.\n" ) );
724 become_daemon(Fork
, no_process_group
);
729 * If we're interactive we want to set our own process group for
732 if (opt_interactive
&& !no_process_group
)
733 setpgid( (pid_t
)0, (pid_t
)0 );
737 /* Setup the async dns. We do it here so it doesn't have all the other
738 stuff initialised and thus chewing memory and sockets */
739 if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
744 if (!directory_exist(lp_lockdir(), NULL
)) {
745 mkdir(lp_lockdir(), 0755);
748 pidfile_create("nmbd");
750 message_register(MSG_FORCE_ELECTION
, nmbd_message_election
);
752 /* Until winsrepl is done. */
753 message_register(MSG_WINS_NEW_ENTRY
, nmbd_wins_new_entry
);
755 message_register(MSG_SHUTDOWN
, nmbd_terminate
);
756 message_register(MSG_SMB_CONF_UPDATED
, msg_reload_nmbd_services
);
757 message_register(MSG_SEND_PACKET
, msg_nmbd_send_packet
);
761 DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port
) );
763 if ( !open_sockets( is_daemon
, global_nmb_port
) ) {
764 kill_async_dns_child();
768 /* Determine all the IP addresses we have. */
771 /* Create an nmbd subnet record for each of the above. */
772 if( False
== create_subnets() ) {
773 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
774 kill_async_dns_child();
778 /* Load in any static local names. */
779 load_lmhosts_file(p_lmhosts
);
780 DEBUG(3,("Loaded hosts file %s\n", p_lmhosts
));
782 /* If we are acting as a WINS server, initialise data structures. */
783 if( !initialise_wins() ) {
784 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
785 kill_async_dns_child();
790 * Register nmbd primary workgroup and nmbd names on all
791 * the broadcast subnets, and on the WINS server (if specified).
792 * Also initiate the startup of our primary workgroup (start
793 * elections if we are setup as being able to be a local
797 if( False
== register_my_workgroup_and_names() ) {
798 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
799 kill_async_dns_child();
803 /* We can only take signals in the select. */
804 BlockSignals( True
, SIGTERM
);
810 kill_async_dns_child();