How a LocalSystem Service can run an application as a user [C#]? - c#

On my local machine I am running an administrative c# service as LocalSystem called Serv.exe which performs various tasks. One of the tasks it needs to perform is to launch an application under the USER account (currently logged on), not as admin - as this violates security.
The obvious solution would be simple impersonation when launching the application - however I run into a small problem whereas I am not priviledged to the user account credentials (Username & Password) and therefore am unable to impersonate in the conventional way.
So, using a C# service running as LocalSystem when logged on to a User account - is there anyway I can launch an application as that User?
From the comments:
what happens is that the Application itself asks the Service to do a job and then terminates. when the job is funished the application must restart itself - I thought the best way would be to have the service restart it when it was done ...
Any help would be greatly appreciated.
Thanks,

You can use Windows Scheduler to start your app as a user.
Take a look at this wrapper - http://www.firatatagun.com/c-windows-task-scheduler-wrapper-classes-c-sharp/2010/04/22/
and then you can simply create a scheduled task to run your software immediately, afterward you can delete this redundant task after 2 seconds.
Sample code:
using (TaskService ts = new TaskService())
{
// Create a new task
const string taskName = "RunMyProcessNowAsUser";
Task t = ts.AddTask(taskName,
new TimeTrigger() { StartBoundary = DateTime.Now, Enabled = false },
new ExecAction("YourProcess.exe");
t.Run();
// delete the task after 2 seconds.
new Action(() =>
{
Thread.Sleep(2000);
using (TaskService ts2 = new TaskService())
{
ts2.RootFolder.DeleteTask(taskName);
}
}).BeginInvoke(null, null);
}

Instead of breaching security this way you can make the application wait and then restart itself. See this SO question and this one.

Related

c# : Create windows scheduled task as a different user

I'm creating Windows Scheduled Tasks dynamically from c# using the build-in TaskService and TaskDefinition libraries.
But for some of them, we need to create then to run as a different user (Local Service or Network Service). As the tasks are created and removed dynamically we cannot edit all of them manually to change the user. We need to do it via code.
Is is possible?
I've tried the following settings:
TaskDefinition.Principal.Id = "NETWORK SERVICE";
TaskDefinition.Principal.LogonType = TaskLogonType.ServiceAccount;
but this gives me the very descript error when creating the task:
System.Runtime.InteropServices.COMException: '(52,4):Task:'
Without those 2 lines, it works but creates them as the logged in user.
I've played around with the Task Scheduler stuff a bit and have replicated your problem. I believe I’ve found some things out, maybe they can help.
1. Firstly if your making Tasks in the debugger using Services Accounts, you'll want to ensure your Visual Studio or other IDE is launched as administrator to ensure you have the correct privileges to do this task.
2. I'm not sure if you do this later in your code but to make the task save and run as NETWORK SERVICE, I had to Identify Network Service as NT AUTHORITY\\NETWORKSERVICE in both the principle and on the RegisterTaskDefinition method:
TaskService tService = new TaskService();
TaskDefinition tDefinition = tService.NewTask();
tDefinition.Principal.Id = "NT AUTHORITY\\NETWORKSERVICE";
tDefinition.Principal.LogonType = TaskLogonType.ServiceAccount;
tDefinition.RegistrationInfo.Description = "Testing";
tDefinition.Triggers.Add(new DailyTrigger {DaysInterval = 2});
tDefinition.Actions.Add(new ExecAction("notepad.exe"));
tService.RootFolder.RegisterTaskDefinition(#"Test", tDefinition, TaskCreation.CreateOrUpdate,
"NT AUTHORITY\\NETWORKSERVICE", null,
TaskLogonType.ServiceAccount);
I used the above code to make a test Task that got successfully added to my scheduler as Network Service as shown below:
I'm guessing that one or both of the above points may have stopped the task from being added, hope that helps

Creating Scheduled Task from MVC sometimes fails via LocalService user

I'm creating a Windows Scheduled Task from a MVC app # by using the c# TaskService namespace.
It normally works fine if the IIS AppPool is set to run as the LocalService user, but every now and then we find a server where it fails to create the Scheduled Task. If we change the AppPool user to a local (admin) user, then it works. But I would prefer to run the AppPool under a system user of some kind.
I don't have any specific error message yet as I can't replicate the error myself.
Are there any rigths/settings/permissions that can cause the LocalService user not to be able to create the Scheduled Tasks?
(PS: LocalSystem and the IIS AppPool users also does not work)
using (TaskService ts = new TaskService())
{
TaskDefinition td = ts.NewTask();
td.RegistrationInfo.Description = "My Task";
var trigger = new RegistrationTrigger() { Delay = TimeSpan.FromSeconds(1) };
trigger.Repetition.Interval = new TimeSpan(1, 0, 0));
td.Triggers.Add(trigger);
td.Actions.Add(new ExecAction("C:\Folder\program.exe"));
td.Settings.AllowDemandStart = task.AllowDemandStart;
td.Settings.Hidden = task.Hidden;
ts.RootFolder.RegisterTaskDefinition("My Task", td); //Assumption is that error happens on this line
}
I cannot close this as duplicate because it has a bounty; but for reference this has been answered here
Permissions required to create/modify tasks in Windows Task Scheduler
"The account needs to have read/write permissions to the "Tasks" directory. Here's the path:
%SystemRoot%\system32\Tasks\
However, there was an additional problem where Windows Server 2003 didn't like me specifying Local System as the account that the task would run under. It seemed to not like me passing in a null password which is how you specify Local System. I worked around the problem by making a local account on the server for tasks to run under and specifying this new account."

link app with windows service like shut down so that process never end?

link app with windows process so that when user terminated or end the process it says used by another process and also need to insert it into system file like shutdown file using c sharp so that my app never end or terminates
i tried that material but not usefull
this.ShowInTaskbar = false;
I also tried that code in click:
WindowsImpersonationContext ctx = null;
if (!WindowsIdentity.GetCurrent().IsSystem)
{
ctx = WindowsIdentity.Impersonate(System.IntPtr.Zero);
}
string thisuser = WindowsIdentity.GetCurrent().Name;
But have a look at image it is still present in process, what I want is that my process never stops.
what I want is that my process never stops.
To ensure that your process is always running and is started when Windows boots it's easiest to create a windows service instead. It will probably still show up somewhere in task manager and could be killed manually by the user. But windows will try to keep it running.
How to create a service:
https://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx
And if you need other programs to communicate with your service I find it easy to use a WCF service instead.
https://msdn.microsoft.com/en-us/library/bb386386.aspx

start sql server engine permission

I have created a windows application that start\stop windows service
now when i tried to start\stop sq-server engine from my application it throw an exception
when i run my Application as administrator it works
now i can run my application as administrator using app.manifest but the problem is that my client does not have permission as administrator
what type of permission my Application need and how to do that?
public static void start()
{
ServiceController sc = new ServiceController(ServiceName, ServerName);
sc.Start();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
}
public static void stop()
{
ServiceController sc = new ServiceController(ServiceName, ServerName);
sc.Stop();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
}
Your app is limited to the permissions of the person running it. If they don't have rights to do something, then neither will your application. You say that your client is not an administrator, so in order for your app to work for them an administrator will have to grant their login the permissions needed to start/stop services.
One of the following needs to happen:
The user needs to get admin rights
An admin needs to assign the user permissions to start/stop
services
Your program will need to be run under alternate credentials
For the 3rd option, this can be done at least a couple different ways:
Shift-right-click an application and it will give you a menu
option to run as another user. This option requires someone to be
there to enter their credentials every time you run the application
this way.
Add the ability for someone to enter their credentials into your
application and then impersonate them in your application when
starting/stopping services. This method would allow you to give
them the option to save their credentials for future use (not saying
that's a good idea though).

How to start a process from an IIS hosted WCF service?

I would like to run a process from an intranet client on the WCF service side. In my case a client asks a server to create a new process on the server's machine under the provided credentials. WCF service is hosted on IIS 7.5 and I start a process using this code
var processInfo = new ProcessStartInfo("C:\\Windows\\System32\\notepad.exe")
{
UserName = "some user",
Password = MakeSecureString("some password"),
UseShellExecute = false,
LoadUserProfile = true
};
Process process = Process.Start(processInfo);
This code works if I host WCF service as a self-hosted console application running under admin user and I see the notepad started under another user. It fails on IIS with no exception, but process is immediately terminated
process.HasExited = true;
process.ExitCode = -1073741502;
On IIS WCF application is running under the user with admin rights and has got full trust defined in web.config. I cannot use self hosted application as it doesn't support easy continuous delivery (like WebDeploy with IIS web farms).
Q: How can I start a process on a server side from WCF service hosted on IIS?
EDIT:
I stumbled upon this post, with similar issues and I tried all the methods there, including all possible variations for Process.Start and P/Invoke with CreateProcessWithLogonW and CreateProcessAsUser I also tried granting additional permissions to users. Non of this would work with the error messages identical to the ones the guy had posted.
Oleksii, the point is that if you host the WCF service in a console application, there is a windows session (a user logged in and Windows Explorer loaded) for that user and the notepad is opened and shown for that user, so you see it in the UI.
when you host your WCF service in IIS, being a server, IIS requires and allows no user interaction and works also if no user is logged in; in that context there is no UI to host your notepad or other UI enabled applications, you could execute a process for elaboration or other batch jobs but not render a windows UI application, because Windows Explorer is not loaded for you and there is no place to render your process's UI.
here is what I use to call GnuPGP to do encryption. How does your setup compare?
private int ExecuteCommand(string arguments, string passPhrase, int timeout)
{
Process processObject;
ProcessStartInfo pInfo = new ProcessStartInfo(_executablePath, arguments);
pInfo.CreateNoWindow = true;
pInfo.UseShellExecute = false;
pInfo.RedirectStandardInput = true;
pInfo.RedirectStandardOutput = true;
pInfo.RedirectStandardError = true;
processObject = Process.Start(pInfo);
if (!string.IsNullOrEmpty(passPhrase))
{
processObject.StandardInput.WriteLine(passPhrase);
processObject.StandardInput.Flush();
}
string result = processObject.StandardOutput.ReadToEnd();
string error = processObject.StandardError.ReadToEnd();
if (!processObject.WaitForExit(timeout))
{
throw new TimeoutException("GnuPG operation timeout. Waited " + timeout + " milliseconds ");
}
int exitcode = processObject.ExitCode;
Error = error;
Output = result;
return exitcode;
}
There's an apppool setting to make sure it loads the user profile.
loadUserProfile Optional Boolean attribute.
Specifies whether IIS loads the user profile for the application pool identity. Setting
this value to false causes IIS to revert to IIS 6.0 behavior. IIS 6.0 does not load the
user profile for an application pool identity.
The default value is false.
That along with being a domain user as the identity with enough permissions might work?? I know that at a minimum the user will need a user profile.
That said, it's a little bit of an odd architecture. It seems like a better arch would be to have a persistent process like a windows service that the site communicates with but I'm not sure what your constraints are.
Hope that helps.

Categories

Resources