Re: [Exim] disabling .forward files & ignore_enotdir

Top Page
Delete this message
Reply to this message
Author: Dave C.
Date:  
To: Corin Hartland-Swann
CC: exim-users
Subject: Re: [Exim] disabling .forward files & ignore_enotdir
On Fri, 15 Sep 2000, Corin Hartland-Swann wrote:

>
> Hi there,
>
> I've just started playing with exim, after looking for a while for a
> decent replacement for sendmail. I'm really impressed with it so far, and
> have been getting along really well with the copious on-line docs.
>
> One of the things that I wanted to do is disable the handling of user's
> .forward files. First I tried removing the whole userforward director, but
> that didn't work (it used its defaults instead). So instead I used the
> following config:


Try removing (or commenting out) the director, and then send the exim
daemon a HUP signal to tell it to reread the config..

There is no 'default' set of directors - exim uses only what is
specified in its config file..


>
> userforward:
>   driver         = forwardfile
>   file_directory = /doesnt_exist
>   file           = .forward
>   ignore_enotdir = yes

>
> However, all deliveries fail with this setup:
>
> email@address cannot be resolved at this time:
> failed to stat /doesnt_exist (No such file or directory)
>
> >From looking through directors/forwardfile.c when the stat() on
> /doesnt_exist/.forward fails it gives this error message (even though it
> was trying to stat the file, and not the directory as it reports).
>
> It seems that, on Linux at any rate, if you stat a file which has a
> directory in its path that doesn't exist AT ALL, it returns ENOENT and not
> ENOTDIR. It only return ENOTDIR if the first directory in the path that
> isn't a directory exists, but is actually a file. I think that what was
> meant by ignore_enotdir should also ignore ENOENT errors.
>
> The fix for this is to add extra logic to the stat() part:
>
> 1) if we get ENOENT from stat(file) then stat(directory) and use the rc
>    from that
> 2) if we get ENOENT or ENOTDIR from that, and ignore_enotdir is set, print
>    a debug() message stating that there is a non-directory on the path,
>    set yield=DECLINE and goto RESTORE_UID
> 3) otherwise drop back to giving the error message above

>
> I've attached a patch that implements these changes.
>
> Regards,
>
> Corin
>
> /------------------------+-------------------------------------\
> | Corin Hartland-Swann   | Direct: +44 (0) 20 7544 4676        |
> | Commerce Internet Ltd  | Mobile: +44 (0) 79 5854 0027        |
> | 22 Cavendish Buildings |    Tel: +44 (0) 20 7491 2000        |
> | Gilbert Street         |    Fax: +44 (0) 20 7491 2010        |
> | Mayfair                |    Web: http://www.commerce.uk.net/ |
> | London W1K 5HJ         | E-Mail: cdhs@???        |
> \------------------------+-------------------------------------/

>


--

*** forwardfile.c    Thu Jul 20 12:08:47 2000
--- forwardfile-new.c    Fri Sep 15 00:33:16 2000
***************
*** 460,474 ****
        DEBUG(2) debug_printf("successful stat of %s\n", directory);
        }
      }
    saved_errno = errno;
    alarm(0);
    signal(SIGALRM, SIG_DFL);
  
    if (sigalrm_seen || rc != 0)
      {
!     addr->message = string_sprintf("failed to stat %s (%s)", directory,
!       sigalrm_seen? "timeout" : strerror(saved_errno));
!     yield = DEFER;
      goto RESTORE_UID;             /* skip forward */
      }
  
--- 460,491 ----
        DEBUG(2) debug_printf("successful stat of %s\n", directory);
        }
      }
+   else if (errno == ENOENT && !sigalrm_seen)
+     {
+     rc = stat(directory, &statbuf);
+     if (rc == 0)
+       {
+       DEBUG(2) debug_printf("successful stat of %s\n", directory);
+       }
+     }
    saved_errno = errno;
    alarm(0);
    signal(SIGALRM, SIG_DFL);
  
    if (sigalrm_seen || rc != 0)
      {
!     if (!sigalrm_seen && (errno == ENOENT || errno == ENOTDIR) && ob->ignore_enotdir)
!     {
!         DEBUG(2) debug_printf("non-directory on path %s: file assumed not to "
!           "exist\n", filename);
!         yield = DECLINE;
!     }
!     else
!     {
!       addr->message = string_sprintf("failed to stat %s (%s)", directory,
!         sigalrm_seen? "timeout" : strerror(saved_errno));
!       yield = DEFER;
!     }
      goto RESTORE_UID;             /* skip forward */
      }