Most mail servers overwrite the 'Return-path' header sent by the PHP mail() function by a default email address (httpd@hostingcompany.com or apache@drupal.org). This is bad as the bounced emails will not be routed back to the sender or the original Return-path address. If you have your own server you can change it in the php.ini, but in the case of a shared hosting or on a multidomain server, you need to specify it for your own site.

The PHP mail() offers the additional_parameters to fix that. -fme@mysite.com will ensure that the Return-path of the email you send is me@mysite.com

This patch adds this line to the mail function of common.inc:

'-f'.$defaults['Return-Path']

and uses the site_mail variable as default Return-Path.

CommentFileSizeAuthor
#170 mail-131737-170.patch3.43 KBjvns
#169 mail-131737-169.patch3.66 KBjvns
#168 mail-131737-168.patch3 KBAlbert Volkman
#161 mail-131737-161.patch2.63 KBoriol_e9g
#156 131737.png124.89 KBkattekrab
#152 mail-131737-152.patch2.48 KBxjm
#151 mail-131737-150.patch2.3 KBxjm
#148 mail-131737-148.patch2.23 KBxjm
#135 131737-134.patch1.86 KBxjm
#135 interdiff-130-134.txt1.85 KBxjm
#130 131737-returnPath-130.patch2.03 KBaspilicious
#116 DefaultMailSystem-return_path-131737-115.patch2.42 KBpillarsdotnet
#112 DefaultMailSystem-return_path-131737-112.patch2.47 KBpillarsdotnet
#111 DefaultMailSystem-return_path-131737-111.patch2.41 KBpillarsdotnet
#110 DefaultMailSystem-return_path-131737-110.patch11.94 KBpillarsdotnet
#106 DefaultMailSystem-return_path-131737-106.patch1.89 KBpillarsdotnet
#100 131737-100.patch1.4 KBdhthwy
#97 131737_shut_mail_up_97.patch559 bytesscor
#79 properly_formatted_mail_return_path_d6.patch2.92 KBmalc0mn
#76 properly_formatted_mail_return_path_d6.patch2.29 KBmalc0mn
#65 properly_formatted_mail_return_path_d7.patch2.98 KBmalc0mn
#61 properly_formatted_mail_return_path_d7.patch2.98 KBmalc0mn
#59 properly_formatted_mail_return_path_d7.patch2.99 KBmalc0mn
#56 properly_formatted_mail_return_path_d7.patch3.03 KBmalc0mn
#53 properlyformattedmailreturnpath.patch3.05 KBmalc0mn
#49 propermailreturnpath.patch3.05 KBmalc0mn
#46 mailreturnpath.patch3 KBmalc0mn
#37 mailreturnpath.patch3 KBnvanhove
#31 131737-set-the-return-path-correctly-in-sendmail.patch2.21 KBmrfelton
#19 do-the-return-path-correctly_9.patch2.19 KBPancho
#17 return_path.patch1.05 KBv1nce
#9 Return-Path3.patch1.26 KBscor
#2 Return-Path2.patch1.4 KBscor
Return-Path.patch675 bytesscor
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Steven’s picture

Status: Active » Needs work
  • Please set the status of your issues with patches to "patch (code needs review)". This will make it show up in the patch queue, so others can find it and look at it.
  • For security reasons, you should use mime_header_encode() on the return path when passing it to mail(). That way, modules don't need to worry about header injection exploits.
  • You should use CVS to roll your patches. It is not only much faster, but it's also much easier for us to apply and test your patch locally. You should also roll your patches from the root of a Drupal tree and with the right arguments. Check the handbook for cvs diff instructions.
scor’s picture

FileSize
1.4 KB

All right. This should look better.
There are comments along with the code I added.

1. the default envelope Return-Path address is set: site-mail or ini_get('sendmail_from'). It will be overwritten by $from if it is present.
2. the return path is passed through mime_header_encode(), and then in the additional_parameters of mail().

Steven’s picture

What happens if you're not using sendmail?

scor’s picture

Nothing different than before. The patch makes sure that $return_path is not empty before applying it to the mail function.

+    if($return_path != ''){
+      $additional_parameters = '-f'. $return_path;
+    }

If no sendmail value is found through ini_get('sendmail_from'), then the default site-mail value is used.
I tried with a fresh install of drupal, and if no sendmail address is found (no from, no sendmail_from and no site-mail), then the emails are sent with an empty from field.

drewish’s picture

scor, why not just set the 'Return-Path' as part of the initial assignment of the $defaults array?

scor’s picture

This is already done, but the point of this patch is to add the -f option in the mail function, otherwise PHP will overwrite our return-path by the one set on the server. See the first post for more details.

scor’s picture

From the PHP Mail() function page:
- The additional_parameters parameter was added in PHP 4.0.5
- The additional_parameters parameter is disabled in safe_mode and the mail() function will expose a warning message and return FALSE when used (PHP 4.2.3)

That means they could be some issue on some configurations older than PHP 4.0.5.
There is a module here : http://drupal.org/project/returnpath
Don't you think it would be good to have this basic feature in the core instead of having to use an extra module?

drewish’s picture

we only support php 4.3.3 and higher

(personally i think it's silly some created a module for a one line patch)

scor’s picture

Status: Needs work » Needs review
FileSize
1.26 KB

re The additional_parameters parameter is disabled in safe_mode and the mail() function will expose a warning message and return FALSE when used (PHP 4.2.3)
-> I added the safe_mode compatibility to the patch.

What happens if you're not using sendmail?

Steven, I got it working fine on 3 different servers: postfix, Exim 4.63 and qmail (all with safe_mode OFF).

before: Return-Path: <httpd@web9.hostingcompany.com>
after: Return-Path: <myemail@mysite.com>

is there any chance to get this committed before next month?

scor’s picture

Does that patch need more testing before being commited?
I've been using it for a while now without any problem.

drewish’s picture

it's a pain in the ass getting enough reviews to get something committed. but it needs testing because if it gets committed and breaks a bunch of people's sites it's a pain in everyone's butt.

drumm’s picture

Status: Needs review » Needs work

I do not think this patch avoids or gracefully handles this:

The user that the webserver runs as should be added as a trusted user to the sendmail configuration to prevent a 'X-Warning' header from being added to the message when the envelope sender (-f) is set using this method. For sendmail users, this file is /etc/mail/trusted-users.

http://us3.php.net/manual/en/function.mail.php

This patch especially needs testing on a Windows server.

Damien Tournoud’s picture

Version: 5.x-dev » 7.x-dev

#252502: Sent emails rejected by mail servers when using PHP mail() was a duplicate.

Also bumping release because that "issue" (I would say "inconvenience", because drupal_mail_wrapper() exists just for this purpose) is present in all supported versions.

arhak’s picture

subscribing

AmrMostafa’s picture

I think this is a pretty important issue which I duplicated. But I also don't know of any portable way to achieve this (except not relying on PHP's mail()). The -f parameter is a sendmail option. Fortunately, all popular mail packages always come with a bin compatible with /usr/bin/sendmail. So -f should be fine across different *nixes.

Windows remains. Anyone on windows?

mustangduce’s picture

Component: user system » theme system

One key item to note here is the mail header. Unless the user that apache is running as is added to the /etc/mail/trusted-users file Sendmail will append a warning in the email header like this:

X-Authentication-Warning: webserver.hostingcompany.com: user set sender to address@somedomainname.com using -f

This is caught by most/all spam filtering agents (or at least the good ones). Make sure your provider has this configured, I have been with several that did not but after a brief call with thier support most agreed to make the change (one even changed thier server build SOP to add the apache user as a trusted user on every build!)

v1nce’s picture

FileSize
1.05 KB

Subscribing. Updated patch for d5.

scor’s picture

marking http://drupal.org/node/165938 as duplicate.

Pancho’s picture

Status: Needs work » Needs review
FileSize
2.19 KB

Here is the working patch for D7 from the duplicate issue...

Status: Needs review » Needs work

The last submitted patch failed testing.

Pancho’s picture

Status: Needs work » Needs review

@Damien in #13:
No. This is not just an incovenience. We're passing the header wrongly to PHP's mail() function - that's nothing less than a bug in core.

We can't expect admins to install a contrib module, only to achieve Drupal's core functionality works correctly.

Plus: contrib can not even solve it correctly. Return path module (which currently fixes it) is not compatible with other mail backends (see #98412: Incompatible with smtp.module (redeclared function)), because they all use drupal_mail_wrapper(), and it can be used only by one module at the same time.

So please let's go on testing and improving this, so this enerving bug finally gets fixed.

Damien Tournoud’s picture

@Pancho: in that case, you will need to do your homework. Will this "-f" flag works with non-sendmail backends? With Postfix? With Exim? With QMail? Under Windows? In safe mode? On shared hosting?

Also note that the "we can't have several mail backend" issue is being solved for D7 in #331180: fix pluggable smtp/mail framework.

Pancho’s picture

Sure. We can do all these tests on different backends, platforms and configurations. And surely I'm ready to take a major part of that work on me.

But since when is it the patch writer's duty to do all the testing work, "my homework" as you call it? I didn't say the patch were rtbc, did I? Sorry, but the way you put it is not okay.

Now, I'm working on another issue atm. But as soon as I'm done with that, I'll come back to this. Then I will check #331180, possibly rework this patch here and write a testing plan.

gpk’s picture

Component: base system » theme system
Status: Needs work » Needs review

@22: #9 says this can work with postfix, Exim 4.63 and qmail. It won't work with safe mode (would be best not to try -f in this case). In Windows there is the possibility of ini_set()-ting sendmail_from. I have -f working very nicely on cPanel shared hosting (PHP running as Apache module) - without any X-Warning header. See also http://drupal.org/node/165938#comment-1153548). I think cPanel automatically sorts out the question of "trusted" users.

The X-Warning header may be the killer though - see #12 and #16. Even if that is not a problem, this is all a bit of a mess :P

BTW is there a use case for using returnpath and smtp contrib modules at the same time? SMTP servers seem to set the Return-Path: for you. (OK, returnpath and a mime email backend is a realistic but incompatible combination in D6/D5).

[slightly updated]

sun’s picture

Component: theme system » base system
Status: Needs review » Needs work

The popular PHPMailer library just does the following (simplified):

public function MailSend($header, $body) {
  ...
  $params = sprintf("-oi -f %s", $this->Sender);

  if (strlen(ini_get('safe_mode')) < 1) {
    $old_from = ini_get('sendmail_from');
    ini_set('sendmail_from', $this->Sender);
    @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
  }
  else {
    @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
  }
  if (isset($old_from)) {
    ini_set('sendmail_from', $old_from);
  }
}

I.e. the additional flag(s) are set if defined safe_mode is disabled, and 'sendmail_from' is overidden for Windows.

The same is done for the sendmail method.

gpk’s picture

Component: theme system » base system
Status: Needs review » Needs work

Yes...

... and if it doesn't work on your particular server (i.e. you get X-Warning headers) then you can try another sending method, e.g. sendmail (as you mention), or smtp.

FWIW I think Joomla bundles PHPMailer, but from a quick glance at the code I couldn't work out which sending method it uses or how it handles this problem.

mfb’s picture

Subscribe.

malc0mn’s picture

I'm confused about these lines in http://drupal.org/files/issues/do-the-return-path-correctly_9_0.patch:

+    // If 'Return-Path' isn't already set in php.ini, we pass it separately
+    // as an additional parameter instead of in the header.
+    // However, if PHP's 'safe_mode' is on, this is not allowed.
+    if (isset($headers['Return-Path']) && !ini_get('safe_mode')) {
+      $return_path_set = strpos(ini_get('sendmail_path'), ' -f');
+      if (!$return_path_set) {
+        $message['Return-Path'] = $headers['Return-Path'];
+        unset($headers['Return-Path']);
+      }
+    }

This does not allow you to override the Return-Path using the mail_alter hook. Was this intentional?

I've adapted the patch for a site I'm maintaining to:

+    if (isset($message['headers']['Return-Path'])) {
+      $return_path_set = strpos(ini_get('sendmail_path'), ' -f');
+      if (!$return_path_set) {
+        $message['Return-Path'] = $message['headers']['Return-Path'];
+        unset($message['headers']['Return-Path']);
+      }
+    }

Should this not be the intention instead of the original code? I'm guessing it was, since it was placed after the drupal_alter() call.

rapsli’s picture

subscribing

mrfelton’s picture

subscribing

mrfelton’s picture

I agree with @malc0mn in #28. Attached is the modified patch:

nvanhove’s picture

Subscribing.

@mrfelton: shouldn't the status be "needs review" right now?

mrfelton’s picture

@nvanhove: yes, forgot to update status. thanks.

mrfelton’s picture

Status: Needs work » Needs review

@nvanhove: yes, forgot to update status. thanks.

Status: Needs review » Needs work

The last submitted patch, 131737-set-the-return-path-correctly-in-sendmail.patch, failed testing.

nvanhove’s picture

Hmmm patch didn't work. Probably because it is so old.
@mrfelton: could you redo the patch?

nvanhove’s picture

FileSize
3 KB

Recreated #31

nvanhove’s picture

Status: Needs work » Needs review
malc0mn’s picture

I can confirm that this has helped us out on numerous occasions. How about adding it to the core in a new release?

nvanhove’s picture

@malc0mn, if you can confirm the patch in #37 works in Drupal7, we could get it in :)

malc0mn’s picture

Good point, I'll see what I can do!

Dries’s picture

Status: Needs review » Reviewed & tested by the community

I think this is a valid bug report, and from what I can tell (and reading the PHP docs), the fix looks correct.

malc0mn’s picture

Just finished setting up the latest dev release as a sandbox on our dev environment to test the patch.

EDIT:

Version used: February 3, 2010 - 14:04, drupal-7.x-dev.tar.gz, 2.19 MB e2145089f78c88d46660d7973906701b

Patching went nicely:

$ patch -p0 < mailreturnpath.patch 
patching file includes/mail.inc
patching file modules/system/system.mail.inc

And for the testing:

1. Logs without patch:

Feb  3 15:02:14 development sendmail[94598]: o13E2EX8094598: from=www, size=953, class=0, nrcpts=1, msgid=<201002031402.o13E2EX8094598@ourserver.be>, relay=www@localhost

Feb  3 15:02:14 development sm-mta[94599]: o13E2E6W094599: from=<www@ourserver.be>, size=1182, class=0, nrcpts=1, msgid=<201002031402.o13E2EX8094598@ourserver.be>, proto=ESMTP, daemon=IPv4, relay=localhost [127.0.0.1]

Feb  3 15:02:14 development sendmail[94598]: o13E2EX8094598: to=my@mail.com, ctladdr=www (80/80), delay=00:00:00, xdelay=00:00:00, mailer=relay, pri=30953, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (o13E2E6W094599 Message accepted for delivery)

Feb  3 15:02:14 development sm-mta[94601]: o13E2E6W094599: to=<my@mail.com>, ctladdr=<www@ourserver.be> (80/80), delay=00:00:00, xdelay=00:00:00, mailer=relay, pri=31182, relay=[X.X.X.X] [X.X.X.X], dsn=2.0.0, stat=Sent (Ok: queued as B82BA33C14)

Bad, baaaad! ;-)

