From 56920681eaf2c5eb08fc75baee4939d15d03b0ea Mon Sep 17 00:00:00 2001 From: Stefan Tomanek Date: Tue, 31 Mar 2015 22:32:11 +0100 Subject: [PATCH] add --tftp-no-fail to ignore missing tftp root (cherry picked from commit 30d0879ed55cb67b1b735beab3d93f3bb3ef1dd2) Conflicts: CHANGELOG src/dnsmasq.c src/dnsmasq.h src/option.c --- dnsmasq.conf.example | 3 +++ man/dnsmasq.8 | 3 +++ src/dnsmasq.c | 42 +++++++++++++++++++++++++++++++----------- src/dnsmasq.h | 4 +++- src/option.c | 3 +++ 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example index 1bd305d..67be99a 100644 --- a/dnsmasq.conf.example +++ b/dnsmasq.conf.example @@ -486,6 +486,9 @@ # Set the root directory for files available via FTP. #tftp-root=/var/ftpd +# Do not abort if the tftp-root is unavailable +#tftp-no-fail + # Make the TFTP server more secure: with this set, only files owned by # the user dnsmasq is running as will be send over the net. #tftp-secure diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index 0b8e04f..2ff4b96 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -1670,6 +1670,9 @@ Absolute paths (starting with /) are allowed, but they must be within the tftp-root. If the optional interface argument is given, the directory is only used for TFTP requests via that interface. .TP +.B --tftp-no-fail +Do not abort startup if specified tftp root directories are inaccessible. +.TP .B --tftp-unique-root Add the IP address of the TFTP client as a path component on the end of the TFTP-root (in standard dotted-quad format). Only valid if a diff --git a/src/dnsmasq.c b/src/dnsmasq.c index 5c7750d..b6fa285 100644 --- a/src/dnsmasq.c +++ b/src/dnsmasq.c @@ -58,6 +58,9 @@ int main (int argc, char **argv) struct dhcp_context *context; struct dhcp_relay *relay; #endif +#ifdef HAVE_TFTP + int tftp_prefix_missing = 0; +#endif #ifdef LOCALEDIR setlocale(LC_ALL, ""); @@ -623,7 +626,7 @@ int main (int argc, char **argv) #endif #ifdef HAVE_TFTP - if (option_bool(OPT_TFTP)) + if (option_bool(OPT_TFTP)) { DIR *dir; struct tftp_prefix *p; @@ -632,24 +635,33 @@ int main (int argc, char **argv) { if (!((dir = opendir(daemon->tftp_prefix)))) { - send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix); - _exit(0); + tftp_prefix_missing = 1; + if (!option_bool(OPT_TFTP_NO_FAIL)) + { + send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix); + _exit(0); + } } closedir(dir); } - + for (p = daemon->if_prefix; p; p = p->next) { + p->missing = 0; if (!((dir = opendir(p->prefix)))) - { - send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix); - _exit(0); - } + { + p->missing = 1; + if (!option_bool(OPT_TFTP_NO_FAIL)) + { + send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix); + _exit(0); + } + } closedir(dir); } } #endif - + if (daemon->port == 0) my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION); else if (daemon->cachesize != 0) @@ -743,8 +755,9 @@ int main (int argc, char **argv) #endif #ifdef HAVE_TFTP - if (option_bool(OPT_TFTP)) - { + if (option_bool(OPT_TFTP)) + { + struct tftp_prefix *p; #ifdef FD_SETSIZE if (FD_SETSIZE < (unsigned)max_fd) max_fd = FD_SETSIZE; @@ -754,7 +767,14 @@ int main (int argc, char **argv) daemon->tftp_prefix ? _("root is ") : _("enabled"), daemon->tftp_prefix ? daemon->tftp_prefix: "", option_bool(OPT_TFTP_SECURE) ? _("secure mode") : ""); + + if (tftp_prefix_missing) + my_syslog(MS_TFTP | LOG_WARNING, _("warning: %s inaccessible"), daemon->tftp_prefix); + for (p = daemon->if_prefix; p; p = p->next) + if (p->missing) + my_syslog(MS_TFTP | LOG_WARNING, _("warning: TFTP directory %s inaccessible"), p->prefix); + /* This is a guess, it assumes that for small limits, disjoint files might be served, but for large limits, a single file will be sent to may clients (the file only needs diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 1dd61c5..086cb67 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -238,7 +238,8 @@ struct event_desc { #define OPT_DNSSEC_NO_SIGN 48 #define OPT_LOCAL_SERVICE 49 #define OPT_LOOP_DETECT 50 -#define OPT_LAST 51 +#define OPT_TFTP_NO_FAIL 51 +#define OPT_LAST 52 /* extra flags for my_syslog, we use a couple of facilities since they are known not to occupy the same bits as priorities, no matter how syslog.h is set up. */ @@ -888,6 +889,7 @@ struct addr_list { struct tftp_prefix { char *interface; char *prefix; + int missing; struct tftp_prefix *next; }; diff --git a/src/option.c b/src/option.c index 209fa69..fa5e4d3 100644 --- a/src/option.c +++ b/src/option.c @@ -147,6 +147,7 @@ struct myoption { #define LOPT_LOCAL_SERVICE 335 #define LOPT_DNSSEC_TIME 336 #define LOPT_LOOP_DETECT 337 +#define LOPT_TFTP_NO_FAIL 338 #ifdef HAVE_GETOPT_LONG static const struct option opts[] = @@ -227,6 +228,7 @@ static const struct myoption opts[] = { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES }, { "enable-tftp", 2, 0, LOPT_TFTP }, { "tftp-secure", 0, 0, LOPT_SECURE }, + { "tftp-no-fail", 0, 0, LOPT_TFTP_NO_FAIL }, { "tftp-unique-root", 0, 0, LOPT_APREF }, { "tftp-root", 1, 0, LOPT_PREFIX }, { "tftp-max", 1, 0, LOPT_TFTP_MAX }, @@ -402,6 +404,7 @@ static struct { { LOPT_PREFIX, ARG_DUP, "[,]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL }, { LOPT_APREF, OPT_TFTP_APREF, NULL, gettext_noop("Add client IP address to tftp-root."), NULL }, { LOPT_SECURE, OPT_TFTP_SECURE, NULL, gettext_noop("Allow access only to files owned by the user running dnsmasq."), NULL }, + { LOPT_TFTP_NO_FAIL, OPT_TFTP_NO_FAIL, NULL, gettext_noop("Do not terminate the service if TFTP directories are inaccessible."), NULL }, { LOPT_TFTP_MAX, ARG_ONE, "", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" }, { LOPT_NOBLOCK, OPT_TFTP_NOBLOCK, NULL, gettext_noop("Disable the TFTP blocksize extension."), NULL }, { LOPT_TFTP_LC, OPT_TFTP_LC, NULL, gettext_noop("Convert TFTP filenames to lowercase"), NULL }, -- 2.1.4