简体   繁体   中英

Killing a Windows process from a C# console application: how do I set permissions?

Using Process.Kill() from an ASP.NET web application, I get a Win32Exception with text "Access is denied".

Searching the web has several times told me to set permissions. However I don't really understand the Windows XP User system well enough to know how to get started.

At the time the exception is thrown, Thread.CurrentPrincipal.Identity has the following visible properties:

  1. AuthenticationType = ""
  2. IsAuthenticated = "false"
  3. Name = ""

WindowsIdentity.GetCurrent() shows me logged in as "NAME\\ASPNET" but I don't think that this is relevant.

What do I need to do? Can I somehow get the thread to log in as some Windows user?

I think you're on the right way, the problem with "Access denied" is due to ASP.NET process running with ASPNET user which has limited rights and that's what you're getting an error. What you could do is to set up imersnation for your web application. You can it either by changing web.config or in code. More about impersonation you can read here

web.comfig is realtively easy, you need to add a following line into the system.web section of your web.config

<identity impersonate="true" userName="domain\user" password="password" />

user need to have admin rights on the server

if you would like to perform the impersonation in code below is an example of how you could do this:

...
WindowsImpersonationContext context = ImpersonateUser("domain", "user", "password");
// kill your process
context.Undo();
...

[DllImport("advapi32.dll")]
private static extern bool LogonUser(
    String lpszUsername, String lpszDomain, String lpszPassword,
    int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("advapi32.dll")]
private static extern bool DuplicateToken(
    IntPtr ExistingTokenHandle, int ImpersonationLevel,
    ref IntPtr DuplicateTokenHandle);

[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);


private enum SecurityImpersonationLevel
{
    SecurityAnonymous,
    SecurityIdentification,
    SecurityImpersonation,
    SecurityDelegation
}

private enum LogonTypes
{
    LOGON32_PROVIDER_DEFAULT=0,
    LOGON32_LOGON_INTERACTIVE=2,
    LOGON32_LOGON_NETWORK=3,
    LOGON32_LOGON_BATCH=4,
    LOGON32_LOGON_SERVICE=5,
    LOGON32_LOGON_UNLOCK=7,
    LOGON32_LOGON_NETWORK_CLEARTEXT=8,
    LOGON32_LOGON_NEW_CREDENTIALS=9
}

public static WindowsImpersonationContext ImpersonateUser(string domain, string username, string password)
{
    WindowsImpersonationContext result = null;
    IntPtr existingTokenHandle = IntPtr.Zero;
    IntPtr duplicateTokenHandle = IntPtr.Zero;

    try
    {
        if (LogonUser(username, domain, password,
            (int)LogonTypes.LOGON32_LOGON_NETWORK_CLEARTEXT, (int)LogonTypes.LOGON32_PROVIDER_DEFAULT,
            ref existingTokenHandle))
        {
            if (DuplicateToken(existingTokenHandle,
                (int)SecurityImpersonationLevel.SecurityImpersonation,
                ref duplicateTokenHandle))
            {
                WindowsIdentity newId = new WindowsIdentity(duplicateTokenHandle);
                result = newId.Impersonate();
            }
        }
    }
    finally
    {
        if (existingTokenHandle != IntPtr.Zero)
            CloseHandle(existingTokenHandle);
        if (duplicateTokenHandle != IntPtr.Zero)
            CloseHandle(duplicateTokenHandle);
    }
    return result;
}

hope this helps, regards

You need to run your C# application as an user with sufficient privileges.

If you cannot trust the ASP AppPool with such privileges (you shouldn't) you need to create a separate service that runs under an account with sufficent privileges and have protocol between the low privileged app and the higher privileged service to communicate with the purpose of killing a process.

Don't impersonate a high privileged user in the AppPool. You must present its password and by this you have effectively elevated the low privileged account to the high privileged one, by all effective means, in case of AppPool compromise, is just as if you run the AppPool under high privilege and did not accomplish any isolation.

Building on Serge Gubenko's answer, Here is the code to impersonate and kill a process (where in his answer he wrote "//kill your process"):

using (WindowsImpersonationContext context = ImpersonateUser("domain", "user", "password"))
    {
        Process[] proc = Process.GetProcessesByName("process name");
        if (proc.Length > 0)
            proc[0].Kill();

        context.Undo();
    }

You still need to use the rest of the code in his answer. Note that if you are not part of a domain just enter an empty string

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM