This is copied from a debian bug report that I opened. As a result, some
of the line numbers below may not match the source package, but they
should be close enough that it doesn't matter.
From the documentation:
-- begin --
SetSender
Unless this is explicitly given as false, we attempt to automatically
set the -f argument to the first address that can be extracted from
the "From:" field of the message (if there is one).
What is the -f, and why do we use it?
Suppose we did not use -f, and you gave an explicit "From:" field in
your message: in this case, the sendmail "envelope" would indicate the
real user your process was running under, as a way of preventing mail
forgery. Using the -f switch causes the sender to be set in the
envelope as well.
-- end --
A simple test case:
root@test:~# cat test.pl
#!/usr/bin/perl -w
use strict;
use MIME::Lite;
my $msg = MIME::Lite->new(
From =>'foo@hrsmart.com',
To =>'sallen@hrsmart.com',
Subject =>'Helloooooo, nurse!',
Data =>"How's it goin', eh?"
);
$msg->send();
root@test:~# perl test.pl
root@test:~# tail -3 /var/log/exim/mainlog
2006-09-11 10:30:04 1GMnjX-0007Br-00 <= root@hrsmart.com U=root P=local
S=507
2006-09-11 10:30:04 1GMnjX-0007Br-00 => sallen@hrsmart.com R=lookuphost
T=remote_smtp H=mail.hrsmart.com [xx.xx.xx.xx]
2006-09-11 10:30:04 1GMnjX-0007Br-00 Completed
Here's the resulting message source:
X-Real-To: sallen@hrsmart.com
Return-Path: <root@hrsmart.com>
Received: from test.hrsmart.com ([xx.xx.xx.xx] verified)
by franklin.hrsmart.com (SMTP)
with ESMTP id 2191773 for sallen@hrsmart.com; Mon, 11 Sep 2006
10:30:20 -0500
Received: from root by test.hrsmart.com with local (Exim 3.36 #1 (Debian))
id 1GMnjX-0007Br-00
for <sallen@hrsmart.com>; Mon, 11 Sep 2006 10:30:03 -0500
Content-Disposition: inline
Content-Length: 19
Content-Transfer-Encoding: binary
Content-Type: text/plain
MIME-Version: 1.0
X-Mailer: MIME::Lite 3.01 (F2.72; B3.04; Q3.03)
Date: Mon, 11 Sep 2006 15:30:02 UT
From: foo@hrsmart.com
To: sallen@hrsmart.com
Subject: Helloooooo, nurse!
Message-Id: <E1GMnjX-0007Br-00@test.hrsmart.com>
How's it goin', eh?
An alternate test case:
root@test:~# cat test.pl
#!/usr/bin/perl -w
use strict;
use MIME::Lite;
my $msg = MIME::Lite->new(
From =>'foo@hrsmart.com',
To =>'sallen@hrsmart.com',
Subject =>'Helloooooo, nurse!',
Data =>"How's it goin', eh?"
);
$msg->send_by_sendmail();
root@test:~# perl test.pl
root@test:~# tail -3 /var/log/exim/mainlog
2006-09-11 10:36:50 1GMnq6-0007Cg-00 <= foo@hrsmart.com U=root P=local S=507
2006-09-11 10:36:50 1GMnq6-0007Cg-00 => sallen@hrsmart.com R=lookuphost
T=remote_smtp H=mail.hrsmart.com [xx.xx.xx.xx]
2006-09-11 10:36:50 1GMnq6-0007Cg-00 Completed
Message source:
X-Real-To: sallen@hrsmart.com
Return-Path: <foo@hrsmart.com>
Received: from test.hrsmart.com ([xx.xx.xx.xx] verified)
by franklin.hrsmart.com (SMTP)
with ESMTP id 2191967 for sallen@hrsmart.com; Mon, 11 Sep 2006
10:37:06 -0500
Received: from root by test.hrsmart.com with local (Exim 3.36 #1 (Debian))
id 1GMnq6-0007Cg-00
for <sallen@hrsmart.com>; Mon, 11 Sep 2006 10:36:50 -0500
Content-Disposition: inline
Content-Length: 19
Content-Transfer-Encoding: binary
Content-Type: text/plain
MIME-Version: 1.0
X-Mailer: MIME::Lite 3.01 (F2.72; B3.04; Q3.03)
Date: Mon, 11 Sep 2006 15:36:50 UT
From: foo@hrsmart.com
To: sallen@hrsmart.com
Subject: Helloooooo, nurse!
Message-Id: <E1GMnq6-0007Cg-00@test.hrsmart.com>
How's it goin', eh?
Things to note:
1. The log lines in test #2 shows the message from foo, not root.
2. The Return-Path header in #2 shows the message from foo, not root.
These are the effects of the SetSender flag. It is supposed to be active
by default, per the documentation.
The problem is a result of an inconsistency in send_by_sendmail, which I
am filing an additional bug report about. send_by_sendmail has two
"modes" of operation. In the first, if arguments are passed in, no
further processing is done. A pipe is opened to sendmail, and the
message is sent using that pipe. The sendmail instance is executed using
only the arguments passed in to send_by_sendmail; no further processing
is done. This means the SetSender flag is ignored.
The *actual* problem causing this issue is because the send() function
uses default arguments for send_by_sendmail, which triggers the
inconsistent behaviour noted above. From the module source:
380 ### Our sending facilities:
381 my $Sender = "sendmail";
382 my %SenderArgs = (
383 "sendmail" => ["$SENDMAIL -t -oi -oem"],
384 "smtp" => [],
385 "sub" => [],
386 );
.... <snip> ....
2440 sub send {
2441 my $self = shift;
2442
2443 if (ref($self)) { ### instance method:
2444 my ($method, @args);
2445 if (@_) { ### args; use them
just this once
2446 $method = 'send_by_' . shift;
2447 @args = @_;
2448 }
2449 else { ### no args; use
defaults
2450 $method = "send_by_$Sender";
2451 @args = @{$SenderArgs{$Sender} || []};
2452 }
2453 $self->verify_data if $AUTO_VERIFY; ### prevents
missing parts!
2454 return $self->$method(@args);
2455 }
.... <snip> ....
2536 sub send_by_sendmail {
2537 my $self = shift;
2538
2539 if (@_ == 1) { ### Use the given command...
2540 my $sendmailcmd = shift @_;
2541
2542 ### Do it:
2543 open SENDMAIL, "|$sendmailcmd" or Carp::croak "open
|$sendmailcmd: $!\n";
2544 $self->print(\*SENDMAIL);
2545 close SENDMAIL;
2546 return (($? >> 8) ? undef : 1);
2547 }
2548 else { ### Build the command...
2549 my %p = @_;
2550 $p{Sendmail} ||= "/usr/lib/sendmail";
2551
2552 ### Start with the command and basic args:
2553 my @cmd = ($p{Sendmail}, @{$p{BaseArgs} || ['-t', '-oi',
'-oem']});
2554
2555 ### See if we are forcibly setting the sender:
2556 $p{SetSender} = 1 if defined($p{FromSender});
2557
2558 ### Add the -f argument, unless we're explicitly told
NOT to:
2559 unless (exists($p{SetSender}) and !$p{SetSender}) {
2560 my $from = $p{FromSender} || ($self->get('From'))[0];
Suggested fixes:
1. Move the default argument construction to a separate function:
sub build_sendmail_args
{
# do the work occurring in lines 2549 - 2965
}
2. Change Sender Args like so:
380 ### Our sending facilities:
381 my $Sender = "sendmail";
382 my %SenderArgs = (
383 "sendmail" => [ build_sendmail_args() ],
384 "smtp" => [],
385 "sub" => [],
386 );
3. Modify sub send_by_sendmail to use build_sendmail_args (to avoid code
duplication)
4. Modify the documentation:
SetSender
Unless this is explicitly given as false **or unless you override the
arguments being passed to sendmail**, we attempt to automatically set
the -f argument to the first address that can be extracted from the
"From:" field of the message (if there is one).