~ubuntu-branches/ubuntu/hardy/exim4/hardy-proposed

« back to all changes in this revision

Viewing changes to src/rda.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Haber
  • Date: 2005-07-02 06:08:34 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050702060834-qk17pd52kb9nt3bj
Tags: 4.52-1
* new upstream version 4.51. (mh)
  * adapt 70_remove_exim-users_references
  * remove 37_gnutlsparams
  * adapt 36_pcre
  * adapt 31_eximmanpage
* fix package priorities to have them in sync with override again. (mh)
* Fix error in nb (Norwegian) translation.
  Thanks to Helge Hafting. (mh). Closes: #315775
* Standards-Version: 3.6.2, no changes needed. (mh)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Cambridge: exim/exim-src/src/rda.c,v 1.8 2005/06/27 14:29:43 ph10 Exp $ */
 
2
 
1
3
/*************************************************
2
4
*     Exim - an Internet mail transport agent    *
3
5
*************************************************/
4
6
 
5
 
/* Copyright (c) University of Cambridge 1995 - 2004 */
 
7
/* Copyright (c) University of Cambridge 1995 - 2005 */
6
8
/* See the file NOTICE for conditions of use and distribution. */
7
9
 
8
10
/* This module contains code for extracting addresses from a forwarding list
297
299
  }
298
300
filebuf[statbuf.st_size] = 0;
299
301
 
300
 
/* Don't pass statbuf.st_size directly to debug_printf. On some systems it
301
 
is a long, which may not be the same as an int. */
302
 
 
303
302
DEBUG(D_route)
304
 
  {
305
 
  int size = (int)statbuf.st_size;
306
 
  debug_printf("%d bytes read from %s\n", size, filename);
307
 
  }
 
303
  debug_printf(OFF_T_FMT " bytes read from %s\n", statbuf.st_size, filename);
308
304
 
309
 
fclose(fwd);
 
305
(void)fclose(fwd);
310
306
return filebuf;
311
307
 
312
308
/* Return an error: the string is already set up. */
313
309
 
314
310
ERROR_RETURN:
315
311
*yield = FF_ERROR;
316
 
fclose(fwd);
 
312
(void)fclose(fwd);
317
313
return NULL;
318
314
}
319
315
 
327
323
forwarding list, or to run a filter file and get addresses from there.
328
324
 
329
325
Arguments:
330
 
  rdata               the redirection block
331
 
  options             the options bits
332
 
  include_directory   restrain to this directory
333
 
  generated           where to hang generated addresses
334
 
  error               for error messages
335
 
  eblockp             for details of skipped syntax errors (NULL => no skip)
336
 
  filtertype          set to the filter type:
337
 
                        FILTER_FORWARD => a traditional .forward file
338
 
                        FILTER_EXIM    => an Exim filter file
339
 
                        FILTER_SIEVE   => a Sieve filter file
340
 
                      a system filter is always forced to be FILTER_EXIM
 
326
  rdata                     the redirection block
 
327
  options                   the options bits
 
328
  include_directory         restrain to this directory
 
329
  sieve_vacation_directory  passed to sieve_interpret
 
330
  sieve_useraddress         passed to sieve_interpret
 
331
  sieve_subaddress          passed to sieve_interpret
 
332
  generated                 where to hang generated addresses
 
333
  error                     for error messages
 
334
  eblockp                   for details of skipped syntax errors
 
335
                              (NULL => no skip)
 
336
  filtertype                set to the filter type:
 
337
                              FILTER_FORWARD => a traditional .forward file
 
338
                              FILTER_EXIM    => an Exim filter file
 
339
                              FILTER_SIEVE   => a Sieve filter file
 
340
                            a system filter is always forced to be FILTER_EXIM
341
341
 
342
 
Returns:              a suitable return for rda_interpret()
 
342
Returns:                    a suitable return for rda_interpret()
343
343
*/
344
344
 
345
345
static int
346
346
rda_extract(redirect_block *rdata, int options, uschar *include_directory,
347
 
  address_item **generated, uschar **error, error_block **eblockp,
348
 
  int *filtertype)
 
347
  uschar *sieve_vacation_directory, uschar *sieve_useraddress,
 
348
  uschar *sieve_subaddress, address_item **generated, uschar **error,
 
349
  error_block **eblockp, int *filtertype)
