I've been asked to alter a PHP.ini file on a windows 2008 machine running IIS so that the [man]mail[/man] function will work on a remote SMTP server rather than localhost. The remote server requires a username and password which I have obtained, but the mail function is failing with this new configuration (it worked before when it was set to localhost).

Per this page, I have put these PHP.ini configuration values in :

[mail function]
SMTP = host.domain.com
smtp_port = 25
username = myusername
password = s0m3p4ssw0rd
mail.log = "C:\Windows\temp\php-mail-log.log"

When I visit a test script, there is a long pause before it says "not ok";

<?php

if(mail('me@mydomain.com','test subject','test message')){

  echo('ok');

}

else{

  echo('not ok');

}
?>

I suspect that there is no SMTP server responding on port 25 and this is why it times out. I have been unable to locate any mail-related errors in the main php error log and the mail log location i specified above is completely empty.

Any advice about how to proceed here would be most appreciated.

    There are no such PHP directives as 'username' and 'password' - the internal PHP mail() function can't do SMTP authentication. That is why you must use external classes/libraries to send through any SMTP server that requires authentication.

      I had noticed that the php docs on [man]mail[/man] neglected to mention username and password parameters, but this page featured a variety of posts where people claimed it work just great. Others where it was not so great.

      Kind of a bummer you can't supply username/pass in php.ini. I almost always use PEAR::Mail myself which is pretty awesome, but I'm working with a legacy project and the project manager really wants some kind of centralized solution if possible. Any thoughts on configuring PHP rather than changing every occurence of the mail function?

        sneakyimp wrote:

        Any thoughts on configuring PHP rather than changing every occurence of the mail function?

        Only thought I have is that it's simply impossible at the moment; the core PHP functions don't support any type of SMTP authentication. The only "configuration" change you could make to solve this would be to point PHP to use an open SMTP relay (e.g. set one up on localhost) that simply relays all outgoing mail through the real SMTP server using the required authentication credentials (so that PHP doesn't have to know them and/or support their implementation).

          Thanks for your consideration of my smtp woes. I've posted to the PECL dev list to clarify this issue and at the same time suggest it as a nice-to-have feature.

          Creating an SMTP relay is a bit beyond my realm of experience but I think this team might have someone who can help me out.

          I tried redefining the mail function but got a fatal error:

          <?php
          
          function mail($to, $subject, $message, $additional_headers, $additional_parameters) {
            die('my mail function mooahahaha');
          }
          
          
          $to      = 'me@mydomain.com';
          $subject = 'test email from the mac';
          $message = 'this email was sent from the iMac';
          
          mail($to, $subject, $message);
          
          ?>
          

          Fatal error: Cannot redeclare mail() in /usr/local/apache2/htdocs/mail.php on line 5

            sneakyimp wrote:

            I tried redefining the mail function but got a fatal error

            Aye - PHP doesn't support any type of function overloading/undefining in PHP code - you'd have to modify the PHP source code in order to do that.

              I posted the pecl development list (which is actually the wrong list) and got a response about this:

              You can't specify the host/username/password for the mail() function through php.ini variables.
              You can however set the path for your sendmail binary (this is what sendmail_path does), or replace it with a wrapper script, if you like, and you can pass custom arguments for the sendmail binary.
              so you could potentially do 4 different way to use an external smtp server:
              1, play with the 5th parameter of the mail function, and force the sendmail to use the external smtp.
              2, set the sendmail_path to your wrapper script, which manages the mail relay, and the php mail function will call that script.
              3, configure your local mta(exim/postfix, etc.) to use the external smtp az a smarthost.
              4, use some smtp library (PEAR Mail, PHPMailer, swiftmailer) which supports remote smtp with authentication.

              #1 - having read the docs on [man]mail[/man], I see that this $additional_parameters argument to the mail function is fed to whatever script/executable is specified in the sendmail_path in PHP.ini. Unfortunately sendmail_path is only applicable to *nix systems. I don't know for sure, but I suspect this 5th parameter will have no impact on a windows machine? Also, this would require changes to the dozens of little code projects to add the 5th param.

              There is, however, a Windows Server 2008 configuration related to SMTP mail (see attached screenshot). Does anyone know if I might specify a user/pass here and have these settings apply to PHP? I'm experimenting with this a bit but have been unable to get logging working on this machine to see what the problems are. Any tips are welcome.

              #2 - Again, sendmail_path doesn't appear to apply to windows machines. I'd love to see an example of this in action though. Sounds intriguging.

              #3 - Can anyone comment on the MTA suggestion in a windows context? Sorry, very noobish on windows server.

              #4 - the original suggestion. Always a possibility but would require many changes to lots of different little code projects.

                sneakyimp;10969893 wrote:

                #1 - having read the docs on [man]mail[/man], I see that this $additional_parameters argument to the mail function is fed to whatever script/executable is specified in the sendmail_path in PHP.ini. Unfortunately sendmail_path is only applicable to *nix systems.

                Er... just how carefully did you say you've read the docs? :p From the PHP manual in regards to sendmail_path:

                PHP Manual wrote:

                This directive works also under Windows.

                sneakyimp;10969893 wrote:

                There is, however, a Windows Server 2008 configuration related to SMTP mail (see attached screenshot). Does anyone know if I might specify a user/pass here and have these settings apply to PHP?

                Careful - that's not a part of Windows Server 2k8 you're looking at - that's IIS (something that's available on previous versions of Windows as well).

                I do recall using (or at least I thought I used it successfully) the built-in SMTP relay server that IIS has the option of installing. It's been a while, and it was an older version of IIS (Windows Server 2003 and IIS 5 or 6, probably), but I would assume that it all works the same.

                I actually have a VM of Windows Server 2k8 on my laptop (I think), so I might be able to fire that up and give IIS + SMTP relay (to a secured external SMTP server) a shot here in an hour or so, but again, assuming you've got everything configured correctly (PHP scripts point to localhost, SMTP server is started (verify using netstat to see if something is LISTENING on TCP port 25/smtp), firewall allows outbound traffic on port 25 from the web server, etc. etc.), I don't see why this wouldn't work.

                sneakyimp;10969893 wrote:

                #2 - Again, sendmail_path doesn't appear to apply to windows machines.

                See 1st paragraph above.

                sneakyimp;10969893 wrote:

                #3 - Can anyone comment on the MTA suggestion in a windows context?

                Since I'm assuming you don't have Microsoft Exchange Server installed in the enterprise (otherwise why would you be wanting an external SMTP host, eh?), note that there are several MTA's available in Windows flavors; just do a Google search for "Windows MTA" or "Windows SMTP server" and you should find plenty of hits.

                  When I said I read the docs on mail, I meant that one page on mail itself. I had scanned that other page before and somehow overlooked that bit. What made me think this value was ignored was the comment in the PHP.ini itself which says 'for unix only':

                  ; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
                  ; http://php.net/sendmail-path
                  ;sendmail_path =
                  

                  Obviously this conflicts with the documents. Who should I notify?

                  As for the the MTA and such, the sending of mail by the mail function does work properly if I set it to localhost/port 25. The problem is that mail does not get delivered because this machine is an amazon compute instance and its servername/IP is not included in the SFP record for this particular domain. I advised them to try and add it, but I think the suspicion is that the IP address might change often and they are also a bit un-hip to the whole SPF thing so it confuses them.

                  The IIS setting -- FINE if it's IIS rather than windows 2008. It apparently doesn't work to change it. The setting in PHP.ini overrides it every time.

                  Given that sendmail_path might work, what on earth would I set it to? I'm not particularly good at windows shell scripting and am unsure how to parse out any parameters which might be supplied to any such script.sh.

                  Again, the goal here is just to get PHP sending mail through a particular server and not just sending mail from localhost. It sounds like you are suggesting it might be possible to configure the SMTP relay on this server to log into some remote machine with a particular username/pass but I'm not at all clear on where these settings might live on the windows stack or whether this might impact more than just PHP on this machine.

                  I appreciate your help but don't kill yourself over it.

                    sneakyimp wrote:

                    this machine is an amazon compute instance and its servername/IP is not included in the SFP record for this particular domain.

                    Are all of the instances at least guaranteed to be on the same subnet? You can add entire ranges (e.g. 123.34.56.0/24) to the SPF record.

                    Speaking of, don't you have control over the DNS for your domain? The SPF record is nothing but a TXT record in the DNS zone, so I would assume that you have control over modifying it yoruself.

                    sneakyimp wrote:

                    It apparently doesn't work to change it. The setting in PHP.ini overrides it every time.

                    Er... no it doesn't - the two have nothing to do with each other. If you're using the SMTP relay in IIS, then you should be pointing all PHP scripts to 'localhost' since you're wanting to connect to the SMTP server that IIS starts. If you still have the external SMTP value in php.ini, then PHP isn't using the IIS SMTP server at all.

                    sneakyimp wrote:

                    Given that sendmail_path might work, what on earth would I set it to?

                    Well you'd set it to run this "wrapper" script you'd have to create. You'd probably have to invoke the PHP parser, so you'd probably want a string like "C:/php/php.exe -f C:/path/to/your/mail-wrapper.php". Then again, since the main PHP directory should be in your system's PATH environment variable anyway (assuming PHP was properly installed), you coud probably just do "php -f c:/path/to/your/mail-wrapper.php"). YMMV.

                    sneakyimp wrote:

                    It sounds like you are suggesting it might be possible to configure the SMTP relay on this server to log into some remote machine with a particular username/pass but I'm not at all clear on where these settings might live on the windows stack

                    Well if you're using IIS, and want to use the built-in SMTP server, then you've already shown us the screenshot of the location where you'd configure all of that. However, if you're not pointing PHP to the SMTP daemon that IIS spawns (e.g. on localhost, as I said above), then you're bypassing IIS and thus none of the relay settings will matter.

                      Thanks so much for your continued assistance, bg.

                      Not crazy about the subnet idea because it would be quite easy for someone else to randomly get an amazon compute instance in such a subnet. Given the complexity of the PHP/mail stack, SPF is starting to look increasingly attractive.

                      PHP seems to only care about the SMTP setting in the PHP.ini file and does not appear to use the IIS setting at all. For example, I set SMTP to localhost on port 25 and this script echoes OK:

                      <?php
                      if(mail('me@mydomain.com','test subject','test message')){
                            echo('ok');
                      }else{
                            echo('not ok');
                      }
                      ?>
                      

                      I imagine it isn't using the IIS SMTP settings because I have intentionally set the IIS SMTP settings to a server which does not exist. If I set the IIS credentials to some valid domain with proper credentials the testemail.php script still returns OK, the mail logs on the remote SMTP server never register any login attempt, and the mail does not arrive for most domains, although we have gotten one mail through this way. I believe 'localhost' will actually send an email out to the target domain and its' the SPF that's preventing delivery.

                      If I change the value for SMTP inside PHP.ini to some broken/non-existent server or some server that requires authentication, I get 'NOT OK' from my script.

                      What is not clear at all is how mail gets sent when I set the SMTP value in PHP.ini to 'localhost/port 25'. As you saw in my other thread, I can't get the mail log working to obtain additional info.

                        sneakyimp wrote:

                        PHP seems to only care about the SMTP setting in the PHP.ini file and does not appear to use the IIS setting at all.

                        Again, that's how it's supposed to be since the two have no relation to each other.

                        I don't understand why you think PHP and IIS are supposed to be playing together or whatnot. You configure the IIS SMTP daemon to relay all outgoing mail through a different SMTP server. You then configure PHP to send all mail via 'localhost' - e.g. the IIS SMTP daemon. PHP isn't supposed to be able to see the external mail server - that's the whole point of having a relay.

                        EDIT: As for your other point, of course PHP will still return true even if you configure IIS incorrectly; IIS will still accept the incoming message for delivery, so PHP is none the wiser. The IIS SMTP daemon's error log, however, will note that it was unable to relay the message along to the next SMTP server.

                          Yes I know that when php uses send mail, it hands the mail off to something and the true/false value returned by the [man]mail[/man] function is entirely determined by the response of that agent, whosoever that agent happens to be.

                          Whether this is IIS or something else on a windows machine is a bit beyond me. I know that PHP is going to try to connect to localhost on port 25 (or whatever port i specify) due to my PHP.ini settings. This means PHP is probably going to talk to the MTA on the server. What is a mystery to me is where I might configure this shadowy mail agent and whether it's IIS or something else which I must locate somehow. I have no idea where to configure the IIS SMTP daemon apart from within the IIS configuration control panel and I have configured this value for the particular site that I'm working with. I've tried a variety of different sites, tested my php script, and these IIS settings do not ever result in an effort to contact the remote SMTP server -- I know because I've watched the log files while my testemail.php script runs.

                          As I attempted to describe in my post above, I configured PHP.ini to have an SMTP value of localhost and then tried a variety of settings for the IIS SMTP control panel. None of them resulted in any contact at all with the remote SMTP servers. To summarize:
                          1) configure PHP.ini to use localhost/port 25
                          2) configure the IIS settings to check some remote SMTP server which I control and which lets me send mail from thunderbird
                          3) go watch the mail log on my SMTP server as I attempt to send mail via my test script
                          4) weep bitterly as no mail log entry appears for my server

                          I've attached a screenshot of the place where I'm trying to configure IIS/SMTP. It doesn't seem to help one bit.

                          I was sincerely hoping to get some log files to see what the story is with mail but have only managed to locate the php error log (which is not helpful) and the IIS request log which just lists the page requests.

                            Interesting news today. The IP address of our server is listed in the PBL on spamhaus:
                            http://www.spamhaus.org/pbl/query/PBL328859
                            It would appear from that link that Amazon doesn't want this server to send any outbound mail. This rules out trying to fix the problem using an SPF record.

                            This still leaves me with the task of sending mail from PHP to a remote server. My coworker alex got the mail log working. Apparently SMTP mail logging is not enabled by default and enabling it involves 'adding Custom Logging and ODBC Logging roles to the Web Server in the Server Manager' -- whatever that means. The SMTP mail log is located at
                            C:\Windows\System32\LogFiles\SMTPSVC1 and, while it does give a very good idea of how remote mail servers respond to the locally running SMTP server's attempts to send mail, it does not give any indication of what exactly is responsible for performing this action or how it might be configured.

                            The Help file on the SMTP config I toyed with in IIS says these SMTP settings correspond to applications which use the System.Net.Mail API. The comments on that page all complain about how the information is misleading. I have a funny feeling PHP does not use this API.

                              Write a Reply...