Re: [Exim] retry db owned by root

Top Page
Delete this message
Reply to this message
Author: Philip Hazel
Date:  
To: Kirill Miazine
CC: exim-users
Subject: Re: [Exim] retry db owned by root
On Wed, 27 Nov 2002, Kirill Miazine wrote:

> http://pub.krot.org/tmp/debug4.10.12



locking /var/spool/exim/db/retry.lockfile
locked /var/spool/exim/db/retry.lockfile
failed to open DB file /var/spool/exim/db/retry: Inappropriate file type or formatno retry data available


That output is odd, because I fixed the typo that has run two lines
together. Please look at lines 213-214 of dbfn.c. They should read:

   DEBUG(D_hints_lookup)
     debug_printf(CS string_open_failed(save_errno, "DB file %s\n", buffer));


Is the \n present?

However, that is a minor problem. The major problem still remains. I
think I understand the sequence of events now. From the debug output I
can deduce the following:

. Exim tried to open the database for reading, and it got that error.

. However, the DBM library created the file.

. Because the error was not ENOENT ("no such file or directory"), Exim
did not itself try to create the file.

. Because it did not try to create the file, it did not obey the code
that changes the owner to exim.

I think it is naughty of the library to create a file that the caller is
trying to open for reading. We can double-check this by inserting the
line

debug_printf("++++ flags=%d O_RDONLY=%d\n", flags, O_RDONLY);

at the start of the dbfn_open() function in dbfn.c, but I'm pretty sure
that flags will be O_RDONLY in this case.

Exim clearly can't run the code for ownership changing every time it
opens the file - that would be hugely wasteful for existing files.
Therefore, it needs to know when it creates the file.

It also seems rather wasteful to run a stat() on the file each time -
actually, that would be hard, because it doesn't in general know the
file name. The different DBM libraries have different conventions
for file names.

Hmm. I suppose I could change the code so that it runs the ownership
check EITHER if it knows it created the file, OR if there is any kind
of error of the original attempt to open the file. That would avoid
running it in most cases. OK. Below is a patch to try that.

If you can get away from your books for another 10 minutes...

--
Philip Hazel            University of Cambridge Computing Service,
ph10@???      Cambridge, England. Phone: +44 1223 334714.



*** exim-4.10.12/src/dbfn.c      Wed Nov 27 14:40:30 2002
--- dbfn.c     Thu Nov 28 09:48:55 2002
***************
*** 148,159 ****
  sprintf(CS buffer, "%s/db/%s", spool_directory, name);
  EXIM_DBOPEN(buffer, flags, EXIMDB_MODE, &(dbblock->dbptr));


! if (dbblock->dbptr == NULL && errno == ENOENT)
    {
-   DEBUG(D_hints_lookup)
-     debug_printf("%s appears not to exist: trying to create\n", buffer);
    created = TRUE;
!   EXIM_DBOPEN(buffer, flags|O_CREAT, EXIMDB_MODE, &(dbblock->dbptr));
    }


save_errno = errno;
--- 148,162 ----
sprintf(CS buffer, "%s/db/%s", spool_directory, name);
EXIM_DBOPEN(buffer, flags, EXIMDB_MODE, &(dbblock->dbptr));

! if (dbblock->dbptr == NULL)
    {
    created = TRUE;
!   if (errno == ENOENT)
!     {
!     DEBUG(D_hints_lookup)
!       debug_printf("%s appears not to exist: trying to create\n", buffer);
!     EXIM_DBOPEN(buffer, flags|O_CREAT, EXIMDB_MODE, &(dbblock->dbptr));
!     }
    }


save_errno = errno;