One of the most common ways a PHP application will try and launch an external program is to use the exec function. However, if you are trying to use a script using this exec function and you are an IIS user using the default anonymous IIS user account then you'll almost certainly experience the Warning: exec() [function.exec]: Unable to fork error. This is because by default the anonymous IIS user account has minimal access to your system, and in particular every executable file in your Windows system32 directory are explicitly set to deny access to this account. Now that we know why you get this error, lets see if we can get a working solution.
Most scripts that use the exec function are trying to get access to the command line interpreter, so in this example we'll look at how we can give PHP access to the cmd.exe executable. The utility we'll use here is called cacls.exe which is a very handy utility that comes with Windows that allows you to display and modify access control lists on files and folders. First off, lets have a look at the standard ACL for the cmd.exe file in the Windows system32 directory. To do this open a command prompt and type in;
This should give you an output like this;
Here you'll see that the anonymous IIS user account (IUSR_LAPTOP) has no permissions at all to cmd.exe. Next lets create a simple PHP script to test the exec function. Enter the following into a file called exec.php (or similar, as long as it has the PHP extension);
echo exec('cmd /c echo Hello World!');
Once you've done that, save the file into your webroot and then access it via your Internet browser. Providing you have the display_error directive in php.ini set to on it should return the following error;
Warning: exec() [function.exec]: Unable to fork [cmd /c echo Hello World!] in C:\Inetpub\wwwroot\exec.php on line 2
Now lets head back to the command prompt to modify the ACL on cmd.exe. To do this type the following into the command prompt;
cacls %COMSPEC% /E /G %COMPUTERNAME%\IUSR_%COMPUTERNAME%:R
What this command does is alter the existing ACL to grant the read permission to the cmd.exe executable to the anonymous IIS user account. We can verify this now by running the very first command in this article again which should now return this;
You should now be able to run the PHP test script from above again, but this time instead of an error you should be greeted with a "Hello World!" message.
If you find that the script you are using is trying to access a file other than cmd.exe, then it should be a simple matter of substitution. One word of warning though which is that by modifying the ACL in this way is loosening the security on your system which could potentially be abused. If you have any comments or questions please feel free to post them here or in the forums.