JDK-6410605 : (process) Vista: Runtime.exec does not prompt when programs need elevated privileges
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 5.0,6
  • Priority: P3
  • Status: Resolved
  • Resolution: Won't Fix
  • OS: windows_vista
  • CPU: x86
  • Submitted: 2006-04-08
  • Updated: 2013-07-29
  • Resolved: 2013-07-29
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
A windows-vista program can advertise that it needs elevated privilege, either by having a manifest files that says so, or being a Windows Installer, or by other means.
If such an executable (such as the java installer) is launched from a command shell, vista will prompt the user to allow running. (all this assumes a normal user with admin privileges)
If the same program is executed using Runtime.getRuntime().exec(), the call will fail with an IOException the 740 error which means:
ERROR_ELEVATION_REQUIRED: The requested operation requires elevation.

java.io.IOException: CreateProcess: C:\jre59234.dat /s /v"/qn WEBSTARTICON=1 INS
TALLDIR=\"C:\Program Files\Java\j2re1.4.2_07\\"" error=740
        at java.lang.ProcessImpl.create(Native Method)
        at java.lang.ProcessImpl.<init>(Unknown Source)
        at java.lang.ProcessImpl.start(Unknown Source)
        at java.lang.ProcessBuilder.start(Unknown Source)
        at java.lang.Runtime.exec(Unknown Source)
        at java.lang.Runtime.exec(Unknown Source)
        at java.lang.Runtime.exec(Unknown Source)
        at test.execute(test.java:12)
        at test.main(test.java:6)

use the following simple java program:
public class Run {

