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/>.
23 #include "system/filesys.h"
24 #include "popt_common.h"
25 #include "nmbd/nmbd.h"
31 int global_nmb_port = -1;
33 extern bool rescan_listen_set;
34 extern bool global_in_nmbd;
36 extern bool override_logfile;
38 /* have we found LanMan clients yet? */
39 bool found_lm_clients = False;
41 /* what server type are we currently */
43 time_t StartupTime = 0;
45 struct event_context *nmbd_event_context(void)
47 return server_event_context();
50 /**************************************************************************** **
51 Handle a SIGTERM in band.
52 **************************************************************************** */
54 static void terminate(struct messaging_context *msg)
56 DEBUG(0,("Got SIGTERM: going down...\n"));
58 /* Write out wins.dat file if samba is a WINS server */
59 wins_write_database(0,False);
61 /* Remove all SELF registered names from WINS */
64 /* Announce all server entries as 0 time-to-live, 0 type. */
65 announce_my_servers_removed();
67 /* If there was an async dns child - kill it. */
68 kill_async_dns_child();
71 serverid_deregister(messaging_server_id(msg));
78 static void nmbd_sig_term_handler(struct tevent_context *ev,
79 struct tevent_signal *se,
85 struct messaging_context *msg = talloc_get_type_abort(
86 private_data, struct messaging_context);
91 static bool nmbd_setup_sig_term_handler(struct messaging_context *msg)
93 struct tevent_signal *se;
95 se = tevent_add_signal(nmbd_event_context(),
98 nmbd_sig_term_handler,
101 DEBUG(0,("failed to setup SIGTERM handler"));
108 static void msg_reload_nmbd_services(struct messaging_context *msg,
111 struct server_id server_id,
114 static void nmbd_sig_hup_handler(struct tevent_context *ev,
115 struct tevent_signal *se,
121 struct messaging_context *msg = talloc_get_type_abort(
122 private_data, struct messaging_context);
124 DEBUG(0,("Got SIGHUP dumping debug info.\n"));
125 msg_reload_nmbd_services(msg, NULL, MSG_SMB_CONF_UPDATED,
126 messaging_server_id(msg), NULL);
129 static bool nmbd_setup_sig_hup_handler(struct messaging_context *msg)
131 struct tevent_signal *se;
133 se = tevent_add_signal(nmbd_event_context(),
134 nmbd_event_context(),
136 nmbd_sig_hup_handler,
139 DEBUG(0,("failed to setup SIGHUP handler"));
146 /**************************************************************************** **
147 Handle a SHUTDOWN message from smbcontrol.
148 **************************************************************************** */
150 static void nmbd_terminate(struct messaging_context *msg,
153 struct server_id server_id,
159 /**************************************************************************** **
160 Expire old names from the namelist and server list.
161 **************************************************************************** */
163 static void expire_names_and_servers(time_t t)
165 static time_t lastrun = 0;
169 if ( t < (lastrun + 5) )
174 * Expire any timed out names on all the broadcast
175 * subnets and those registered with the WINS server.
176 * (nmbd_namelistdb.c)
182 * Go through all the broadcast subnets and for each
183 * workgroup known on that subnet remove any expired
184 * server names. If a workgroup has an empty serverlist
185 * and has itself timed out then remove the workgroup.
186 * (nmbd_workgroupdb.c)
189 expire_workgroups_and_servers(t);
192 /************************************************************************** **
193 Reload the list of network interfaces.
194 Doesn't return until a network interface is up.
195 ************************************************************************** */
197 static void reload_interfaces(time_t t)
201 bool print_waiting_msg = true;
202 struct subnet_record *subrec;
204 if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
210 if (!interfaces_changed()) {
216 /* the list of probed interfaces has changed, we may need to add/remove
220 /* find any interfaces that need adding */
221 for (n=iface_count() - 1; n >= 0; n--) {
222 char str[INET6_ADDRSTRLEN];
223 const struct interface *iface = get_interface(n);
224 struct in_addr ip, nmask;
227 DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
231 /* Ensure we're only dealing with IPv4 here. */
232 if (iface->ip.ss_family != AF_INET) {
233 DEBUG(2,("reload_interfaces: "
234 "ignoring non IPv4 interface.\n"));
238 ip = ((const struct sockaddr_in *)(const void *)&iface->ip)->sin_addr;
239 nmask = ((const struct sockaddr_in *)(const void *)
240 &iface->netmask)->sin_addr;
243 * We don't want to add a loopback interface, in case
244 * someone has added 127.0.0.1 for smbd, nmbd needs to
245 * ignore it here. JRA.
248 if (is_loopback_addr((const struct sockaddr *)(const void *)&iface->ip)) {
249 DEBUG(2,("reload_interfaces: Ignoring loopback "
251 print_sockaddr(str, sizeof(str), &iface->ip) ));
255 for (subrec=subnetlist; subrec; subrec=subrec->next) {
256 if (ip_equal_v4(ip, subrec->myip) &&
257 ip_equal_v4(nmask, subrec->mask_ip)) {
263 /* it wasn't found! add it */
264 DEBUG(2,("Found new interface %s\n",
266 sizeof(str), &iface->ip) ));
267 subrec = make_normal_subnet(iface);
269 register_my_workgroup_one_subnet(subrec);
273 /* find any interfaces that need deleting */
274 for (subrec=subnetlist; subrec; subrec=subrec->next) {
275 for (n=iface_count() - 1; n >= 0; n--) {
276 struct interface *iface = get_interface(n);
277 struct in_addr ip, nmask;
281 /* Ensure we're only dealing with IPv4 here. */
282 if (iface->ip.ss_family != AF_INET) {
283 DEBUG(2,("reload_interfaces: "
284 "ignoring non IPv4 interface.\n"));
287 ip = ((struct sockaddr_in *)(void *)
288 &iface->ip)->sin_addr;
289 nmask = ((struct sockaddr_in *)(void *)
290 &iface->netmask)->sin_addr;
291 if (ip_equal_v4(ip, subrec->myip) &&
292 ip_equal_v4(nmask, subrec->mask_ip)) {
297 /* oops, an interface has disapeared. This is
298 tricky, we don't dare actually free the
299 interface as it could be being used, so
300 instead we just wear the memory leak and
301 remove it from the list of interfaces without
303 DEBUG(2,("Deleting dead interface %s\n",
304 inet_ntoa(subrec->myip)));
305 close_subnet(subrec);
309 rescan_listen_set = True;
311 /* We need to wait if there are no subnets... */
312 if (FIRST_SUBNET == NULL) {
313 void (*saved_handler)(int);
315 if (print_waiting_msg) {
316 DEBUG(0,("reload_interfaces: "
317 "No subnets to listen to. Waiting..\n"));
318 print_waiting_msg = false;
322 * Whilst we're waiting for an interface, allow SIGTERM to
325 saved_handler = CatchSignal(SIGTERM, SIG_DFL);
327 /* We only count IPv4, non-loopback interfaces here. */
328 while (iface_count_v4_nl() == 0) {
333 CatchSignal(SIGTERM, saved_handler);
336 * We got an interface, go back to blocking term.
343 /**************************************************************************** **
344 Reload the services file.
345 **************************************************************************** */
347 static bool reload_nmbd_services(bool test)
351 set_remote_machine_name("nmbd", False);
354 const char *fname = lp_configfile();
355 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
356 set_dyn_CONFIGFILE(fname);
361 if ( test && !lp_file_list_changed() )
364 ret = lp_load_global(get_dyn_CONFIGFILE());
366 /* perhaps the config filename is now set */
368 DEBUG( 3, ( "services not loaded\n" ) );
369 reload_nmbd_services( True );
375 /**************************************************************************** **
376 * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
377 **************************************************************************** */
379 static void msg_reload_nmbd_services(struct messaging_context *msg,
382 struct server_id server_id,
385 write_browse_list( 0, True );
386 dump_all_namelists();
387 reload_nmbd_services( True );
389 reload_interfaces(0);
392 static void msg_nmbd_send_packet(struct messaging_context *msg,
395 struct server_id src,
398 struct packet_struct *p = (struct packet_struct *)data->data;
399 struct subnet_record *subrec;
400 struct sockaddr_storage ss;
401 const struct sockaddr_storage *pss;
402 const struct in_addr *local_ip;
404 DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src)));
406 if (data->length != sizeof(struct packet_struct)) {
407 DEBUG(2, ("Discarding invalid packet length from %u\n",
408 (unsigned int)procid_to_pid(&src)));
412 if ((p->packet_type != NMB_PACKET) &&
413 (p->packet_type != DGRAM_PACKET)) {
414 DEBUG(2, ("Discarding invalid packet type from %u: %d\n",
415 (unsigned int)procid_to_pid(&src), p->packet_type));
419 in_addr_to_sockaddr_storage(&ss, p->ip);
420 pss = iface_ip((struct sockaddr *)(void *)&ss);
423 DEBUG(2, ("Could not find ip for packet from %u\n",
424 (unsigned int)procid_to_pid(&src)));
428 local_ip = &((const struct sockaddr_in *)pss)->sin_addr;
429 subrec = FIRST_SUBNET;
432 p->send_fd = (p->packet_type == NMB_PACKET) ?
433 subrec->nmb_sock : subrec->dgram_sock;
435 for (subrec = FIRST_SUBNET; subrec != NULL;
436 subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
437 if (ip_equal_v4(*local_ip, subrec->myip)) {
438 p->send_fd = (p->packet_type == NMB_PACKET) ?
439 subrec->nmb_sock : subrec->dgram_sock;
444 if (p->packet_type == DGRAM_PACKET) {
446 p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
447 p->packet.dgram.header.source_port = 138;
453 /**************************************************************************** **
454 The main select loop.
455 **************************************************************************** */
457 static void process(struct messaging_context *msg)
462 time_t t = time(NULL);
463 TALLOC_CTX *frame = talloc_stackframe();
466 * Check all broadcast subnets to see if
467 * we need to run an election on any of them.
471 run_election = check_elections();
474 * Read incoming UDP packets.
478 if (listen_for_packets(msg, run_election)) {
484 * Process all incoming packets
485 * read above. This calls the success and
486 * failure functions registered when response
487 * packets arrrive, and also deals with request
488 * packets from other sources.
495 * Run any elections - initiate becoming
496 * a local master browser if we have won.
503 * Send out any broadcast announcements
504 * of our server names. This also announces
505 * the workgroup name if we are a local
507 * (nmbd_sendannounce.c)
510 announce_my_server_names(t);
513 * Send out any LanMan broadcast announcements
514 * of our server names.
515 * (nmbd_sendannounce.c)
518 announce_my_lm_server_names(t);
521 * If we are a local master browser, periodically
522 * announce ourselves to the domain master browser.
523 * This also deals with syncronising the domain master
524 * browser server lists with ourselves as a local
526 * (nmbd_sendannounce.c)
529 announce_myself_to_domain_master_browser(t);
532 * Fullfill any remote announce requests.
533 * (nmbd_sendannounce.c)
539 * Fullfill any remote browse sync announce requests.
540 * (nmbd_sendannounce.c)
543 browse_sync_remote(t);
546 * Scan the broadcast subnets, and WINS client
547 * namelists and refresh any that need refreshing.
554 * Scan the subnet namelists and server lists and
555 * expire thos that have timed out.
559 expire_names_and_servers(t);
562 * Write out a snapshot of our current browse list into
563 * the browse.dat file. This is used by smbd to service
564 * incoming NetServerEnum calls - used to synchronise
565 * browse lists over subnets.
566 * (nmbd_serverlistdb.c)
569 write_browse_list(t, False);
572 * If we are a domain master browser, we have a list of
573 * local master browsers we should synchronise browse
574 * lists with (these are added by an incoming local
575 * master browser announcement packet). Expire any of
576 * these that are no longer current, and pull the server
577 * lists from each of these known local master browsers.
578 * (nmbd_browsesync.c)
581 dmb_expire_and_sync_browser_lists(t);
584 * Check that there is a local master browser for our
585 * workgroup for all our broadcast subnets. If one
586 * is not found, start an election (which we ourselves
587 * may or may not participate in, depending on the
588 * setting of the 'local master' parameter.
592 check_master_browser_exists(t);
595 * If we are configured as a logon server, attempt to
596 * register the special NetBIOS names to become such
597 * (WORKGROUP<1c> name) on all broadcast subnets and
598 * with the WINS server (if used). If we are configured
599 * to become a domain master browser, attempt to register
600 * the special NetBIOS name (WORKGROUP<1b> name) to
602 * (nmbd_become_dmb.c)
608 * If we are a WINS server, do any timer dependent
609 * processing required.
610 * (nmbd_winsserver.c)
613 initiate_wins_processing(t);
616 * If we are a domain master browser, attempt to contact the
617 * WINS server to get a list of all known WORKGROUPS/DOMAINS.
618 * This will only work to a Samba WINS server.
619 * (nmbd_browsesync.c)
622 if (lp_enhanced_browsing())
623 collect_all_workgroup_names_from_wins_server(t);
626 * Go through the response record queue and time out or re-transmit
627 * and expired entries.
631 retransmit_or_expire_response_records(t);
634 * check to see if any remote browse sync child processes have completed
637 sync_check_completion();
640 * regularly sync with any other DMBs we know about
643 if (lp_enhanced_browsing())
646 /* check for new network interfaces */
648 reload_interfaces(t);
650 /* free up temp memory */
655 /**************************************************************************** **
656 Open the socket communication.
657 **************************************************************************** */
659 static bool open_sockets(bool isdaemon, int port)
661 struct sockaddr_storage ss;
662 const char *sock_addr = lp_socket_address();
665 * The sockets opened here will be used to receive broadcast
666 * packets *only*. Interface specific sockets are opened in
667 * make_subnet() in namedbsubnet.c. Thus we bind to the
668 * address "0.0.0.0". The parameter 'socket address' is
672 if (!interpret_string_addr(&ss, sock_addr,
673 AI_NUMERICHOST|AI_PASSIVE)) {
674 DEBUG(0,("open_sockets: unable to get socket address "
675 "from string %s", sock_addr));
678 if (ss.ss_family != AF_INET) {
679 DEBUG(0,("open_sockets: unable to use IPv6 socket"
686 ClientNMB = open_socket_in(SOCK_DGRAM, port,
693 if (ClientNMB == -1) {
697 ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
701 if (ClientDGRAM == -1) {
702 if (ClientNMB != 0) {
708 /* we are never interested in SIGPIPE */
709 BlockSignals(True,SIGPIPE);
711 set_socket_options( ClientNMB, "SO_BROADCAST" );
712 set_socket_options( ClientDGRAM, "SO_BROADCAST" );
714 /* Ensure we're non-blocking. */
715 set_blocking( ClientNMB, False);
716 set_blocking( ClientDGRAM, False);
718 DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
722 /**************************************************************************** **
724 **************************************************************************** */
726 int main(int argc, const char *argv[])
729 bool opt_interactive;
731 bool no_process_group;
734 char *p_lmhosts = NULL;
736 struct messaging_context *msg;
741 OPT_NO_PROCESS_GROUP,
744 struct poptOption long_options[] = {
746 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon(default)" },
747 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)" },
748 {"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools & etc)" },
749 {"no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
750 {"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
751 {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 0, "Load a netbios hosts file"},
752 {"port", 'p', POPT_ARG_INT, &global_nmb_port, 0, "Listen on the specified port" },
760 * Do this before any other talloc operation
762 talloc_enable_null_tracking();
763 frame = talloc_stackframe();
765 setup_logging(argv[0], DEBUG_DEFAULT_STDOUT);
769 global_nmb_port = NMB_PORT;
771 pc = poptGetContext("nmbd", argc, argv, long_options, 0);
772 while ((opt = poptGetNextOpt(pc)) != -1) {
777 case OPT_INTERACTIVE:
778 opt_interactive = true;
783 case OPT_NO_PROCESS_GROUP:
784 no_process_group = true;
790 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
791 poptBadOption(pc, 0), poptStrerror(opt));
792 poptPrintUsage(pc, stderr, 0);
798 global_in_nmbd = true;
800 StartupTime = time(NULL);
802 sys_srandom(time(NULL) ^ sys_getpid());
804 if (!override_logfile) {
806 if (asprintf(&lfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) {
809 lp_set_logfile(lfile);
814 dump_core_setup("nmbd", lp_logfile());
816 /* POSIX demands that signals are inherited. If the invoking process has
817 * these signals masked, we will have problems, as we won't receive them. */
818 BlockSignals(False, SIGHUP);
819 BlockSignals(False, SIGUSR1);
820 BlockSignals(False, SIGTERM);
823 /* we are never interested in SIGFPE */
824 BlockSignals(True,SIGFPE);
827 /* We no longer use USR2... */
829 BlockSignals(True, SIGUSR2);
832 if ( opt_interactive ) {
837 if ( log_stdout && Fork ) {
838 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
843 setup_logging(argv[0], DEBUG_STDOUT);
845 setup_logging( argv[0], DEBUG_FILE);
850 DEBUG(0,("nmbd version %s started.\n", samba_version_string()));
851 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
853 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
854 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
858 msg = messaging_init(NULL, server_event_context());
863 if ( !reload_nmbd_services(False) )
869 reload_nmbd_services( True );
871 if (strequal(lp_workgroup(),"*")) {
872 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
878 if (!is_daemon && !is_a_socket(0)) {
879 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
883 if (is_daemon && !opt_interactive) {
884 DEBUG( 2, ( "Becoming a daemon.\n" ) );
885 become_daemon(Fork, no_process_group, log_stdout);
890 * If we're interactive we want to set our own process group for
893 if (opt_interactive && !no_process_group)
894 setpgid( (pid_t)0, (pid_t)0 );
898 /* Setup the async dns. We do it here so it doesn't have all the other
899 stuff initialised and thus chewing memory and sockets */
900 if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
901 start_async_dns(msg);
905 if (!directory_exist(lp_lockdir())) {
906 mkdir(lp_lockdir(), 0755);
909 pidfile_create("nmbd");
911 status = reinit_after_fork(msg, nmbd_event_context(),
914 if (!NT_STATUS_IS_OK(status)) {
915 DEBUG(0,("reinit_after_fork() failed\n"));
919 if (!nmbd_setup_sig_term_handler(msg))
921 if (!nmbd_setup_sig_hup_handler(msg))
924 /* get broadcast messages */
926 if (!serverid_register(procid_self(),
930 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
934 messaging_register(msg, NULL, MSG_FORCE_ELECTION,
935 nmbd_message_election);
937 /* Until winsrepl is done. */
938 messaging_register(msg, NULL, MSG_WINS_NEW_ENTRY,
939 nmbd_wins_new_entry);
941 messaging_register(msg, NULL, MSG_SHUTDOWN,
943 messaging_register(msg, NULL, MSG_SMB_CONF_UPDATED,
944 msg_reload_nmbd_services);
945 messaging_register(msg, NULL, MSG_SEND_PACKET,
946 msg_nmbd_send_packet);
950 DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
952 if ( !open_sockets( is_daemon, global_nmb_port ) ) {
953 kill_async_dns_child();
957 /* Determine all the IP addresses we have. */
960 /* Create an nmbd subnet record for each of the above. */
961 if( False == create_subnets() ) {
962 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
963 kill_async_dns_child();
967 /* Load in any static local names. */
969 set_dyn_LMHOSTSFILE(p_lmhosts);
971 load_lmhosts_file(get_dyn_LMHOSTSFILE());
972 DEBUG(3,("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE()));
974 /* If we are acting as a WINS server, initialise data structures. */
975 if( !initialise_wins() ) {
976 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
977 kill_async_dns_child();
982 * Register nmbd primary workgroup and nmbd names on all
983 * the broadcast subnets, and on the WINS server (if specified).
984 * Also initiate the startup of our primary workgroup (start
985 * elections if we are setup as being able to be a local
989 if( False == register_my_workgroup_and_names() ) {
990 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
991 kill_async_dns_child();
995 if (!initialize_nmbd_proxy_logon()) {
996 DEBUG(0,("ERROR: Failed setup nmbd_proxy_logon.\n"));
997 kill_async_dns_child();
1001 if (!nmbd_init_packet_server()) {
1002 kill_async_dns_child();
1009 kill_async_dns_child();