349
350
{
350
351
uschar *data;
351
352
 
360
361
*filtertype = system_filtering? FILTER_EXIM : rda_is_filter(data);
361
362
 
362
363
/* Filter interpretation is done by a general function that is also called from
363
 
the filter testing option (-bf). Several features of string expansion may be
364
 
locked out at sites that don't trust users. This is done by setting flags in
 
364
the filter testing option (-bf). There are two versions: one for Exim filtering
 
365
and one for Sieve filtering. Several features of string expansion may be locked
 
366
out at sites that don't trust users. This is done by setting flags in
365
367
expand_forbid that the expander inspects. */
366
368
 
367
369
if (*filtertype != FILTER_FORWARD)
369
371
  int frc;
370
372
  int old_expand_forbid = expand_forbid;
371
373
 
 
374
  DEBUG(D_route) debug_printf("data is %s filter program\n",
 
375
    (*filtertype == FILTER_EXIM)? "an Exim" : "a Sieve");
 
376
 
 
377
  /* RDO_FILTER is an "allow" bit */
 
378
 
372
379
  if ((options & RDO_FILTER) == 0)
373
380
    {
374
381
    *error = US"filtering not enabled";
375
382
    return FF_ERROR;
376
383
    }
377
384
 
378
 
  DEBUG(D_route) debug_printf("data is %s filter program\n",
379
 
    (*filtertype == FILTER_EXIM)? "an Exim" : "a Sieve");
380
 
 
381
385
  expand_forbid =
382
386
    (expand_forbid & ~RDO_FILTER_EXPANSIONS) |
383
387
    (options & RDO_FILTER_EXPANSIONS);
384
 
  frc = ((*filtertype == FILTER_EXIM)? filter_interpret : sieve_interpret)
385
 
    (data, options, generated, error);
 
388
 
 
389
  /* RDO_{EXIM,SIEVE}_FILTER are forbid bits */
 
390
 
 
391
  if (*filtertype == FILTER_EXIM)
 
392
    {
 
393
    if ((options & RDO_EXIM_FILTER) != 0)
 
394
      {
 
395
      *error = US"Exim filtering not enabled";
 
396
      return FF_ERROR;
 
397
      }
 
398
    frc = filter_interpret(data, options, generated, error);
 
399
    }
 
400
  else
 
401
    {
 
402
    if ((options & RDO_SIEVE_FILTER) != 0)
 
403
      {
 
404
      *error = US"Sieve filtering not enabled";
 
405
      return FF_ERROR;
 
406
      }
 
407
    frc = sieve_interpret(data, options, sieve_vacation_directory,
 
408
      sieve_useraddress, sieve_subaddress, generated, error);
 
409
    }
 
410
 
386
411
  expand_forbid = old_expand_forbid;
387
412
  return frc;
388
413
  }
421
446
rda_write_string(int fd, uschar *s)
422
447
{
423
448
int len = (s == NULL)? 0 : Ustrlen(s) + 1;
424
 
write(fd, &len, sizeof(int));
425
 
if (s != NULL) write(fd, s, len);
 
449
(void)write(fd, &len, sizeof(int));
 
450
if (s != NULL) (void)write(fd, s, len);
426
451
}
427
452
 
428
453
 
482
507
    process (which is usually running as root).
483
508
 
484
509
Arguments:
485
 
  rdata              redirect data (file + constraints, or data string)
486
 
  options            options to pass to the extraction functions,
487
 
                       plus ENOTDIR and EACCES handling bits
488
 
  include_directory  restrain :include: to this directory
489
 
  ugid               uid/gid to run under - if NULL, no change
490
 
  generated          where to hang generated addresses, initially NULL
491
 
  error              pointer for error message
492
 
  eblockp            for skipped syntax errors; NULL if no skipping
493
 
  filtertype         set to the type of file:
494
 
                       FILTER_FORWARD => traditional .forward file
495
 
                       FILTER_EXIM    => an Exim filter file
496
 
                       FILTER_SIEVE   => a Sieve filter file
497
 
                     a system filter is always forced to be FILTER_EXIM
498
 
  rname              router name for error messages in the format
499
 
                       "xxx router" or "system filter"
 
510
  rdata                     redirect data (file + constraints, or data string)
 
511
  options                   options to pass to the extraction functions,
 
512
                              plus ENOTDIR and EACCES handling bits
 
513
  include_directory         restrain :include: to this directory
 
514
  sieve_vacation_directory  directory 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"
500
528
 
501
529
Returns:        values from extraction function, or FF_NONEXIST:
502
530
                  FF_DELIVERED     success, a significant action was taken
512
540
 
513
541
int
514
542
rda_interpret(redirect_block *rdata, int options, uschar *include_directory,
515
 
  ugid_block *ugid, address_item **generated, uschar **error,
516
 
  error_block **eblockp, int *filtertype, uschar *rname)
 
543
  uschar *sieve_vacation_directory, uschar *sieve_useraddress,
 
544
  uschar *sieve_subaddress, ugid_block *ugid, address_item **generated,
 
545
  uschar **error, error_block **eblockp, int *filtertype, uschar *rname)
517
546
{
518
547
int fd, rc, pfd[2];
519
548
int yield, status;
556
585
     rda_is_filter(data) == FILTER_FORWARD && /* It's not a filter script, */
557
586
     Ustrstr(data, ":include:") == NULL))     /* and there's no :include: */
558
587
  {
559
 
  return rda_extract(rdata, options, include_directory, generated, error,
560
 
    eblockp, filtertype);
 
588
  return rda_extract(rdata, options, include_directory,
 
589
    sieve_vacation_directory, sieve_useraddress, sieve_subaddress,
 
590
    generated, error, eblockp, filtertype);
561
591
  }
562
592
 
563
593
/* We need to run the processing code in a sub-process. However, if we can
585
615
  header_line *waslast = header_last;   /* Save last header */
586
616
 
