English 中文(简体)
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 "NAMEASPNET" 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="domainuser" 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





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Transaction handling with TransactionScope

I am implementing Transaction using TransactionScope with the help this MSDN article http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx I just want to confirm that is ...

System.Web.Mvc.Controller Initialize

i have the following base controller... public class BaseController : Controller { protected override void Initialize(System.Web.Routing.RequestContext requestContext) { if (...

Microsoft.Contracts namespace

For what it is necessary Microsoft.Contracts namespace in asp.net? I mean, in what cases I could write using Microsoft.Contracts;?

Separator line in ASP.NET

I d like to add a simple separator line in an aspx web form. Does anyone know how? It sounds easy enough, but still I can t manage to find how to do it.. 10x!

热门标签