38

I am using PHP with Apache on Linux, with Sendmail. I use the PHP mail function. The email is sent, but the envelope has the Apache_user@localhostname in MAIL FROM (example nobody@conniptin.internal) and some remote mail servers reject this because the domain doesn't exist (obviously). Using mail, can I force it to change the envelope MAIL FROM?

EDIT: If I add a header in the fourth field of the mail() function, that changes the From field in the headers of the body of the message, and DOES NOT change the envelope MAIL FROM.

I can force it by spawning sendmail with sendmail -t -odb -oi -frealname@realhost and piping the email contents to it. Is this a better approach?

Is there a better, simpler, more PHP appropriate way of doing this?

EDIT: The bottom line is I should have RTM. Thanks for the answers folks, the fifth parameter works and all is well.

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
codebunny
  • 2,829
  • 3
  • 22
  • 24

6 Answers6

78

mail() has a 4th and 5th parameter (optional). The 5th argument is what should be passed as options directly to sendmail. I use the following:

mail('to@blah.com','subject!','body!','From: from@blah.com','-f from@blah.com');
Lucas Oman
  • 15,597
  • 2
  • 44
  • 45
  • 2
    Note: You may need to add the sender to /etc/mail/trusted-users as well. – Devon Oct 07 '08 at 15:33
  • Couldn't find trusted-users on my machine :/ – Doug Molineux May 25 '11 at 22:37
  • 10
    @Lucas Oman: +1 your answer is right, just wanted to warn whoever might be interested that on almost all shared hosting services (cPanel/WHM) the PHP mail function 5th parameter `-f ...` is disabled by `SAFE MODE Restriction in effect` and would simply show a PHP Warning without changing the default envelope-from therefor your answer in these cases would not be an option. And regarding Devon comment the `/etc/mail/trusted-users` can not be changed on shared hosting because belongs to the main server configuration. – Marco Demaio Aug 08 '11 at 18:49
  • 2
    Adding to my last comment `safe_mode` is DEPRECATED since PHP 5.3.0 [ref. http://php.net/manual/en/features.safe-mode.php] therefor if your shared hosting service still has got it you can complain to its tech support. When PHP `safe_mode` is `Off` the Lucas Oman answer works perfectly. – Marco Demaio Aug 09 '11 at 11:08
  • This doesn't work on Windows (which sends via SMTP). Only when using sendmail. For windows you need to modify PHP config or call `ini_set('sendmail_from', 'yourmail@example.com');`. – Simon East Aug 27 '14 at 05:52
2

PHP Official documentation for mail()

bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )

...

additional_parameters (optional)

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.

This parameter is escaped by escapeshellcmd() internally to prevent command execution. escapeshellcmd() prevents command execution, but allows to add additional parameters. For security reasons, it is recommended for the user to sanitize this parameter to avoid adding unwanted parameters to the shell command.

Since escapeshellcmd() is applied automatically, some characters that are allowed as email addresses by internet RFCs cannot be used. mail() can not allow such characters, so in programs where the use of such characters is required, alternative means of sending emails (such as using a framework or a library) is recommended.

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.

Val Kornea
  • 4,469
  • 3
  • 40
  • 41
  • any idea where would i find the equivalent to `/etc/mail/trusted-users` in a non unix environment like shared hosting? – oldboy Mar 21 '18 at 02:28
1

You can try this (im not sure tho):

ini_set("sendmail_from", yourmail@example.com);
mail(...);
ini_restore("sendmail_from");
Joe Scylla
  • 701
  • 3
  • 5
  • Good idea, I tried this on shared hosting, but unfortunately this is not a workaround because when `safe_mode=On` even the `ini_set("sendmail_from"` is ignored. And when `safe_mode=Off` Lucas Oman answer is easier and faster [http://stackoverflow.com/questions/179014/how-to-change-envelope-from-address-using-php-mail/179061#179061] – Marco Demaio Aug 09 '11 at 11:16
  • 1
    This only works on Windows servers (as noted in PHP.ini), but great tip. – Simon East Aug 28 '14 at 07:09
1

I would also recommend checking into PHPMailer. It's great for creating and sending email, making the process a lot easier, along with support for SMTP.

Darryl Hein
  • 142,451
  • 95
  • 218
  • 261
  • PHPMailer seems to use exactly the PHP mail 5th paramater `-f ...` as suggested by Lucas Oman in his answer above. You can see it in `function MailSend` in PHPMailer source file `class.phpmailer.php` – Marco Demaio Aug 08 '11 at 18:45
0

following to php manual additinal -f parameter need to be passed to mail function

Not as many write here "-f from@email.com" but without white space "-ffrom@email.com"

https://www.php.net/manual/en/function.mail.php

See example#4 in manual

Tony
  • 11
  • 1
-10

What you actually need to do is change the hostname of the machine Apache is running on, plus the user Apache is running as.

In your current case it is:

  • Apache user:nobody
  • Server hostname: conniptin.internal

Changing those two values is pretty simple and will solve the root of your problem.

Although if you need to do it from PHP then perhaps use the system/exec functions. I do not think it will work in practice though, as you need to restart Apache and probably also the entire host for the new names to be used.

mr-euro
  • 2,732
  • 5
  • 23
  • 27
  • Changing the hostname, and running Apache as a different user, have far-reaching consequences (serious security consequences in the latter case) and are often not permitted by organisation policy or by your shared hosting provider. – qris Dec 10 '13 at 08:53
  • Well, this DID solve MY problems (after some googling)... But I am on a VPS. – Roemer Jan 02 '16 at 16:39