2. Logs with patch:

Feb  3 15:03:55 development sendmail[94618]: o13E3tlb094618: Authentication-Warning: development.int.nascom.be: www set sender to drupal.site@admin.be using -f

Feb  3 15:03:55 development sendmail[94618]: o13E3tlb094618: from=drupal.site@admin.be, size=911, class=0, nrcpts=1, msgid=<201002031403.o13E3tlb094618@ourserver.be>, relay=www@localhost

Feb  3 15:03:55 development sm-mta[94619]: o13E3t52094619: from=<drupal.site@admin.be>, size=1322, class=0, nrcpts=1, msgid=<201002031403.o13E3tlb094618@ourserver.be>, proto=ESMTP, daemon=IPv4, relay=localhost [127.0.0.1]

Feb  3 15:03:57 development sendmail[94618]: o13E3tlb094618: to=my@mail.com, ctladdr=drupal.site@admin.be (80/80), delay=00:00:02, xdelay=00:00:02, mailer=relay, pri=30911, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (o13E3t52094619 Message accepted for delivery)

Feb  3 15:03:57 development sm-mta[94621]: o13E3t52094619: to=<my@mail.com>, delay=00:00:02, xdelay=00:00:00, mailer=relay, pri=31322, relay=[X.X.X.X] [X.X.X.X], dsn=2.0.0, stat=Sent (Ok: queued as 4B32433C14)

Saweeet! ;-)

NOTE: the warning you see in the logs nicely shows the patch is doing what it should. The warning can be avoided by adding www as trusted mail user.

Nico Heulsen’s picture

Nice work.. This realy should be into core!

mfb’s picture

Status: Reviewed & tested by the community » Needs work

The comments mention safe_mode but the current version of the patch doesn't actually check for safe_mode.

malc0mn’s picture

FileSize
3 KB

Bad news. If PHP is run in safe mode, this patch will trigger some errors:

    *  Warning: mail(): SAFE MODE Restriction in effect. The fifth parameter is disabled in SAFE MODE in DefaultMailSystem->mail()  (line 76 of /data/drupal7-sandbox/static/drupal-7.x-dev/modules/system/system.mail.inc).
    * Unable to send e-mail. Contact the site administrator if the problem persists.

Somwhere along the way we seem to have dropped this bit of code:

<?php
 && !ini_get('safe_mode')
?>

I have attached a modified patch to correct this, and looking into a 2nd problem that has been introduced by this line:

<?php
$message['Return-Path'] ? '-f ' . $message['Return-Path'] : ''
?>

-f is not allowed in the safe mode.

nvanhove’s picture

Status: Needs work » Needs review
nvanhove’s picture

That seems to be my patch instead of yours?

malc0mn’s picture

FileSize
3.05 KB

OK, I think the patch attached here does the trick, please ignore or even better delete the patch in my previous post since I cannot seem to do this myself.

The annoying thing is that when we're in safe mode, the fifth parameter in the PHP mail() function is not allowed. You can pass whatever you want (null, an empty string, ...) PHP will complain about this, hence the somewhat silly approach in the patch to work around this. If someone has a better idea, please let me know!

