[Exim] disabling .forward files & ignore_enotdir

Top Page
Delete this message
Reply to this message
Author: Corin Hartland-Swann
Date:  
To: exim-users
Subject: [Exim] disabling .forward files & ignore_enotdir

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:

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 */
      }