]> git.ipfire.org Git - people/dweismueller/ipfire-2.x.git/blobdiff - src/patches/dnsmasq/0057-Tweak-DNSSEC-timestamp-code-to-create-file-later-rem.patch
dnsmasq: Import more patches from upstream
[people/dweismueller/ipfire-2.x.git] / src / patches / dnsmasq / 0057-Tweak-DNSSEC-timestamp-code-to-create-file-later-rem.patch
diff --git a/src/patches/dnsmasq/0057-Tweak-DNSSEC-timestamp-code-to-create-file-later-rem.patch b/src/patches/dnsmasq/0057-Tweak-DNSSEC-timestamp-code-to-create-file-later-rem.patch
new file mode 100644 (file)
index 0000000..df47cd0
--- /dev/null
@@ -0,0 +1,202 @@
+From 360f2513ab12a9bf1e262d388dd2ea8a566590a3 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Sat, 7 Mar 2015 18:28:06 +0000
+Subject: [PATCH 57/57] Tweak DNSSEC timestamp code to create file later,
+ removing need to chown it.
+
+---
+ man/dnsmasq.8 |  3 ++-
+ src/dnsmasq.c | 35 ++++++++++++++++++++++-------------
+ src/dnsmasq.h |  3 ++-
+ src/dnssec.c  | 18 ++++++++++--------
+ 4 files changed, 36 insertions(+), 23 deletions(-)
+
+diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
+index 097e7d75145c..2db780d90987 100644
+--- a/man/dnsmasq.8
++++ b/man/dnsmasq.8
+@@ -678,7 +678,8 @@ which have not been throughly checked.
+ Enables an alternative way of checking the validity of the system time for DNSSEC (see --dnssec-no-timecheck). In this case, the 
+ system time is considered to be valid once it becomes later than the timestamp on the specified file. The file is created and 
+ its timestamp set automatically by dnsmasq. The file must be stored on a persistent filesystem, so that it and its mtime are carried 
+-over system restarts. 
++over system restarts. The timestamp file is created after dnsmasq has dropped root, so it must be in a location writable by the 
++unprivileged user that dnsmasq runs as.
+ .TP
+ .B --proxy-dnssec
+ Copy the DNSSEC Authenticated Data bit from upstream servers to downstream clients and cache it.  This is an 
+diff --git a/src/dnsmasq.c b/src/dnsmasq.c
+index 9e05c0e31569..f3e5bcffec4f 100644
+--- a/src/dnsmasq.c
++++ b/src/dnsmasq.c
+@@ -58,9 +58,6 @@ int main (int argc, char **argv)
+   struct dhcp_context *context;
+   struct dhcp_relay *relay;
+ #endif
+-#ifdef HAVE_DNSSEC
+-  int badtime;
+-#endif
+ #ifdef LOCALEDIR
+   setlocale(LC_ALL, "");
+@@ -156,10 +153,10 @@ int main (int argc, char **argv)
+     {
+ #ifdef HAVE_DNSSEC
+       if (!daemon->ds)
+-      die(_("No trust anchors provided for DNSSEC"), NULL, EC_BADCONF);
++      die(_("no trust anchors provided for DNSSEC"), NULL, EC_BADCONF);
+       
+       if (daemon->cachesize < CACHESIZ)
+-      die(_("Cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
++      die(_("cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
+ #else 
+       die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
+ #endif
+@@ -172,10 +169,10 @@ int main (int argc, char **argv)
+ #ifdef HAVE_CONNTRACK
+   if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
+-    die (_("Cannot use --conntrack AND --query-port"), NULL, EC_BADCONF); 
++    die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF); 
+ #else
+   if (option_bool(OPT_CONNTRACK))
+-    die(_("Conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
++    die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
+ #endif
+ #ifdef HAVE_SOLARIS_NETWORK
+@@ -195,7 +192,7 @@ int main (int argc, char **argv)
+ #ifndef HAVE_LOOP
+   if (option_bool(OPT_LOOP_DETECT))
+-    die(_("Loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
++    die(_("loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
+ #endif
+   
+   now = dnsmasq_time();
+@@ -373,10 +370,6 @@ int main (int argc, char **argv)
+   if (baduser)
+     die(_("unknown user or group: %s"), baduser, EC_BADCONF);
+-#ifdef HAVE_DNSSEC  
+-  badtime = setup_timestamp(ent_pw);
+-#endif
+-
+   /* implement group defaults, "dip" if available, or group associated with uid */
+   if (!daemon->group_set && !gp)
+     {
+@@ -693,10 +686,23 @@ int main (int argc, char **argv)
+ #ifdef HAVE_DNSSEC
+   if (option_bool(OPT_DNSSEC_VALID))
+     {
++      int rc;
++
++      /* Delay creating the timestamp file until here, after we've changed user, so that
++       it has the correct owner to allow updating the mtime later. 
++       This means we have to report fatal errors via the pipe. */
++      if ((rc = setup_timestamp()) == -1)
++      {
++        send_event(err_pipe[1], EVENT_TIME_ERR, errno, daemon->timestamp_file);
++        _exit(0);
++      }
++      
+       my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
++      
+       if (option_bool(OPT_DNSSEC_TIME))
+       my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload"));
+-      if (badtime)
++      
++      if (rc == 1)
+       my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
+     }
+ #endif
+@@ -1170,6 +1176,9 @@ static void fatal_event(struct event_desc *ev, char *msg)
+     case EVENT_TFTP_ERR:
+       die(_("TFTP directory %s inaccessible: %s"), msg, EC_FILE);
++    
++    case EVENT_TIME_ERR:
++      die(_("cannot create timestamp file %s: %s" ), msg, EC_BADCONF);
+     }
+ }     
+       
+diff --git a/src/dnsmasq.h b/src/dnsmasq.h
+index a451cb4dd03c..fc7259881358 100644
+--- a/src/dnsmasq.h
++++ b/src/dnsmasq.h
+@@ -167,6 +167,7 @@ struct event_desc {
+ #define EVENT_INIT      21
+ #define EVENT_NEWADDR   22
+ #define EVENT_NEWROUTE  23
++#define EVENT_TIME_ERR  24
+ /* Exit codes. */
+ #define EC_GOOD        0
+@@ -1152,7 +1153,7 @@ int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char
+ int dnskey_keytag(int alg, int flags, unsigned char *rdata, int rdlen);
+ size_t filter_rrsigs(struct dns_header *header, size_t plen);
+ unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name);
+-int setup_timestamp(struct passwd *ent_pw);
++int setup_timestamp(void);
+ /* util.c */
+ void rand_init(void);
+diff --git a/src/dnssec.c b/src/dnssec.c
+index c60eacf73c6b..ad0d6f072ba2 100644
+--- a/src/dnssec.c
++++ b/src/dnssec.c
+@@ -397,18 +397,21 @@ static int serial_compare_32(unsigned long s1, unsigned long s2)
+ /* Called at startup. If the timestamp file is configured and exists, put its mtime on
+    timestamp_time. If it doesn't exist, create it, and set the mtime to 1-1-2015.
+-   Change the ownership to the user we'll be running as, so that we can update the mtime.
++   return -1 -> Cannot create file.
++           0 -> not using timestamp, or timestamp exists and is in past.
++           1 -> timestamp exists and is in future.
+ */
++
+ static time_t timestamp_time;
+ static int back_to_the_future;
+-int setup_timestamp(struct passwd *ent_pw)
++int setup_timestamp(void)
+ {
+   struct stat statbuf;
+   
+   back_to_the_future = 0;
+   
+-  if (!option_bool(OPT_DNSSEC_VALID) || !daemon->timestamp_file)
++  if (!daemon->timestamp_file)
+     return 0;
+   
+   if (stat(daemon->timestamp_file, &statbuf) != -1)
+@@ -428,7 +431,8 @@ int setup_timestamp(struct passwd *ent_pw)
+   
+   if (errno == ENOENT)
+     {
+-      int fd = open(daemon->timestamp_file, O_WRONLY | O_CREAT | O_NONBLOCK, 0666);
++      /* NB. for explanation of O_EXCL flag, see comment on pidfile in dnsmasq.c */ 
++      int fd = open(daemon->timestamp_file, O_WRONLY | O_CREAT | O_NONBLOCK | O_EXCL, 0666);
+       if (fd != -1)
+       {
+         struct utimbuf timbuf;
+@@ -436,14 +440,12 @@ int setup_timestamp(struct passwd *ent_pw)
+         close(fd);
+         
+         timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
+-        if (utime(daemon->timestamp_file, &timbuf) == 0 &&
+-            (!ent_pw || getuid() != 0 || chown(daemon->timestamp_file, ent_pw->pw_uid, -1) == 0))
++        if (utime(daemon->timestamp_file, &timbuf) == 0)
+           goto check_and_exit;
+       }
+     }
+-  die(_("Cannot create timestamp file %s: %s" ), daemon->timestamp_file, EC_BADCONF);
+-  return 0;
++  return -1;
+ }
+ /* Check whether today/now is between date_start and date_end */
+-- 
+2.1.0
+