Now at jessie, I find that my "strace trick" does not work anymore. Testing with my cutdown code suggests that the culprit may be the ... setreuid(0,uid) ... in original mail.local, as changing that to either of setreuid(uid,0) setreuid(uid,uid) allows maillock() to succeed.
The comments in mail.local were that it changed UID to better handle quota checks. But then: - should not it change GID also? - do quotas go by real or effective IDs? So many questions... more digging required. Test code below: cut down long ago from mail.local, not yet verified whether mail.local code changed since. Cheers, Paul Paul Szabo [email protected] http://www.maths.usyd.edu.au/u/psz/ School of Mathematics and Statistics University of Sydney Australia ===== /* Testing code mimicking sendmail mail.local . Compile with cc mytest.c -llockfile Fails if we use ... setreuid(0, uid) ... as in original mail.local, but succeeds with either ... setreuid(uid, 0) ... or ... setreuid(uid, uid) ... so maybe bug is in sendmail, after all. */ #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <errno.h> #include <maillock.h> int main(argc, argv) int argc; char *argv[]; { /* name and UID of some plain user */ char *p = "psz"; uid_t uid = 1001; int off; /* use a reasonable umask */ (void) umask(0077); /* This was setreuid(0,uid) in original sendmail mail.local */ /* change UID for quota checks */ if (setreuid(uid, uid) < 0) { printf("450 setreuid(0, %d) errno=%d (r=%d, e=%d)\n", (int) uid, errno, (int) getuid(), (int) geteuid()); exit(1); } /* printf("Before:\n"); system("ls -al /var/mail"); */ if ((off = maillock(p, 15)) != 0) { printf("lockmailbox %s code %d errno=%d\n", p, off, errno); } /* printf("During:\n"); system("ls -al /var/mail"); */ mailunlock(); /* printf("After:\n"); system("ls -al /var/mail"); */ }

