[net.bugs.4bsd] 4.2 lost mail

crp@ccivax.UUCP (Chuck Privitera) (01/14/85)

Index:	bin/mail.c 4.2BSD

Description:
	Queued mail to a local user never gets delivered and nobody
	is notified of the failure.
Repeat-By:
	Add the line:
		Odqueue
	to ~/.mailcf. Send mail to a local user. It will never be
	delivered. The letter will show up in /usr/spool/mqueue/syslog
	with stat=Sent, but it really wasn't.
Fix:
	The problem is that when sendmail runs the mail queue,
	it invokes /bin/mail as the sender, and uses the -r
	(set from person) option. /bin/mail exits with a usage
	error but never sets a bad exit status, so sendmail thinks
	all went well. The first step to this solution was to
	have /bin/mail set an error when invoked illegally.
	This change will at least tell sendmail that there was
	a problem so that it will return the mail to the sender.
	A context diff follows:

Script started on Mon Jan 14 09:33:58 1985
root(21)> rcsdiff -c3 -r1.2 -r1.3 mail.c
RCS file: RCS/mail.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -c3 -r1.2 -r1.3
*** /tmp/,RCSt1001235   Mon Jan 14 09:34:29 1985
--- /tmp/,RCSt2001235   Mon Jan 14 09:34:35 1985
***************
*** 455,460
                            strcmp(my_name, "network") &&
                            strcmp(my_name, "uucp")) {
                                usage();
                                done();
                        }
                        gaver++;

--- 455,461 -----
                            strcmp(my_name, "network") &&
                            strcmp(my_name, "uucp")) {
                                usage();
+                               error = EX_NOPERM;
                                done();
                        }
                        gaver++;
***************
*** 612,617
  {
  
        fprintf(stderr, "Usage: mail [ -f ] people . . .\n");
  }
  
  #include <sys/socket.h>

--- 613,619 -----
  {
  
        fprintf(stderr, "Usage: mail [ -f ] people . . .\n");
+       error = EX_USAGE;
  }
  
  #include <sys/socket.h>

crp@ccivax.UUCP (Chuck Privitera) (01/14/85)

Index:	usr.lib/sendmail/src/envelope.c 4.2BSD

Description:
	When delivering queued mail, sendmail incorrectly invokes
	the mailer with the -r or -f (set sender) option, causing
	local mail to be dropped on the floor. Remote mail goes
	O.K.
Repeat-By:
	Force mail to a local user to be queued either by cranking
	the load up over 8, specifying -odq on the command line, or
	adding Odqueue to ~/.mailcf. If you have not installed the
	fix to /bin/mail suggested in the previous article, the local
	user will never get the message, and /usr/spool/mqueue/syslog
	will say that the letter was sent. If you have installed the
	fix to /bin/mail, the mail will be returned with an insufficient
	permission error.
Fix:
	There are actually two (or more?) possible fixes for this.
	The first one (not listed here) is to change /bin/mail's
	-r option to allow the user to specify the from person,
	iff they are a trusted user, or if the  person they are
	trying to become is the same as the person that they are.
	Just as sendmail's -f option is documented to work. This does
	not seem unreasonable, but it does seem more like a kludge
	AROUND the problem instead of a fix FOR the problem.
	(This was the first approach we took here with much
	success, but I had a bit of a guilty concience about
	doing it this way). The real problem is with a check in
	sendmail/envelope.c/setsender(), around line 592, there is a
	permission check that looks like:
		...
		... && getuid() != 0)
			from = NULL;

	I've ommitted the rest of the statement on purpose, because
	of its (documented in the code) questionable security. It
	will also be ommitted in the fix, but there is only one
	check that looks anything like this so ... The check for
	getuid() != 0 is to allow su'ed people to use the -f option to
	sendmail. However, when running the queue, this check
	is false (i.e. getuid() == 0).  The correct test should
	be:
>                   questionable code  && 
>                   (QueueRun || getuid() != 0) )
	

