PHP mail and ISP relays

This did my head in so I thought it worthy of a small write up.

Here the problem: I wanted to send an email from a DRUPAL 5.12 site hosted on a home linux configured with sendmail/postfix and a SMART RELAYHOST.

Sounds simply enough.

Here is my simple test program in PHP to send an email.

$Name = "Da Duder";
$email = "";
$recipient = "";
$mail_body = "The text for the mail...";
$subject = "Subject for reviewer";
$header = "From: ". $Name . " <" . $email . ">\r\n";
mail($recipient, $subject, $mail_body, $header);

Doesn't get easier than that. Now this is where the fun starts. If you look at the mail log.

Mail log says postfix. I thought the problem might have been to do with my sendmail configuration so I installed postfix. It turns out that it wasn't related both suffer from the same fate.


Dec  3 16:05:53 elmo postfix/pickup[13979]: 06BCA92EE80: uid=48 from=<apache>
Dec  3 16:05:53 elmo postfix/cleanup[14081]: 06BCA92EE80: message-id=<20081203160553.06BCA92EE80@elmo.local>
Dec  3 16:05:53 elmo postfix/qmgr[13980]: 06BCA92EE80: from=<apache@elmo.local>, size=330, nrcpt=1 (queue active)
Dec  3 16:05:53 elmo postfix/smtp[14083]: 06BCA92EE80: to=<>,[]:25, delay=0.21, delays=0.06/0.02/0.07/0.06, dsn=2.0.0, status=sent (250 OK id=1L7sEh-0000Yg-Kl)
Dec  3 16:05:53 elmo postfix/qmgr[13980]: 06BCA92EE80: removed

You see that the envelope-sender is actually apache@elmo.local this address is checked by spam's filter says “Hay that not valid I'll reject that”.

So what you need to do is tell sendmail that it should use the “from:” as the envelope sender too.

Small modification to the PHP and this is done. Why did that take me an hours to figure out? God only knows.

mail($recipient, $subject, $mail_body, $header,'-f'.$email);

So back to DRUPAL the PHP mail() function is wrapped by the function drupal_mail() in the includes/ file.

So we tweak the invokation like so:

function extract_email_from($string){
  preg_match_all("/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]+/i", $string, $matches);
  return $matches[0][0];
function drupal_mail($mailkey, $to, $subject, $body, $from = NULL, $headers = array()) {
.. snip ..
    return mail(
      str_replace("\r", '', $body),
      join("\n", $mimeheaders),
      '-f '.extract_email_from($defaults['From'])