    public static void main(String[] args) {
        if (args.length < 1) {
            System.out.println("Usage: Run <filename> <arg1> ...");
        } else try {
        } catch (Throwable t) {
Then type 
"java Run jre-6-beta-bin-b59g-windows-i586-06_feb_2006.exe"
(or using any installer executable you have)

Justification: - the shortest answer - we must follow MS way for the case. They got the same dilemma for legacy applications and they, have a full set of options, forbid UAC in CreateProcess call. - in accordance with MS documentation we have a choice: 1] to use an intermediate program ([cmd /c] - is a good candidate for all practical purposes) 2] to call the [ShellExecuteEx]. The [ShellExecuteEx] call is a hard call. It means that for correct function execution the COM subsystem have to be initialize before the action. Practically, it loads the major of MS Explore with custom extensions into the Java address space. - both 1], 2] mentioned choices (and it's the reason why the [CreateProcess] function does not support UAC) forbid input/output redirection and piping. That is because parent and child processes are in different security levels. In this limitation we declare that it is a programmer responsibility to create the privileged intermediate process with desired fictional.

I agree with Alexey's evaluation, the best solution may be to do nothing. This means the solution for those that need to launch a process with elevated privileges is to use an intermediate program.

Good problem review: http://mark.koli.ch/2009/12/uac-prompt-from-java-createprocess-error740-the-requested-operation-requires-elevation.html We have a choice: switching to [ShellExecuteEx] in case of [error=740], or running the intermediate process with the privilege in manifest. That is the MS recommendations for a problem. The problem is for pipes and IOE redirection. [ShellExecuteEx] doesn't allow piping or redirection, but we cannot do the action any way due to the difference in the security level. At least for piping that is obvious. It is not so clear for redirection, but seems we should not. In the case of UAC and non-empty IOE/pine in the parameters we need to do nothing and return [error=740] without any other activity. The communication between the programs in different security levels must be broken. An additional difficulty exists for AWT headless mode. The absence of GUI is not a guaranty of administrative account in common case, but user has no chance to evaluate the privilege on a server in the interactive mode. The best way to solve the problem: do nothing. We can declare that it is a programmer responsibility to create the privileged intermediate process with desired fictional.

EVALUATION The standard answer for running with elevated privileges should be just as on Unix - if permissions are insufficient, you get something like a "permission denied" error. You can respond by re-running the program with more permissions, using something like "sudo". On Windows, you can do this via Run As Administrator UI action. Many Windows users will keep a Command Prompt window permanently in Administrator mode. Consider the analogue of accessing a file. Some file access will fail because the originating process has insufficient privileges; there is no way around starting some other process; process elevation can not occur while running some process, but instead requires running a new process. Java would have no choice but to throw an exception (barring an extraordinary split of the Java executable into an unprivileged ordinary executable and a "service" running in Administrator mode) If we did what cmd.exe does, and use ShellExecute, will we be able to communicate with the child process using pipes as required by the Process spec? The Cygwin project seems to have the same problem as Java, also with no obvious solution.

EVALUATION Googling around finds the following: The Cygwin project also has serious issues with CreateProcess vs ShellExecute: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1020271&SiteID=1&mode=1 Here's a guy who has created an "elevate" wrapper command that works by running ShellExecute (with the underdocumented "runas" "verb" (whatever that is)) http://www.wintellect.com/cs/blogs/jrobbins/archive/2007/03/27/elevate-a-process-at-the-command-line-in-vista.aspx Cygwin folks believe that cmd calls CreateProcess, and if that gets ERROR_ELEVATION_REQUIRED, then calls ShellExecute, as suggested by others. This Microsoft document officially suggests use of ShellExecute: http://download.microsoft.com/download/5/6/a/56a0ed11-e073-42f9-932b-38acd478f46d/WindowsVistaUACDevReqs.doc Here's a guy who has seriously worked on getting CreateProcess to work with process elevation. Should Sun hire him? http://www.codeproject.com/useritems/UAC__The_Definitive_Guide.asp

EVALUATION ShellExecute, instead of CreateProcess, should give the security popup. There are differences, but we can do some experiments.


EVALUATION This is tough. It seems java should have 3 runtime modes, and the example in the bug description will behave differently: 1. Standard Mode: No change. Behavior: fail with that 740 error 2. Elevated Mode: Which means java.exe itself is running with admin privilege. It's easy to try out this mode now, just check 'run as admin' in java.exe's compatibility property page. Behavior: a UAC dialog pops out when java.exe is launched, click OK and the installer got executed. 3. Vista Mode: This means java.exe can request admin privilege on-demand (Try time and date setting in Vista and you know what this means). Behavior: java.exe starts without any hassle, but when CreateProcess is called, the UAC dialog pops out request elevation. The 3rd mode looks perfect but is too Windows native. This also reminds me of the AutoUpdate bug in Vista which should be played in the same way: jusched.exe should be started when user logon to Vista, when it detects that JRE needs to be updated, a UAC dialog should pops out requesting for admin privilege to install the updates.

EVALUATION The above argument does not convince me. In my opinion, the proposed change would be a regression. When an OS changes its security model to forbid operations that used to be permitted, it is exactly right for Java methods that attempt those operations to throw an informative exception, as the current implementation does. Runtime.exec is doing nothing more or less than calling the native API CreateProcess in the standard way, and CreateProcess returns an error code in the standard way. Why should Runtime.exec disagree with the OS?

EVALUATION Runtime.exec is not being asked to prompt for anything. It is the os that will generate any such prompts if it determines that the executable needs elevated privileges. This is a regression from all previous versions of windows. Existing applications will fail (unnecessarily) when they call Runtime.exec().

EVALUATION The current behavior is certainly what one would expect. Runtime.exec is not an API that one would expect to "ask the user" whether the operation should proceed. Therefore, changing this to an RFE. Perhaps the security group should get involved? Perhaps an "interactive" flag should be added to ProcessBuilder?

EVALUATION A sub-process may frequently communicate with the user, and may even have a rich GUI, as long as it is not run headless. It is windows that is popping up the authentication dialog, and I agree, that on headless servers, or scheduled batch type runs, that would be a problem. (even java aside) I suppose in such cases the process that might launch a sub-process that needs evelated privileges would itself need to run with elevated priviliges. (is there any plan to include a javaev.exe and a corrisponsing manifest that would allow you to run an elevated java process ?) For existing applications and installers downloaded by Java Web Start, launching cmd.exe is not really an option (we would have to change existing deployed application that are not all ours), although this will work fine for the control panel CR (6406802). Would it be possible to include a system property that controled how Runtime.exec() launched processees on Vista, so that it could be set to cause behavior as cmd.exe?

WORK AROUND If you like the way that cmd.exe start processes, there is no reason you can't do Runtime.exec(...."cmd.exe", "/c", "myprog"...) Also, users can simply re-run their application using "Run As Administrator"

EVALUATION Note that the about-to-be-integrated changes for 6192449: (process) Runtime.exec error message on Windows should be improved will cause a more usable IOException message detail to be generated. At first glance, it is *not* obvious that putting up a dialog box to prompt "the user" is the right thing to do. This Windows box might be a server in a closet or the job might be running in the middle of the night. I think that I, as a user, would prefer the current behavior of throwing a proper IOException instead of hanging mysteriously. I just don't "get" how anyone is supposed to get work done when there's an elevation message popup once a second. On Windows, my understanding is that all process invocation is done using CreateProcess. But there are myriad of flags. Which one is responsible for the current behavior? Likely the ones that request to run DETACHED. Java subprocesses typically run "in the background" with their standard I/O redirected to their parent JDK. In other words, JDK subprocesses are *not* typically expected to communicate with the user.