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 static struct messaging_context *nmbd_messaging_context(void)
52 struct messaging_context *msg_ctx = server_messaging_context();
53 if (likely(msg_ctx != NULL)) {
56 smb_panic("Could not init nmbd's messaging context.\n");
60 /**************************************************************************** **
61 Handle a SIGTERM in band.
62 **************************************************************************** */
64 static void terminate(struct messaging_context *msg)
66 DEBUG(0,("Got SIGTERM: going down...\n"));
68 /* Write out wins.dat file if samba is a WINS server */
69 wins_write_database(0,False);
71 /* Remove all SELF registered names from WINS */
74 /* Announce all server entries as 0 time-to-live, 0 type. */
75 announce_my_servers_removed();
77 /* If there was an async dns child - kill it. */
78 kill_async_dns_child();
81 serverid_deregister(messaging_server_id(msg));
88 static void nmbd_sig_term_handler(struct tevent_context *ev,
89 struct tevent_signal *se,
95 struct messaging_context *msg = talloc_get_type_abort(
96 private_data, struct messaging_context);
101 static bool nmbd_setup_sig_term_handler(struct messaging_context *msg)
103 struct tevent_signal *se;
105 se = tevent_add_signal(nmbd_event_context(),
106 nmbd_event_context(),
108 nmbd_sig_term_handler,
111 DEBUG(0,("failed to setup SIGTERM handler"));
118 static void msg_reload_nmbd_services(struct messaging_context *msg,
121 struct server_id server_id,
124 static void nmbd_sig_hup_handler(struct tevent_context *ev,
125 struct tevent_signal *se,
131 DEBUG(0,("Got SIGHUP dumping debug info.\n"));
132 msg_reload_nmbd_services(nmbd_messaging_context(),
133 NULL, MSG_SMB_CONF_UPDATED,
134 procid_self(), NULL);
137 static bool nmbd_setup_sig_hup_handler(void)
139 struct tevent_signal *se;
141 se = tevent_add_signal(nmbd_event_context(),
142 nmbd_event_context(),
144 nmbd_sig_hup_handler,
147 DEBUG(0,("failed to setup SIGHUP handler"));
154 /**************************************************************************** **
155 Handle a SHUTDOWN message from smbcontrol.
156 **************************************************************************** */
158 static void nmbd_terminate(struct messaging_context *msg,
161 struct server_id server_id,
167 /**************************************************************************** **
168 Expire old names from the namelist and server list.
169 **************************************************************************** */
171 static void expire_names_and_servers(time_t t)
173 static time_t lastrun = 0;
177 if ( t < (lastrun + 5) )
182 * Expire any timed out names on all the broadcast
183 * subnets and those registered with the WINS server.
184 * (nmbd_namelistdb.c)
190 * Go through all the broadcast subnets and for each
191 * workgroup known on that subnet remove any expired
192 * server names. If a workgroup has an empty serverlist
193 * and has itself timed out then remove the workgroup.
194 * (nmbd_workgroupdb.c)
197 expire_workgroups_and_servers(t);
200 /************************************************************************** **
201 Reload the list of network interfaces.
202 Doesn't return until a network interface is up.
203 ************************************************************************** */
205 static void reload_interfaces(time_t t)
209 bool print_waiting_msg = true;
210 struct subnet_record *subrec;
212 if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
218 if (!interfaces_changed()) {
224 /* the list of probed interfaces has changed, we may need to add/remove
228 /* find any interfaces that need adding */
229 for (n=iface_count() - 1; n >= 0; n--) {
230 char str[INET6_ADDRSTRLEN];
231 const struct interface *iface = get_interface(n);
232 struct in_addr ip, nmask;
235 DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
239 /* Ensure we're only dealing with IPv4 here. */
240 if (iface->ip.ss_family != AF_INET) {
241 DEBUG(2,("reload_interfaces: "
242 "ignoring non IPv4 interface.\n"));
246 ip = ((const struct sockaddr_in *)(const void *)&iface->ip)->sin_addr;
247 nmask = ((const struct sockaddr_in *)(const void *)
248 &iface->netmask)->sin_addr;
251 * We don't want to add a loopback interface, in case
252 * someone has added 127.0.0.1 for smbd, nmbd needs to
253 * ignore it here. JRA.
256 if (is_loopback_addr((const struct sockaddr *)(const void *)&iface->ip)) {
257 DEBUG(2,("reload_interfaces: Ignoring loopback "
259 print_sockaddr(str, sizeof(str), &iface->ip) ));
263 for (subrec=subnetlist; subrec; subrec=subrec->next) {
264 if (ip_equal_v4(ip, subrec->myip) &&
265 ip_equal_v4(nmask, subrec->mask_ip)) {
271 /* it wasn't found! add it */
272 DEBUG(2,("Found new interface %s\n",
274 sizeof(str), &iface->ip) ));
275 subrec = make_normal_subnet(iface);
277 register_my_workgroup_one_subnet(subrec);
281 /* find any interfaces that need deleting */
282 for (subrec=subnetlist; subrec; subrec=subrec->next) {
283 for (n=iface_count() - 1; n >= 0; n--) {
284 struct interface *iface = get_interface(n);
285 struct in_addr ip, nmask;
289 /* Ensure we're only dealing with IPv4 here. */
290 if (iface->ip.ss_family != AF_INET) {
291 DEBUG(2,("reload_interfaces: "
292 "ignoring non IPv4 interface.\n"));
295 ip = ((struct sockaddr_in *)(void *)
296 &iface->ip)->sin_addr;
297 nmask = ((struct sockaddr_in *)(void *)
298 &iface->netmask)->sin_addr;
299 if (ip_equal_v4(ip, subrec->myip) &&
300 ip_equal_v4(nmask, subrec->mask_ip)) {
305 /* oops, an interface has disapeared. This is
306 tricky, we don't dare actually free the
307 interface as it could be being used, so
308 instead we just wear the memory leak and
309 remove it from the list of interfaces without
311 DEBUG(2,("Deleting dead interface %s\n",
312 inet_ntoa(subrec->myip)));
313 close_subnet(subrec);
317 rescan_listen_set = True;
319 /* We need to wait if there are no subnets... */
320 if (FIRST_SUBNET == NULL) {
321 void (*saved_handler)(int);
323 if (print_waiting_msg) {
324 DEBUG(0,("reload_interfaces: "
325 "No subnets to listen to. Waiting..\n"));
326 print_waiting_msg = false;
330 * Whilst we're waiting for an interface, allow SIGTERM to
333 saved_handler = CatchSignal(SIGTERM, SIG_DFL);
335 /* We only count IPv4, non-loopback interfaces here. */
336 while (iface_count_v4_nl() == 0) {
341 CatchSignal(SIGTERM, saved_handler);
344 * We got an interface, go back to blocking term.
351 /**************************************************************************** **
352 Reload the services file.
353 **************************************************************************** */
355 static bool reload_nmbd_services(bool test)
359 set_remote_machine_name("nmbd", False);
362 const char *fname = lp_configfile();
363 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
364 set_dyn_CONFIGFILE(fname);
369 if ( test && !lp_file_list_changed() )
372 ret = lp_load_global(get_dyn_CONFIGFILE());
374 /* perhaps the config filename is now set */
376 DEBUG( 3, ( "services not loaded\n" ) );
377 reload_nmbd_services( True );
383 /**************************************************************************** **
384 * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
385 **************************************************************************** */
387 static void msg_reload_nmbd_services(struct messaging_context *msg,
390 struct server_id server_id,
393 write_browse_list( 0, True );
394 dump_all_namelists();
395 reload_nmbd_services( True );
397 reload_interfaces(0);
400 static void msg_nmbd_send_packet(struct messaging_context *msg,
403 struct server_id src,
406 struct packet_struct *p = (struct packet_struct *)data->data;
407 struct subnet_record *subrec;
408 struct sockaddr_storage ss;
409 const struct sockaddr_storage *pss;
410 const struct in_addr *local_ip;
412 DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src)));
414 if (data->length != sizeof(struct packet_struct)) {
415 DEBUG(2, ("Discarding invalid packet length from %u\n",
416 (unsigned int)procid_to_pid(&src)));
420 if ((p->packet_type != NMB_PACKET) &&
421 (p->packet_type != DGRAM_PACKET)) {
422 DEBUG(2, ("Discarding invalid packet type from %u: %d\n",
423 (unsigned int)procid_to_pid(&src), p->packet_type));
427 in_addr_to_sockaddr_storage(&ss, p->ip);
428 pss = iface_ip((struct sockaddr *)(void *)&ss);
431 DEBUG(2, ("Could not find ip for packet from %u\n",
432 (unsigned int)procid_to_pid(&src)));
436 local_ip = &((const struct sockaddr_in *)pss)->sin_addr;
437 subrec = FIRST_SUBNET;
440 p->send_fd = (p->packet_type == NMB_PACKET) ?
441 subrec->nmb_sock : subrec->dgram_sock;
443 for (subrec = FIRST_SUBNET; subrec != NULL;
444 subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
445 if (ip_equal_v4(*local_ip, subrec->myip)) {
446 p->send_fd = (p->packet_type == NMB_PACKET) ?
447 subrec->nmb_sock : subrec->dgram_sock;
452 if (p->packet_type == DGRAM_PACKET) {
454 p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
455 p->packet.dgram.header.source_port = 138;
461 /**************************************************************************** **
462 The main select loop.
463 **************************************************************************** */
465 static void process(struct messaging_context *msg)
470 time_t t = time(NULL);
471 TALLOC_CTX *frame = talloc_stackframe();
474 * Check all broadcast subnets to see if
475 * we need to run an election on any of them.
479 run_election = check_elections();
482 * Read incoming UDP packets.
486 if (listen_for_packets(msg, run_election)) {
492 * Process all incoming packets
493 * read above. This calls the success and
494 * failure functions registered when response
495 * packets arrrive, and also deals with request
496 * packets from other sources.
503 * Run any elections - initiate becoming
504 * a local master browser if we have won.
511 * Send out any broadcast announcements
512 * of our server names. This also announces
513 * the workgroup name if we are a local
515 * (nmbd_sendannounce.c)
518 announce_my_server_names(t);
521 * Send out any LanMan broadcast announcements
522 * of our server names.
523 * (nmbd_sendannounce.c)
526 announce_my_lm_server_names(t);
529 * If we are a local master browser, periodically
530 * announce ourselves to the domain master browser.
531 * This also deals with syncronising the domain master
532 * browser server lists with ourselves as a local
534 * (nmbd_sendannounce.c)
537 announce_myself_to_domain_master_browser(t);
540 * Fullfill any remote announce requests.
541 * (nmbd_sendannounce.c)
547 * Fullfill any remote browse sync announce requests.
548 * (nmbd_sendannounce.c)
551 browse_sync_remote(t);
554 * Scan the broadcast subnets, and WINS client
555 * namelists and refresh any that need refreshing.
562 * Scan the subnet namelists and server lists and
563 * expire thos that have timed out.
567 expire_names_and_servers(t);
570 * Write out a snapshot of our current browse list into
571 * the browse.dat file. This is used by smbd to service
572 * incoming NetServerEnum calls - used to synchronise
573 * browse lists over subnets.
574 * (nmbd_serverlistdb.c)
577 write_browse_list(t, False);
580 * If we are a domain master browser, we have a list of
581 * local master browsers we should synchronise browse
582 * lists with (these are added by an incoming local
583 * master browser announcement packet). Expire any of
584 * these that are no longer current, and pull the server
585 * lists from each of these known local master browsers.
586 * (nmbd_browsesync.c)
589 dmb_expire_and_sync_browser_lists(t);
592 * Check that there is a local master browser for our
593 * workgroup for all our broadcast subnets. If one
594 * is not found, start an election (which we ourselves
595 * may or may not participate in, depending on the
596 * setting of the 'local master' parameter.
600 check_master_browser_exists(t);
603 * If we are configured as a logon server, attempt to
604 * register the special NetBIOS names to become such
605 * (WORKGROUP<1c> name) on all broadcast subnets and
606 * with the WINS server (if used). If we are configured
607 * to become a domain master browser, attempt to register
608 * the special NetBIOS name (WORKGROUP<1b> name) to
610 * (nmbd_become_dmb.c)
616 * If we are a WINS server, do any timer dependent
617 * processing required.
618 * (nmbd_winsserver.c)
621 initiate_wins_processing(t);
624 * If we are a domain master browser, attempt to contact the
625 * WINS server to get a list of all known WORKGROUPS/DOMAINS.
626 * This will only work to a Samba WINS server.
627 * (nmbd_browsesync.c)
630 if (lp_enhanced_browsing())
631 collect_all_workgroup_names_from_wins_server(t);
634 * Go through the response record queue and time out or re-transmit
635 * and expired entries.
639 retransmit_or_expire_response_records(t);
642 * check to see if any remote browse sync child processes have completed
645 sync_check_completion();
648 * regularly sync with any other DMBs we know about
651 if (lp_enhanced_browsing())
654 /* check for new network interfaces */
656 reload_interfaces(t);
658 /* free up temp memory */
663 /**************************************************************************** **
664 Open the socket communication.
665 **************************************************************************** */
667 static bool open_sockets(bool isdaemon, int port)
669 struct sockaddr_storage ss;
670 const char *sock_addr = lp_socket_address();
673 * The sockets opened here will be used to receive broadcast
674 * packets *only*. Interface specific sockets are opened in
675 * make_subnet() in namedbsubnet.c. Thus we bind to the
676 * address "0.0.0.0". The parameter 'socket address' is
680 if (!interpret_string_addr(&ss, sock_addr,
681 AI_NUMERICHOST|AI_PASSIVE)) {
682 DEBUG(0,("open_sockets: unable to get socket address "
683 "from string %s", sock_addr));
686 if (ss.ss_family != AF_INET) {
687 DEBUG(0,("open_sockets: unable to use IPv6 socket"
694 ClientNMB = open_socket_in(SOCK_DGRAM, port,
701 if (ClientNMB == -1) {
705 ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
709 if (ClientDGRAM == -1) {
710 if (ClientNMB != 0) {
716 /* we are never interested in SIGPIPE */
717 BlockSignals(True,SIGPIPE);
719 set_socket_options( ClientNMB, "SO_BROADCAST" );
720 set_socket_options( ClientDGRAM, "SO_BROADCAST" );
722 /* Ensure we're non-blocking. */
723 set_blocking( ClientNMB, False);
724 set_blocking( ClientDGRAM, False);
726 DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
730 /**************************************************************************** **
732 **************************************************************************** */
734 int main(int argc, const char *argv[])
736 static bool is_daemon;
737 static bool opt_interactive;
738 static bool Fork = true;
739 static bool no_process_group;
740 static bool log_stdout;
742 char *p_lmhosts = NULL;
748 OPT_NO_PROCESS_GROUP,
751 struct poptOption long_options[] = {
753 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon(default)" },
754 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)" },
755 {"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools & etc)" },
756 {"no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
757 {"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
758 {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 0, "Load a netbios hosts file"},
759 {"port", 'p', POPT_ARG_INT, &global_nmb_port, 0, "Listen on the specified port" },
767 * Do this before any other talloc operation
769 talloc_enable_null_tracking();
770 frame = talloc_stackframe();
772 setup_logging(argv[0], DEBUG_DEFAULT_STDOUT);
776 global_nmb_port = NMB_PORT;
778 pc = poptGetContext("nmbd", argc, argv, long_options, 0);
779 while ((opt = poptGetNextOpt(pc)) != -1) {
784 case OPT_INTERACTIVE:
785 opt_interactive = true;
790 case OPT_NO_PROCESS_GROUP:
791 no_process_group = true;
797 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
798 poptBadOption(pc, 0), poptStrerror(opt));
799 poptPrintUsage(pc, stderr, 0);
805 global_in_nmbd = true;
807 StartupTime = time(NULL);
809 sys_srandom(time(NULL) ^ sys_getpid());
811 if (!override_logfile) {
813 if (asprintf(&lfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) {
816 lp_set_logfile(lfile);
821 dump_core_setup("nmbd", lp_logfile());
823 /* POSIX demands that signals are inherited. If the invoking process has
824 * these signals masked, we will have problems, as we won't receive them. */
825 BlockSignals(False, SIGHUP);
826 BlockSignals(False, SIGUSR1);
827 BlockSignals(False, SIGTERM);
830 /* we are never interested in SIGFPE */
831 BlockSignals(True,SIGFPE);
834 /* We no longer use USR2... */
836 BlockSignals(True, SIGUSR2);
839 if ( opt_interactive ) {
844 if ( log_stdout && Fork ) {
845 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
850 setup_logging(argv[0], DEBUG_STDOUT);
852 setup_logging( argv[0], DEBUG_FILE);
857 DEBUG(0,("nmbd version %s started.\n", samba_version_string()));
858 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
860 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
861 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
865 if (nmbd_messaging_context() == NULL) {
869 if ( !reload_nmbd_services(False) )
875 reload_nmbd_services( True );
877 if (strequal(lp_workgroup(),"*")) {
878 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
884 if (!is_daemon && !is_a_socket(0)) {
885 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
889 if (is_daemon && !opt_interactive) {
890 DEBUG( 2, ( "Becoming a daemon.\n" ) );
891 become_daemon(Fork, no_process_group, log_stdout);
896 * If we're interactive we want to set our own process group for
899 if (opt_interactive && !no_process_group)
900 setpgid( (pid_t)0, (pid_t)0 );
903 if (nmbd_messaging_context() == NULL) {
908 /* Setup the async dns. We do it here so it doesn't have all the other
909 stuff initialised and thus chewing memory and sockets */
910 if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
911 start_async_dns(nmbd_messaging_context());
915 if (!directory_exist(lp_lockdir())) {
916 mkdir(lp_lockdir(), 0755);
919 pidfile_create("nmbd");
921 status = reinit_after_fork(nmbd_messaging_context(),
922 nmbd_event_context(),
925 if (!NT_STATUS_IS_OK(status)) {
926 DEBUG(0,("reinit_after_fork() failed\n"));
930 if (!nmbd_setup_sig_term_handler(nmbd_messaging_context()))
932 if (!nmbd_setup_sig_hup_handler())
935 /* get broadcast messages */
937 if (!serverid_register(procid_self(),
941 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
945 messaging_register(nmbd_messaging_context(), NULL,
946 MSG_FORCE_ELECTION, nmbd_message_election);
948 /* Until winsrepl is done. */
949 messaging_register(nmbd_messaging_context(), NULL,
950 MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
952 messaging_register(nmbd_messaging_context(), NULL,
953 MSG_SHUTDOWN, nmbd_terminate);
954 messaging_register(nmbd_messaging_context(), NULL,
955 MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
956 messaging_register(nmbd_messaging_context(), NULL,
957 MSG_SEND_PACKET, msg_nmbd_send_packet);
961 DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
963 if ( !open_sockets( is_daemon, global_nmb_port ) ) {
964 kill_async_dns_child();
968 /* Determine all the IP addresses we have. */
971 /* Create an nmbd subnet record for each of the above. */
972 if( False == create_subnets() ) {
973 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
974 kill_async_dns_child();
978 /* Load in any static local names. */
980 set_dyn_LMHOSTSFILE(p_lmhosts);
982 load_lmhosts_file(get_dyn_LMHOSTSFILE());
983 DEBUG(3,("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE()));
985 /* If we are acting as a WINS server, initialise data structures. */
986 if( !initialise_wins() ) {
987 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
988 kill_async_dns_child();
993 * Register nmbd primary workgroup and nmbd names on all
994 * the broadcast subnets, and on the WINS server (if specified).
995 * Also initiate the startup of our primary workgroup (start
996 * elections if we are setup as being able to be a local
1000 if( False == register_my_workgroup_and_names() ) {
1001 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
1002 kill_async_dns_child();
1006 if (!initialize_nmbd_proxy_logon()) {
1007 DEBUG(0,("ERROR: Failed setup nmbd_proxy_logon.\n"));
1008 kill_async_dns_child();
1012 if (!nmbd_init_packet_server()) {
1013 kill_async_dns_child();
1018 process(nmbd_messaging_context());
1020 kill_async_dns_child();