Bug#736666: /usr/lib/sm.bin/mail.local: lockmailbox failed code 75 EX_TEMPFAIL

2015-12-23 Thread paul . szabo
I now verified that I get good results by changing mail.local.c (within
sendmail or sendmail-bin) as per patch below. My patch only addresses
the issue of locking the /var/mail/USER file (with minimal changes to
code); does not attempt to better handle group quotas, nor to improve
security by giving up privileges early.

Please consider adopting this patch or some similar change. 

Please re-assign this bug back to sendmail.

---

I am curious as to how does mail ever work for others: am I the last one
still using sendmail and mail.local for local delivery?

Thanks, Paul

Paul Szabo   p...@maths.usyd.edu.au   http://www.maths.usyd.edu.au/u/psz/
School of Mathematics and Statistics   University of SydneyAustralia


==


diff -r -U10 a/mail.local/mail.local.c b/mail.local/mail.local.c
--- a/mail.local/mail.local.c   2015-12-23 13:12:41.0 +1100
+++ b/mail.local/mail.local.c   2015-12-23 21:15:56.0 +1100
@@ -1408,24 +1408,52 @@
 */
 
 bool   Locked = false;
 
 #ifdef MAILLOCK
 int
 lockmbox(name)
char *name;
 {
int r = 0;
+/*
+ * Often we get here with RUID=0 EUID=user (why?!) and maillock()
+ * (or /usr/bin/dotlockfile within?) does not like that, can cope
+ * with RUID=user EUID=0 instead. Swap them... then swap back.
+ * Wonder whether could (should!) have given up all privileges,
+ * even setting "correct" GIDs, long ago...
+ */
+   uid_t ruid,euid;
+   int swapped = 0;
 
if (Locked)
return 0;
-   if ((r = maillock(name, 15)) == L_SUCCESS)
+
+   ruid = getuid();
+   euid = geteuid();
+   /* syslog(LOG_ERR, "Before maillock had r=%d e=%d", (int)getuid(), 
(int)geteuid()); */
+   if ((int)ruid == 0 && (int)euid != 0)
+   {
+   (void)setreuid(euid,ruid);
+   /* syslog(LOG_ERR, "Swapped, now r=%d e=%d", (int)getuid(), 
(int)geteuid()); */
+   swapped = 1;
+   }
+ 
+   r = maillock(name, 15);
+
+   if (swapped)
+   {
+   (void)setreuid(ruid,euid);
+   /* syslog(LOG_ERR, "Swapped back r=%d e=%d", (int)getuid(), 
(int)geteuid()); */
+   }
+
+   if (r == L_SUCCESS)
{
Locked = true;
return 0;
}
switch (r)
{
  case L_TMPLOCK:   /* Can't create tmp file */
  case L_TMPWRITE:  /* Can't write pid into lockfile */
  case L_MAXTRYS:   /* Failed after retrycnt attempts */
errno = 0;
@@ -1438,22 +1466,41 @@
errno = 0;
r = EX_UNAVAILABLE;
break;
}
return r;
 }
 
 void
 unlockmbox()
 {
+   uid_t ruid,euid;
+   int swapped = 0;
+
if (Locked)
+   {
+   ruid = getuid();
+   euid = geteuid();
+   /* syslog(LOG_ERR, "Before mailunlock had r=%d e=%d", 
(int)getuid(), (int)geteuid()); */
+   if ((int)ruid == 0 && (int)euid != 0)
+   {
+   (void)setreuid(euid,ruid);
+   /* syslog(LOG_ERR, "Swapped, now r=%d e=%d", 
(int)getuid(), (int)geteuid()); */
+   swapped = 1;
+   }
mailunlock();
+   if (swapped)
+   {
+   (void)setreuid(ruid,euid);
+   /* syslog(LOG_ERR, "Swapped back r=%d e=%d", 
(int)getuid(), (int)geteuid()); */
+   }
+   }
Locked = false;
 }
 #else /* MAILLOCK */
 
 char   LockName[MAXPATHLEN];
 
 int
 lockmbox(path)
char *path;
 {



Bug#736666: /usr/lib/sm.bin/mail.local: lockmailbox failed code 75 EX_TEMPFAIL

2015-12-22 Thread paul . szabo
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   p...@maths.usyd.edu.au   http://www.maths.usyd.edu.au/u/psz/
School of Mathematics and Statistics   University of SydneyAustralia


=

/*
   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 
#include 
#include 
#include 
#include 

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"); */
}