crp@ccivax.UUCP (Chuck Privitera) (01/16/85)

I know this article shouldn't go to net.unix-wizards, but the
original was posted there. 

In article <276@uw-beaver> Voradesh Yenbut writes:

> I found that sendmail, compiled with DBM defined, does not call
> initaliases() before it processes queued mails.  So, it will fail
> when looking for an alias name of a local recipient.  As quoted from
> Version.c of sendmail,

>> D 4.16	83/10/16 16:08:08	eric	382	381
>> MRs:	
>> Postpone opening the alias DBM file until after the fork in srvrsmtp so
>> that the alias database is as current as possible; thanks to dagobah!efo
>> (Eben Ostby) for this one.

> it looks like sendmail version 4.16 and above may have this kind of
> problem.

I don't know about you, but my sendmail does alias expansion when
the mail is queued. In the mainline code for sendmail, there is a
switch which does alias initialization only if:
	1. You are running as newaliases (or -bi option given)
	2. You are not running in daemon mode.
Thus, alias expansions are done when you submit mail, so the
only time the daemon has to worry about doing alias expansions
is when mail is submitted via SMTP. And as the note in Version.c
says, initaliases is called in srvrsmtp.

My question is this: has anybody installed this and is it really
necessary?

crp@ccivax.UUCP (Chuck Privitera) (04/11/85)

Description:
	A couple months back in article <276@uw-beaver>, Voradesh
	Yenbut stated:

>	I found that sendmail, compiled with DBM defined, does not
>	call initaliases() before it processes queued mails.  So,
>	it will fail when looking for an alias name of a local
>	recipient.

	Shortly thereafter in article <230@ccivax.UUCP> I rebutted:

>	I don't know about you, but my sendmail does alias expansion when
>	the mail is queued. In the mainline code for sendmail, there is a
>	switch which does alias initialization only if:
>		1. You are running as newaliases (or -bi option given)
>		2. You are not running in daemon mode.
>	Thus, alias expansions are done when you submit mail, so the
>	only time the daemon has to worry about doing alias expansions
>	is when mail is submitted via SMTP. And as the note in Version.c
>	says, initaliases is called in srvrsmtp.

	I ended this article with the question: Is Voradesh's
	fix really necessary? Nobody has responded and I have
	been bitten by NOT installing his fix.

	We have implemented a hashed password file as described in
	the Toronto Usenix conference talk on improving system perform-
	ance.  To make sendmail use the hashed password file, we used
	mdbm distributed on the net (so you can have more than
	one dbm database open at one time). With mdbm, you reference
	a database with a pointer to a structure mdbm (much like
	stdio's FILE pointers), this is how I got bitten. The database
	was never opened so the pointer to the structure mdbm was
	null. While my argument above is entirely valid, sendmail
	still tries to do alias expansion on queue runs. So if you
	use plain ol' dbm, accesses to the database will quietly
	fail but the mail will still be delivered because the
	expansion is already complete. But for future considerations
	(I think 4.2+, 4.3 or whatever will use a hashed password
	 file), you should install Voradesh's fix.
Repeat-by:
	If you really want, use mdbm instead of dbm in sendmail
	and queue a mail message (to anybody, not just an alias).
Fix:
	For those of you who missed it:


> ==================================================================
>   SCCSID(@(#)queue.c	4.2		3/11/84	(no queueing));
> 
> *** /tmp/,RCSt1002663	Fri Dec 21 12:02:11 1984
> --- queue.c	Mon Dec  3 09:35:01 1984
> ***************
> *** 256,261
>   		/* child -- double fork */
>   		if (fork() != 0)
>   			exit(EX_OK);
>   	}
>   # ifdef LOG
>   	if (LogLevel > 11)
> 
> --- 258,266 -----
>   		/* child -- double fork */
>   		if (fork() != 0)
>   			exit(EX_OK);
> + 
> + 		/* open the alias database */
> + 		initaliases(AliasFile, FALSE);
>   	}
>   # ifdef LOG
>   	if (LogLevel > 11)
>