Process.Start() not spawning new process under the same user - c#

I was always under the impression that when you're running a process as (domain\user) mydomain\myuser, when using Process.Start() it would start this new process using the same credentials - mydomain\myuser.
The issue I'm having is that my Process.Start() call seems to be creating a process under the SYSTEM account which is causing me permission issues in the started process (which must run under an admin account due to the work it does). If it changes things - I'm spawning this process (a custom built exe) from within a windows installer.
Any suggestions? I've read about windows group policies (possibly) having an impact on this, but if I'm honest, it's lost on me.
EDIT: a little snippet:
Where exename and commandLine are parameters for this method body:
ProcessStartInfo procInfo = new ProcessStartInfo(exeName, commandLine);
procInfo.WorkingDirectory = workingDirectory;
procInfo.UseShellExecute = false;
procInfo.CreateNoWindow = true;
Process process = Process.Start(procInfo);
Process.WaitForExit();
return process.ExitCode;

Either set procInfo.UseShellExecute to true, or execute cmd as a process with your exe as a parameter to the cmd command. When UseShellExecute is set to false, here are a lot of interesting side effects: UseShellExecute

Your impression is true. Process.Start() will always start the new process under current user's credentials - unless you provide alternative credentials in the ProcessStartInfo or use one of the overloads that take credentials.
There must be another problem - share a snippet of your code.
UPDATE
OK! You did not mention anything about installer. All MSI installers will be running under system since they will be run by "Windows Installer" which you can check and they run under SYSTEM.

Related

C# process cannot run on IIS

I have a web application that has to open a process and wait for exit.
This process is a .sh script that uses Cygwin.
I'm using the following code:
var process = new Process();
var string processFileLocation = #"C:\script.sh";
var string workingDirectoryLocation = #"C:\script";
var processInformation = new ProcessStartInfo(processFileLocation)
{
WorkingDirectory = workingDirectoryLocation,
UseShellExecute = true
};
process.StartInfo = processInformation;
process.Start();
process.WaitForExit();
If I run the application using IISExpress, everything works fine, the script is being callse.
When I add it to IIS, the process simply gets blocked, I never receive any answer from the request that should call the process.
I added "Full control" permission to that folder for the Application Pool that the website uses, but still no diference.
Any idea why it is behaving like this?
Whenever something stops running when put in IIS, there's a high likelihood that it's due to insufficient permissions. Start by running your pool with an administrator account. If it solves the issue, then you can work your way from there to find what permission you were missing.

Process.Start(); as another user works but explorer.exe iexplore.exe throws exception

I'm having problems with a program and its buttons (I know, I'm awesome lol) the buttons can be "programmed" to run programs. They also can be set to run as admin (different credentials).
If I set up simply notepad or cmd or explorer it runs like charm. But if I start iexplore it has got no admin rights.
I had problems before with running explorer.exe the solution was that I had to run it by typing the full path C:\windows\explorer.exe to be able to run it but that I solved it by setting up the VB2015 compiler (?) to Platform target: x64.
My other problem is that if I try to run dsa.msc or generally anything ends with msc it throws the following exception, even if I set up the full path to the syswow64 (or the system32) folder like c:\windows\syswow64\dsa.msc
"The specified executable is not a valid application for this OS platform."
Running the C:\Windows\System32\mmc.exe "services.msc" (or syswow64, with or without the /computer= switch) throws
"The requested operation requires elevation." which I have since I'm able to run services.msc (and all other msc-s from command line with the same user rights)
Thank you.
A beginner.
Basically you don't need to run the host app as administrator! There is a variable (inside your Process instance) called StartInfo (which is an instance of the ProcessStartInfo Class), where Verbs could be used as followed:
Process p = new Process()
{
StartInfo = new ProcessStartInfo("E:\\Users\\Temp\\app.exe")
{
Verb = "runas"
}
};
p.Start();
This will prompt the user to run the app.exe as administrator.
Edit
Running a Process as a defined user:
Process p = new Process()
{
StartInfo = new ProcessStartInfo("E:\\Users\\Temp\\app.exe")
{
Verb = "runas",
Arguments = "/user:Vira"
}
};
For more information about those RUNAS Arguments, click me! :)

run shell command (manage-bde) as administrator from C#

I need to run "manage-bde" shell command from C# code.
The main application process is already running as administrator and is Elevated.
I used code from : UAC self-elevation example on MS website for confirming the app process is elevated.
(http://code.msdn.microsoft.com/windowsdesktop/CSUACSelfElevation-644673d3)
However, when I try to run manage-bde from the C# code, I get "System can't find file specified".
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\\manage-bde.exe";
p.StartInfo.UseShellExecute = true;
p.Start();
As a workaround, I tried to create a batch file that runs the command.
string batchFileName = DateTime.Now.Ticks + ".bat";
StreamWriter writer = new StreamWriter(batchFileName);
writer.WriteLine("manage-bde");
writer.Flush();
writer.Close();
Process p = new Process();
p.StartInfo.FileName = batchFileName;
p.StartInfo.UseShellExecute = true;
p.Start();
The batch file is written , and executed successfully; However, the command "manage-bde" is not recognized.
I changed the code to use the verb "runas" and use admin password and that works, but I want the batch file to work without the need for providing the admin password. The current logged in user is already administrator on the computer but the batch file is not getting executed with the existing admin privileges . I need the batch file to execute and manage-bde to run successfully.
Your help or advice will be very highly appreciated :)
ps: some commands other than manage-bde work fine without need for admin runas.
The reason of the behavior I encountered was the Windows File System Redirector.
In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64
https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187%28v=vs.85%29.aspx
My application build was 32 bits. Whenever it tried to access System32 windows automatically redirected it to SysWow64 which does not contain "manage-bde.exe". I changed the build to 64 bits and then the application could access manage-bde.exe from System32
Even if you're running as the Administrator user, you're not fully elevated if UAC is running. Meaning that you'll have either the UAC prompt come up or you'll be prompted for a password.
The only real way you could get around that is to run your application elevated first, or to write a service that runs with elevated permissions to start your new process.
The alternative of course is to disable UAC, but that is undesirable in most situations.

