modifying PHP settings

Print Friendly, PDF & Email

Consider the following trivial PHP script:

<?php

if( $rv = mail("scott.anderson@wellesley.edu",
   "test email from PHP",
   "body of message" ) ) {
   echo "Success!";
} else {
   echo "Failed:  $rv\n";
}

?>

When I ran this, either from the command line (running as an ordinary user) or via Apache, it *worked* (I got the email and the word “success” was printed), but there was also the following error message:

Warning: mail(/var/log/maillog): failed to open stream: 
Permission denied in /home/ruhlman/public_html/rapp/test-email1.php 
on line 5 Success!

This seemed like an easy thing to fix, but it was anything but.  My first thought was that PHP was connecting to sendmail to send the message, and sendmail wasn’t configured properly.  But every other method of sending mail worked without error.  Furthermore, the /var/log/maillog file was showing the mail messages, so that couldn’t be it.

I used “strace” on the php script, running it as an ordinary user (not Apache):

strace php test-email1.php

And that showed data like this:

lstat("/var/log/maillog", {st_mode=S_IFREG|0620, st_size=35752, ...}) = 0
lstat("/var/log", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/var/log/maillog", O_WRONLY|O_CREAT|O_APPEND, 0666) = -1 EACCES (Permission denied)
write(2, "PHP Warning:  mail(/var/log/mail"..., 139PHP Warning:  mail(/var/log/maillog): failed to open stream: Permission denied in /home/ruhlman/public_html/rapp/test-email1.php on line 5
) = 139
write(1, "\nWarning: mail(/var/log/maillog)"..., 135
Warning: mail(/var/log/maillog): failed to open stream: Permission denied in /home/ruhlman/public_html/rapp/test-email1.php on line 5
) = 135

which I interpreted to mean that PHP was trying to write to /var/log/maillog by itself!  Which means the script would be trying to write to the maillog as me if I ran the script.  Well, that was never going to work and shouldn’t work.  There’s no way I’m going to change /var/log/maillog to be world-writable, and that seemed the only solution.

So, I need to change the place that PHP tries to log mail messages. That’s set in /etc/php.ini to be /var/log/maillog, which is the default.  (Usually, a default is a pretty good value, but I don’t see how this one is ever going to be right.)

Now, the PHP manual tells you that for any PHP configuration variable, you can change it in various places, depending on the variable.  The variable mail.log, according to the manual listing:  http://www.php.net/manual/en/ini.list.php can be changed at PHP_INI_ALL, which means anywhere.  Cool, that’s easy.  I can change it right in the script itself, using the ini_set function to set the mail.log file to a file that is writable by owner and by apache:

 [ruhlman@tempest rapp] ls -l ./maillog 
-rw-rw----. 1 ruhlman apache 521 Apr 15 23:59 ./maillog
[ruhlman@tempest rapp]

Here’s the script that should work fine.

<?php

$rv = ini_set('mail.log','/home/ruhlman/public_html/rapp/maillog');
if( ! $rv ) {
    echo "failed to set mail.log\n";
} else {
    echo "changed mail.log from $rv\n";
}

$log = ini_get('mail.log');

$stat = stat( $log );
$permnum = $stat['mode'];
$permstr = sprintf("%o",$permnum);
echo "<p>mail.log is $log with perms $permstr\n";

if( $rv = mail("scott.anderson@wellesley.edu",
    "test email from PHP",
    "body of message" ) ) {
    echo "Success!\n";
} else {
    echo "Failed:  $rv\n";
}

?>

However, that was a miserable failure.  Here’s the output from apache running that script:

failed to set mail.log

mail.log is /var/log/maillog with perms 100620 
Warning: mail(/var/log/maillog): failed to open stream: 
Permission denied in /home/ruhlman/public_html/rapp/test-email2.php 
on line 19 Success!

Hunh.  So, I guess I can’t set it in the script.  Maybe I can set it in the .htaccess file?  Yes, that can be done:

[ruhlman@tempest rapp] cat .htaccess
php_value mail.log /home/ruhlman/public_html/rapp/maillog

But first, you have to tell Apache that .htaccess files in this directory tree can change php_values.  Here’s the relevant lines from a file in /etc/httpd/conf.d/ that configures this directory:

# Added in April 2013 to see if we can set a PHP value in .htaccess in that directory
<Directory /home/ruhlman/public_html>
AllowOverride FileInfo AuthConfig Limit Options
</Directory>

It’s the adding of options that makes the difference.  Before that, my efforts with .htaccess were fruitless.  I’ve also since learned from this manual page on configuring PHP mail http://www.php.net/manual/en/mail.configuration.php that the mail.log variable might be PHP_INI_PERDIR instead of PHP_INI_ALL, which would explain why I couldn’t change it in the script.  There’s also mention, in http://www.php.net/manual/en/configuration.changes.modes.php   of a .user.ini file, which might be easier than changing the <Directory> element in the system httpd file just so that .htaccess can be used. to change the mail.log variable.  However, this page http://php.net/manual/en/configuration.file.per-user.php suggests that maybe that’s for non-Apache installations.

Anyhow, this was hard to debug, but ultimately successful.  Hopefully, this post will save someone else some heartache.

About CS SysAdmins

The CS Department System Administrators
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *