0ffc61c770f573eec727c0b326c05ae68e4bbf4f
[exim.git] / src / src / rda.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* Copyright (c) The Exim maintainers 2020 - 2021 */
7 /* See the file NOTICE for conditions of use and distribution. */
8
9 /* This module contains code for extracting addresses from a forwarding list
10 (from an alias or forward file) or by running the filter interpreter. It may do
11 this in a sub-process if a uid/gid are supplied. */
12
13
14 #include "exim.h"
15
16 enum { FILE_EXIST, FILE_NOT_EXIST, FILE_EXIST_UNCLEAR };
17
18 #define REPLY_EXISTS    0x01
19 #define REPLY_EXPAND    0x02
20 #define REPLY_RETURN    0x04
21
22
23 /*************************************************
24 *         Check string for filter program        *
25 *************************************************/
26
27 /* This function checks whether a string is actually a filter program. The rule
28 is that it must start with "# Exim filter ..." (any capitalization, spaces
29 optional). It is envisaged that in future, other kinds of filter may be
30 implemented. That's why it is implemented the way it is. The function is global
31 because it is also called from filter.c when checking filters.
32
33 Argument:  the string
34
35 Returns:   FILTER_EXIM    if it starts with "# Exim filter"
36            FILTER_SIEVE   if it starts with "# Sieve filter"
37            FILTER_FORWARD otherwise
38 */
39
40 /* This is an auxiliary function for matching a tag. */
41
42 static BOOL
43 match_tag(const uschar *s, const uschar *tag)
44 {
45 for (; *tag; s++, tag++)
46   if (*tag == ' ')
47     {
48     while (*s == ' ' || *s == '\t') s++;
49     s--;
50     }
51   else
52    if (tolower(*s) != tolower(*tag)) break;
53
54 return (*tag == 0);
55 }
56
57 /* This is the real function. It should be easy to add checking different
58 tags for other types of filter. */
59
60 int
61 rda_is_filter(const uschar *s)
62 {
63 Uskip_whitespace(&s);                   /* Skips initial blank lines */
64 if (match_tag(s, CUS"# exim filter"))           return FILTER_EXIM;
65 else if (match_tag(s, CUS"# sieve filter"))     return FILTER_SIEVE;
66 else                                            return FILTER_FORWARD;
67 }
68
69
70
71
72 /*************************************************
73 *         Check for existence of file            *
74 *************************************************/
75
76 /* First of all, we stat the file. If this fails, we try to stat the enclosing
77 directory, because a file in an unmounted NFS directory will look the same as a
78 non-existent file. It seems that in Solaris 2.6, statting an entry in an
79 indirect map that is currently unmounted does not cause the mount to happen.
80 Instead, dummy data is returned, which defeats the whole point of this test.
81 However, if a stat() is done on some object inside the directory, such as the
82 "." back reference to itself, then the mount does occur. If an NFS host is
83 taken offline, it is possible for the stat() to get stuck until it comes back.
84 To guard against this, stick a timer round it. If we can't access the "."
85 inside the directory, try the plain directory, just in case that helps.
86
87 Argument:
88   filename   the file name
89   error      for message on error
90
91 Returns:     FILE_EXIST          the file exists
92              FILE_NOT_EXIST      the file does not exist
93              FILE_EXIST_UNCLEAR  cannot determine existence
94 */
95
96 static int
97 rda_exists(uschar *filename, uschar **error)
98 {
99 int rc, saved_errno;
100 struct stat statbuf;
101 uschar * s;
102
103 if ((rc = Ustat(filename, &statbuf)) >= 0) return FILE_EXIST;
104 saved_errno = errno;
105
106 s = string_copy(filename);
107 sigalrm_seen = FALSE;
108
109 if (saved_errno == ENOENT)
110   {
111   uschar * slash = Ustrrchr(s, '/');
112   Ustrcpy(slash+1, US".");
113
114   ALARM(30);
115   rc = Ustat(s, &statbuf);
116   if (rc != 0 && errno == EACCES && !sigalrm_seen)
117     {
118     *slash = 0;
119     rc = Ustat(s, &statbuf);
120     }
121   saved_errno = errno;
122   ALARM_CLR(0);
123
124   DEBUG(D_route) debug_printf("stat(%s)=%d\n", s, rc);
125   }
126
127 if (sigalrm_seen || rc != 0)
128   {
129   *error = string_sprintf("failed to stat %s (%s)", s,
130     sigalrm_seen?  "timeout" : strerror(saved_errno));
131   return FILE_EXIST_UNCLEAR;
132   }
133
134 *error = string_sprintf("%s does not exist", filename);
135 DEBUG(D_route) debug_printf("%s\n", *error);
136 return FILE_NOT_EXIST;
137 }
138
139
140
141 /*************************************************
142 *     Get forwarding list from a file            *
143 *************************************************/
144
145 /* Open a file and read its entire contents into a block of memory. Certain
146 opening errors are optionally treated the same as "file does not exist".
147
148 ENOTDIR means that something along the line is not a directory: there are
149 installations that set home directories to be /dev/null for non-login accounts
150 but in normal circumstances this indicates some kind of configuration error.
151
152 EACCES means there's a permissions failure. Some users turn off read permission
153 on a .forward file to suspend forwarding, but this is probably an error in any
154 kind of mailing list processing.
155
156 The redirect block that contains the file name also contains constraints such
157 as who may own the file, and mode bits that must not be set. This function is
158
159 Arguments:
160   rdata       rdirect block, containing file name and constraints
161   options     for the RDO_ENOTDIR and RDO_EACCES options
162   error       where to put an error message
163   yield       what to return from rda_interpret on error
164
165 Returns:      pointer to string in store; NULL on error
166 */
167
168 static uschar *
169 rda_get_file_contents(const redirect_block *rdata, int options, uschar **error,
170   int *yield)
171 {
172 FILE *fwd;
173 uschar *filebuf;
174 uschar *filename = rdata->string;
175 BOOL uid_ok = !rdata->check_owner;
176 BOOL gid_ok = !rdata->check_group;
177 struct stat statbuf;
178
179 /* Reading a file is a form of expansion; we wish to deny attackers the
180 capability to specify the file name. */
181
182 if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for file read not permitted\n", filename)))
183   {
184   *yield = FF_ERROR;
185   return NULL;
186   }
187
188 /* Attempt to open the file. If it appears not to exist, check up on the
189 containing directory by statting it. If the directory does not exist, we treat
190 this situation as an error (which will cause delivery to defer); otherwise we
191 pass back FF_NONEXIST, which causes the redirect router to decline.
192
193 However, if the ignore_enotdir option is set (to ignore "something on the
194 path is not a directory" errors), the right behaviour seems to be not to do the
195 directory test. */
196
197 if (!(fwd = Ufopen(filename, "rb"))) switch(errno)
198   {
199   case ENOENT:          /* File does not exist */
200     DEBUG(D_route) debug_printf("%s does not exist\n%schecking parent directory\n",
201       filename, options & RDO_ENOTDIR ? "ignore_enotdir set => skip " : "");
202     *yield =
203         options & RDO_ENOTDIR || rda_exists(filename, error) == FILE_NOT_EXIST
204         ? FF_NONEXIST : FF_ERROR;
205     return NULL;
206
207   case ENOTDIR:         /* Something on the path isn't a directory */
208     if (!(options & RDO_ENOTDIR)) goto DEFAULT_ERROR;
209     DEBUG(D_route) debug_printf("non-directory on path %s: file assumed not to "
210       "exist\n", filename);
211     *yield = FF_NONEXIST;
212     return NULL;
213
214   case EACCES:           /* Permission denied */
215     if (!(options & RDO_EACCES)) goto DEFAULT_ERROR;
216     DEBUG(D_route) debug_printf("permission denied for %s: file assumed not to "
217       "exist\n", filename);
218     *yield = FF_NONEXIST;
219     return NULL;
220
221 DEFAULT_ERROR:
222   default:
223     *error = string_open_failed("%s", filename);
224     *yield = FF_ERROR;
225     return NULL;
226   }
227
228 /* Check that we have a regular file. */
229
230 if (fstat(fileno(fwd), &statbuf) != 0)
231   {
232   *error = string_sprintf("failed to stat %s: %s", filename, strerror(errno));
233   goto ERROR_RETURN;
234   }
235
236 if ((statbuf.st_mode & S_IFMT) != S_IFREG)
237   {
238   *error = string_sprintf("%s is not a regular file", filename);
239   goto ERROR_RETURN;
240   }
241
242 /* Check for unwanted mode bits */
243
244 if ((statbuf.st_mode & rdata->modemask) != 0)
245   {
246   *error = string_sprintf("bad mode (0%o) for %s: 0%o bit(s) unexpected",
247     statbuf.st_mode, filename, statbuf.st_mode & rdata->modemask);
248   goto ERROR_RETURN;
249   }
250
251 /* Check the file owner and file group if required to do so. */
252
253 if (!uid_ok)
254   if (rdata->pw && statbuf.st_uid == rdata->pw->pw_uid)
255     uid_ok = TRUE;
256   else if (rdata->owners)
257     for (int i = 1; i <= (int)(rdata->owners[0]); i++)
258       if (rdata->owners[i] == statbuf.st_uid) { uid_ok = TRUE; break; }
259
260 if (!gid_ok)
261   if (rdata->pw && statbuf.st_gid == rdata->pw->pw_gid)
262     gid_ok = TRUE;
263   else if (rdata->owngroups)
264     for (int i = 1; i <= (int)(rdata->owngroups[0]); i++)
265       if (rdata->owngroups[i] == statbuf.st_gid) { gid_ok = TRUE; break; }
266
267 if (!uid_ok || !gid_ok)
268   {
269   *error = string_sprintf("bad %s for %s", uid_ok? "group" : "owner", filename);
270   goto ERROR_RETURN;
271   }
272
273 /* Put an upper limit on the size of the file, just to stop silly people
274 feeding in ridiculously large files, which can easily be created by making
275 files that have holes in them. */
276
277 if (statbuf.st_size > MAX_FILTER_SIZE)
278   {
279   *error = string_sprintf("%s is too big (max %d)", filename, MAX_FILTER_SIZE);
280   goto ERROR_RETURN;
281   }
282
283 /* Read the file in one go in order to minimize the time we have it open. */
284
285 filebuf = store_get(statbuf.st_size + 1, is_tainted(filename));
286
287 if (fread(filebuf, 1, statbuf.st_size, fwd) != statbuf.st_size)
288   {
289   *error = string_sprintf("error while reading %s: %s",
290     filename, strerror(errno));
291   goto ERROR_RETURN;
292   }
293 filebuf[statbuf.st_size] = 0;
294
295 DEBUG(D_route) debug_printf(OFF_T_FMT " %sbytes read from %s\n",
296   statbuf.st_size, is_tainted(filename) ? "(tainted) " : "", filename);
297
298 (void)fclose(fwd);
299 return filebuf;
300
301 /* Return an error: the string is already set up. */
302
303 ERROR_RETURN:
304 *yield = FF_ERROR;
305 (void)fclose(fwd);
306 return NULL;
307 }
308
309
310
311 /*************************************************
312 *      Extract info from list or filter          *
313 *************************************************/
314
315 /* This function calls the appropriate function to extract addresses from a
316 forwarding list, or to run a filter file and get addresses from there.
317
318 Arguments:
319   rdata                     the redirection block
320   options                   the options bits
321   include_directory         restrain to this directory
322   sieve_vacation_directory  passed to sieve_interpret
323   sieve_enotify_mailto_owner passed to sieve_interpret
324   sieve_useraddress         passed to sieve_interpret
325   sieve_subaddress          passed to sieve_interpret
326   generated                 where to hang generated addresses
327   error                     for error messages
328   eblockp                   for details of skipped syntax errors
329                               (NULL => no skip)
330   filtertype                set to the filter type:
331                               FILTER_FORWARD => a traditional .forward file
332                               FILTER_EXIM    => an Exim filter file
333                               FILTER_SIEVE   => a Sieve filter file
334                             a system filter is always forced to be FILTER_EXIM
335
336 Returns:                    a suitable return for rda_interpret()
337 */
338
339 static int
340 rda_extract(const redirect_block * rdata, int options,
341   const uschar * include_directory, const uschar * sieve_vacation_directory,
342   const uschar * sieve_enotify_mailto_owner, const uschar * sieve_useraddress,
343   const uschar * sieve_subaddress, address_item ** generated, uschar ** error,
344   error_block ** eblockp, int * filtertype)
345 {
346 const uschar * data;
347
348 if (rdata->isfile)
349   {
350   int yield = 0;
351   if (!(data = rda_get_file_contents(rdata, options, error, &yield)))
352     return yield;
353   }
354 else data = rdata->string;
355
356 *filtertype = f.system_filtering ? FILTER_EXIM : rda_is_filter(data);
357
358 /* Filter interpretation is done by a general function that is also called from
359 the filter testing option (-bf). There are two versions: one for Exim filtering
360 and one for Sieve filtering. Several features of string expansion may be locked
361 out at sites that don't trust users. This is done by setting flags in
362 expand_forbid that the expander inspects. */
363
364 if (*filtertype != FILTER_FORWARD)
365   {
366   int frc;
367   int old_expand_forbid = expand_forbid;
368
369   DEBUG(D_route) debug_printf("data is %s filter program\n",
370     *filtertype == FILTER_EXIM ? "an Exim" : "a Sieve");
371
372   /* RDO_FILTER is an "allow" bit */
373
374   if (!(options & RDO_FILTER))
375     {
376     *error = US"filtering not enabled";
377     return FF_ERROR;
378     }
379
380   expand_forbid =
381     expand_forbid & ~RDO_FILTER_EXPANSIONS  |  options & RDO_FILTER_EXPANSIONS;
382
383   /* RDO_{EXIM,SIEVE}_FILTER are forbid bits */
384
385   if (*filtertype == FILTER_EXIM)
386     {
387     if ((options & RDO_EXIM_FILTER) != 0)
388       {
389       *error = US"Exim filtering not enabled";
390       return FF_ERROR;
391       }
392     frc = filter_interpret(data, options, generated, error);
393     }
394   else
395     {
396     if (options & RDO_SIEVE_FILTER)
397       {
398       *error = US"Sieve filtering not enabled";
399       return FF_ERROR;
400       }
401     frc = sieve_interpret(data, options, sieve_vacation_directory,
402       sieve_enotify_mailto_owner, sieve_useraddress, sieve_subaddress,
403       generated, error);
404     }
405
406   expand_forbid = old_expand_forbid;
407   return frc;
408   }
409
410 /* Not a filter script */
411
412 DEBUG(D_route) debug_printf("file is not a filter file\n");
413
414 return parse_forward_list(data,
415   options,                           /* specials that are allowed */
416   generated,                         /* where to hang them */
417   error,                             /* for errors */
418   deliver_domain,                    /* to qualify \name */
419   include_directory,                 /* restrain to directory */
420   eblockp);                          /* for skipped syntax errors */
421 }
422
423
424
425
426 /*************************************************
427 *         Write string down pipe                 *
428 *************************************************/
429
430 /* This function is used for transferring a string down a pipe between
431 processes. If the pointer is NULL, a length of zero is written.
432
433 Arguments:
434   fd         the pipe
435   s          the string
436
437 Returns:     -1 on error, else 0
438 */
439
440 static int
441 rda_write_string(int fd, const uschar *s)
442 {
443 int len = s ? Ustrlen(s) + 1 : 0;
444 return (  write(fd, &len, sizeof(int)) != sizeof(int)
445        || (s   &&  write(fd, s, len) != len)
446        )
447        ? -1 : 0;
448 }
449
450
451
452 /*************************************************
453 *          Read string from pipe                 *
454 *************************************************/
455
456 /* This function is used for receiving a string from a pipe.
457
458 Arguments:
459   fd         the pipe
460   sp         where to put the string
461
462 Returns:     FALSE if data missing
463 */
464
465 static BOOL
466 rda_read_string(int fd, uschar **sp)
467 {
468 int len;
469
470 if (read(fd, &len, sizeof(int)) != sizeof(int)) return FALSE;
471 if (len == 0)
472   *sp = NULL;
473 else
474   /* We know we have enough memory so disable the error on "len" */
475   /* coverity[tainted_data] */
476   /* We trust the data source, so untainted */
477   if (read(fd, *sp = store_get(len, FALSE), len) != len) return FALSE;
478 return TRUE;
479 }
480
481
482
483 /*************************************************
484 *         Interpret forward list or filter       *
485 *************************************************/
486
487 /* This function is passed a forward list string (unexpanded) or the name of a
488 file (unexpanded) whose contents are the forwarding list. The list may in fact
489 be a filter program if it starts with "#Exim filter" or "#Sieve filter". Other
490 types of filter, with different initial tag strings, may be introduced in due
491 course.
492
493 The job of the function is to process the forwarding list or filter. It is
494 pulled out into this separate function, because it is used for system filter
495 files as well as from the redirect router.
496
497 If the function is given a uid/gid, it runs a subprocess that passes the
498 results back via a pipe. This provides security for things like :include:s in
499 users' .forward files, and "logwrite" calls in users' filter files. A
500 sub-process is NOT used when:
501
502   . No uid/gid is provided
503   . The input is a string which is not a filter string, and does not contain
504     :include:
505   . The input is a file whose non-existence can be detected in the main
506     process (which is usually running as root).
507
508 Arguments:
509   rdata                     redirect data (file + constraints, or data string)
510   options                   options to pass to the extraction functions,
511                               plus ENOTDIR and EACCES handling bits
512   include_directory         restrain :include: to this directory
513   sieve_vacation_directory  directory passed to sieve_interpret
514   sieve_enotify_mailto_owner passed to sieve_interpret
515   sieve_useraddress         passed to sieve_interpret
516   sieve_subaddress          passed to sieve_interpret
517   ugid                      uid/gid to run under - if NULL, no change
518   generated                 where to hang generated addresses, initially NULL
519   error                     pointer for error message
520   eblockp                   for skipped syntax errors; NULL if no skipping
521   filtertype                set to the type of file:
522                               FILTER_FORWARD => traditional .forward file
523                               FILTER_EXIM    => an Exim filter file
524                               FILTER_SIEVE   => a Sieve filter file
525                             a system filter is always forced to be FILTER_EXIM
526   rname                     router name for error messages in the format
527                               "xxx router" or "system filter"
528
529 Returns:        values from extraction function, or FF_NONEXIST:
530                   FF_DELIVERED     success, a significant action was taken
531                   FF_NOTDELIVERED  success, no significant action
532                   FF_BLACKHOLE     :blackhole:
533                   FF_DEFER         defer requested
534                   FF_FAIL          fail requested
535                   FF_INCLUDEFAIL   some problem with :include:
536                   FF_FREEZE        freeze requested
537                   FF_ERROR         there was a problem
538                   FF_NONEXIST      the file does not exist
539 */
540
541 int
542 rda_interpret(redirect_block * rdata, int options,
543   const uschar * include_directory, const uschar * sieve_vacation_directory,
544   const uschar * sieve_enotify_mailto_owner, const uschar * sieve_useraddress,
545   const uschar * sieve_subaddress, const ugid_block * ugid, address_item ** generated,
546   uschar ** error, error_block ** eblockp, int * filtertype, const uschar * rname)
547 {
548 int fd, rc, pfd[2];
549 int yield, status;
550 BOOL had_disaster = FALSE;
551 pid_t pid;
552 uschar *data;
553 uschar *readerror = US"";
554 void (*oldsignal)(int);
555
556 DEBUG(D_route) debug_printf("rda_interpret (%s): '%s'\n",
557   rdata->isfile ? "file" : "string", string_printing(rdata->string));
558
559 /* Do the expansions of the file name or data first, while still privileged. */
560
561 if (!(data = expand_string(rdata->string)))
562   {
563   if (f.expand_string_forcedfail) return FF_NOTDELIVERED;
564   *error = string_sprintf("failed to expand \"%s\": %s", rdata->string,
565     expand_string_message);
566   return FF_ERROR;
567   }
568 rdata->string = data;
569
570 DEBUG(D_route)
571   debug_printf("expanded: '%s'%s\n", data, is_tainted(data) ? " (tainted)":"");
572
573 if (rdata->isfile && data[0] != '/')
574   {
575   *error = string_sprintf("\"%s\" is not an absolute path", data);
576   return FF_ERROR;
577   }
578
579 /* If no uid/gid are supplied, or if we have a data string which does not start
580 with #Exim filter or #Sieve filter, and does not contain :include:, do all the
581 work in this process. Note that for a system filter, we always have a file, so
582 the work is done in this process only if no user is supplied. */
583
584 if (!ugid->uid_set ||                         /* Either there's no uid, or */
585     (!rdata->isfile &&                        /* We've got the data, and */
586      rda_is_filter(data) == FILTER_FORWARD && /* It's not a filter script, */
587      Ustrstr(data, ":include:") == NULL))     /* and there's no :include: */
588   return rda_extract(rdata, options, include_directory,
589     sieve_vacation_directory, sieve_enotify_mailto_owner, sieve_useraddress,
590     sieve_subaddress, generated, error, eblockp, filtertype);
591
592 /* We need to run the processing code in a sub-process. However, if we can
593 determine the non-existence of a file first, we can decline without having to
594 create the sub-process. */
595
596 if (rdata->isfile && rda_exists(data, error) == FILE_NOT_EXIST)
597   return FF_NONEXIST;
598
599 /* If the file does exist, or we can't tell (non-root mounted NFS directory)
600 we have to create the subprocess to do everything as the given user. The
601 results of processing are passed back via a pipe. */
602
603 if (pipe(pfd) != 0)
604   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "creation of pipe for filter or "
605     ":include: failed for %s: %s", rname, strerror(errno));
606
607 /* Ensure that SIGCHLD is set to SIG_DFL before forking, so that the child
608 process can be waited for. We sometimes get here with it set otherwise. Save
609 the old state for resetting on the wait. Ensure that all cached resources are
610 freed so that the subprocess starts with a clean slate and doesn't interfere
611 with the parent process. */
612
613 oldsignal = signal(SIGCHLD, SIG_DFL);
614 search_tidyup();
615
616 if ((pid = exim_fork(US"router-interpret")) == 0)
617   {
618   header_line *waslast = header_last;   /* Save last header */
619   int fd_flags = -1;
620
621   fd = pfd[pipe_write];
622   (void)close(pfd[pipe_read]);
623
624   if ((fd_flags = fcntl(fd, F_GETFD)) == -1) goto bad;
625   if (fcntl(fd, F_SETFD, fd_flags | FD_CLOEXEC) == -1) goto bad;
626
627   exim_setugid(ugid->uid, ugid->gid, FALSE, rname);
628
629   /* Addresses can get rewritten in filters; if we are not root or the exim
630   user (and we probably are not), turn off rewrite logging, because we cannot
631   write to the log now. */
632
633   if (ugid->uid != root_uid && ugid->uid != exim_uid)
634     {
635     DEBUG(D_rewrite) debug_printf("turned off address rewrite logging (not "
636       "root or exim in this process)\n");
637     BIT_CLEAR(log_selector, log_selector_size, Li_address_rewrite);
638     }
639
640   /* Now do the business */
641
642   yield = rda_extract(rdata, options, include_directory,
643     sieve_vacation_directory, sieve_enotify_mailto_owner, sieve_useraddress,
644     sieve_subaddress, generated, error, eblockp, filtertype);
645
646   /* Pass back whether it was a filter, and the return code and any overall
647   error text via the pipe. */
648
649   if (  write(fd, filtertype, sizeof(int)) != sizeof(int)
650      || write(fd, &yield, sizeof(int)) != sizeof(int)
651      || rda_write_string(fd, *error) != 0
652      )
653     goto bad;
654
655   /* Pass back the contents of any syntax error blocks if we have a pointer */
656
657   if (eblockp)
658     {
659     for (error_block * ep = *eblockp; ep; ep = ep->next)
660       if (  rda_write_string(fd, ep->text1) != 0
661          || rda_write_string(fd, ep->text2) != 0
662          )
663         goto bad;
664     if (rda_write_string(fd, NULL) != 0)    /* Indicates end of eblocks */
665       goto bad;
666     }
667
668   /* If this is a system filter, we have to pass back the numbers of any
669   original header lines that were removed, and then any header lines that were
670   added but not subsequently removed. */
671
672   if (f.system_filtering)
673     {
674     int i = 0;
675     for (header_line * h = header_list; h != waslast->next; i++, h = h->next)
676       if (  h->type == htype_old
677          && write(fd, &i, sizeof(i)) != sizeof(i)
678          )
679         goto bad;
680
681     i = -1;
682     if (write(fd, &i, sizeof(i)) != sizeof(i))
683         goto bad;
684
685     while (waslast != header_last)
686       {
687       waslast = waslast->next;
688       if (waslast->type != htype_old)
689         if (  rda_write_string(fd, waslast->text) != 0
690            || write(fd, &(waslast->type), sizeof(waslast->type))
691               != sizeof(waslast->type)
692            )
693           goto bad;
694       }
695     if (rda_write_string(fd, NULL) != 0)    /* Indicates end of added headers */
696       goto bad;
697     }
698
699   /* Write the contents of the $n variables */
700
701   if (write(fd, filter_n, sizeof(filter_n)) != sizeof(filter_n))
702     goto bad;
703
704   /* If the result was DELIVERED or NOTDELIVERED, we pass back the generated
705   addresses, and their associated information, through the pipe. This is
706   just tedious, but it seems to be the only safe way. We do this also for
707   FAIL and FREEZE, because a filter is allowed to set up deliveries that
708   are honoured before freezing or failing. */
709
710   if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED ||
711       yield == FF_FAIL || yield == FF_FREEZE)
712     {
713     for (address_item * addr = *generated; addr; addr = addr->next)
714       {
715       int reply_options = 0;
716       int ig_err = addr->prop.ignore_error ? 1 : 0;
717
718       if (  rda_write_string(fd, addr->address) != 0
719          || write(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode)
720          || write(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags)
721          || rda_write_string(fd, addr->prop.errors_address) != 0
722          || write(fd, &ig_err, sizeof(ig_err)) != sizeof(ig_err)
723          )
724         goto bad;
725
726       if (addr->pipe_expandn)
727         for (uschar ** pp = addr->pipe_expandn; *pp; pp++)
728           if (rda_write_string(fd, *pp) != 0)
729             goto bad;
730       if (rda_write_string(fd, NULL) != 0)
731         goto bad;
732
733       if (!addr->reply)
734         {
735         if (write(fd, &reply_options, sizeof(int)) != sizeof(int))    /* 0 means no reply */
736           goto bad;
737         }
738       else
739         {
740         reply_options |= REPLY_EXISTS;
741         if (addr->reply->file_expand) reply_options |= REPLY_EXPAND;
742         if (addr->reply->return_message) reply_options |= REPLY_RETURN;
743         if (  write(fd, &reply_options, sizeof(int)) != sizeof(int)
744            || write(fd, &(addr->reply->expand_forbid), sizeof(int))
745               != sizeof(int)
746            || write(fd, &(addr->reply->once_repeat), sizeof(time_t))
747               != sizeof(time_t)
748            || rda_write_string(fd, addr->reply->to) != 0
749            || rda_write_string(fd, addr->reply->cc) != 0
750            || rda_write_string(fd, addr->reply->bcc) != 0
751            || rda_write_string(fd, addr->reply->from) != 0
752            || rda_write_string(fd, addr->reply->reply_to) != 0
753            || rda_write_string(fd, addr->reply->subject) != 0
754            || rda_write_string(fd, addr->reply->headers) != 0
755            || rda_write_string(fd, addr->reply->text) != 0
756            || rda_write_string(fd, addr->reply->file) != 0
757            || rda_write_string(fd, addr->reply->logfile) != 0
758            || rda_write_string(fd, addr->reply->oncelog) != 0
759            )
760           goto bad;
761         }
762       }
763
764     if (rda_write_string(fd, NULL) != 0)   /* Marks end of addresses */
765       goto bad;
766     }
767
768   /* OK, this process is now done. Free any cached resources. Must use _exit()
769   and not exit() !! */
770
771 out:
772   (void)close(fd);
773   search_tidyup();
774   exim_underbar_exit(EXIT_SUCCESS);
775
776 bad:
777   DEBUG(D_rewrite) debug_printf("rda_interpret: failed write to pipe\n");
778   goto out;
779   }
780
781 /* Back in the main process: panic if the fork did not succeed. */
782
783 if (pid < 0)
784   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork failed for %s", rname);
785
786 /* Read the pipe to get the data from the filter/forward. Our copy of the
787 writing end must be closed first, as otherwise read() won't return zero on an
788 empty pipe. Afterwards, close the reading end. */
789
790 (void)close(pfd[pipe_write]);
791
792 /* Read initial data, including yield and contents of *error */
793
794 fd = pfd[pipe_read];
795 if (read(fd, filtertype, sizeof(int)) != sizeof(int) ||
796     read(fd, &yield, sizeof(int)) != sizeof(int) ||
797     !rda_read_string(fd, error)) goto DISASTER;
798
799 /* Read the contents of any syntax error blocks if we have a pointer */
800
801 if (eblockp)
802   {
803   error_block *e;
804   for (error_block ** p = eblockp; ; p = &e->next)
805     {
806     uschar *s;
807     if (!rda_read_string(fd, &s)) goto DISASTER;
808     if (!s) break;
809     e = store_get(sizeof(error_block), FALSE);
810     e->next = NULL;
811     e->text1 = s;
812     if (!rda_read_string(fd, &s)) goto DISASTER;
813     e->text2 = s;
814     *p = e;
815     }
816   }
817
818 /* If this is a system filter, read the identify of any original header lines
819 that were removed, and then read data for any new ones that were added. */
820
821 if (f.system_filtering)
822   {
823   int hn = 0;
824   header_line *h = header_list;
825
826   for (;;)
827     {
828     int n;
829     if (read(fd, &n, sizeof(int)) != sizeof(int)) goto DISASTER;
830     if (n < 0) break;
831     while (hn < n)
832       {
833       hn++;
834       if (!(h = h->next)) goto DISASTER_NO_HEADER;
835       }
836     h->type = htype_old;
837     }
838
839   for (;;)
840     {
841     uschar *s;
842     int type;
843     if (!rda_read_string(fd, &s)) goto DISASTER;
844     if (!s) break;
845     if (read(fd, &type, sizeof(type)) != sizeof(type)) goto DISASTER;
846     header_add(type, "%s", s);
847     }
848   }
849
850 /* Read the values of the $n variables */
851
852 if (read(fd, filter_n, sizeof(filter_n)) != sizeof(filter_n)) goto DISASTER;
853
854 /* If the yield is DELIVERED, NOTDELIVERED, FAIL, or FREEZE there may follow
855 addresses and data to go with them. Keep them in the same order in the
856 generated chain. */
857
858 if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED ||
859     yield == FF_FAIL || yield == FF_FREEZE)
860   {
861   address_item **nextp = generated;
862
863   for (;;)
864     {
865     int i, reply_options;
866     address_item *addr;
867     uschar *recipient;
868     uschar *expandn[EXPAND_MAXN + 2];
869
870     /* First string is the address; NULL => end of addresses */
871
872     if (!rda_read_string(fd, &recipient)) goto DISASTER;
873     if (!recipient) break;
874
875     /* Hang on the end of the chain */
876
877     addr = deliver_make_addr(recipient, FALSE);
878     *nextp = addr;
879     nextp = &(addr->next);
880
881     /* Next comes the mode and the flags fields */
882
883     if (  read(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode)
884        || read(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags)
885        || !rda_read_string(fd, &addr->prop.errors_address)
886        || read(fd, &i, sizeof(i)) != sizeof(i)
887        )
888       goto DISASTER;
889     addr->prop.ignore_error = (i != 0);
890
891     /* Next comes a possible setting for $thisaddress and any numerical
892     variables for pipe expansion, terminated by a NULL string. The maximum
893     number of numericals is EXPAND_MAXN. Note that we put filter_thisaddress
894     into the zeroth item in the vector - this is sorted out inside the pipe
895     transport. */
896
897     for (i = 0; i < EXPAND_MAXN + 1; i++)
898       {
899       uschar *temp;
900       if (!rda_read_string(fd, &temp)) goto DISASTER;
901       if (i == 0) filter_thisaddress = temp;           /* Just in case */
902       expandn[i] = temp;
903       if (temp == NULL) break;
904       }
905
906     if (i > 0)
907       {
908       addr->pipe_expandn = store_get((i+1) * sizeof(uschar *), FALSE);
909       addr->pipe_expandn[i] = NULL;
910       while (--i >= 0) addr->pipe_expandn[i] = expandn[i];
911       }
912
913     /* Then an int containing reply options; zero => no reply data. */
914
915     if (read(fd, &reply_options, sizeof(int)) != sizeof(int)) goto DISASTER;
916     if ((reply_options & REPLY_EXISTS) != 0)
917       {
918       addr->reply = store_get(sizeof(reply_item), FALSE);
919
920       addr->reply->file_expand = (reply_options & REPLY_EXPAND) != 0;
921       addr->reply->return_message = (reply_options & REPLY_RETURN) != 0;
922
923       if (read(fd,&(addr->reply->expand_forbid),sizeof(int)) !=
924             sizeof(int) ||
925           read(fd,&(addr->reply->once_repeat),sizeof(time_t)) !=
926             sizeof(time_t) ||
927           !rda_read_string(fd, &addr->reply->to) ||
928           !rda_read_string(fd, &addr->reply->cc) ||
929           !rda_read_string(fd, &addr->reply->bcc) ||
930           !rda_read_string(fd, &addr->reply->from) ||
931           !rda_read_string(fd, &addr->reply->reply_to) ||
932           !rda_read_string(fd, &addr->reply->subject) ||
933           !rda_read_string(fd, &addr->reply->headers) ||
934           !rda_read_string(fd, &addr->reply->text) ||
935           !rda_read_string(fd, &addr->reply->file) ||
936           !rda_read_string(fd, &addr->reply->logfile) ||
937           !rda_read_string(fd, &addr->reply->oncelog))
938         goto DISASTER;
939       }
940     }
941   }
942
943 /* All data has been transferred from the sub-process. Reap it, close the
944 reading end of the pipe, and we are done. */
945
946 WAIT_EXIT:
947 while ((rc = wait(&status)) != pid)
948   if (rc < 0 && errno == ECHILD)      /* Process has vanished */
949     {
950     log_write(0, LOG_MAIN, "redirection process %d vanished unexpectedly", pid);
951     goto FINAL_EXIT;
952     }
953
954 DEBUG(D_route)
955   debug_printf("rda_interpret: subprocess yield=%d error=%s\n", yield, *error);
956
957 if (had_disaster)
958   {
959   *error = string_sprintf("internal problem in %s: failure to transfer "
960     "data from subprocess: status=%04x%s%s%s", rname,
961     status, readerror,
962     *error ? US": error=" : US"",
963     *error ? *error : US"");
964   log_write(0, LOG_MAIN|LOG_PANIC, "%s", *error);
965   }
966 else if (status != 0)
967   log_write(0, LOG_MAIN|LOG_PANIC, "internal problem in %s: unexpected status "
968     "%04x from redirect subprocess (but data correctly received)", rname,
969     status);
970
971 FINAL_EXIT:
972 (void)close(fd);
973 signal(SIGCHLD, oldsignal);   /* restore */
974 return yield;
975
976
977 /* Come here if the data indicates removal of a header that we can't find */
978
979 DISASTER_NO_HEADER:
980 readerror = US" readerror=bad header identifier";
981 had_disaster = TRUE;
982 yield = FF_ERROR;
983 goto WAIT_EXIT;
984
985 /* Come here is there's a shambles in transferring the data over the pipe. The
986 value of errno should still be set. */
987
988 DISASTER:
989 readerror = string_sprintf(" readerror='%s'", strerror(errno));
990 had_disaster = TRUE;
991 yield = FF_ERROR;
992 goto WAIT_EXIT;
993 }
994
995 /* End of rda.c */