views:

433

answers:

4

The Problem

I have a PHP script that uses shell_exec to run a pdf-to-text converter. To simplify the problem I've created a short script that uses shell_exec to just echo the output of the dir command.

<?php
$cmd = 'C:\\WINDOWS\\system32\\cmd.exe /c ';
echo shell_exec($cmd.' dir');
?>

When I run this on my Apache server, everything works as expected. When I switch to IIS, it's as though the line is skipped entirely: no errors, no output, no logs, no nothing.

Unfortunately, I need to use IIS because I'm going to authenticate my users against active directory.


Here's what I've tried so far:

  • Issue the command through cmd.exe /c rather than issuing it directly
  • Give Read & Execute permission to SERVICE on "C:\WINDOWS\system32\cmd.exe"
  • Give Read & Execute permission to NETWORK SERVICE on "C:\WINDOWS\system32\cmd.exe"
  • Give Read & Execute permission to IUSR_MACHINENAME on "C:\WINDOWS\system32\cmd.exe"
  • Give Read & Execute permission to Everyone on "C:\WINDOWS\system32\cmd.exe" (don't worry, it didn't stay like that for long, haha)
  • Run PHP as an ASAPI module
    • This is my standard configuration
  • Run PHP as a CGI extention
    • This does not work, I get an error: CGI Error The specified CGI application misbehaved by not returning a complete set of HTTP headers.
  • In IIS Manager, set Execute Permissions to Scripts and Executables on your website
  • Added html markup and other php functions to script to see if that gets processed; it does. It's as if the shell_exec bit just gets skipped.

Thank you so much for looking at this question, I am now pulling my hair out with the problem

Cheers, Iain


Update 1

I really didn't want to do this, but as a stop gap until I find a proper solution I'm running Apache on the web server (which runs shell_exec fine) and I call my apache script via cURL. It's ugly, but it works :).


Update 2

I'm beginning to think this isn't so much an issue with IIS or permissions as such, but perhaps a result of some policy we have on our network - although I can't imagine what. Any ideas from left of field?

A: 

I'd say Read & Execute permission to the User thats running IIS (if thats not IUSR_MACHINENAME)

Andrew Kolesnikov
Thanks cruxt. The user that runs IIS is in fact IUSR_MACHINENAME. Out of shear despiration I also tried setting Read no dice. Thanks for reminding me to put this in my list of tried things though :)
Iain Fraser
+1  A: 

couple of notes

if you want to execute a .exe directly, you can use proc_open() with $other_options=array('bypass_shell'=>TRUE)

also procmon.exe (sysinternals) is you best friend when digging into this class of problem

steelbytes
A: 

Unfortunately, I need to use IIS because I'm going to authenticate my users against active directory.

The premise for basing your application on IIS is flawed. There's nothing to stop you doing this with Apache. Indeed, you don't even need to run it on a MS-Windows OS.

Have a google for how to set up all this up.

Note that with IIS and local clients potentially using NTLM, the security policy gets thrown out of the window. The IIS handler thread may run with the credentials of a NTLM MSIE client. Or not. Debugging this stuff will drive you mad!

C.

symcbean
As with the comment I made to Miky D, moving to Apache from IIS isn't really an option for me because it's what our organisation uses for pretty much all of our web based infrastructure. WIMP works very well in all other respects, so totally overhauling our web infrastructure to solve one problem isn't really justifiable for us. But thanks for your insight and your time.
Iain Fraser
A: 

Here's a few points:

  • Regarding PHP skipping the shell_exec function, make sure that PHP is not running in safe mode. From the PHP manual - on the shell_exe page:

Note: This function is disabled when PHP is running in safe mode.

It also appears that this is quite a known problem with executing shell commands from PHP in Windows. The consensus seems to be that the best way to get it to work is to have PHP running in FastCGI mode (I know you tried this already and said you couldn't get it to work - hence my second point). You may find this Microsoft IIS Forum thread helpful.


  • Now, as far as having to run PHP on Windows in order to authenticate against Active Directory - you don't have to!

Apache provides LDAP authentication via the mod_auth_ldap. And PHP provides LDAP support through the following functions:

Active Directory is an implementation of LDAP. So, you with any LDAP client you can perform authentication against Active Directory.

P.S. You can either use the Apache mod_auth_ldap, or the PHP LDAP functions - you don't need to use both at the same time to make this work. The Apache mod_auth_ldap works at the HTTP protocol level, whereas the PHP LDAP Functions give you more control over the authentication and authorization process.

Miky Dinescu
Thanks Miky, I will certainly look into that. As for running IIS instead of Apache; it's more than just authentiction, pretty much all of our web-based infrastructure runs on IIS so moving to Apache would be a pretty bold move - and a move I don't have the authority to make. I do actually use PHPs ldap functionality to authenticate on the application, it's more to do with the fact that IIS will run as the authenticated user - allowing use and modification of files on the network belonging to that person.
Iain Fraser