ApplicationPool user vs StartInfo.Username?

I've been testing ( for the last 4 days) the variety of options to start a Process under iis7 ( asp.net)
I did find a solution.
As long as we don't need to interact with desktop, and only need to run cmd ( or something like that) the solution is simple:
w3wp user-> should be high privileged user.
Process start info (StartInfo.Username)-> should be also high privileged user.
However, there is a catch ( according to my testings):
Both users have to be the same (if we want cmd to execute)! this is the only way it will work.
So here are my 2 questions:
Why they both must be the same? Can't w3wp HighPrivilegedUSerA run (via process.startInfo) cmd as HighPriviligedUSerB?
Both users are domain admins.( which are also admins in my local group). Does only domain admin/local admin can run processes on the local machine?
p.s. All folders permissions are everyone : full controll ( including c:\windows\*.* /s and including cmd.exe permissions) and both users, as mentioned, are admins on local machine with same cloned permissions.IIS7 handler mapping * [static file] is set to read+execute
Also, the full cmd command is:
cmd /c time /t >c:\1.txt. A success is if the file exists.( and I succeed, only when both account were the same).
Full code:
Process proc = new Process();
proc.StartInfo.FileName = "cmd";
proc.StartInfo.UserName = "Royin"; //<-- only if this user is the same as w3wp user , the operation succeed !
proc.StartInfo.Domain = ...;
proc.StartInfo.WorkingFolder = #"c:\windows\system32";
proc.StartInfo.Password = ...
proc.StartInfo.Arguments = #"/c time /t >c:\1.txt"
proc.Start();
Ok, first, I HIGHLY recommend using the excellent SysInternals ProcessMonitor to help troubleshoot any issue like this: Process Monitor.
This app will basically tell you every action a process is attempting to take, so in your situation, you'd see it try to call QueryOpen, ProcessCreate, etc.
Have you checked what the ExitCode of the process is under the failing scenario? I'd be willing to bet real money it's coming back as 0xC0000142 (-1073741502), which means something like "failed to load DLL" or something. Running anything under the system32 path, even with privileged user credentials, is going to run into oddball issues with permissions, again due to the initialization procedure for creating a process.
Basically, the Process.Start flow looks something like this:
(assumptions: UserA == process running w3wp, UserB == impersonation ctx, UserC == credentials specified in process start info)
First, UserB isn't going to have much impact, as we've discussed in other conversations; any process creation stuff is going to be based on the process token of the "launching entity", so the credentials of UserA are the ones we'll be looking at.
The runtime says "Hey, can UserA access the file name specified in StartInfo.FileName?"
Windows responds yes/no, but also "BUT, to use that, you also need to be able to read all these other DLLs"
Runtime responds "Ok, can UserA access those DLLs?"
If the answer to all the above is yes, then the runtime says "Ok, logon this user and try creating a new process with cmd line and arguments..."
You are most-likely running into issues with either #2 or #4, as the default app pool identity has no read-access rights to the System32 folder. This is why when you switch the identity of the w3wp process to a privileged account, it works.
You could try a couple things, but the easiest option is probably switching back to a low-privilege account (like default app pool identity), but grant read-only access to the system32 folder to that account.
I would ABSOLUTELY not run w3wp as a privileged user, though - that is just asking for massive headaches should anything nasty happen, like somebody hacking you.
Oh, last thoughts:
DON'T set UseShellExecute to true if you can help it, it does weird stuff.
DON'T set LoadUserProfile to true if you can help it, it also does weird stuff, and is really slow as well.
DO set CreateNoWindow to true if you can, otherwise you'll see lotsa windows opening/closing on the server
DO use RedirectStandardOutput / RedirectStandardError instead of piping the output, it's way more controllable and gives better feedback when things go wrong.
DO always check the ExitCode of the process if it doesn't look like it worked

How to run a server-side application via ASP.Net(C# or VB)

I wanted to build a front end web page so that I can start and stop various programs on my server remotely. I know that Shell will open something locally, but how can I make an ASP.Net page which activates programs server-side? Googling got me the "Shell" method, but I don't think that works server-side. Any ideas?
Take a look at the System.Diagnostics.Process class. It can allow you to start and stop an executable on the server.
You would have to impersonate an account that has sufficient privileged to run the application, though. You can use the UserName and Password properties of the System.Diagnostics.ProcessStartInfo object that you pass to Process.Start.
Edit
For an example, you could do the following:
var startInfo = new ProcessStartInfo("C:\MyServerApp.exe", "/A /B /C");
startInfo.UserName = "LocalUser";
// It's a bad idea to hard code the password in the app, this is just an example
startInfo.Password = "SomePass";
var process = Process.Start(startInfo);
// Not a good idea to wait in a web app, but you can until the process completes
process.WaitForExit();

Categories