587
617
  fd = pfd[pipe_write];
588
 
  close(pfd[pipe_read]);
 
618
  (void)close(pfd[pipe_read]);
589
619
  exim_setugid(ugid->uid, ugid->gid, FALSE, rname);
590
620
 
591
621
  /* Addresses can get rewritten in filters; if we are not root or the exim
601
631
 
602
632
  /* Now do the business */
603
633
 
604
 
  yield = rda_extract(rdata, options, include_directory, generated, error,
605
 
    eblockp, filtertype);
 
634
  yield = rda_extract(rdata, options, include_directory,
 
635
    sieve_vacation_directory, sieve_useraddress, sieve_subaddress, generated,
 
636
    error, eblockp, filtertype);
606
637
 
607
638
  /* Pass back whether it was a filter, and the return code and any overall
608
639
  error text via the pipe. */
609
640
 
610
 
  write(fd, filtertype, sizeof(int));
611
 
  write(fd, &yield, sizeof(int));
 
641
  (void)write(fd, filtertype, sizeof(int));
 
642
  (void)write(fd, &yield, sizeof(int));
612
643
  rda_write_string(fd, *error);
613
644
 
614
645
  /* Pass back the contents of any syntax error blocks if we have a pointer */
634
665
    header_line *h;
635
666
    for (h = header_list; h != waslast->next; i++, h = h->next)
636
667
      {
637
 
      if (h->type == htype_old) write(fd, &i, sizeof(i));
 
668
      if (h->type == htype_old) (void)write(fd, &i, sizeof(i));
638
669
      }
639
670
    i = -1;
640
 
    write(fd, &i, sizeof(i));
 
671
    (void)write(fd, &i, sizeof(i));
641
672
 
642
673
    while (waslast != header_last)
643
674
      {
645
676
      if (waslast->type != htype_old)
646
677
        {
647
678
        rda_write_string(fd, waslast->text);
648
 
        write(fd, &(waslast->type), sizeof(waslast->type));
 
679
        (void)write(fd, &(waslast->type), sizeof(waslast->type));
649
680
        }
650
681
      }
651
682
    rda_write_string(fd, NULL);    /* Indicates end of added headers */
653
684
 
654
685
  /* Write the contents of the $n variables */
655
686
 
656
 
  write(fd, filter_n, sizeof(filter_n));
 
687
  (void)write(fd, filter_n, sizeof(filter_n));
657
688
 
658
689
  /* If the result was DELIVERED or NOTDELIVERED, we pass back the generated
659
690
  addresses, and their associated information, through the pipe. This is
670
701
      int reply_options = 0;
671
702
 
672
703
      rda_write_string(fd, addr->address);
673
 
      write(fd, &(addr->mode), sizeof(addr->mode));
674
 
      write(fd, &(addr->flags), sizeof(addr->flags));
 
704
      (void)write(fd, &(addr->mode), sizeof(addr->mode));
 
705
      (void)write(fd, &(addr->flags), sizeof(addr->flags));
675
706
      rda_write_string(fd, addr->p.errors_address);
676
707
 
677
708
      if (addr->pipe_expandn != NULL)
683
714
      rda_write_string(fd, NULL);
684
715
 
685
716
      if (addr->reply == NULL)
686
 
        write(fd, &reply_options, sizeof(int));    /* 0 means no reply */
 
717
        (void)write(fd, &reply_options, sizeof(int));    /* 0 means no reply */
687
718
      else
688
719
        {
689
720
        reply_options |= REPLY_EXISTS;
690
721
        if (addr->reply->file_expand) reply_options |= REPLY_EXPAND;
691
722
        if (addr->reply->return_message) reply_options |= REPLY_RETURN;
692
 
        write(fd, &reply_options, sizeof(int));
693
 
        write(fd, &(addr->reply->expand_forbid), sizeof(int));
694
 
        write(fd, &(addr->reply->once_repeat), sizeof(time_t));
 
723
        (void)write(fd, &reply_options, sizeof(int));
 
724
        (void)write(fd, &(addr->reply->expand_forbid), sizeof(int));
 
725
        (void)write(fd, &(addr->reply->once_repeat), sizeof(time_t));
695
726
        rda_write_string(fd, addr->reply->to);
696
727
        rda_write_string(fd, addr->reply->cc);
697
728
        rda_write_string(fd, addr->reply->bcc);
711
742
 
712
743
  /* OK, this process is now done. Must use _exit() and not exit() !! */
713
744
 
714
 
  close(fd);
 
745
  (void)close(fd);
715
746
  _exit(0);
716
747
  }
717
748
 
724
755
writing end must be closed first, as otherwise read() won't return zero on an
725
756
empty pipe. Afterwards, close the reading end. */
726
757
 
727
 
close(pfd[pipe_write]);
 
758
(void)close(pfd[pipe_write]);
728
759
 
729
760
/* Read initial data, including yield and contents of *error */
730
761
 
909
940
  }
910
941
 
911
942
FINAL_EXIT:
912
 
close(fd);
 
943
(void)close(fd);
913
944
signal(SIGCHLD, oldsignal);   /* restore */
914
945
return yield;
915
946