Bug#736666: /usr/lib/sm.bin/mail.local: lockmailbox failed code 75 EX_TEMPFAIL

2014-01-25 Thread Paul Szabo
Package: sendmail-bin
Version: 8.14.4-4
Severity: normal
File: /usr/lib/sm.bin/mail.local


The wheezy mail.local is unable to deliver mail. I was getting syslog
lines like:

Jan 26 07:41:37 bari mail.local[11136]: lockmailbox psz failed; error code 75 
Jan 26 07:41:37 bari sm-mta[11135]: s0PKfb67011134: 
to=p...@bari.maths.usyd.edu.au, delay=00:00:00, xdelay=00:00:00, 
mailer=local, pri=30977, dsn=4.0.0, stat=Deferred: local mailer 
(/usr/lib/sm.bin/mail.local) exited with EX_TEMPFAIL

Looking into the problem with strace, I noticed that running mail.local
with strace -f allowed it to succeed. A possible workaround is to move
mail.local to some new name and replacing or wrapping it with a script:

#!/bin/bash -
# mail.local fails, but behind strace it works just fine... weird??!!
# Start by doing:
#   mv -i /usr/lib/sm.bin/mail.local /usr/lib/sm.bin/mail.local.REAL
# then create this script in its place.
exec strace -o /dev/null -f /usr/lib/sm.bin/mail.local.REAL $@


=


The following short C code demonstrates the issue.


/*
   Testing with code mimicking sendmail mail.local .
   Compile with
 cc mytest.c -llockfile
   Fails when running plain or with strace, but succeeds
   when running with  strace -f  as shown below:
root# ./a.out
lockmailbox psz code 2 errno=1
root# strace -o outx ./a.out
lockmailbox psz code 2 errno=1
root# strace -o outy -f ./a.out
root# 
   Another oddity: in the output of strace -f I see
   geteuid32() return 0 within the children (in the execed
   /usr/bin/dotlockfile): should not that return 1001?
*/

#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);

/* change UID for quota checks */
if (setreuid(0, uid)  0)
{
printf(450 setreuid(0, %d) errno=%d (r=%d, e=%d)\n,
(int) uid, errno, (int) getuid(), (int) geteuid());
exit(1);
}

if ((off = maillock(p, 15)) != 0)
{
printf(lockmailbox %s code %d errno=%d\n, p, off, errno);
}

mailunlock();
}


=

Thanks, Paul

Paul Szabo   p...@maths.usyd.edu.au   http://www.maths.usyd.edu.au/u/psz/
School of Mathematics and Statistics   University of SydneyAustralia


-- Package-specific info:
Ouput of /usr/share/bug/sendmail-bin/script:

ls -alR /etc/mail:
/etc/mail:
total 124
drwxr-sr-x   7 smmta smmsp  1024 Jan 23 07:41 .
drwxr-xr-x 172 root  root  10240 Jan 23 11:11 ..
-rwxr-xr--   1 root  smmsp  8043 Jan 23 09:00 Makefile
-rw---   1 root  root   4261 Jan 22 12:35 access
-rw-r-   1 smmta smmsp  3072 Dec 22  2009 access.db
-rw-r--r--   1 root  smmsp 0 Dec 22  2009 aliases
-rw-r-   1 smmta smmsp  3072 Jan 23 07:41 aliases.db
-rw-r--r--   1 root  smmsp  2804 Jan 23 09:00 databases
-rw-r--r--   1 root  root   5657 Jul 17  2008 helpfile
-rw-r--r--   1 root  smmsp33 Dec 22  2009 local-host-names
drwxr-sr-x   2 smmta smmsp  1024 Dec 22  2009 m4
drwxr-xr-x   2 root  root   1024 Jan 22 12:35 peers
drwxr-xr-x   2 root  smmsp  1024 Jul 16  2008 sasl
-rw-r--r--   1 root  smmsp  9491 Jan 23 07:41 sendmail.cf
-rw-r--r--   1 root  root   8997 Jan 22 12:35 sendmail.cf.old
-rw-r--r--   1 root  root  10032 May  6  2002 sendmail.conf
-rw-r--r--   1 root  smmsp46 Jan 23 07:41 sendmail.mc
drwxr-sr-x   2 smmta smmsp  1024 Dec 22  2009 smrsh
-rw-r--r--   1 root  smmsp  8844 Jan 23 07:41 submit.cf
-rw-r--r--   1 root  smmsp55 Jan 22 12:35 submit.cf.errors
-rw-r--r--   1 root  root   8350 Jan 22 12:35 submit.cf.old
-rw-r--r--   1 root  smmsp59 Jan 23 07:41 submit.mc
drwxr-xr-x   2 smmta smmsp  1024 Dec 22  2009 tls
-rw-r--r--   1 root  smmsp 0 Dec 22  2009 trusted-users

