views:

446

answers:

2

using Process.Kill() from an ASP.NET web application...

I get a Win32Exception with text "Access is denied"

googling 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?

thanks and much love

+1  A: 

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.

Remus Rusanu
but how do i "run the C# application as a user with sufficient privileges"?
HaterTot
You grant the needed priviledges to the account running the application, ie. to NAME\ASPNET, from the Local Security Policy application (in Administrative Tools) and add NAME\ASPNET to the 'Debug Programs' privilege. See http://support.microsoft.com/kb/155075
Remus Rusanu
thanks dude this was helpful too
HaterTot
+1  A: 

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

serge_gubenko
HaterTot