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 3 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, see <http://www.gnu.org/licenses/>.
24 #include "popt_common.h"
25 #include "librpc/gen_ndr/messaging.h"
29 int global_nmb_port
= -1;
31 extern bool rescan_listen_set
;
32 extern bool global_in_nmbd
;
34 extern bool override_logfile
;
36 /* have we found LanMan clients yet? */
37 bool found_lm_clients
= False
;
39 /* what server type are we currently */
41 time_t StartupTime
= 0;
43 struct event_context
*nmbd_event_context(void)
45 static struct event_context
*ctx
;
47 if (!ctx
&& !(ctx
= event_context_init(NULL
))) {
48 smb_panic("Could not init nmbd event context");
53 struct messaging_context
*nmbd_messaging_context(void)
55 static struct messaging_context
*ctx
;
58 ctx
= messaging_init(NULL
, procid_self(),
59 nmbd_event_context());
62 DEBUG(0, ("Could not init nmbd messaging context.\n"));
67 /**************************************************************************** **
68 Handle a SIGTERM in band.
69 **************************************************************************** */
71 static void terminate(void)
73 DEBUG(0,("Got SIGTERM: going down...\n"));
75 /* Write out wins.dat file if samba is a WINS server */
76 wins_write_database(0,False
);
78 /* Remove all SELF registered names from WINS */
81 /* Announce all server entries as 0 time-to-live, 0 type. */
82 announce_my_servers_removed();
84 /* If there was an async dns child - kill it. */
85 kill_async_dns_child();
88 serverid_deregister(procid_self());
95 static void nmbd_sig_term_handler(struct tevent_context
*ev
,
96 struct tevent_signal
*se
,
105 static bool nmbd_setup_sig_term_handler(void)
107 struct tevent_signal
*se
;
109 se
= tevent_add_signal(nmbd_event_context(),
110 nmbd_event_context(),
112 nmbd_sig_term_handler
,
115 DEBUG(0,("failed to setup SIGTERM handler"));
122 static void msg_reload_nmbd_services(struct messaging_context
*msg
,
125 struct server_id server_id
,
128 static void nmbd_sig_hup_handler(struct tevent_context
*ev
,
129 struct tevent_signal
*se
,
135 DEBUG(0,("Got SIGHUP dumping debug info.\n"));
136 msg_reload_nmbd_services(nmbd_messaging_context(),
137 NULL
, MSG_SMB_CONF_UPDATED
,
138 procid_self(), NULL
);
141 static bool nmbd_setup_sig_hup_handler(void)
143 struct tevent_signal
*se
;
145 se
= tevent_add_signal(nmbd_event_context(),
146 nmbd_event_context(),
148 nmbd_sig_hup_handler
,
151 DEBUG(0,("failed to setup SIGHUP handler"));
158 /**************************************************************************** **
159 Handle a SHUTDOWN message from smbcontrol.
160 **************************************************************************** */
162 static void nmbd_terminate(struct messaging_context
*msg
,
165 struct server_id server_id
,
171 /**************************************************************************** **
172 Possibly continue after a fault.
173 **************************************************************************** */
175 static void fault_continue(void)
180 /**************************************************************************** **
181 Expire old names from the namelist and server list.
182 **************************************************************************** */
184 static void expire_names_and_servers(time_t t
)
186 static time_t lastrun
= 0;
190 if ( t
< (lastrun
+ 5) )
195 * Expire any timed out names on all the broadcast
196 * subnets and those registered with the WINS server.
197 * (nmbd_namelistdb.c)
203 * Go through all the broadcast subnets and for each
204 * workgroup known on that subnet remove any expired
205 * server names. If a workgroup has an empty serverlist
206 * and has itself timed out then remove the workgroup.
207 * (nmbd_workgroupdb.c)
210 expire_workgroups_and_servers(t
);
213 /************************************************************************** **
214 Reload the list of network interfaces.
215 Doesn't return until a network interface is up.
216 ************************************************************************** */
218 static void reload_interfaces(time_t t
)
222 bool print_waiting_msg
= true;
223 struct subnet_record
*subrec
;
225 if (t
&& ((t
- lastt
) < NMBD_INTERFACES_RELOAD
)) {
231 if (!interfaces_changed()) {
237 /* the list of probed interfaces has changed, we may need to add/remove
241 /* find any interfaces that need adding */
242 for (n
=iface_count() - 1; n
>= 0; n
--) {
243 char str
[INET6_ADDRSTRLEN
];
244 const struct interface
*iface
= get_interface(n
);
245 struct in_addr ip
, nmask
;
248 DEBUG(2,("reload_interfaces: failed to get interface %d\n", n
));
252 /* Ensure we're only dealing with IPv4 here. */
253 if (iface
->ip
.ss_family
!= AF_INET
) {
254 DEBUG(2,("reload_interfaces: "
255 "ignoring non IPv4 interface.\n"));
259 ip
= ((struct sockaddr_in
*)(void *)&iface
->ip
)->sin_addr
;
260 nmask
= ((struct sockaddr_in
*)(void *)
261 &iface
->netmask
)->sin_addr
;
264 * We don't want to add a loopback interface, in case
265 * someone has added 127.0.0.1 for smbd, nmbd needs to
266 * ignore it here. JRA.
269 if (is_loopback_addr((struct sockaddr
*)(void *)&iface
->ip
)) {
270 DEBUG(2,("reload_interfaces: Ignoring loopback "
272 print_sockaddr(str
, sizeof(str
), &iface
->ip
) ));
276 for (subrec
=subnetlist
; subrec
; subrec
=subrec
->next
) {
277 if (ip_equal_v4(ip
, subrec
->myip
) &&
278 ip_equal_v4(nmask
, subrec
->mask_ip
)) {
284 /* it wasn't found! add it */
285 DEBUG(2,("Found new interface %s\n",
287 sizeof(str
), &iface
->ip
) ));
288 subrec
= make_normal_subnet(iface
);
290 register_my_workgroup_one_subnet(subrec
);
294 /* find any interfaces that need deleting */
295 for (subrec
=subnetlist
; subrec
; subrec
=subrec
->next
) {
296 for (n
=iface_count() - 1; n
>= 0; n
--) {
297 struct interface
*iface
= get_interface(n
);
298 struct in_addr ip
, nmask
;
302 /* Ensure we're only dealing with IPv4 here. */
303 if (iface
->ip
.ss_family
!= AF_INET
) {
304 DEBUG(2,("reload_interfaces: "
305 "ignoring non IPv4 interface.\n"));
308 ip
= ((struct sockaddr_in
*)(void *)
309 &iface
->ip
)->sin_addr
;
310 nmask
= ((struct sockaddr_in
*)(void *)
311 &iface
->netmask
)->sin_addr
;
312 if (ip_equal_v4(ip
, subrec
->myip
) &&
313 ip_equal_v4(nmask
, subrec
->mask_ip
)) {
318 /* oops, an interface has disapeared. This is
319 tricky, we don't dare actually free the
320 interface as it could be being used, so
321 instead we just wear the memory leak and
322 remove it from the list of interfaces without
324 DEBUG(2,("Deleting dead interface %s\n",
325 inet_ntoa(subrec
->myip
)));
326 close_subnet(subrec
);
330 rescan_listen_set
= True
;
332 /* We need to wait if there are no subnets... */
333 if (FIRST_SUBNET
== NULL
) {
334 void (*saved_handler
)(int);
336 if (print_waiting_msg
) {
337 DEBUG(0,("reload_interfaces: "
338 "No subnets to listen to. Waiting..\n"));
339 print_waiting_msg
= false;
343 * Whilst we're waiting for an interface, allow SIGTERM to
346 saved_handler
= CatchSignal(SIGTERM
, SIG_DFL
);
348 /* We only count IPv4, non-loopback interfaces here. */
349 while (iface_count_v4_nl() == 0) {
354 CatchSignal(SIGTERM
, saved_handler
);
357 * We got an interface, go back to blocking term.
364 /**************************************************************************** **
365 Reload the services file.
366 **************************************************************************** */
368 static bool reload_nmbd_services(bool test
)
372 set_remote_machine_name("nmbd", False
);
375 const char *fname
= lp_configfile();
376 if (file_exist(fname
) && !strcsequal(fname
,get_dyn_CONFIGFILE())) {
377 set_dyn_CONFIGFILE(fname
);
382 if ( test
&& !lp_file_list_changed() )
385 ret
= lp_load(get_dyn_CONFIGFILE(), True
, False
, False
, True
);
387 /* perhaps the config filename is now set */
389 DEBUG( 3, ( "services not loaded\n" ) );
390 reload_nmbd_services( True
);
396 /**************************************************************************** **
397 * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
398 **************************************************************************** */
400 static void msg_reload_nmbd_services(struct messaging_context
*msg
,
403 struct server_id server_id
,
406 write_browse_list( 0, True
);
407 dump_all_namelists();
408 reload_nmbd_services( True
);
410 reload_interfaces(0);
413 static void msg_nmbd_send_packet(struct messaging_context
*msg
,
416 struct server_id src
,
419 struct packet_struct
*p
= (struct packet_struct
*)data
->data
;
420 struct subnet_record
*subrec
;
421 struct sockaddr_storage ss
;
422 const struct sockaddr_storage
*pss
;
423 const struct in_addr
*local_ip
;
425 DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src
)));
427 if (data
->length
!= sizeof(struct packet_struct
)) {
428 DEBUG(2, ("Discarding invalid packet length from %u\n",
429 (unsigned int)procid_to_pid(&src
)));
433 if ((p
->packet_type
!= NMB_PACKET
) &&
434 (p
->packet_type
!= DGRAM_PACKET
)) {
435 DEBUG(2, ("Discarding invalid packet type from %u: %d\n",
436 (unsigned int)procid_to_pid(&src
), p
->packet_type
));
440 in_addr_to_sockaddr_storage(&ss
, p
->ip
);
441 pss
= iface_ip((struct sockaddr
*)(void *)&ss
);
444 DEBUG(2, ("Could not find ip for packet from %u\n",
445 (unsigned int)procid_to_pid(&src
)));
449 local_ip
= &((const struct sockaddr_in
*)pss
)->sin_addr
;
450 subrec
= FIRST_SUBNET
;
453 p
->send_fd
= (p
->packet_type
== NMB_PACKET
) ?
454 subrec
->nmb_sock
: subrec
->dgram_sock
;
456 for (subrec
= FIRST_SUBNET
; subrec
!= NULL
;
457 subrec
= NEXT_SUBNET_EXCLUDING_UNICAST(subrec
)) {
458 if (ip_equal_v4(*local_ip
, subrec
->myip
)) {
459 p
->send_fd
= (p
->packet_type
== NMB_PACKET
) ?
460 subrec
->nmb_sock
: subrec
->dgram_sock
;
465 if (p
->packet_type
== DGRAM_PACKET
) {
467 p
->packet
.dgram
.header
.source_ip
.s_addr
= local_ip
->s_addr
;
468 p
->packet
.dgram
.header
.source_port
= 138;
474 /**************************************************************************** **
475 The main select loop.
476 **************************************************************************** */
478 static void process(void)
483 time_t t
= time(NULL
);
484 TALLOC_CTX
*frame
= talloc_stackframe();
487 * Check all broadcast subnets to see if
488 * we need to run an election on any of them.
492 run_election
= check_elections();
495 * Read incoming UDP packets.
499 if(listen_for_packets(run_election
)) {
505 * Process all incoming packets
506 * read above. This calls the success and
507 * failure functions registered when response
508 * packets arrrive, and also deals with request
509 * packets from other sources.
516 * Run any elections - initiate becoming
517 * a local master browser if we have won.
524 * Send out any broadcast announcements
525 * of our server names. This also announces
526 * the workgroup name if we are a local
528 * (nmbd_sendannounce.c)
531 announce_my_server_names(t
);
534 * Send out any LanMan broadcast announcements
535 * of our server names.
536 * (nmbd_sendannounce.c)
539 announce_my_lm_server_names(t
);
542 * If we are a local master browser, periodically
543 * announce ourselves to the domain master browser.
544 * This also deals with syncronising the domain master
545 * browser server lists with ourselves as a local
547 * (nmbd_sendannounce.c)
550 announce_myself_to_domain_master_browser(t
);
553 * Fullfill any remote announce requests.
554 * (nmbd_sendannounce.c)
560 * Fullfill any remote browse sync announce requests.
561 * (nmbd_sendannounce.c)
564 browse_sync_remote(t
);
567 * Scan the broadcast subnets, and WINS client
568 * namelists and refresh any that need refreshing.
575 * Scan the subnet namelists and server lists and
576 * expire thos that have timed out.
580 expire_names_and_servers(t
);
583 * Write out a snapshot of our current browse list into
584 * the browse.dat file. This is used by smbd to service
585 * incoming NetServerEnum calls - used to synchronise
586 * browse lists over subnets.
587 * (nmbd_serverlistdb.c)
590 write_browse_list(t
, False
);
593 * If we are a domain master browser, we have a list of
594 * local master browsers we should synchronise browse
595 * lists with (these are added by an incoming local
596 * master browser announcement packet). Expire any of
597 * these that are no longer current, and pull the server
598 * lists from each of these known local master browsers.
599 * (nmbd_browsesync.c)
602 dmb_expire_and_sync_browser_lists(t
);
605 * Check that there is a local master browser for our
606 * workgroup for all our broadcast subnets. If one
607 * is not found, start an election (which we ourselves
608 * may or may not participate in, depending on the
609 * setting of the 'local master' parameter.
613 check_master_browser_exists(t
);
616 * If we are configured as a logon server, attempt to
617 * register the special NetBIOS names to become such
618 * (WORKGROUP<1c> name) on all broadcast subnets and
619 * with the WINS server (if used). If we are configured
620 * to become a domain master browser, attempt to register
621 * the special NetBIOS name (WORKGROUP<1b> name) to
623 * (nmbd_become_dmb.c)
629 * If we are a WINS server, do any timer dependent
630 * processing required.
631 * (nmbd_winsserver.c)
634 initiate_wins_processing(t
);
637 * If we are a domain master browser, attempt to contact the
638 * WINS server to get a list of all known WORKGROUPS/DOMAINS.
639 * This will only work to a Samba WINS server.
640 * (nmbd_browsesync.c)
643 if (lp_enhanced_browsing())
644 collect_all_workgroup_names_from_wins_server(t
);
647 * Go through the response record queue and time out or re-transmit
648 * and expired entries.
652 retransmit_or_expire_response_records(t
);
655 * check to see if any remote browse sync child processes have completed
658 sync_check_completion();
661 * regularly sync with any other DMBs we know about
664 if (lp_enhanced_browsing())
668 * clear the unexpected packet queue
673 /* check for new network interfaces */
675 reload_interfaces(t
);
677 /* free up temp memory */
682 /**************************************************************************** **
683 Open the socket communication.
684 **************************************************************************** */
686 static bool open_sockets(bool isdaemon
, int port
)
688 struct sockaddr_storage ss
;
689 const char *sock_addr
= lp_socket_address();
692 * The sockets opened here will be used to receive broadcast
693 * packets *only*. Interface specific sockets are opened in
694 * make_subnet() in namedbsubnet.c. Thus we bind to the
695 * address "0.0.0.0". The parameter 'socket address' is
699 if (!interpret_string_addr(&ss
, sock_addr
,
700 AI_NUMERICHOST
|AI_PASSIVE
)) {
701 DEBUG(0,("open_sockets: unable to get socket address "
702 "from string %s", sock_addr
));
705 if (ss
.ss_family
!= AF_INET
) {
706 DEBUG(0,("open_sockets: unable to use IPv6 socket"
713 ClientNMB
= open_socket_in(SOCK_DGRAM
, port
,
720 if (ClientNMB
== -1) {
724 ClientDGRAM
= open_socket_in(SOCK_DGRAM
, DGRAM_PORT
,
728 if (ClientDGRAM
== -1) {
729 if (ClientNMB
!= 0) {
735 /* we are never interested in SIGPIPE */
736 BlockSignals(True
,SIGPIPE
);
738 set_socket_options( ClientNMB
, "SO_BROADCAST" );
739 set_socket_options( ClientDGRAM
, "SO_BROADCAST" );
741 /* Ensure we're non-blocking. */
742 set_blocking( ClientNMB
, False
);
743 set_blocking( ClientDGRAM
, False
);
745 DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
749 /**************************************************************************** **
751 **************************************************************************** */
753 int main(int argc
, const char *argv
[])
755 static bool is_daemon
;
756 static bool opt_interactive
;
757 static bool Fork
= true;
758 static bool no_process_group
;
759 static bool log_stdout
;
761 char *p_lmhosts
= NULL
;
767 OPT_NO_PROCESS_GROUP
,
770 struct poptOption long_options
[] = {
772 {"daemon", 'D', POPT_ARG_NONE
, NULL
, OPT_DAEMON
, "Become a daemon(default)" },
773 {"interactive", 'i', POPT_ARG_NONE
, NULL
, OPT_INTERACTIVE
, "Run interactive (not a daemon)" },
774 {"foreground", 'F', POPT_ARG_NONE
, NULL
, OPT_FORK
, "Run daemon in foreground (for daemontools & etc)" },
775 {"no-process-group", 0, POPT_ARG_NONE
, NULL
, OPT_NO_PROCESS_GROUP
, "Don't create a new process group" },
776 {"log-stdout", 'S', POPT_ARG_NONE
, NULL
, OPT_LOG_STDOUT
, "Log to stdout" },
777 {"hosts", 'H', POPT_ARG_STRING
, &p_lmhosts
, 'H', "Load a netbios hosts file"},
778 {"port", 'p', POPT_ARG_INT
, &global_nmb_port
, NMB_PORT
, "Listen on the specified port" },
782 TALLOC_CTX
*frame
= talloc_stackframe(); /* Setup tos. */
787 global_nmb_port
= NMB_PORT
;
789 pc
= poptGetContext("nmbd", argc
, argv
, long_options
, 0);
790 while ((opt
= poptGetNextOpt(pc
)) != -1) {
795 case OPT_INTERACTIVE
:
796 opt_interactive
= true;
801 case OPT_NO_PROCESS_GROUP
:
802 no_process_group
= true;
808 d_fprintf(stderr
, "\nInvalid option %s: %s\n\n",
809 poptBadOption(pc
, 0), poptStrerror(opt
));
810 poptPrintUsage(pc
, stderr
, 0);
816 global_in_nmbd
= true;
818 StartupTime
= time(NULL
);
820 sys_srandom(time(NULL
) ^ sys_getpid());
822 if (!override_logfile
) {
824 if (asprintf(&lfile
, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) {
827 lp_set_logfile(lfile
);
831 fault_setup((void (*)(void *))fault_continue
);
832 dump_core_setup("nmbd");
834 /* POSIX demands that signals are inherited. If the invoking process has
835 * these signals masked, we will have problems, as we won't receive them. */
836 BlockSignals(False
, SIGHUP
);
837 BlockSignals(False
, SIGUSR1
);
838 BlockSignals(False
, SIGTERM
);
841 /* we are never interested in SIGFPE */
842 BlockSignals(True
,SIGFPE
);
845 /* We no longer use USR2... */
847 BlockSignals(True
, SIGUSR2
);
850 if ( opt_interactive
) {
855 if ( log_stdout
&& Fork
) {
856 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
860 setup_logging( argv
[0], log_stdout
);
864 DEBUG(0,("nmbd version %s started.\n", samba_version_string()));
865 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE
));
867 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
868 DEBUG(0, ("error opening config file\n"));
872 if (nmbd_messaging_context() == NULL
) {
876 if ( !reload_nmbd_services(False
) )
882 reload_nmbd_services( True
);
884 if (strequal(lp_workgroup(),"*")) {
885 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
891 if (!is_daemon
&& !is_a_socket(0)) {
892 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
896 if (is_daemon
&& !opt_interactive
) {
897 DEBUG( 2, ( "Becoming a daemon.\n" ) );
898 become_daemon(Fork
, no_process_group
, log_stdout
);
903 * If we're interactive we want to set our own process group for
906 if (opt_interactive
&& !no_process_group
)
907 setpgid( (pid_t
)0, (pid_t
)0 );
910 if (nmbd_messaging_context() == NULL
) {
915 /* Setup the async dns. We do it here so it doesn't have all the other
916 stuff initialised and thus chewing memory and sockets */
917 if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
922 if (!directory_exist(lp_lockdir())) {
923 mkdir(lp_lockdir(), 0755);
926 pidfile_create("nmbd");
928 status
= reinit_after_fork(nmbd_messaging_context(),
929 nmbd_event_context(),
930 procid_self(), false);
932 if (!NT_STATUS_IS_OK(status
)) {
933 DEBUG(0,("reinit_after_fork() failed\n"));
937 if (!nmbd_setup_sig_term_handler())
939 if (!nmbd_setup_sig_hup_handler())
942 /* get broadcast messages */
944 if (!serverid_register(procid_self(),
945 FLAG_MSG_GENERAL
|FLAG_MSG_DBWRAP
)) {
946 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
950 messaging_register(nmbd_messaging_context(), NULL
,
951 MSG_FORCE_ELECTION
, nmbd_message_election
);
953 /* Until winsrepl is done. */
954 messaging_register(nmbd_messaging_context(), NULL
,
955 MSG_WINS_NEW_ENTRY
, nmbd_wins_new_entry
);
957 messaging_register(nmbd_messaging_context(), NULL
,
958 MSG_SHUTDOWN
, nmbd_terminate
);
959 messaging_register(nmbd_messaging_context(), NULL
,
960 MSG_SMB_CONF_UPDATED
, msg_reload_nmbd_services
);
961 messaging_register(nmbd_messaging_context(), NULL
,
962 MSG_SEND_PACKET
, msg_nmbd_send_packet
);
966 DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port
) );
968 if ( !open_sockets( is_daemon
, global_nmb_port
) ) {
969 kill_async_dns_child();
973 /* Determine all the IP addresses we have. */
976 /* Create an nmbd subnet record for each of the above. */
977 if( False
== create_subnets() ) {
978 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
979 kill_async_dns_child();
983 /* Load in any static local names. */
985 set_dyn_LMHOSTSFILE(p_lmhosts
);
987 load_lmhosts_file(get_dyn_LMHOSTSFILE());
988 DEBUG(3,("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE()));
990 /* If we are acting as a WINS server, initialise data structures. */
991 if( !initialise_wins() ) {
992 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
993 kill_async_dns_child();
998 * Register nmbd primary workgroup and nmbd names on all
999 * the broadcast subnets, and on the WINS server (if specified).
1000 * Also initiate the startup of our primary workgroup (start
1001 * elections if we are setup as being able to be a local
1005 if( False
== register_my_workgroup_and_names() ) {
1006 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
1007 kill_async_dns_child();
1011 if (!initialize_nmbd_proxy_logon()) {
1012 DEBUG(0,("ERROR: Failed setup nmbd_proxy_logon.\n"));
1013 kill_async_dns_child();
1022 kill_async_dns_child();