add --tftp-no-fail to ignore missing tftp root

This commit is contained in:
Stefan Tomanek
2015-03-31 22:32:11 +01:00
committed by Simon Kelley
parent fd6ad9e481
commit 30d0879ed5
6 changed files with 45 additions and 11 deletions

View File

@@ -72,6 +72,9 @@ version 2.73
on systems without an RTC, whilst allowing DNS queries before the on systems without an RTC, whilst allowing DNS queries before the
clock is valid so that NTP can run. Thanks to clock is valid so that NTP can run. Thanks to
Kevin Darbyshire-Bryant for developing this idea. Kevin Darbyshire-Bryant for developing this idea.
Add --tftp-no-fail option. Thanks to Stefan Tomanek for
the patch.
version 2.72 version 2.72

View File

@@ -486,6 +486,9 @@
# Set the root directory for files available via FTP. # Set the root directory for files available via FTP.
#tftp-root=/var/ftpd #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 # 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. # the user dnsmasq is running as will be send over the net.
#tftp-secure #tftp-secure

View File

@@ -1711,6 +1711,9 @@ Absolute paths (starting with /) are allowed, but they must be within
the tftp-root. If the optional interface argument is given, the the tftp-root. If the optional interface argument is given, the
directory is only used for TFTP requests via that interface. directory is only used for TFTP requests via that interface.
.TP .TP
.B --tftp-no-fail
Do not abort startup if specified tftp root directories are inaccessible.
.TP
.B --tftp-unique-root .B --tftp-unique-root
Add the IP address of the TFTP client as a path component on the end 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 of the TFTP-root (in standard dotted-quad format). Only valid if a

View File

@@ -58,6 +58,9 @@ int main (int argc, char **argv)
struct dhcp_context *context; struct dhcp_context *context;
struct dhcp_relay *relay; struct dhcp_relay *relay;
#endif #endif
#ifdef HAVE_TFTP
int tftp_prefix_missing = 0;
#endif
#ifdef LOCALEDIR #ifdef LOCALEDIR
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
@@ -636,7 +639,7 @@ int main (int argc, char **argv)
#endif #endif
#ifdef HAVE_TFTP #ifdef HAVE_TFTP
if (option_bool(OPT_TFTP)) if (option_bool(OPT_TFTP))
{ {
DIR *dir; DIR *dir;
struct tftp_prefix *p; struct tftp_prefix *p;
@@ -645,24 +648,33 @@ int main (int argc, char **argv)
{ {
if (!((dir = opendir(daemon->tftp_prefix)))) if (!((dir = opendir(daemon->tftp_prefix))))
{ {
send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix); tftp_prefix_missing = 1;
_exit(0); if (!option_bool(OPT_TFTP_NO_FAIL))
{
send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix);
_exit(0);
}
} }
closedir(dir); closedir(dir);
} }
for (p = daemon->if_prefix; p; p = p->next) for (p = daemon->if_prefix; p; p = p->next)
{ {
p->missing = 0;
if (!((dir = opendir(p->prefix)))) if (!((dir = opendir(p->prefix))))
{ {
send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix); p->missing = 1;
_exit(0); if (!option_bool(OPT_TFTP_NO_FAIL))
} {
send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix);
_exit(0);
}
}
closedir(dir); closedir(dir);
} }
} }
#endif #endif
if (daemon->port == 0) if (daemon->port == 0)
my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION); my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
else if (daemon->cachesize != 0) else if (daemon->cachesize != 0)
@@ -772,7 +784,8 @@ int main (int argc, char **argv)
#ifdef HAVE_TFTP #ifdef HAVE_TFTP
if (option_bool(OPT_TFTP)) if (option_bool(OPT_TFTP))
{ {
struct tftp_prefix *p;
#ifdef FD_SETSIZE #ifdef FD_SETSIZE
if (FD_SETSIZE < (unsigned)max_fd) if (FD_SETSIZE < (unsigned)max_fd)
max_fd = FD_SETSIZE; max_fd = FD_SETSIZE;
@@ -782,7 +795,14 @@ int main (int argc, char **argv)
daemon->tftp_prefix ? _("root is ") : _("enabled"), daemon->tftp_prefix ? _("root is ") : _("enabled"),
daemon->tftp_prefix ? daemon->tftp_prefix: "", daemon->tftp_prefix ? daemon->tftp_prefix: "",
option_bool(OPT_TFTP_SECURE) ? _("secure mode") : ""); 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, /* This is a guess, it assumes that for small limits,
disjoint files might be served, but for large limits, disjoint files might be served, but for large limits,
a single file will be sent to may clients (the file only needs a single file will be sent to may clients (the file only needs

View File

@@ -240,7 +240,8 @@ struct event_desc {
#define OPT_LOCAL_SERVICE 49 #define OPT_LOCAL_SERVICE 49
#define OPT_LOOP_DETECT 50 #define OPT_LOOP_DETECT 50
#define OPT_EXTRALOG 51 #define OPT_EXTRALOG 51
#define OPT_LAST 52 #define OPT_TFTP_NO_FAIL 52
#define OPT_LAST 53
/* extra flags for my_syslog, we use a couple of facilities since they are known /* 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. */ not to occupy the same bits as priorities, no matter how syslog.h is set up. */
@@ -901,6 +902,7 @@ struct addr_list {
struct tftp_prefix { struct tftp_prefix {
char *interface; char *interface;
char *prefix; char *prefix;
int missing;
struct tftp_prefix *next; struct tftp_prefix *next;
}; };

View File

@@ -153,6 +153,7 @@ struct myoption {
#define LOPT_DHOPT_INOTIFY 341 #define LOPT_DHOPT_INOTIFY 341
#define LOPT_HOST_INOTIFY 342 #define LOPT_HOST_INOTIFY 342
#define LOPT_DNSSEC_STAMP 343 #define LOPT_DNSSEC_STAMP 343
#define LOPT_TFTP_NO_FAIL 344
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
static const struct option opts[] = static const struct option opts[] =
@@ -235,6 +236,7 @@ static const struct myoption opts[] =
{ "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES }, { "dhcp-ignore-names", 2, 0, LOPT_NO_NAMES },
{ "enable-tftp", 2, 0, LOPT_TFTP }, { "enable-tftp", 2, 0, LOPT_TFTP },
{ "tftp-secure", 0, 0, LOPT_SECURE }, { "tftp-secure", 0, 0, LOPT_SECURE },
{ "tftp-no-fail", 0, 0, LOPT_TFTP_NO_FAIL },
{ "tftp-unique-root", 0, 0, LOPT_APREF }, { "tftp-unique-root", 0, 0, LOPT_APREF },
{ "tftp-root", 1, 0, LOPT_PREFIX }, { "tftp-root", 1, 0, LOPT_PREFIX },
{ "tftp-max", 1, 0, LOPT_TFTP_MAX }, { "tftp-max", 1, 0, LOPT_TFTP_MAX },
@@ -419,6 +421,7 @@ static struct {
{ LOPT_PREFIX, ARG_DUP, "<dir>[,<iface>]", gettext_noop("Export files by TFTP only from the specified subtree."), NULL }, { LOPT_PREFIX, ARG_DUP, "<dir>[,<iface>]", 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_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_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, "<integer>", gettext_noop("Maximum number of conncurrent TFTP transfers (defaults to %s)."), "#" }, { LOPT_TFTP_MAX, ARG_ONE, "<integer>", 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_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 }, { LOPT_TFTP_LC, OPT_TFTP_LC, NULL, gettext_noop("Convert TFTP filenames to lowercase"), NULL },