My fix in attach which only patches the modules/system/system.mail.inc file, not the includes/mail.inc file.
The previous patch swapped the order of some variables in incudes/mail.inc which in my humble opinion, and proven during my testing, makes no difference.

malc0mn’s picture

@#48: only slightly modified. I should not have posted it, for which my apologies. If only I could delete it...

scor’s picture

+++ modules/system/system.mail.inc	(working copy)
@@ -41,23 +41,55 @@
+     } else {
+      // the fifth parameter is not allowed in safe mode
+      // no matter what you set for the fifth parameter (NULL, '', ...),
+      // PHP will always 'complain'
+      // so this means bad headers when in safe mode, unless php.ini is
+      // set up correctly

} else { should be in two lines. also, comments can run up to the 80th characters, so we could save some space here.

usually comments are not deleted from the issue queues.

malc0mn’s picture

I will fix this!

malc0mn’s picture

@#51: revised patch in attach (formatted else & comments running to col 80)

Refer to #49 for more information concerning the patch.

scor’s picture

Status: Needs review » Needs work
+++ modules/system/system.mail.inc	(working copy)
@@ -41,23 +41,55 @@
+      }
+    } ¶
+  ¶
+  ¶
+  ¶
+  ¶

we don't need so many empty lines here. Please also fix the whitespaces issues in both code blocks.

malc0mn’s picture

I simply took them form the original patch, however I shall remove them.

malc0mn’s picture

New patch with fixed formatting attached, as requested.

nvanhove’s picture

Status: Needs work » Needs review
sun’s picture

+++ modules/system/system.mail.inc	(working copy)
@@ -41,23 +41,50 @@
+    if(isset($message['Return-Path']) && !ini_get('safe_mode')) {

Missing space after "if".

+++ modules/system/system.mail.inc	(working copy)
@@ -41,23 +41,50 @@
+      $mail_result =  mail(
...
+      $mail_result =  mail(

Duplicate space here.

+++ modules/system/system.mail.inc	(working copy)
@@ -41,23 +41,50 @@
+        // Note: e-mail uses CRLF for line-endings. PHP's API requires LF
+        // on Unix and CRLF on Windows. Drupal automatically guesses the
+        // line-ending format appropriate for your system. If you need to
+        // override this, adjust $conf['mail_line_endings'] in settings.php.
+        preg_replace('@\r?\n@', $line_endings, $message['body']),
+        // For headers, PHP's API suggests that we use CRLF normally,
+        // but some MTAs incorrectly replace LF with CRLF. See #234403.
+        join("\n", $mimeheaders),
...
+        preg_replace('@\r?\n@', $line_endings, $message['body']),
+        join("\n", $mimeheaders)

Ideally, we should prepare those two arguments before the conditional execution logic, so 1) no duplicate code and 2) no missing docs in the else case.

+++ modules/system/system.mail.inc	(working copy)
@@ -41,23 +41,50 @@
+      // the fifth parameter is not allowed in safe mode no matter what you set
+      // for the fifth parameter (NULL, '', ...), PHP will always 'complain' so
+      // this means bad headers when in safe mode, unless php.ini is set up
+      // correctly

This comment needs some love. :)

"The optional $additional_parameters argument to mail() is not allowed if safe_mode is enabled. Passing any value throws a PHP warning and makes mail() return FALSE."

Powered by Dreditor.

malc0mn’s picture

@58: very true concerning the preparation of the arguments... Why didn't I see/do that in the first place :(

New patch in attach solving:

- space issues 'if (' and ' = mail('
- lovely comments
- preparation of mail() arguments

scor’s picture

+++ modules/system/system.mail.inc	(working copy)
@@ -41,23 +41,53 @@
+    // prepare mail commands

Make this a sentence: start with upper case and end with '.'

+++ modules/system/system.mail.inc	(working copy)
@@ -41,23 +41,53 @@
+      );    ¶

last trailing space to be removed

malc0mn’s picture

sun’s picture

Status: Needs review » Reviewed & tested by the community

Thanks - looks good to me.

mfb’s picture

Status: Reviewed & tested by the community » Needs work

There is some wrong indentation (single space instead of two)

sun’s picture

