How to log all calls to a function in PHP? (mail() function)
Asked Answered
L

4

9

I have a dedicated server with tens of virtual hosts. I want to determine what file is calling mail() function and log this globally. I need something like that:

[Wed Feb 13 10:42:39 2013] mail() called from /var/www/example1.php on line 70
[Wed Feb 13 10:42:40 2013] mail() called from /var/www/example2.php on line 70

I can't use debug_backtrace() or similar because I can't add this to any PHP file in the server. Can I log all function calls globally in a file like errors are logged to a file like error.log?

Thanks

Liar answered 13/2, 2013 at 9:56 Comment(6)
The simplest way would be to create your own function, like, sendMail, witch logs actions and sends mail.Tapir
Can xdebug.org or code.google.com/p/webgrind help you out ?Farley
xdebug offers such functionality, although globally enabling trace on all of your vhosts might not be a good idea performance-wise.Gondar
@DainisAbols: He does not own the code.Gondar
Thanks, but this is not valid for me: if I have 50 virtual hosts with his own WordPress/Joomla/Drupal I can't edit any PHP file to replace mail() function. The same for xdebug, I can't enable this for all vhosts, my server will explode...Liar
I found something specific for mail() function, available from PHP 5.3: php.net/manual/es/mail.configuration.php. mail.log logs all calls to mail() function with the full path of the file that calls it. Anyway, I'm interested in resolve this question for any PHP function, can be interesting for many of us...Liar
C
3

In general, you are going to have trouble with this; PHP doesn't provide a logging mechanism built-in, so you'll need to add something to your PHP system to do it.

The options as I see it:

  1. Modify the PHP code. Given what you've said in the question, I guess this isn't an option, but it needs to be stated, as it is the obvious answer. (PHP's mail() function is so basic that anyone writing PHP code really ought to be using a wrapper class for it anyway just to retain their sanity)

  2. If we're talking specifically about the mail() function, then we could log it by logging the sendmail client that mail() calls. Your sendmail system on the server is probably controlled by a unix shell script that is called by PHP's mail() function. You should be able to modify this shell script to log the mail events. This probably won't be able to give you details like the line number, but it will tell you the user that is doing it, etc.

  3. Use the Suhosin PHP hardening patch. This is a patch for PHP that provides dozens of security-related features; I would strongly recommend it for a shared hosting environment anyway. But for you it also includes logging features, which may allow you to log usage of particular functions, including filename and line number -- ie exactly the scenario you're looking for. This is the solution I'd recommend .... the only big problem you'll have here is if you've kept your PHP version bang up to date, because Suhosin is currently only available for PHP 5.3, not 5.4. As a PHP developer, I would be pushing to get PHP 5.4 on my server, but as a provider, 5.3 is still supported, so there's nothing wrong with it. (on the flip side, if you are still on 5.2 you should be upgrading ASAP, as it's been unsupported for years and has known security holes).

Cockatrice answered 13/2, 2013 at 10:18 Comment(1)
Thanks SDC, I tried to set sendmail_path but it doesn't tell me what file is calling mail() function. But I'm using Suhosin so will take a look to logging features, seems to be exactly what I need. Thanks!Liar
C
3

As of >= PHP 5.3.0, you can simply specify a path to the desired location of your logilfe in your php.ini:

mail.log = /path/to/some/logfile

See the PHP docs for details.

Chiropody answered 8/12, 2015 at 21:57 Comment(1)
Wonderful, thanks! I overlooked this for years.Saltire
R
0

What you can do is, download php source code, edit this file:

ext/standard/mail.c

and add logger there.

Then recompile.

That's probably only way you can implicitly debug who's calling your php function from where.

Rafaelof answered 13/2, 2013 at 10:22 Comment(0)
C
0

To block mail() just delete /usr/sbin/sendmail from php's chroot and force authenticated smtp.

Chew answered 6/11, 2014 at 23:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.