Warning: exec() [function.exec]: Unable to fork
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;
cacls %COMPSEC%
This should give you an output like this;
C:\WINDOWS\system32\cmd.exe LAPTOP\IUSR_LAPTOP:N
BUILTIN\Users:R
BUILTIN\Power Users:R
BUILTIN\Administrators:F
NT AUTHORITY\SYSTEM:FHere 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);
<?php
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;
C:\WINDOWS\system32\cmd.exe LAPTOP\IUSR_LAPTOP:R
BUILTIN\Administrators:F
BUILTIN\Power Users:R
NT AUTHORITY\SYSTEM:F
BUILTIN\Users:RYou 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.
- 3683 reads









This didn't help
I am using a different user for the application and granted this user permission to use cmd.exe, but still get Unable to fork.
Without knowing anything
Without knowing anything about the account you have setup I'm not going to be a great deal of help. I'd start by checking things like group memberships and your local security policy and compare that to the IIS user account.
----------------
Dominic Ryan
3 x Microsoft IIS MVP, MCSE, MCSA
IIS Aid owner/webmaster
very good Tip
I solved problem ... !
Glad I could
Glad I could help!
----------------
Dominic Ryan
3 x Microsoft IIS MVP, MCSE, MCSA
IIS Aid owner/webmaster
substitute cmd.exe with cacls.exe
cmd.exe does work as suggested above..but when I substitute it with cacls.exe and grant cacls.exe/IUSER the same permission as cmd.exe, it doesn't work.
Below is the php code....
$filepath = "c:\ppan";
$username = "ppan";
$cmd = "c:\windows\system32\cacls.exe ".$filepath." /e /g ".$username.":F";
echo $cmd;
$result = exec($cmd);
echo $result;
I want to run above to grant ppan the full control right to his own directory. But when I copy the command "c:\windows\system32\cacls.exe c:\ppan /e /g ppan:F", it works at perfectly in the command prompt. Can you help please?
NOTE: I'm using IIS!!
I don't have my test
I don't have my test environment available at the moment, but you could try specifying cmd.exe to execute you cacls command by doing something like this;
$filepath = "c:\ppan";$username = "ppan";
$cacls = "c:\windows\system32\cacls.exe";
$cmd = "c:\windows\system32\cmd.exe /c ".$cacls." /e /g ".$filepath." ".$username.":F";
echo $cmd;
$result = exec($cmd);
echo $result;
----------------
Dominic Ryan
4 x Microsoft IIS MVP, MCSE, MCSA
IIS Aid owner/webmaster
Still No Joy With exec()
I still cannot get an exec() call to work. The access permissions on the individual file I am trying to execute (GNU diff.exe) allow the IUSR_%COMPUTERNAME% account full control. I also set the IIS execute permissions on the virtual directory to Scripts & Executables. But still no joy. Anything else I should look for?
Thanks!
Michael M.
What happens if you try and
What happens if you try and run the sample script detailed in the article?
----------------
Dominic Ryan
4 x Microsoft IIS MVP, MCSE, MCSA
IIS Aid owner/webmaster
Post new comment