constification
[exim.git] / src / src / rda.c
index 574b86cdd57b959de52d7f1498ad7afdcd00de70..35794c2ffdd613a77a7ef39d3d0f224a7b7bff49 100644 (file)
@@ -3,7 +3,7 @@
 *************************************************/
 
 /* Copyright (c) University of Cambridge 1995 - 2018 */
 *************************************************/
 
 /* Copyright (c) University of Cambridge 1995 - 2018 */
-/* Copyright (c) The Exim maintainers 2020 */
+/* Copyright (c) The Exim maintainers 2020 - 2021 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* This module contains code for extracting addresses from a forwarding list
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* This module contains code for extracting addresses from a forwarding list
@@ -42,7 +42,7 @@ Returns:   FILTER_EXIM    if it starts with "# Exim filter"
 static BOOL
 match_tag(const uschar *s, const uschar *tag)
 {
 static BOOL
 match_tag(const uschar *s, const uschar *tag)
 {
-for (; *tag != 0; s++, tag++)
+for (; *tag; s++, tag++)
   if (*tag == ' ')
     {
     while (*s == ' ' || *s == '\t') s++;
   if (*tag == ' ')
     {
     while (*s == ' ' || *s == '\t') s++;
@@ -60,10 +60,10 @@ tags for other types of filter. */
 int
 rda_is_filter(const uschar *s)
 {
 int
 rda_is_filter(const uschar *s)
 {
-while (isspace(*s)) s++;     /* Skips initial blank lines */
-if (match_tag(s, CUS"# exim filter")) return FILTER_EXIM;
-  else if (match_tag(s, CUS"# sieve filter")) return FILTER_SIEVE;
-    else return FILTER_FORWARD;
+Uskip_whitespace(&s);                  /* Skips initial blank lines */
+if (match_tag(s, CUS"# exim filter"))          return FILTER_EXIM;
+else if (match_tag(s, CUS"# sieve filter"))    return FILTER_SIEVE;
+else                                           return FILTER_FORWARD;
 }
 
 
 }
 
 
@@ -166,7 +166,7 @@ Returns:      pointer to string in store; NULL on error
 */
 
 static uschar *
 */
 
 static uschar *
-rda_get_file_contents(redirect_block *rdata, int options, uschar **error,
+rda_get_file_contents(const redirect_block *rdata, int options, uschar **error,
   int *yield)
 {
 FILE *fwd;
   int *yield)
 {
 FILE *fwd;
@@ -179,10 +179,8 @@ struct stat statbuf;
 /* Reading a file is a form of expansion; we wish to deny attackers the
 capability to specify the file name. */
 
 /* Reading a file is a form of expansion; we wish to deny attackers the
 capability to specify the file name. */
 
-if (is_tainted(filename))
+if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for file read not permitted\n", filename)))
   {
   {
-  *error = string_sprintf("Tainted name '%s' for file read not permitted\n",
-                       filename);
   *yield = FF_ERROR;
   return NULL;
   }
   *yield = FF_ERROR;
   return NULL;
   }
@@ -222,7 +220,7 @@ if (!(fwd = Ufopen(filename, "rb"))) switch(errno)
 
 DEFAULT_ERROR:
   default:
 
 DEFAULT_ERROR:
   default:
-    *error = string_open_failed(errno, "%s", filename);
+    *error = string_open_failed("%s", filename);
     *yield = FF_ERROR;
     return NULL;
   }
     *yield = FF_ERROR;
     return NULL;
   }
@@ -339,13 +337,13 @@ Returns:                    a suitable return for rda_interpret()
 */
 
 static int
 */
 
 static int
-rda_extract(redirect_block *rdata, int options, uschar *include_directory,
+rda_extract(const redirect_block *rdata, int options, uschar *include_directory,
   uschar *sieve_vacation_directory, uschar *sieve_enotify_mailto_owner,
   uschar *sieve_useraddress, uschar *sieve_subaddress,
   address_item **generated, uschar **error, error_block **eblockp,
   int *filtertype)
 {
   uschar *sieve_vacation_directory, uschar *sieve_enotify_mailto_owner,
   uschar *sieve_useraddress, uschar *sieve_subaddress,
   address_item **generated, uschar **error, error_block **eblockp,
   int *filtertype)
 {
-uschar *data;
+const uschar * data;
 
 if (rdata->isfile)
   {
 
 if (rdata->isfile)
   {
@@ -615,12 +613,17 @@ with the parent process. */
 oldsignal = signal(SIGCHLD, SIG_DFL);
 search_tidyup();
 
 oldsignal = signal(SIGCHLD, SIG_DFL);
 search_tidyup();
 
-if ((pid = fork()) == 0)
+if ((pid = exim_fork(US"router-interpret")) == 0)
   {
   header_line *waslast = header_last;   /* Save last header */
   {
   header_line *waslast = header_last;   /* Save last header */
+  int fd_flags = -1;
 
   fd = pfd[pipe_write];
   (void)close(pfd[pipe_read]);
 
   fd = pfd[pipe_write];
   (void)close(pfd[pipe_read]);
+
+  if ((fd_flags = fcntl(fd, F_GETFD)) == -1) goto bad;
+  if (fcntl(fd, F_SETFD, fd_flags | FD_CLOEXEC) == -1) goto bad;
+
   exim_setugid(ugid->uid, ugid->gid, FALSE, rname);
 
   /* Addresses can get rewritten in filters; if we are not root or the exim
   exim_setugid(ugid->uid, ugid->gid, FALSE, rname);
 
   /* Addresses can get rewritten in filters; if we are not root or the exim
@@ -768,7 +771,7 @@ if ((pid = fork()) == 0)
 out:
   (void)close(fd);
   search_tidyup();
 out:
   (void)close(fd);
   search_tidyup();
-  exim_underbar_exit(0);
+  exim_underbar_exit(EXIT_SUCCESS);
 
 bad:
   DEBUG(D_rewrite) debug_printf("rda_interpret: failed write to pipe\n");
 
 bad:
   DEBUG(D_rewrite) debug_printf("rda_interpret: failed write to pipe\n");
@@ -956,8 +959,8 @@ if (had_disaster)
   *error = string_sprintf("internal problem in %s: failure to transfer "
     "data from subprocess: status=%04x%s%s%s", rname,
     status, readerror,
   *error = string_sprintf("internal problem in %s: failure to transfer "
     "data from subprocess: status=%04x%s%s%s", rname,
     status, readerror,
-    (*error == NULL)? US"" : US": error=",
-    (*error == NULL)? US"" : *error);
+    *error ? US": error=" : US"",
+    *error ? *error : US"");
   log_write(0, LOG_MAIN|LOG_PANIC, "%s", *error);
   }
 else if (status != 0)
   log_write(0, LOG_MAIN|LOG_PANIC, "%s", *error);
   }
 else if (status != 0)