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"
26 #include "nmbd/nmbd.h"
30 int global_nmb_port = -1;
32 extern bool rescan_listen_set;
33 extern bool global_in_nmbd;
35 extern bool override_logfile;
37 /* have we found LanMan clients yet? */
38 bool found_lm_clients = False;
40 /* what server type are we currently */
42 time_t StartupTime = 0;
44 struct event_context *nmbd_event_context(void)
46 static struct event_context *ctx;
48 if (!ctx && !(ctx = event_context_init(NULL))) {
49 smb_panic("Could not init nmbd event context");
54 struct messaging_context *nmbd_messaging_context(void)
56 static struct messaging_context *ctx;
59 ctx = messaging_init(NULL, procid_self(),
60 nmbd_event_context());
63 DEBUG(0, ("Could not init nmbd messaging context.\n"));
68 /**************************************************************************** **
69 Handle a SIGTERM in band.
70 **************************************************************************** */
72 static void terminate(void)
74 DEBUG(0,("Got SIGTERM: going down...\n"));
76 /* Write out wins.dat file if samba is a WINS server */
77 wins_write_database(0,False);
79 /* Remove all SELF registered names from WINS */
82 /* Announce all server entries as 0 time-to-live, 0 type. */
83 announce_my_servers_removed();
85 /* If there was an async dns child - kill it. */
86 kill_async_dns_child();
89 serverid_deregister(procid_self());
96 static void nmbd_sig_term_handler(struct tevent_context *ev,
97 struct tevent_signal *se,
106 static bool nmbd_setup_sig_term_handler(void)
108 struct tevent_signal *se;
110 se = tevent_add_signal(nmbd_event_context(),
111 nmbd_event_context(),
113 nmbd_sig_term_handler,
116 DEBUG(0,("failed to setup SIGTERM handler"));
123 static void msg_reload_nmbd_services(struct messaging_context *msg,
126 struct server_id server_id,
129 static void nmbd_sig_hup_handler(struct tevent_context *ev,
130 struct tevent_signal *se,
136 DEBUG(0,("Got SIGHUP dumping debug info.\n"));
137 msg_reload_nmbd_services(nmbd_messaging_context(),
138 NULL, MSG_SMB_CONF_UPDATED,
139 procid_self(), NULL);
142 static bool nmbd_setup_sig_hup_handler(void)
144 struct tevent_signal *se;
146 se = tevent_add_signal(nmbd_event_context(),
147 nmbd_event_context(),
149 nmbd_sig_hup_handler,
152 DEBUG(0,("failed to setup SIGHUP handler"));
159 /**************************************************************************** **
160 Handle a SHUTDOWN message from smbcontrol.
161 **************************************************************************** */
163 static void nmbd_terminate(struct messaging_context *msg,
166 struct server_id server_id,
172 /**************************************************************************** **
173 Possibly continue after a fault.
174 **************************************************************************** */
176 static void fault_continue(void)
181 /**************************************************************************** **
182 Expire old names from the namelist and server list.
183 **************************************************************************** */
185 static void expire_names_and_servers(time_t t)
187 static time_t lastrun = 0;
191 if ( t < (lastrun + 5) )
196 * Expire any timed out names on all the broadcast
197 * subnets and those registered with the WINS server.
198 * (nmbd_namelistdb.c)
204 * Go through all the broadcast subnets and for each
205 * workgroup known on that subnet remove any expired
206 * server names. If a workgroup has an empty serverlist
207 * and has itself timed out then remove the workgroup.
208 * (nmbd_workgroupdb.c)
211 expire_workgroups_and_servers(t);
214 /************************************************************************** **
215 Reload the list of network interfaces.
216 Doesn't return until a network interface is up.
217 ************************************************************************** */
219 static void reload_interfaces(time_t t)
223 bool print_waiting_msg = true;
224 struct subnet_record *subrec;
226 if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
232 if (!interfaces_changed()) {
238 /* the list of probed interfaces has changed, we may need to add/remove
242 /* find any interfaces that need adding */
243 for (n=iface_count() - 1; n >= 0; n--) {
244 char str[INET6_ADDRSTRLEN];
245 const struct interface *iface = get_interface(n);
246 struct in_addr ip, nmask;
249 DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
253 /* Ensure we're only dealing with IPv4 here. */
254 if (iface->ip.ss_family != AF_INET) {
255 DEBUG(2,("reload_interfaces: "
256 "ignoring non IPv4 interface.\n"));
260 ip = ((struct sockaddr_in *)(void *)&iface->ip)->sin_addr;
261 nmask = ((struct sockaddr_in *)(void *)
262 &iface->netmask)->sin_addr;
265 * We don't want to add a loopback interface, in case
266 * someone has added 127.0.0.1 for smbd, nmbd needs to
267 * ignore it here. JRA.
270 if (is_loopback_addr((struct sockaddr *)(void *)&iface->ip)) {
271 DEBUG(2,("reload_interfaces: Ignoring loopback "
273 print_sockaddr(str, sizeof(str), &iface->ip) ));
277 for (subrec=subnetlist; subrec; subrec=subrec->next) {
278 if (ip_equal_v4(ip, subrec->myip) &&
279 ip_equal_v4(nmask, subrec->mask_ip)) {
285 /* it wasn't found! add it */
286 DEBUG(2,("Found new interface %s\n",
288 sizeof(str), &iface->ip) ));
289 subrec = make_normal_subnet(iface);
291 register_my_workgroup_one_subnet(subrec);
295 /* find any interfaces that need deleting */
296 for (subrec=subnetlist; subrec; subrec=subrec->next) {
297 for (n=iface_count() - 1; n >= 0; n--) {
298 struct interface *iface = get_interface(n);
299 struct in_addr ip, nmask;
303 /* Ensure we're only dealing with IPv4 here. */
304 if (iface->ip.ss_family != AF_INET) {
305 DEBUG(2,("reload_interfaces: "
306 "ignoring non IPv4 interface.\n"));
309 ip = ((struct sockaddr_in *)(void *)
310 &iface->ip)->sin_addr;
311 nmask = ((struct sockaddr_in *)(void *)
312 &iface->netmask)->sin_addr;
313 if (ip_equal_v4(ip, subrec->myip) &&
314 ip_equal_v4(nmask, subrec->mask_ip)) {
319 /* oops, an interface has disapeared. This is
320 tricky, we don't dare actually free the
321 interface as it could be being used, so
322 instead we just wear the memory leak and
323 remove it from the list of interfaces without
325 DEBUG(2,("Deleting dead interface %s\n",
326 inet_ntoa(subrec->myip)));
327 close_subnet(subrec);
331 rescan_listen_set = True;
333 /* We need to wait if there are no subnets... */
334 if (FIRST_SUBNET == NULL) {
335 void (*saved_handler)(int);
337 if (print_waiting_msg) {
338 DEBUG(0,("reload_interfaces: "
339 "No subnets to listen to. Waiting..\n"));
340 print_waiting_msg = false;
344 * Whilst we're waiting for an interface, allow SIGTERM to
347 saved_handler = CatchSignal(SIGTERM, SIG_DFL);
349 /* We only count IPv4, non-loopback interfaces here. */
350 while (iface_count_v4_nl() == 0) {
355 CatchSignal(SIGTERM, saved_handler);
358 * We got an interface, go back to blocking term.
365 /**************************************************************************** **
366 Reload the services file.
367 **************************************************************************** */
369 static bool reload_nmbd_services(bool test)
373 set_remote_machine_name("nmbd", False);
376 const char *fname = lp_configfile();
377 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
378 set_dyn_CONFIGFILE(fname);
383 if ( test && !lp_file_list_changed() )
386 ret = lp_load(get_dyn_CONFIGFILE(), True , False, False, True);
388 /* perhaps the config filename is now set */
390 DEBUG( 3, ( "services not loaded\n" ) );
391 reload_nmbd_services( True );
397 /**************************************************************************** **
398 * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
399 **************************************************************************** */
401 static void msg_reload_nmbd_services(struct messaging_context *msg,
404 struct server_id server_id,
407 write_browse_list( 0, True );
408 dump_all_namelists();
409 reload_nmbd_services( True );
411 reload_interfaces(0);
414 static void msg_nmbd_send_packet(struct messaging_context *msg,
417 struct server_id src,
420 struct packet_struct *p = (struct packet_struct *)data->data;
421 struct subnet_record *subrec;
422 struct sockaddr_storage ss;
423 const struct sockaddr_storage *pss;
424 const struct in_addr *local_ip;
426 DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src)));
428 if (data->length != sizeof(struct packet_struct)) {
429 DEBUG(2, ("Discarding invalid packet length from %u\n",
430 (unsigned int)procid_to_pid(&src)));
434 if ((p->packet_type != NMB_PACKET) &&
435 (p->packet_type != DGRAM_PACKET)) {
436 DEBUG(2, ("Discarding invalid packet type from %u: %d\n",
437 (unsigned int)procid_to_pid(&src), p->packet_type));
441 in_addr_to_sockaddr_storage(&ss, p->ip);
442 pss = iface_ip((struct sockaddr *)(void *)&ss);
445 DEBUG(2, ("Could not find ip for packet from %u\n",
446 (unsigned int)procid_to_pid(&src)));
450 local_ip = &((const struct sockaddr_in *)pss)->sin_addr;
451 subrec = FIRST_SUBNET;
454 p->send_fd = (p->packet_type == NMB_PACKET) ?
455 subrec->nmb_sock : subrec->dgram_sock;
457 for (subrec = FIRST_SUBNET; subrec != NULL;
458 subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
459 if (ip_equal_v4(*local_ip, subrec->myip)) {
460 p->send_fd = (p->packet_type == NMB_PACKET) ?
461 subrec->nmb_sock : subrec->dgram_sock;
466 if (p->packet_type == DGRAM_PACKET) {
468 p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
469 p->packet.dgram.header.source_port = 138;
475 /**************************************************************************** **
476 The main select loop.
477 **************************************************************************** */
479 static void process(void)
484 time_t t = time(NULL);
485 TALLOC_CTX *frame = talloc_stackframe();
488 * Check all broadcast subnets to see if
489 * we need to run an election on any of them.
493 run_election = check_elections();
496 * Read incoming UDP packets.
500 if(listen_for_packets(run_election)) {
506 * Process all incoming packets
507 * read above. This calls the success and
508 * failure functions registered when response
509 * packets arrrive, and also deals with request
510 * packets from other sources.
517 * Run any elections - initiate becoming
518 * a local master browser if we have won.
525 * Send out any broadcast announcements
526 * of our server names. This also announces
527 * the workgroup name if we are a local
529 * (nmbd_sendannounce.c)
532 announce_my_server_names(t);
535 * Send out any LanMan broadcast announcements
536 * of our server names.
537 * (nmbd_sendannounce.c)
540 announce_my_lm_server_names(t);
543 * If we are a local master browser, periodically
544 * announce ourselves to the domain master browser.
545 * This also deals with syncronising the domain master
546 * browser server lists with ourselves as a local
548 * (nmbd_sendannounce.c)
551 announce_myself_to_domain_master_browser(t);
554 * Fullfill any remote announce requests.
555 * (nmbd_sendannounce.c)
561 * Fullfill any remote browse sync announce requests.
562 * (nmbd_sendannounce.c)
565 browse_sync_remote(t);
568 * Scan the broadcast subnets, and WINS client
569 * namelists and refresh any that need refreshing.
576 * Scan the subnet namelists and server lists and
577 * expire thos that have timed out.
581 expire_names_and_servers(t);
584 * Write out a snapshot of our current browse list into
585 * the browse.dat file. This is used by smbd to service
586 * incoming NetServerEnum calls - used to synchronise
587 * browse lists over subnets.
588 * (nmbd_serverlistdb.c)
591 write_browse_list(t, False);
594 * If we are a domain master browser, we have a list of
595 * local master browsers we should synchronise browse
596 * lists with (these are added by an incoming local
597 * master browser announcement packet). Expire any of
598 * these that are no longer current, and pull the server
599 * lists from each of these known local master browsers.
600 * (nmbd_browsesync.c)
603 dmb_expire_and_sync_browser_lists(t);
606 * Check that there is a local master browser for our
607 * workgroup for all our broadcast subnets. If one
608 * is not found, start an election (which we ourselves
609 * may or may not participate in, depending on the
610 * setting of the 'local master' parameter.
614 check_master_browser_exists(t);
617 * If we are configured as a logon server, attempt to
618 * register the special NetBIOS names to become such
619 * (WORKGROUP<1c> name) on all broadcast subnets and
620 * with the WINS server (if used). If we are configured
621 * to become a domain master browser, attempt to register
622 * the special NetBIOS name (WORKGROUP<1b> name) to
624 * (nmbd_become_dmb.c)
630 * If we are a WINS server, do any timer dependent
631 * processing required.
632 * (nmbd_winsserver.c)
635 initiate_wins_processing(t);
638 * If we are a domain master browser, attempt to contact the
639 * WINS server to get a list of all known WORKGROUPS/DOMAINS.
640 * This will only work to a Samba WINS server.
641 * (nmbd_browsesync.c)
644 if (lp_enhanced_browsing())
645 collect_all_workgroup_names_from_wins_server(t);
648 * Go through the response record queue and time out or re-transmit
649 * and expired entries.
653 retransmit_or_expire_response_records(t);
656 * check to see if any remote browse sync child processes have completed
659 sync_check_completion();
662 * regularly sync with any other DMBs we know about
665 if (lp_enhanced_browsing())
669 * clear the unexpected packet queue
674 /* check for new network interfaces */
676 reload_interfaces(t);
678 /* free up temp memory */
683 /**************************************************************************** **
684 Open the socket communication.
685 **************************************************************************** */
687 static bool open_sockets(bool isdaemon, int port)
689 struct sockaddr_storage ss;
690 const char *sock_addr = lp_socket_address();
693 * The sockets opened here will be used to receive broadcast
694 * packets *only*. Interface specific sockets are opened in
695 * make_subnet() in namedbsubnet.c. Thus we bind to the
696 * address "0.0.0.0". The parameter 'socket address' is
700 if (!interpret_string_addr(&ss, sock_addr,
701 AI_NUMERICHOST|AI_PASSIVE)) {
702 DEBUG(0,("open_sockets: unable to get socket address "
703 "from string %s", sock_addr));
706 if (ss.ss_family != AF_INET) {
707 DEBUG(0,("open_sockets: unable to use IPv6 socket"
714 ClientNMB = open_socket_in(SOCK_DGRAM, port,
721 if (ClientNMB == -1) {
725 ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
729 if (ClientDGRAM == -1) {
730 if (ClientNMB != 0) {
736 /* we are never interested in SIGPIPE */
737 BlockSignals(True,SIGPIPE);
739 set_socket_options( ClientNMB, "SO_BROADCAST" );
740 set_socket_options( ClientDGRAM, "SO_BROADCAST" );
742 /* Ensure we're non-blocking. */
743 set_blocking( ClientNMB, False);
744 set_blocking( ClientDGRAM, False);
746 DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
750 /**************************************************************************** **
752 **************************************************************************** */
754 int main(int argc, const char *argv[])
756 static bool is_daemon;
757 static bool opt_interactive;
758 static bool Fork = true;
759 static bool no_process_group;
760 static bool log_stdout;
762 char *p_lmhosts = NULL;
768 OPT_NO_PROCESS_GROUP,
771 struct poptOption long_options[] = {
773 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon(default)" },
774 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)" },
775 {"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools & etc)" },
776 {"no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
777 {"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
778 {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 'H', "Load a netbios hosts file"},
779 {"port", 'p', POPT_ARG_INT, &global_nmb_port, NMB_PORT, "Listen on the specified port" },
787 * Do this before any other talloc operation
789 talloc_enable_null_tracking();
790 frame = talloc_stackframe();
794 global_nmb_port = NMB_PORT;
796 pc = poptGetContext("nmbd", argc, argv, long_options, 0);
797 while ((opt = poptGetNextOpt(pc)) != -1) {
802 case OPT_INTERACTIVE:
803 opt_interactive = true;
808 case OPT_NO_PROCESS_GROUP:
809 no_process_group = true;
815 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
816 poptBadOption(pc, 0), poptStrerror(opt));
817 poptPrintUsage(pc, stderr, 0);
823 global_in_nmbd = true;
825 StartupTime = time(NULL);
827 sys_srandom(time(NULL) ^ sys_getpid());
829 if (!override_logfile) {
831 if (asprintf(&lfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) {
834 lp_set_logfile(lfile);
838 fault_setup((void (*)(void *))fault_continue );
839 dump_core_setup("nmbd");
841 /* POSIX demands that signals are inherited. If the invoking process has
842 * these signals masked, we will have problems, as we won't receive them. */
843 BlockSignals(False, SIGHUP);
844 BlockSignals(False, SIGUSR1);
845 BlockSignals(False, SIGTERM);
848 /* we are never interested in SIGFPE */
849 BlockSignals(True,SIGFPE);
852 /* We no longer use USR2... */
854 BlockSignals(True, SIGUSR2);
857 if ( opt_interactive ) {
862 if ( log_stdout && Fork ) {
863 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
867 setup_logging( argv[0], log_stdout );
871 DEBUG(0,("nmbd version %s started.\n", samba_version_string()));
872 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
874 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
875 DEBUG(0, ("error opening config file\n"));
879 if (nmbd_messaging_context() == NULL) {
883 if ( !reload_nmbd_services(False) )
889 reload_nmbd_services( True );
891 if (strequal(lp_workgroup(),"*")) {
892 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
898 if (!is_daemon && !is_a_socket(0)) {
899 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
903 if (is_daemon && !opt_interactive) {
904 DEBUG( 2, ( "Becoming a daemon.\n" ) );
905 become_daemon(Fork, no_process_group, log_stdout);
910 * If we're interactive we want to set our own process group for
913 if (opt_interactive && !no_process_group)
914 setpgid( (pid_t)0, (pid_t)0 );
917 if (nmbd_messaging_context() == NULL) {
922 /* Setup the async dns. We do it here so it doesn't have all the other
923 stuff initialised and thus chewing memory and sockets */
924 if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
929 if (!directory_exist(lp_lockdir())) {
930 mkdir(lp_lockdir(), 0755);
933 pidfile_create("nmbd");
935 status = reinit_after_fork(nmbd_messaging_context(),
936 nmbd_event_context(),
937 procid_self(), false);
939 if (!NT_STATUS_IS_OK(status)) {
940 DEBUG(0,("reinit_after_fork() failed\n"));
944 if (!nmbd_setup_sig_term_handler())
946 if (!nmbd_setup_sig_hup_handler())
949 /* get broadcast messages */
951 if (!serverid_register(procid_self(),
952 FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) {
953 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
957 messaging_register(nmbd_messaging_context(), NULL,
958 MSG_FORCE_ELECTION, nmbd_message_election);
960 /* Until winsrepl is done. */
961 messaging_register(nmbd_messaging_context(), NULL,
962 MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
964 messaging_register(nmbd_messaging_context(), NULL,
965 MSG_SHUTDOWN, nmbd_terminate);
966 messaging_register(nmbd_messaging_context(), NULL,
967 MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
968 messaging_register(nmbd_messaging_context(), NULL,
969 MSG_SEND_PACKET, msg_nmbd_send_packet);
973 DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
975 if ( !open_sockets( is_daemon, global_nmb_port ) ) {
976 kill_async_dns_child();
980 /* Determine all the IP addresses we have. */
983 /* Create an nmbd subnet record for each of the above. */
984 if( False == create_subnets() ) {
985 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
986 kill_async_dns_child();
990 /* Load in any static local names. */
992 set_dyn_LMHOSTSFILE(p_lmhosts);
994 load_lmhosts_file(get_dyn_LMHOSTSFILE());
995 DEBUG(3,("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE()));
997 /* If we are acting as a WINS server, initialise data structures. */
998 if( !initialise_wins() ) {
999 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
1000 kill_async_dns_child();
1005 * Register nmbd primary workgroup and nmbd names on all
1006 * the broadcast subnets, and on the WINS server (if specified).
1007 * Also initiate the startup of our primary workgroup (start
1008 * elections if we are setup as being able to be a local
1012 if( False == register_my_workgroup_and_names() ) {
1013 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
1014 kill_async_dns_child();
1018 if (!initialize_nmbd_proxy_logon()) {
1019 DEBUG(0,("ERROR: Failed setup nmbd_proxy_logon.\n"));
1020 kill_async_dns_child();
1029 kill_async_dns_child();