+++ modules/system/system.mail.inc	(working copy)
@@ -41,23 +41,53 @@
+     }
+     else {

Takes a bit to see that there's one leading space too much here, right ;)

Powered by Dreditor.

malc0mn’s picture

@64: Removed those...

nvanhove’s picture

Status: Needs work » Needs review

@malc0mn don't forget to set the status back to needs review so the testbot will pick it up.

malc0mn’s picture

Ah ratz, thanks nvanhove.

sun’s picture

Status: Needs review » Reviewed & tested by the community

Thanks! There we go.

malc0mn’s picture

Fantastic!

Shall I do one for the D6 branch as well?

sebas5384’s picture

Return-Path.patch queued for re-testing.

malc0mn’s picture

@70: that patch would break when running in safe mode... I have a D6 one ready, but want to test it first before submitting. Will be submitting tomorrow morning after testing.

But we'll have to change from 7.x to 6.x in the satus-settings-thingy, no?

scor’s picture

@malc0mn: usually patches get committed to D7 first and then get backported to D6.

malc0mn’s picture

@scor: I was aware of that, hence my question for the D6 one. I have it ready and will post tomorrow.

Can I simply change the version of this issue to '6.x-dev' (& status to 'needs review')when posting the D6 patch or do I need to start a new issue?

scor’s picture

@malc0mn: please leave the version of this issue to 7.x. If you like, post your D6 patch here for the records, and say it's for D6. It can later be picked up (and this issues switched to D6) when D7 is fixed.

malc0mn’s picture

Thanks scor, will do that!

malc0mn’s picture

@74: Scor, D6 patch attached. Made against latest Drupal6 HEAD branch.

Tested in both regular and PHP safe mode.

Dries’s picture

Version: 7.x-dev » 6.x-dev
Status: Reviewed & tested by the community » Needs review

Committed to CVS HEAD. Moving to D6.

scor’s picture

Status: Needs review » Needs work

patch for D6 in #76 should be rerolled using cvs diff -up, see http://drupal.org/patch/create

malc0mn’s picture

Dang, I usually do that... Apparently forgot it here. Done properly now in attach.

malc0mn’s picture

Component: base system » mail system
Status: Needs work » Needs review

component = mail system + needs review

malc0mn’s picture

Anyone had a chance to review this one for D6...? Used it a while now and encountered no probs...

Shawn DeArmond’s picture

#17 worked for me for D5. However, I also had to add this to my theme in order for the Return-Path to be the right address when a webform is submitted and email is sent:

<?php
function phptemplate_webform_mail_headers($form_values, $node, $sid, $cid) {
  $email_form_value = $node->webform['email_from_address'];
  $headers = array(
    'X-Mailer' => 'Drupal Webform (PHP/'. phpversion() .')',
    'Return-Path' => $form_values['submitted'][$email_form_value],
  );
  return $headers;
}
?>
lostchord’s picture

Sorry if this is a really dumb question...but where is the envelope address configured in the Site Configuration?

I'm assuming the intent here is to make it per-site rather than per-server so that in a multi-site environment the email is fully tailored to each site.

I don't see any way of doing this in the D6 configuration at present and as far as I could tell the patches don't seem to add an extra configuration option. So maybe it's there already and I'm just not looking in the right place?

cheers

nvanhove’s picture

There is no configuration option.

We set the Envelope to be as the "From" address:
$headers['From'] = $headers['Sender'] = $headers['Errors-To'] = $headers['Return-Path'] = $default_from;

mfb’s picture

Configurability could be a nice feature request for Drupal 8. My experience is you want the "From:" address to be customer service and the envelope "From" to be technical staff who can handle bounces etc.

lostchord’s picture

I was rather hoping that it would get dropped into D6. I'm using an edit to php.ini to fix this at present and it's not really the right solution. That's what started me searching the forums in the first place.

I think the configurable nature of this would be critical. It should (a) be configurable, and (b) the two addresses should have independent access control so that the envelope From can only be set by the technical staff.

The current solution would, I suspect, open up the possibility of an incorrect address entry silently killing all email from a site.

cheers

lostchord’s picture

FYI

Out of curiosity - and as part of trying to solve this in my own environment - I looked at the headers from a drupal.org email:

Return-Path: <apache@drupal.org>
Errors-To: info@drupal.org
Sender: info@drupal.org
From: info@drupal.org

cheers

turadg’s picture

Why does the patch get the return path from the -f argument in sendmail_path instead of from sendmail_from?

(Referring to properly_formatted_mail_return_path_d6_0.patch )

mrf’s picture

Patch in #79 works well for me in 6.17

guidot’s picture

Status: Needs review » Reviewed & tested by the community

Applied #79 on two D6.17-installations. Works. Thanks very much!

Gábor Hojtsy’s picture

Status: Reviewed & tested by the community » Needs review

This issue is going on for three years, and looks like only half of these notes were addressed, repeated by Steven, Damien and drumm:

The additional_parameters parameter can be used to pass additional flags as command line options to the program configured to be used when sending mail, as defined by the sendmail_path configuration setting. For example, this can be used to set the envelope sender address when using sendmail with the -f sendmail option.

The user that the webserver runs as should be added as a trusted user to the sendmail configuration to prevent a 'X-Warning' header from being added to the message when the envelope sender (-f) is set using this method. For sendmail users, this file is /etc/mail/trusted-users.

From feedback above, looks like other tools are sendmail compatible, so we can reliably pass the -f argument to those. However, two things I've not seen solved:

1. Windows testing was requested multiple times but nobody said they did it.
2. The trusted user issue was not resolved so looks like we are trading one problem for another nasty one.

Who has the answers?

drupalfan2’s picture

I applied patch #79 correctly but no mails come back. Why?
How can I find out, why this does not work?

aspilicious’s picture

Version: 6.x-dev » 7.x-dev

Scor told me to push this back to d7.
I got the following error on my hosting site when a user registrates.
I don't know why, I don't understand what's going on.

Warning: mail(): Policy restriction in effect. The fifth parameter is disabled on this system in DefaultMailSystem->mail() (regel 77 van /customers/chirohoepertingen.be/chirohoepertingen.be/httpd.www/modules/system/system.mail.inc).

Host: one.com

I'm open for any kind of experiment...

sun’s picture

If that also means that no e-mail was/is sent, then I suppose this issue needs to be critical, as users installing D7 may not be able to send or get any mails.

Damien Tournoud’s picture

mail() is one of those PHP functions that gets abused by some hosters. I think we should do the same as for set_time_limit(), and just ignore the warnings triggered by this function using the @ operator. We do have the return value of the function to tell us if the mail was queued or not anyway.

aspilicious’s picture

No problem at all with the mails. User gets created, mails arrive. Just a stupid warning that scares people ;).
Can someone write a patch to ignore this?

(so I can fix my website)

scor’s picture

FileSize
559 bytes

@aspilicious: want to try this patch? implements damz's idea.

aspilicious’s picture

Solved my issue, for me this is rtbc, but I'm not a mail code guru.

dhthwy’s picture

The caution note for Windows on PHP's mail() doc page can be disregarded for 5.2 as it already handles this automatically (this may not be true for PHP < 5.2):

/* This pattern escapes \n. inside the message body. It prevents
 * premature end of message if \n.\n or \r\n.\r\n is encountered
 * and ensures that \n. sequences are properly displayed in the
 * message body. */
#define PHP_WIN32_MAIL_DOT_PATTERN      "\n."
#define PHP_WIN32_MAIL_DOT_REPLACE      "\n.."

On Windows when there is no Sendmail, the 5th parameter passed to mail() is ignored, so it doesn't use -f as that's a Sendmail (and friends) parameter. PHP will use its own internal SMTP mail implementation which gets "Return-Path:" from the ini variable "sendmail_from" and if that is not set, it gets "Return-Path:" from "From:".

