Update copyright dates
[exim.git] / src / src / rda.c
index a12e5de2974719ac9e9cd48fb00a4d01e25a06c4..776805ca4435dd698fc73c9383fce9790362e9b4 100644 (file)
@@ -2,9 +2,10 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
+/* Copyright (c) The Exim maintainers 2020 - 2024 */
 /* Copyright (c) University of Cambridge 1995 - 2018 */
-/* Copyright (c) The Exim maintainers 2020 */
 /* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 
 /* This module contains code for extracting addresses from a forwarding list
 (from an alias or forward file) or by running the filter interpreter. It may do
@@ -166,7 +167,7 @@ Returns:      pointer to string in store; NULL on error
 */
 
 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;
@@ -179,8 +180,10 @@ struct stat statbuf;
 /* Reading a file is a form of expansion; we wish to deny attackers the
 capability to specify the file name. */
 
-if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for file read not permitted\n", filename)))
+if (is_tainted(filename))
   {
+  *error = string_sprintf("Tainted name '%s' for file read not permitted\n",
+                       filename);
   *yield = FF_ERROR;
   return NULL;
   }
@@ -282,7 +285,7 @@ if (statbuf.st_size > MAX_FILTER_SIZE)
 
 /* Read the file in one go in order to minimize the time we have it open. */
 
-filebuf = store_get(statbuf.st_size + 1, is_tainted(filename));
+filebuf = store_get(statbuf.st_size + 1, filename);
 
 if (fread(filebuf, 1, statbuf.st_size, fwd) != statbuf.st_size)
   {
@@ -337,13 +340,13 @@ Returns:                    a suitable return for rda_interpret()
 */
 
 static int
-rda_extract(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)
+rda_extract(const redirect_block * rdata, int options,
+  const uschar * include_directory, const uschar * sieve_vacation_directory,
+  const uschar * sieve_enotify_mailto_owner, const uschar * sieve_useraddress,
+  const uschar * sieve_subaddress, address_item ** generated, uschar ** error,
+  error_block ** eblockp, int * filtertype)
 {
-uschar *data;
+const uschar * data;
 
 if (rdata->isfile)
   {
@@ -440,9 +443,9 @@ Returns:     -1 on error, else 0
 static int
 rda_write_string(int fd, const uschar *s)
 {
-int len = (s == NULL)? 0 : Ustrlen(s) + 1;
+int len = s ? Ustrlen(s) + 1 : 0;
 return (  write(fd, &len, sizeof(int)) != sizeof(int)
-       || (s != NULL  &&  write(fd, s, len) != len)
+       || (s   &&  write(fd, s, len) != len)
        )
        ? -1 : 0;
 }
@@ -463,7 +466,7 @@ Returns:     FALSE if data missing
 */
 
 static BOOL
-rda_read_string(int fd, uschar **sp)
+rda_read_string(int fd, uschar ** sp)
 {
 int len;
 
@@ -474,7 +477,7 @@ else
   /* We know we have enough memory so disable the error on "len" */
   /* coverity[tainted_data] */
   /* We trust the data source, so untainted */
-  if (read(fd, *sp = store_get(len, FALSE), len) != len) return FALSE;
+  if (read(fd, *sp = store_get(len, GET_UNTAINTED), len) != len) return FALSE;
 return TRUE;
 }
 
@@ -539,11 +542,11 @@ Returns:        values from extraction function, or FF_NONEXIST:
 */
 
 int
-rda_interpret(redirect_block *rdata, int options, uschar *include_directory,
-  uschar *sieve_vacation_directory, uschar *sieve_enotify_mailto_owner,
-  uschar *sieve_useraddress, uschar *sieve_subaddress, ugid_block *ugid,
-  address_item **generated, uschar **error, error_block **eblockp,
-  int *filtertype, uschar *rname)
+rda_interpret(redirect_block * rdata, int options,
+  const uschar * include_directory, const uschar * sieve_vacation_directory,
+  const uschar * sieve_enotify_mailto_owner, const uschar * sieve_useraddress,
+  const uschar * sieve_subaddress, const ugid_block * ugid, address_item ** generated,
+  uschar ** error, error_block ** eblockp, int * filtertype, const uschar * rname)
 {
 int fd, rc, pfd[2];
 int yield, status;
@@ -806,7 +809,7 @@ if (eblockp)
     uschar *s;
     if (!rda_read_string(fd, &s)) goto DISASTER;
     if (!s) break;
-    e = store_get(sizeof(error_block), FALSE);
+    e = store_get(sizeof(error_block), GET_UNTAINTED);
     e->next = NULL;
     e->text1 = s;
     if (!rda_read_string(fd, &s)) goto DISASTER;
@@ -863,9 +866,9 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED ||
   for (;;)
     {
     int i, reply_options;
-    address_item *addr;
-    uschar *recipient;
-    uschar *expandn[EXPAND_MAXN + 2];
+    address_item * addr;
+    uschar * recipient, * s;
+    uschar * expandn[EXPAND_MAXN + 2];
 
     /* First string is the address; NULL => end of addresses */
 
@@ -882,10 +885,11 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED ||
 
     if (  read(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode)
        || read(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags)
-       || !rda_read_string(fd, &addr->prop.errors_address)
+       || !rda_read_string(fd, &s)
        || read(fd, &i, sizeof(i)) != sizeof(i)
        )
       goto DISASTER;
+    addr->prop.errors_address = s;
     addr->prop.ignore_error = (i != 0);
 
     /* Next comes a possible setting for $thisaddress and any numerical
@@ -905,7 +909,7 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED ||
 
     if (i > 0)
       {
-      addr->pipe_expandn = store_get((i+1) * sizeof(uschar *), FALSE);
+      addr->pipe_expandn = store_get((i+1) * sizeof(uschar *), GET_UNTAINTED);
       addr->pipe_expandn[i] = NULL;
       while (--i >= 0) addr->pipe_expandn[i] = expandn[i];
       }
@@ -915,7 +919,7 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED ||
     if (read(fd, &reply_options, sizeof(int)) != sizeof(int)) goto DISASTER;
     if ((reply_options & REPLY_EXISTS) != 0)
       {
-      addr->reply = store_get(sizeof(reply_item), FALSE);
+      addr->reply = store_get(sizeof(reply_item), GET_UNTAINTED);
 
       addr->reply->file_expand = (reply_options & REPLY_EXPAND) != 0;
       addr->reply->return_message = (reply_options & REPLY_RETURN) != 0;
@@ -959,16 +963,14 @@ 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 == 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, "internal problem in %s: unexpected status "
     "%04x from redirect subprocess (but data correctly received)", rname,
     status);
-  }
 
 FINAL_EXIT:
 (void)close(fd);