At the moment I have a service which will execute from time to time a .exe file. As the service is run as the SYSTEM user, these subprocesses will also be executed by SYSTEM. Due to security reasons I would like these processes to be executed in the context of a different user without administrative priviliges. Is there a way to do this without having to store the username and the password of this user somehow? If not: How can I save these credentials in a secure way?
I am using C# for the service, but I think that this questions can also be answered in general.
Related
I receive random reports from random users about UnauthorizedAccessException when reading or writing(creating files) to random folder. Usually on their own Documents folder. And more problem is that when app is unable to write its data to {USER}\AppData\Roaming.
The application is running as admin** and usually reports are from Windows 7 and Windows 8 users.
Is there any way to fix this without setting the permission manually.
**To determine if app is running as admin
AppDomain myDomain = Thread.GetDomain();
myDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsPrincipal myPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;
boolean isRunningasAdmin = myPrincipal.IsInRole(WindowsBuiltInRole.Administrator));
edit : in app.manifest
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
With respect to the question: Is it possible to avoid permission related exceptions while attempting to write to the disk?
In short, the answer is: yes this can be accomplished through the use of impersonation.
SOLUTION NOTES
IMPERSONATION & PERMISSIONS
Impersonation is the ability of a thread to execute using a different
security information than the process that owns the thread. Typically,
a thread in a server application impersonates a client. This allows
the server thread to act on behalf of that client to access objects on
the server or validate access to the client's own objects. [SOURCE: A Complete Impersonation Demo]
As highlighted by Aasmund Eldhuset, running as an administrator does not guarantee that you will have the appropriate permissions to access the file system.
As a sanity check, you could create a simple application to ensure that everything is working as expected.
Create a simple WinForms application that will write a text file to disk using impersonation.
See: A Complete Impersonation Demo
Create a test environment with folders/directories and different user permissions
Verify that everything works:
Run the test application and have it write to a directory where you DO have permission.
Run the test application and have it write to a directory where you **DO NOT* have the appropriate permissions.
APPLICATION DESIGN
I suggest that you take user feedback with a grain of salt as it is not uncommon for users to provide inaccurate or incomplete descriptions of problems they are encountering.
In your scenario, I would have your application attempt to write to the directory/folder in question when the application starts. If the write fails, then you can record relevant information (e.g. the name of the user that is executing the write operation) to an event log (e.g. text file) for later review.
ADDITIONAL READING
CodeProject: A Complete Impersonation Demo in C#.NET
Microsoft TechNet: RunAs command
High-Level Overview of Windows Privileges
I have a desktop application (not a service) that can be run using process impersonation. I achieve this by having a separate application which is used as a launcher, and uses CreateProcessWithLogonW to run the application under a different user. Upon the user signing-out of the application, I need to figure out how to make the application run the launcher process under the credentials of the windows session user without prompting for the password.
My current strategy is:
Use ProcessIdToSessionId to get the session id from the application process.
Use WTSQueryUserToken to get the primary user token from the session id.
Use DuplicateTokenEx for something that isn't exactly clear to me.
Use CreateProcessAsUser to run the process.
Currently, WTSQueryUserToken fails with result ERROR_PRIVILEGE_NOT_HELD (http://msdn.microsoft.com/en-us/library/aa383840(v=vs.85).aspx). Is there a different way that I can get that token? Is there another strategy entirely that would work for this?
Also, I am using C# and am fairly new with P/Invokes. Thanks
You can't use WTSQuerUserToken in this scenario.
From http://msdn.microsoft.com/en-us/library/aa383840(v=vs.85).aspx
"To call this function successfully, the calling application must be running within the context of the LocalSystem account and have the SE_TCB_NAME privilege."
I still don't understand how many exe's you have and how many processes are being executed and more importantly why. Perhaps you could explain in more detail?
If the original launcher is still running it might be simpler to message it and tell it to do stuff instead of launch another one from your impersonated process.
How can i prompt for password and user when someone tries to stop a windows service?
It cannot be done.
Services are meant to run outside the user experiance and do not handle GUI interactions. This is something that is left up to the operating system to allow or disallow a user from stopping a service.
It cannot be done directly from the service. However, the service can be managed by another application if the service is set to interact with the desktop. So you could create a second application with a GUI that monitored the service. The service could set some value in shared state file when the services 'Stopping' event fires and wait until the monitoring app writes a confirmation value in the state file. Maybe not what you are looking for exactly but I think you could get the result that you want.
Ordinarily, there's no reason to do this. By default, only administrators can stop a service, and if the service can be stopped at all it makes no sense to ask an administrator for a password to do so: they're an administrator, so by definition they're entitled to do anything.
The one scenario that makes sense is if you want ordinary users to be able to stop the service if they know the password. That way, you can let someone stop the service without giving them administrative rights to the computer. (Even then, in most cases it would be simpler to change the permissions on the service to allow the user(s) in question the right to stop the service; but perhaps, for example, you want users to be have to phone a helpdesk to be given the password.)
The secret to making this work is that the service is entitled to stop itself for any reason without having received a stop request from the operating system. So you can just write a program that the users can run if they want to stop the service. The program accepts the password and sends it to the service over some form of IPC, such as a named pipe. If the password is correct, the service stops.
You could also configure the service so that it doesn't accept stop requests, in which case an administrator would also need the password in order to stop the service nicely. But that wouldn't stop them from stopping the service by killing the service process, or uninstalling the service and rebooting the computer.
I created a windows service that's basically a file watcher that wont run unless a user is logged into the machine its on.
The service is running on a Windows Server 2003 machine. It is designed to listen for excel files in a folder. When there is a excel file, it starts to send some information to a web service. When it's done, it copies the processed file to a archive folder.
Can anyone help me?
Best regards
Baris
Run it as a user that has rights to log on as service on the machine. Make sure this user has an access to the directory you watch.
What i always do in a scenario like that is give the user logon as batch job and logon as a service rights. 1 of these 2 will most likely fix your problem.
You can configure this in the local group policy editor as described here
Be aware though that if your computer is in a domain it is possible that the group policy gets pushed to the server every 15 mins so you might have to talk to a system admin to get things sorted.
When you actually only want to run when someone is logged in, do not use a service but an autostart application in that case.
If you have to be a service because of account privileges, the service may detect the current logins itself, but you may combine a service with a client (autostart) application that connects to the service. That way, you can also show tray incos, status informations and enable the user to control your service using the client application.
Using Win7 and higher, services themselves (running in session 0) can no longer display UI interactions on the user's desktop.
Keep in mind that there may be multiple users logged in on current operating systems...
I was hoping I could get some input on the best way to handle authentication for my application. I have a C# form that has three buttons. One button is for querying tasks on a specific server, one button can start a task, and the last button can end a task.
My question involves the best way to do this for multiple users. I know I can add these users to the administrator group on each server but I really don't want to do this because these are all non-admin users. Also, I am running this against 3 different domains and multiple servers with no trusts.
Is there a way to either create a user that I can give admin rights on all of the servers and then run the C# app as this user (could be domain or local) or is there a better way to handle permissions for schtasks without giving admin rights?
I have researched impersonation but I don't think that does what I need unless I missed something.
Thank you,
Matt
You can use the runas command - this lets you set a user name and password to execute the application under.
You will still need to set the link up for each user/computer.