X-Authentication-Warning is a problem for any software that uses Sendmail with the -f parameter when its user is not on the trust list. This includes Wordpress, Web-based mailers such as Squirrelmail and popular forums such as Vbulletin, etc. This header is added by Sendmail itself and it's a server configuration problem. There is nothing Drupal can do to deal with this short of locating and parsing the server's Sendmail configuration files (and having a trusted-user file is optional btw).

Worst case scenario is that the email with the X-Authentication-Warning header set will be rejected by the receiving SMTP server, however, the SMTP server would have to have very strict policies for it to reject it based on that alone. And this header is not exactly uncommon, even for legit emails.

dhthwy’s picture

FileSize
1.4 KB

As #95 points out, PHP error notices should be inhibited when calling mail(), since there's still a good probability that mail() succeeded.

In order to support Return-Path on Windows we need to set the sendmail_from ini variable. This is what the PHPMailer class in Wordpress does.

xtoc’s picture

xtoc’s picture

I have added the patch from #79 with wincvs, but how can i set a return_path. Where do i need to config that?

bbista4u’s picture

Return-Path.patch queued for re-testing.

devonwarren’s picture

Return-Path.patch queued for re-testing.

pillarsdotnet’s picture

Version: 7.x-dev » 8.x-dev
Issue tags: +Needs backport to D7

Bumping and tagging as per standard policy.

pillarsdotnet’s picture

Re-rolled #100 against 8.x according to current patch guidelines. No other changes.

pillarsdotnet’s picture

Status: Needs review » Needs work

The last submitted patch, DefaultMailSystem-return_path-131737-106.patch, failed testing.

pillarsdotnet’s picture

Status: Needs work » Needs review
Issue tags: +Needs backport to D6, +Needs backport to D7
pillarsdotnet’s picture

Improved patch specifically tests for Windows before modifying the Windows-only setting.

pillarsdotnet’s picture

Sorry; inadvertently included another patch.

Here's the correct one. (Wish there was some way to remove an inadvertently-added patch from the testing queue....)

pillarsdotnet’s picture

Title: Return-Path overwritten by the PHP mail() function » Ensure that the Return-Path is set when sending mail on both Windows and non-Windows systems.
FileSize
2.47 KB

Better title and comments.

pillarsdotnet’s picture

sgabe’s picture

Status: Needs review » Needs work

@pillarsdotnet: Did you test this patch in safe_mode? You can't use additional parameters in safe mode, even if it's NULL it will throw a warning and mail() will return FALSE. However, the rest looks good.

Warning: mail() [function.mail]: SAFE MODE Restriction in effect. The fifth parameter is disabled in SAFE MODE in ...

sgabe’s picture

@pillarsdotnet: I see you have fixed this in HTML Mail, a new patch here still would be nice.

pillarsdotnet’s picture

Status: Needs work » Needs review
FileSize
2.42 KB

Yeah, I found that out and had to fix it on the above projects. Re-rolling...

pillarsdotnet’s picture

pillarsdotnet’s picture

pillarsdotnet’s picture

starkos’s picture

FWIW, on my host, mail sending fails with no error message. If I remove the space in the '-f ' flag, it works fine: '-f' . $message['Return-Path']

If it doesn't matter otherwise, might be worth removing the space.

pillarsdotnet’s picture

@#120: Note that the patch in #116 does remove the space between -f and the return-path address.

sos4nt’s picture

On my host (*nix system, safe mode disabled) mail sending fails when passing a fifth parameter to mail(). There should be a configuration option to disable the use of the fifth parameter.

geerlingguy’s picture

Hitting some strange return-path issues with Windows server. Additionally, this issue could use a little better summary (if possible), as there's a lot of discussion since the OP that takes a bit of time to work through...

darnzen’s picture

I had this problem on one site and it was driving me crazy. The D6 patch posted #76 fixed it. I initially tried putting a ini_set('sendmail_path', '/usr/sbin/sendmail -i -t -fmyemail@returnaddr.com') in the settings.php file, but that didn't work for some reason. Might have something to do with the emails getting sent in a cron run.

pillarsdotnet’s picture

We are still waiting for someone to review (and mark as RTBC) the patch in #116.

