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/>.
27 int global_nmb_port = -1;
29 extern bool rescan_listen_set;
30 extern bool global_in_nmbd;
32 extern bool override_logfile;
34 /* have we found LanMan clients yet? */
35 bool found_lm_clients = False;
37 /* what server type are we currently */
39 time_t StartupTime = 0;
41 struct event_context *nmbd_event_context(void)
43 static struct event_context *ctx;
45 if (!ctx && !(ctx = event_context_init(NULL))) {
46 smb_panic("Could not init nmbd event context");
51 struct messaging_context *nmbd_messaging_context(void)
53 static struct messaging_context *ctx;
56 ctx = messaging_init(NULL, server_id_self(),
57 nmbd_event_context());
60 DEBUG(0, ("Could not init nmbd messaging context.\n"));
65 /**************************************************************************** **
66 Handle a SIGTERM in band.
67 **************************************************************************** */
69 static void terminate(void)
71 DEBUG(0,("Got SIGTERM: going down...\n"));
73 /* Write out wins.dat file if samba is a WINS server */
74 wins_write_database(0,False);
76 /* Remove all SELF registered names from WINS */
79 /* Announce all server entries as 0 time-to-live, 0 type. */
80 announce_my_servers_removed();
82 /* If there was an async dns child - kill it. */
83 kill_async_dns_child();
88 /**************************************************************************** **
89 Handle a SHUTDOWN message from smbcontrol.
90 **************************************************************************** */
92 static void nmbd_terminate(struct messaging_context *msg,
95 struct server_id server_id,
101 /**************************************************************************** **
102 Catch a SIGTERM signal.
103 **************************************************************************** */
105 static SIG_ATOMIC_T got_sig_term;
107 static void sig_term(int sig)
110 sys_select_signal(SIGTERM);
113 /**************************************************************************** **
114 Catch a SIGHUP signal.
115 **************************************************************************** */
117 static SIG_ATOMIC_T reload_after_sighup;
119 static void sig_hup(int sig)
121 reload_after_sighup = 1;
122 sys_select_signal(SIGHUP);
125 /**************************************************************************** **
126 Possibly continue after a fault.
127 **************************************************************************** */
129 static void fault_continue(void)
134 /**************************************************************************** **
135 Expire old names from the namelist and server list.
136 **************************************************************************** */
138 static void expire_names_and_servers(time_t t)
140 static time_t lastrun = 0;
144 if ( t < (lastrun + 5) )
149 * Expire any timed out names on all the broadcast
150 * subnets and those registered with the WINS server.
151 * (nmbd_namelistdb.c)
157 * Go through all the broadcast subnets and for each
158 * workgroup known on that subnet remove any expired
159 * server names. If a workgroup has an empty serverlist
160 * and has itself timed out then remove the workgroup.
161 * (nmbd_workgroupdb.c)
164 expire_workgroups_and_servers(t);
167 /************************************************************************** **
168 Reload the list of network interfaces.
169 Doesn't return until a network interface is up.
170 ************************************************************************** */
172 static void reload_interfaces(time_t t)
176 bool print_waiting_msg = true;
177 struct subnet_record *subrec;
179 if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
185 if (!interfaces_changed()) {
191 /* the list of probed interfaces has changed, we may need to add/remove
195 /* find any interfaces that need adding */
196 for (n=iface_count() - 1; n >= 0; n--) {
197 char str[INET6_ADDRSTRLEN];
198 const struct interface *iface = get_interface(n);
199 struct in_addr ip, nmask;
202 DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
206 /* Ensure we're only dealing with IPv4 here. */
207 if (iface->ip.ss_family != AF_INET) {
208 DEBUG(2,("reload_interfaces: "
209 "ignoring non IPv4 interface.\n"));
213 ip = ((struct sockaddr_in *)&iface->ip)->sin_addr;
214 nmask = ((struct sockaddr_in *)&iface->netmask)->sin_addr;
217 * We don't want to add a loopback interface, in case
218 * someone has added 127.0.0.1 for smbd, nmbd needs to
219 * ignore it here. JRA.
222 if (is_loopback_addr((struct sockaddr *)&iface->ip)) {
223 DEBUG(2,("reload_interfaces: Ignoring loopback "
225 print_sockaddr(str, sizeof(str), &iface->ip) ));
229 for (subrec=subnetlist; subrec; subrec=subrec->next) {
230 if (ip_equal_v4(ip, subrec->myip) &&
231 ip_equal_v4(nmask, subrec->mask_ip)) {
237 /* it wasn't found! add it */
238 DEBUG(2,("Found new interface %s\n",
240 sizeof(str), &iface->ip) ));
241 subrec = make_normal_subnet(iface);
243 register_my_workgroup_one_subnet(subrec);
247 /* find any interfaces that need deleting */
248 for (subrec=subnetlist; subrec; subrec=subrec->next) {
249 for (n=iface_count() - 1; n >= 0; n--) {
250 struct interface *iface = get_interface(n);
251 struct in_addr ip, nmask;
255 /* Ensure we're only dealing with IPv4 here. */
256 if (iface->ip.ss_family != AF_INET) {
257 DEBUG(2,("reload_interfaces: "
258 "ignoring non IPv4 interface.\n"));
261 ip = ((struct sockaddr_in *)&iface->ip)->sin_addr;
262 nmask = ((struct sockaddr_in *)&iface->netmask)->sin_addr;
263 if (ip_equal_v4(ip, subrec->myip) &&
264 ip_equal_v4(nmask, subrec->mask_ip)) {
269 /* oops, an interface has disapeared. This is
270 tricky, we don't dare actually free the
271 interface as it could be being used, so
272 instead we just wear the memory leak and
273 remove it from the list of interfaces without
275 DEBUG(2,("Deleting dead interface %s\n",
276 inet_ntoa(subrec->myip)));
277 close_subnet(subrec);
281 rescan_listen_set = True;
283 /* We need to wait if there are no subnets... */
284 if (FIRST_SUBNET == NULL) {
285 void (*saved_handler)(int);
287 if (print_waiting_msg) {
288 DEBUG(0,("reload_interfaces: "
289 "No subnets to listen to. Waiting..\n"));
290 print_waiting_msg = false;
294 * Whilst we're waiting for an interface, allow SIGTERM to
297 saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
299 /* We only count IPv4, non-loopback interfaces here. */
300 while (iface_count_v4_nl() == 0) {
305 CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
308 * We got an interface, go back to blocking term.
315 /**************************************************************************** **
316 Reload the services file.
317 **************************************************************************** */
319 static bool reload_nmbd_services(bool test)
323 set_remote_machine_name("nmbd", False);
326 const char *fname = lp_configfile();
327 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
328 set_dyn_CONFIGFILE(fname);
333 if ( test && !lp_file_list_changed() )
336 ret = lp_load(get_dyn_CONFIGFILE(), True , False, False, True);
338 /* perhaps the config filename is now set */
340 DEBUG( 3, ( "services not loaded\n" ) );
341 reload_nmbd_services( True );
347 /**************************************************************************** **
348 * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
349 **************************************************************************** */
351 static void msg_reload_nmbd_services(struct messaging_context *msg,
354 struct server_id server_id,
357 write_browse_list( 0, True );
358 dump_all_namelists();
359 reload_nmbd_services( True );
361 reload_interfaces(0);
364 static void msg_nmbd_send_packet(struct messaging_context *msg,
367 struct server_id src,
370 struct packet_struct *p = (struct packet_struct *)data->data;
371 struct subnet_record *subrec;
372 struct sockaddr_storage ss;
373 const struct sockaddr_storage *pss;
374 const struct in_addr *local_ip;
376 DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src)));
378 if (data->length != sizeof(struct packet_struct)) {
379 DEBUG(2, ("Discarding invalid packet length from %d\n",
380 procid_to_pid(&src)));
384 if ((p->packet_type != NMB_PACKET) &&
385 (p->packet_type != DGRAM_PACKET)) {
386 DEBUG(2, ("Discarding invalid packet type from %d: %d\n",
387 procid_to_pid(&src), p->packet_type));
391 in_addr_to_sockaddr_storage(&ss, p->ip);
392 pss = iface_ip((struct sockaddr *)&ss);
395 DEBUG(2, ("Could not find ip for packet from %d\n",
396 procid_to_pid(&src)));
400 local_ip = &((const struct sockaddr_in *)pss)->sin_addr;
401 subrec = FIRST_SUBNET;
403 p->fd = (p->packet_type == NMB_PACKET) ?
404 subrec->nmb_sock : subrec->dgram_sock;
406 for (subrec = FIRST_SUBNET; subrec != NULL;
407 subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
408 if (ip_equal_v4(*local_ip, subrec->myip)) {
409 p->fd = (p->packet_type == NMB_PACKET) ?
410 subrec->nmb_sock : subrec->dgram_sock;
415 if (p->packet_type == DGRAM_PACKET) {
417 p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
418 p->packet.dgram.header.source_port = 138;
424 /**************************************************************************** **
425 The main select loop.
426 **************************************************************************** */
428 static void process(void)
433 time_t t = time(NULL);
434 TALLOC_CTX *frame = talloc_stackframe();
437 * Check all broadcast subnets to see if
438 * we need to run an election on any of them.
442 run_election = check_elections();
445 * Read incoming UDP packets.
449 if(listen_for_packets(run_election)) {
455 * Handle termination inband.
464 * Process all incoming packets
465 * read above. This calls the success and
466 * failure functions registered when response
467 * packets arrrive, and also deals with request
468 * packets from other sources.
475 * Run any elections - initiate becoming
476 * a local master browser if we have won.
483 * Send out any broadcast announcements
484 * of our server names. This also announces
485 * the workgroup name if we are a local
487 * (nmbd_sendannounce.c)
490 announce_my_server_names(t);
493 * Send out any LanMan broadcast announcements
494 * of our server names.
495 * (nmbd_sendannounce.c)
498 announce_my_lm_server_names(t);
501 * If we are a local master browser, periodically
502 * announce ourselves to the domain master browser.
503 * This also deals with syncronising the domain master
504 * browser server lists with ourselves as a local
506 * (nmbd_sendannounce.c)
509 announce_myself_to_domain_master_browser(t);
512 * Fullfill any remote announce requests.
513 * (nmbd_sendannounce.c)
519 * Fullfill any remote browse sync announce requests.
520 * (nmbd_sendannounce.c)
523 browse_sync_remote(t);
526 * Scan the broadcast subnets, and WINS client
527 * namelists and refresh any that need refreshing.
534 * Scan the subnet namelists and server lists and
535 * expire thos that have timed out.
539 expire_names_and_servers(t);
542 * Write out a snapshot of our current browse list into
543 * the browse.dat file. This is used by smbd to service
544 * incoming NetServerEnum calls - used to synchronise
545 * browse lists over subnets.
546 * (nmbd_serverlistdb.c)
549 write_browse_list(t, False);
552 * If we are a domain master browser, we have a list of
553 * local master browsers we should synchronise browse
554 * lists with (these are added by an incoming local
555 * master browser announcement packet). Expire any of
556 * these that are no longer current, and pull the server
557 * lists from each of these known local master browsers.
558 * (nmbd_browsesync.c)
561 dmb_expire_and_sync_browser_lists(t);
564 * Check that there is a local master browser for our
565 * workgroup for all our broadcast subnets. If one
566 * is not found, start an election (which we ourselves
567 * may or may not participate in, depending on the
568 * setting of the 'local master' parameter.
572 check_master_browser_exists(t);
575 * If we are configured as a logon server, attempt to
576 * register the special NetBIOS names to become such
577 * (WORKGROUP<1c> name) on all broadcast subnets and
578 * with the WINS server (if used). If we are configured
579 * to become a domain master browser, attempt to register
580 * the special NetBIOS name (WORKGROUP<1b> name) to
582 * (nmbd_become_dmb.c)
588 * If we are a WINS server, do any timer dependent
589 * processing required.
590 * (nmbd_winsserver.c)
593 initiate_wins_processing(t);
596 * If we are a domain master browser, attempt to contact the
597 * WINS server to get a list of all known WORKGROUPS/DOMAINS.
598 * This will only work to a Samba WINS server.
599 * (nmbd_browsesync.c)
602 if (lp_enhanced_browsing())
603 collect_all_workgroup_names_from_wins_server(t);
606 * Go through the response record queue and time out or re-transmit
607 * and expired entries.
611 retransmit_or_expire_response_records(t);
614 * check to see if any remote browse sync child processes have completed
617 sync_check_completion();
620 * regularly sync with any other DMBs we know about
623 if (lp_enhanced_browsing())
627 * clear the unexpected packet queue
633 * Reload the services file if we got a sighup.
636 if(reload_after_sighup) {
637 DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
638 msg_reload_nmbd_services(nmbd_messaging_context(),
639 NULL, MSG_SMB_CONF_UPDATED,
640 procid_self(), NULL);
642 reload_after_sighup = 0;
645 /* check for new network interfaces */
647 reload_interfaces(t);
649 /* free up temp memory */
654 /**************************************************************************** **
655 Open the socket communication.
656 **************************************************************************** */
658 static bool open_sockets(bool isdaemon, int port)
660 struct sockaddr_storage ss;
661 const char *sock_addr = lp_socket_address();
664 * The sockets opened here will be used to receive broadcast
665 * packets *only*. Interface specific sockets are opened in
666 * make_subnet() in namedbsubnet.c. Thus we bind to the
667 * address "0.0.0.0". The parameter 'socket address' is
671 if (!interpret_string_addr(&ss, sock_addr,
672 AI_NUMERICHOST|AI_PASSIVE)) {
673 DEBUG(0,("open_sockets: unable to get socket address "
674 "from string %s", sock_addr));
677 if (ss.ss_family != AF_INET) {
678 DEBUG(0,("open_sockets: unable to use IPv6 socket"
685 ClientNMB = open_socket_in(SOCK_DGRAM, port,
692 if (ClientNMB == -1) {
696 ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
700 if (ClientDGRAM == -1) {
701 if (ClientNMB != 0) {
707 /* we are never interested in SIGPIPE */
708 BlockSignals(True,SIGPIPE);
710 set_socket_options( ClientNMB, "SO_BROADCAST" );
711 set_socket_options( ClientDGRAM, "SO_BROADCAST" );
713 /* Ensure we're non-blocking. */
714 set_blocking( ClientNMB, False);
715 set_blocking( ClientDGRAM, False);
717 DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
721 /**************************************************************************** **
723 **************************************************************************** */
725 int main(int argc, const char *argv[])
727 static bool is_daemon;
728 static bool opt_interactive;
729 static bool Fork = true;
730 static bool no_process_group;
731 static bool log_stdout;
733 char *p_lmhosts = NULL;
739 OPT_NO_PROCESS_GROUP,
742 struct poptOption long_options[] = {
744 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon(default)" },
745 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)" },
746 {"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools & etc)" },
747 {"no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
748 {"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
749 {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 'H', "Load a netbios hosts file"},
750 {"port", 'p', POPT_ARG_INT, &global_nmb_port, NMB_PORT, "Listen on the specified port" },
754 TALLOC_CTX *frame = talloc_stackframe(); /* Setup tos. */
758 global_nmb_port = NMB_PORT;
760 pc = poptGetContext("nmbd", argc, argv, long_options, 0);
761 while ((opt = poptGetNextOpt(pc)) != -1) {
766 case OPT_INTERACTIVE:
767 opt_interactive = true;
772 case OPT_NO_PROCESS_GROUP:
773 no_process_group = true;
779 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
780 poptBadOption(pc, 0), poptStrerror(opt));
781 poptPrintUsage(pc, stderr, 0);
787 global_in_nmbd = true;
789 StartupTime = time(NULL);
791 sys_srandom(time(NULL) ^ sys_getpid());
793 if (!override_logfile) {
795 if (asprintf(&lfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) {
798 lp_set_logfile(lfile);
802 fault_setup((void (*)(void *))fault_continue );
803 dump_core_setup("nmbd");
805 /* POSIX demands that signals are inherited. If the invoking process has
806 * these signals masked, we will have problems, as we won't receive them. */
807 BlockSignals(False, SIGHUP);
808 BlockSignals(False, SIGUSR1);
809 BlockSignals(False, SIGTERM);
811 CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
812 CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
815 /* we are never interested in SIGFPE */
816 BlockSignals(True,SIGFPE);
819 /* We no longer use USR2... */
821 BlockSignals(True, SIGUSR2);
824 if ( opt_interactive ) {
829 if ( log_stdout && Fork ) {
830 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
834 setup_logging( argv[0], log_stdout );
838 DEBUG(0,("nmbd version %s started.\n", samba_version_string()));
839 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
841 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
842 DEBUG(0, ("error opening config file\n"));
846 if (nmbd_messaging_context() == NULL) {
850 if ( !reload_nmbd_services(False) )
856 reload_nmbd_services( True );
858 if (strequal(lp_workgroup(),"*")) {
859 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
865 if (!is_daemon && !is_a_socket(0)) {
866 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
870 if (is_daemon && !opt_interactive) {
871 DEBUG( 2, ( "Becoming a daemon.\n" ) );
872 become_daemon(Fork, no_process_group);
877 * If we're interactive we want to set our own process group for
880 if (opt_interactive && !no_process_group)
881 setpgid( (pid_t)0, (pid_t)0 );
884 if (nmbd_messaging_context() == NULL) {
889 /* Setup the async dns. We do it here so it doesn't have all the other
890 stuff initialised and thus chewing memory and sockets */
891 if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
896 if (!directory_exist(lp_lockdir())) {
897 mkdir(lp_lockdir(), 0755);
900 pidfile_create("nmbd");
902 if (!reinit_after_fork(nmbd_messaging_context(),
903 nmbd_event_context(), false)) {
904 DEBUG(0,("reinit_after_fork() failed\n"));
908 /* get broadcast messages */
909 claim_connection(NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP);
911 messaging_register(nmbd_messaging_context(), NULL,
912 MSG_FORCE_ELECTION, nmbd_message_election);
914 /* Until winsrepl is done. */
915 messaging_register(nmbd_messaging_context(), NULL,
916 MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
918 messaging_register(nmbd_messaging_context(), NULL,
919 MSG_SHUTDOWN, nmbd_terminate);
920 messaging_register(nmbd_messaging_context(), NULL,
921 MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
922 messaging_register(nmbd_messaging_context(), NULL,
923 MSG_SEND_PACKET, msg_nmbd_send_packet);
927 DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
929 if ( !open_sockets( is_daemon, global_nmb_port ) ) {
930 kill_async_dns_child();
934 /* Determine all the IP addresses we have. */
937 /* Create an nmbd subnet record for each of the above. */
938 if( False == create_subnets() ) {
939 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
940 kill_async_dns_child();
944 /* Load in any static local names. */
946 set_dyn_LMHOSTSFILE(p_lmhosts);
948 load_lmhosts_file(get_dyn_LMHOSTSFILE());
949 DEBUG(3,("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE()));
951 /* If we are acting as a WINS server, initialise data structures. */
952 if( !initialise_wins() ) {
953 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
954 kill_async_dns_child();
959 * Register nmbd primary workgroup and nmbd names on all
960 * the broadcast subnets, and on the WINS server (if specified).
961 * Also initiate the startup of our primary workgroup (start
962 * elections if we are setup as being able to be a local
966 if( False == register_my_workgroup_and_names() ) {
967 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
968 kill_async_dns_child();
977 kill_async_dns_child();