/etc/mail/m4:
total 2
drwxr-sr-x 2 smmta smmsp 1024 Dec 22  2009 .
drwxr-sr-x 7 smmta smmsp 1024 Jan 23 07:41 ..
-rw-r- 1 root  smmsp0 Dec 22  2009 dialup.m4
-rw-r- 1 root  smmsp0 Dec 22  2009 provider.m4

/etc/mail/peers:
total 2
drwxr-xr-x 2 root  root  1024 Jan 22 12:35 .
drwxr-sr-x 7 smmta smmsp 1024 Jan 23 07:41 ..

/etc/mail/sasl:
total 2
drwxr-xr-x 2 root  smmsp 1024 Jul 16  2008 .
drwxr-sr-x 7 smmta smmsp 1024 Jan 23 07:41 ..

/etc/mail/smrsh:
total 2
drwxr-sr-x 2 smmta smmsp 1024 Dec 22  2009 .
drwxr-sr-x 7 smmta smmsp 1024 Jan 23 07:41 ..
lrwxrwxrwx 1 root  smmsp   26 Dec 22  2009 mail.local - 
/usr/lib/sm.bin/mail.local
lrwxrwxrwx 1 root  smmsp   17 Dec 22  2009 procmail - /usr/bin/procmail
lrwxrwxrwx 1 root  smmsp   17 Dec 22  2009 vacation - /usr/bin/vacation

/etc/mail/tls:
total 23
drwxr-xr-x 2 smmta smmsp 1024 Dec 22  2009 .
drwxr-sr-x 7 smmta smmsp 1024 Jan 23 07:41 ..
-rw-r--r-- 1 root  root 7 Dec 22  2009 no_prompt
-rw--- 1 root  root  1191 Dec 22  2009 sendmail-client.cfg
-rw-r--r-- 

Bug#736666: /usr/lib/sm.bin/mail.local: lockmailbox failed code 75 EX_TEMPFAIL

2014-01-25 Thread Andreas Beckmann
Control: reassign -1 liblockfile1 1.09-5
Control: affects -1 + sendmail-bin

On 2014-01-25 22:28, Paul Szabo wrote:
 The wheezy mail.local is unable to deliver mail. I was getting syslog
 lines like:
 
 Jan 26 07:41:37 bari mail.local[11136]: lockmailbox psz failed; error code 75 
 Jan 26 07:41:37 bari sm-mta[11135]: s0PKfb67011134: 
 to=p...@bari.maths.usyd.edu.au, delay=00:00:00, xdelay=00:00:00, 
 mailer=local, pri=30977, dsn=4.0.0, stat=Deferred: local mailer 
 (/usr/lib/sm.bin/mail.local) exited with EX_TEMPFAIL
 
 Looking into the problem with strace, I noticed that running mail.local
 with strace -f allowed it to succeed. A possible workaround is to move

sounds like a race condition, strace will change the timing ...

 The following short C code demonstrates the issue.
 
 
 /*
Testing with code mimicking sendmail mail.local .
Compile with
  cc mytest.c -llockfile
Fails when running plain or with strace, but succeeds
when running with  strace -f  as shown below:
 root# ./a.out
 lockmailbox psz code 2 errno=1
 root# strace -o outx ./a.out
 lockmailbox psz code 2 errno=1
 root# strace -o outy -f ./a.out
 root# 
Another oddity: in the output of strace -f I see
geteuid32() return 0 within the children (in the execed
/usr/bin/dotlockfile): should not that return 1001?
 */
 
 #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);
 
   /* change UID for quota checks */
   if (setreuid(0, uid)  0)
   {
   printf(450 setreuid(0, %d) errno=%d (r=%d, e=%d)\n,
   (int) uid, errno, (int) getuid(), (int) geteuid());
   exit(1);
   }
 
   if ((off = maillock(p, 15)) != 0)
   {
   printf(lockmailbox %s code %d errno=%d\n, p, off, errno);
   }
 
   mailunlock();
 }

Thanks for the testcase. Reassigning to liblockfile.


Andreas


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org