If nobody is willing to do that, we might as well mark this issue closed (won't fix).

pillarsdotnet’s picture

Status: Needs review » Closed (won't fix)

Closing for lack of interest. Please re-open only if you are willing to provide a patch review.

sun’s picture

Status: Closed (won't fix) » Needs review
Issue tags: +Windows
aspilicious’s picture

Ok I had a lot of problems with this on my localhost (windows) and on my live sites. (one.com)
The patch works and removes all the warnings.
All mails get delivered.

On localhost there is one warning left: "Error occured, contact administrator if problem persist" (my own translation cause the site is in dutch. Anyway thnx for the patch :D

Note: tested in d7 had to reroll the patch in 116

aspilicious’s picture

aspilicious’s picture

FileSize
2.03 KB

Here is a D8 reroll if its needed

xjm’s picture

It seems that this solution is well-tested. See #128, #124, #120, and relevant affected contrib projects in #113.

(Note for reviewers, as I did a double-take on this: The lack of space between the -f flag and the return path is intended. See #120 / #121.)

I can't think of a way to write a test for this bug, since it is tied to specific server/environment configurations.

If this passes testbot, I believe this is RTBC.

chx’s picture

Status: Needs review » Reviewed & tested by the community

The thing is, even if we could write an automated test, it'd be written in a way that only runs when Windows is present so the testbot would happily ignore. We certainly wont be worse off this committed than not.

Edit: The problem with the test is not Windows but sending a mail for real and checking results.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

I would invert the logic of the if/then; this code is far more likely to run on non-Windows hosts, so that should be default check.

xjm’s picture

Assigned: Unassigned » xjm

On it.

xjm’s picture

Status: Needs work » Needs review
FileSize
1.85 KB
1.86 KB

Inverted the logic and switched the order of the if/else. Sending for a date with testbot.

xjm’s picture

Assigned: xjm » Unassigned
aspilicious’s picture

Windows machine localhost fails:

"Unable to send e-mail. Contact the site administrator if the problem persists."

Could be a localhost xamp issue.
Other live hosts (not windows) don't report errors anymore.

aspilicious’s picture

Ok lets clarify :)

- Before patch:

* cheap shared hosts ==> mail arrives but warnings because of fifth parameter
* Localhost fails: this warning and mail doesn't arrive

Warning: mail() [function.mail]: Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in DefaultMailSystem->mail() (line 76 of C:\xampp\htdocs\drupal8\modules\system\system.mail.inc).

Unable to send e-mail. Contact the site administrator if the problem persists.

- After patch

* cheap shared host ==> mail arrives and no warning
* Localhost: only this warning but mail doesn't arrive

Unable to send e-mail. Contact the site administrator if the problem persists.

aspilicious’s picture

Status: Needs review » Reviewed & tested by the community

Ok as it turns out this was a xamp localhost mailing issue. Moving back to rtbc.

aspilicious’s picture

Same patch applies to D7.

catch’s picture

Status: Reviewed & tested by the community » Needs work

We're still checking for safe_mode but the comment explaining why has disappeared from the patch (also there's no else { any more so what happens if it's enabled now?).

xjm’s picture

+++ b/modules/system/system.mail.incundefined
@@ -66,25 +66,30 @@ class DefaultMailSystem implements MailSystemInterface {
     if (isset($message['Return-Path']) && !ini_get('safe_mode')) {
...
-    else {
-      // The optional $additional_parameters argument to mail() is not allowed
-      // if safe_mode is enabled. Passing any value throws a PHP warning and
-      // makes mail() return FALSE.
-      $mail_result = mail(
-        $message['to'],
-        $mail_subject,
-        $mail_body,

Clarifying after following up in IRC: This is the "else" condition and comment catch is referring to. There's no case now for when safe mode is true; both our cases are inside the first if. I'll look back in previous patches for when the change was made.

xjm’s picture

It looks like the safe mode else case went away as far back as #110. #114 and #122 refer to safe mode. There's also a lot of discussion about it earlier in the issue, but since it goes back to 2007 it's hard to say what's relevant and what's not. Can someone clarify what is supposed to happen when safe mode is enabled? Is it intended that the mail is simply not sent?

pillarsdotnet’s picture

Can someone clarify what is supposed to happen when safe mode is enabled? Is it intended that the mail is simply not sent?

No, that was not the intent. Clearly there was a logic error in my patches.

xjm’s picture

Assigned: Unassigned » xjm

Alright, I'll quickly reroll with the deleted else condition then. Thanks!

Edit: Also, it looks like the windows condition can be the same regardless, so I'll refactor it a little.

catch’s picture

fwiw since safe mode is deprecated in PHP 5.3 I'd be fine with throwing warnings when it's enabled in 8.x, but for backport we shouldn't change behaviour.

xjm’s picture

Oops, lost this one in a crosspost.

xjm’s picture

Status: Needs work » Needs review
FileSize
2.23 KB

Alright, I re-added a case for safe mode on non-Windows systems. I also added a comment to indicate that the lack of space between -f and the optional parameter is intentional.

One thing I noticed is that I can't find an explicit explanation here for the addition of @ to suppress warnings from mail(). The closest I can find is sun's comment in #25. We should probably add a comment justifying why we do this, since it's not exactly a best practice generally.

Edit: Found that explanation in #95.

xjm’s picture

Assigned: xjm » Unassigned

Status: Needs review » Needs work

The last submitted patch, mail-131737-148.patch, failed testing.

xjm’s picture

FileSize
2.3 KB

Wrong diff again... sorry.

xjm’s picture

Status: Needs work » Needs review
FileSize
2.48 KB

With that comment explaining the @.

Please test this patch with:

  1. Windows.
  2. Non-Windows.
  3. Non-Windows with safe mode enabled.
xjm’s picture

Issue tags: +Needs manual testing

Please test #152 and report which of the three scenarios you tested and what the results were. Thanks!

xjm’s picture

@aspilicious reported in IRC that he tested the patch on "a crappy host" with safe mode enabled with a limiting PHP configuration as well as on a Windows localhost, and in both cases the mail was sent successfully, without error messages. (Without the patch, he gets errors when attempting to send mail in both cases.)

kattekrab’s picture

Tested on ubuntu / php5.3 / apache / postfix.

First test
Return path is set to site_mail with safe_mode disabled. : mail sent ok

Return path is set to www-data@... with safe_mode enabled. : mail sent ok

Second test
Unable to send mail at all - but this may be unrelated. Will reboot and try again.

kattekrab’s picture

FileSize
124.89 KB

Ok!

Sorry it's taken so long to get back to this. Patch tested. Screenshots attached.

All good. Double plus good for ubuntu 10.04 / php5.3 / apache / postfix

:)

aspilicious’s picture

Status: Needs review » Reviewed & tested by the community

OMFG YEES!

xjm’s picture

To clarify, as I understand the error messages seen in #156 are the result of safe mode file system configuration issues unrelated to the mail issue. The emails were sent properly both with and without safe mode. :)

xjm’s picture

Alright, posting with less New Year's Eve this time.

  • aspilicious tested the patch on a windows localhost as well as a "remote host" with a limiting configuration that had caused error messages without the patch. In both cases the message was sent fine without the error.
  • KatteKrab tested the patch on a non-Windows install both with and without safe mode enabled.
  • Both times, she set me as the recipient for the message, and I received it. (ACROSS THE INTERNET!)
  • Without safe mode enabled, there were no error messages, as seen in the top third of the screenshot.
  • The bottom two thirds of the screenshot are with safe mode enabled, before and after the message is sent. So, the error message seen in the screenshot was present before sending the message as well as after. This is related to a misconfiguration of the filesystem for safe mode (lots of results on d.o if you search for this message; see for example #979462: using xcache: fopen() [function.fopen]: SAFE MODE Restriction in effect. The script whose uid is X is not allowed to access /tmp and http://drupal.org/node/655992). So it's not related to the patch.
catch’s picture

Version: 8.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Thanks folks. Committed/pushed to 8.x. Will need a re-roll for 7.x.

oriol_e9g’s picture

Status: Patch (to be ported) » Needs review
FileSize
2.63 KB

Status: Needs review » Needs work

The last submitted patch, mail-131737-161.patch, failed testing.

oriol_e9g’s picture

Status: Needs review » Needs work

Poll test error?? WTF! O.o I'm going to try a re-test.

oriol_e9g’s picture

Status: Needs work » Needs review

#161: mail-131737-161.patch queued for re-testing.

xjm’s picture

Status: Needs work » Reviewed & tested by the community
webchick’s picture

Version: 7.x-dev » 6.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)
Issue tags: -Needs backport to D7

Committed and pushed to 7.x. Thanks!

Moving down to D6. Needs a re-roll there.

David_Rothstein’s picture

Note that the D7 commit for this issue seems to have accidentally included the fix for #1353030: Increase length of "alt" and "title" text for images as well.

Albert Volkman’s picture

Status: Patch (to be ported) » Needs review
FileSize
3 KB

D6 backport.

jvns’s picture

FileSize
3.66 KB

In the patch on #168, $message['Return-Path'] never gets set, so the -f parameter never gets added. This is because the part of the code from system.mail.inc that sets $message['Return-Path'] is missing.

Here's an updated patch which fixes this. Copied everything in the mail() function in system.mail.inc into the initial else{} clause of drupal_mail_send. I've tested it on a Linux server with postfix, and it seems to work correctly, where the patch in #168 doesn't.

jvns’s picture

FileSize
3.43 KB

The patch in #169 doesn't work. Here's an updated patch which I've tested more thoroughly and sends mail correctly on a Linux server with postfix.

mstrelan’s picture

#170 works for me on exim.

ifixyourpc’s picture

Version: 6.x-dev » 7.18

Hi all,
Total Drupal Noob here and wondered if you could assist..
I got my Template installed but am getting the return path error (i believe)..

Notice: mail(): Policy restriction in effect. The fifth parameter is disabled on this system in DefaultMailSystem->mail() (line 76 of /customers/2/0/a/samanthascakes.co.uk/httpd.www/modules/system/system.mail.inc).
Notice: mail(): Policy restriction in effect. The fifth parameter is disabled on this system in DefaultMailSystem->mail() (line 76 of /customers/2/0/a/samanthascakes.co.uk/httpd.www/modules/system/system.mail.inc).

Is it the "system.mail.inc" file i need to edit?


/**
 * @file
 * Drupal core implementations of MailSystemInterface.
 */

/**
 * The default Drupal mail backend using PHP's mail function.
 */
class DefaultMailSystem implements MailSystemInterface {
  /**
   * Concatenate and wrap the e-mail body for plain-text mails.
   *
   * @param $message
   *   A message array, as described in hook_mail_alter().
   *
   * @return
   *   The formatted $message.
   */
  public function format(array $message) {
    // Join the body array into one string.
    $message['body'] = implode("\n\n", $message['body']);
    // Convert any HTML to plain-text.
    $message['body'] = drupal_html_to_text($message['body']);
    // Wrap the mail body for sending.
    $message['body'] = drupal_wrap_mail($message['body']);
    return $message;
  }

  /**
   * Send an e-mail message, using Drupal variables and default settings.
   *
   * @see http://php.net/manual/en/function.mail.php
   * @see drupal_mail()
   *
   * @param $message
   *   A message array, as described in hook_mail_alter().
   * @return
   *   TRUE if the mail was successfully accepted, otherwise FALSE.
   */
  public function mail(array $message) {
    // If 'Return-Path' isn't already set in php.ini, we pass it separately
    // as an additional parameter instead of in the header.
    // However, if PHP's 'safe_mode' is on, this is not allowed.
    if (isset($message['headers']['Return-Path']) && !ini_get('safe_mode')) {
      $return_path_set = strpos(ini_get('sendmail_path'), ' -f');
      if (!$return_path_set) {
        $message['Return-Path'] = $message['headers']['Return-Path'];
        unset($message['headers']['Return-Path']);
      }
    }
    $mimeheaders = array();
    foreach ($message['headers'] as $name => $value) {
      $mimeheaders[] = $name . ': ' . mime_header_encode($value);
    }
    $line_endings = variable_get('mail_line_endings', MAIL_LINE_ENDINGS);
    // Prepare mail commands.
    $mail_subject = mime_header_encode($message['subject']);
    // Note: e-mail uses CRLF for line-endings. PHP's API requires LF
    // on Unix and CRLF on Windows. Drupal automatically guesses the
    // line-ending format appropriate for your system. If you need to
    // override this, adjust $conf['mail_line_endings'] in settings.php.
    $mail_body = preg_replace('@\r?\n@', $line_endings, $message['body']);
    // For headers, PHP's API suggests that we use CRLF normally,
    // but some MTAs incorrectly replace LF with CRLF. See #234403.
    $mail_headers = join("\n", $mimeheaders);
    if (isset($message['Return-Path']) && !ini_get('safe_mode')) {
      $mail_result = mail(
        $message['to'],
        $mail_subject,
        $mail_body,
        $mail_headers,
        // Pass the Return-Path via sendmail's -f command.
        '-f ' . $message['Return-Path']
      );
    }
    else {
      // The optional $additional_parameters argument to mail() is not allowed
      // if safe_mode is enabled. Passing any value throws a PHP warning and
      // makes mail() return FALSE.
      $mail_result = mail(
        $message['to'],
        $mail_subject,
        $mail_body,
        $mail_headers
      );
    }
    return $mail_result;
  }
}

/**
 * A mail sending implementation that captures sent messages to a variable.
 *
 * This class is for running tests or for development.
 */
class TestingMailSystem extends DefaultMailSystem implements MailSystemInterface {
  /**
   * Accept an e-mail message and store it in a variable.
   *
   * @param $message
   *   An e-mail message.
   */
  public function mail(array $message) {
    $captured_emails = variable_get('drupal_test_email_collector', array());
    $captured_emails[] = $message;
    variable_set('drupal_test_email_collector', $captured_emails);
    return TRUE;
  }
}


pillarsdotnet’s picture

Version: 7.18 » 6.x-dev
jerry’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

The D6 backport in #170 works fine for me on 6.34. Let's get this committed, if possible.

Status: Reviewed & tested by the community » Closed (outdated)

Automatically closed because Drupal 6 is no longer supported. If the issue verifiably applies to later versions, please reopen with details and update the version.