Is there a way to request elevated privileges from the os, for "just a part" of a c# program?
I'm writing a bunch of integrationtests using NUnit. One of the things I'm testing is if the application under test correctly connects to port 843. The test opens a listening socket at port 843, and then throws all sorts of responses to the application under test, and verifies if the application behaves correctly.
Opening a listening socket on port 843 requires admin privileges however.
I'd like to find the least intrusive way to be able to run this test. I could run the entire NUnit suite as root/admin, but that would make a lot of stuff run as root, that really doesn't need to be ran as root, which I'd like to prevent.
If required below code would help you to find out if the current logged in user is admin or not:
using System;
using System.Security.Principal;
class Test
{
public static void Main()
{
if (new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
{
Console.WriteLine("I am an admin.");
}
}
}
Nope. Elevation is all or nothing. Typically if elevation is required, the app bootstraps itself into an elevated state.
Yes, you could take a look at the LogonUser function. Here's a sample.
A process has to be started with elevated privileges to have elevated rights. You cannot change your elevated status "in process".
A way to work around this is to do as Task Manager. If you run that "unelevated" and click on "Show processes for all users", it basically kills of the old task manager process and starts a new one with elevated privileges in order to do the job.
Related
I have read other questions on SO in regards to security and registry keys, nothing has helped me solve my particular use case scenario.
Here's my scenario:
What I'm Trying To Do
I want to, in code, delete a windows event log.
The Problem
When executing the function, I receive a System.ComponentModel.Win32Exception. The exception message is "Access is denied".
How I Am Doing It Currently
I am using an impersonator function that I wrote which wraps around the EventLog.Delete function, it drops me into a user context that has full access to the EventLog Registry Hive. Subsequently the logs I am interested in also have full access for this particular user.
My Question
Why do I receive a "Access Is Denied" if the user I am running under (through impersonation) has full access to the log in question? I've tested my Impersonation function and it works as expected for other code I've written. I don't get why I would get access denied for this.
In another scenario with my impersonation function it works just fine, for example if I tried to write to a file that the user context that is running the program does not have write access to, then I would not be able to write to the text file, however if I use my impersonation to drop into a user context that does have write access then it works just fine (I can write to the file). So I just don't understand why the same concept can't be applied to registry keys.
What am I missing here?
The Code
Exception Message
My Test
Where sw-test is a user I created for testing purposes, it has full access permissions to the registry we are trying to delete.
[TestMethod]
public void DeleteEventLog_ValidatedUser_DeleteLog()
{
using (new Impersonator(Environment.UserDomainName, "sw-test", "pswd"))
{
Logging logging = new Logging();
logging.DeleteEventLog("testLog");
}
}
Okay I eventually got around to figuring this out, there were two issues at play here that were causing the mentioned exception being thrown, they are as follows:
1. Visual Studio was NOT running in administrator mode.
Not running visual studio in administrator mode was one part of the problem, this seems to be associated with access tokens in the windows OS. According to a source I read, if I run a program without UAC on (which is my scenario, I have it off), then the program being run gets a copy of my access token. However if I have UAC enabled, the program gets a copy of my access token but it is a restricted access token. (see: What precisely does 'Run as administrator' do?) - To be honest this doesn't really make sense in my case, why do I have to run as admin if I have UAC off? Shouldn't visual studio have an unrestricted copy of my access token? I am in the administrator group with UAC off...
2. Not Specifying NewCredentials As a Logon32Type In Impersonation
I don't really understand it but as soon as I specified this for my impersonation everything started working perfectly, I read a blog about it, it talks about how it was introduced in the VISTA days and how it was mainly used to specify credentials to outbound network connections to servers, and was mainly used to remedy security-related issues server-side. Don't see how it correlates to interfacing with local event logs though. (see: https://blogs.msdn.microsoft.com/winsdk/2015/08/25/logonuser-logon32_logon_new_credentials-what-is-this-flag-used-for/)
Code
using (new Impersonator(Environment.UserDomainName, "sw-test", "pswd", Advapi32.Logon32Type.NewCredentials))
{
EventLog.CreateEventSource("testSource", "testLog");
EventLog.Delete("testLog");
}
Where the NewCredentials is an int 9
I have a program on a server(for example \\192.168.0.1\sharefolder\test.exe). I put the shortcut of program into clients. Users can run the program by that shortcut. When I want to update my program in server, it occurs an error says "file in use".. now, how can I kill all processes in clients that run my program (by shortcut) on server.
I use this code:
foreach (var process in Process.GetProcessesByName("quartus_pgm"))
{
process.kill();
}
//file.delete();
But this code is not enough because this code only kill processes running on the server and still I can not update the program and the error occurs..
Mahyar, hello!
I recomend you to use "Shadow Copying Assemblies" mechanism provided by .NET. In few words:
1. you have 1 app (exe) that referenced on several dlls (libraries with all logic/UI/...).
2. you can replace dlls without stopping app (exe).
For more information you can read this MSDN article.
This approach may require to do some refactoring of your app.
I'm trying to determine if another application is running as an administrator. There are 100's of SO questions about finding if your application is or not, but not for another application.
If I do var processes = Process.GetProcesses(); and loop through them, they don't appear to have any "Elevated" or "IsAdministrator" properties on them. I also found a function on here to get the Owner but they all come back as "My-Laptop\Me" so that's not working for me the way I hoped it would.
Is there a way to find this? I'm on Win 8.1 and would prefer something that works for 7 as well, but if it only works for 8.1+ that's totally fine.
Thanks!
EDIT:
My application has to run as an administrator.
You can use the technique from this answer, just replace Process.GetCurrentProcess().Handle with the Process.Handle of the other process.
If you look at the code (there's quite a bit of code there) it get the process "user token" (the permissions the process is running under) and checks if this token has the administrator role or not,
Assuming your process is not running as administrator, trying to get information about a process that is elevated via UAC (such as its MainWindowTitle) will throw an AccessDenied exception, where a non-elevated process will permit you access to that information. This assumes you also verify the owner of the process to check that it's you.
try
{
var foo = process.MainWindowTitle;
return false; //Process is not elevated
}
catch (Win32Exception ex)
{
return true; //Process is elevated if ex error code is AccessDenied
}
The other day, I came across an application that when you run it, it comes up with the UAC screen and requests to be run with administrator privileges. Clicking 'Yes' on the UAC screen runs the application like normal. The interesting thing is that if you click 'No', the application, instead of exiting, still runs, but runs in a limited user account (with less functionality, of course).
My question is, how can I configure my C# application to do this? I know my application can have an application manifest to run in elevated privileges, but how do I duplicate the kind of behavior I just explained above?
To do this with a different elevated application you can use a "launcher" (or the launcher is the "normal" app).
If you wanted three applications you might have a WinForms launcher something like:
[STAThread]
static void Main()
{
const int ERROR_CANCELLED = 1223;
try
{
Process.Start("el.exe");
// ran el in elevated node...
}
catch (Win32Exception ex)
{
if (ex.NativeErrorCode == ERROR_CANCELLED)
{
Process.Start("normal.exe");
}
}
}
If you were doing two applications, you could do something like:
[STAThread]
static void Main()
{
const int ERROR_CANCELLED = 1223;
try
{
Process.Start("el.exe");
// ran el in elevated node...
}
catch (Win32Exception ex)
{
if (ex.NativeErrorCode == ERROR_CANCELLED)
{
// "continue" as un-elevated app.
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
You can keep all the code in one application. The application manifest does not request the application to be run elevated, it uses asInvoker level.
When the application is started, it tries to re-start itself elevated. I mean it starts another process with runas verb. If it succeeds, then the first instance just exists.
If elevation was not successful, then it continues to run with limited functionality.
But think about the user experience:
Not everyone in the world works as administrator. For them, elevation would not look as clicking Continue button, the UAC will ask them to provide user name and password of an administrator.
From this point of view, Microsoft recommended approach works great: run as regular user until you really need to elevate. All elevation points should be clearly marked in the UI. You can still use the same exe file to run non-elevated and elevated instances, yet you must implement a communication mechanism so the non-elevated instance can provide all the data to perform the operation requested by the user. Once you started elevated instance, you can keep it running and exit the non-elevated one, so that other operations could be performed without elevation.
Thus it means more effort, but a much better user experience.
I am using the below code to disable the task manager for a kiosk application which works perfectly
public void DisableTaskManager()
{
RegistryKey regkey;
string keyValueInt = "1";
string subKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
try
{
regkey = Registry.CurrentUser.CreateSubKey(subKey);
regkey.SetValue("DisableTaskMgr", keyValueInt);
regkey.Close();
}
catch (Exception ex)
{
MessageBox.Show("DisableTaskManager" + ex.ToString());
}
}
But when i run this in OS hardened machine i get the following error,
DisableTaskManagerSystem.UnauthorizedAccessException:
Access to the registry key 'HKey_Current_User\Software\Mictrosoft\Windows\CurrentVersion\Policies\System' is denied.
at Microsoft.win32.RegistryKey.win32Error(int32 errorcode, String str)
How can i overcome this ? I need to do this for a Kiosk application.
take a look at this, im not yet a good enough C# Developer to comment but i know that during my work with other developers they came accross the UAC In windows 7, If thats what were talking about here.
http://www.aneef.net/2009/06/29/request-uac-elevation-for-net-application-managed-code/
Well the guy that set up that machine basically asked the reverse... "How do I prevent a non-administrator from messing with group policy". So rather engaging in a group policy arms race, you can either do it at install time when running as an admin, or just skip that part of the code when not running as a user that has permission to do so.
Don't have your application disable task manager but instead use a windows service or scheduled task. Your application is going to run in the context of the current user and won't have rights to the registry key. Instead you can create either a windows service or a scheduled task which can run as a user with higher privileges and can write to the registry.
With a windows service you can communicate it through any IPC mechanism such as custom service messages, Sockets, .NET Remoting, WCF, or whatever, to tell it to turn task manager on/off.
the code requires an elevated privilege to access registry. However there is just a fragment of code that requires these extra permission. To handle such scenarios impersonation is used i.e. you will execute this application as normal user only but that particular piece of code will be executed as if you were an Administrator.
http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx