| Hi,
|
| I am trying to get a usertoken from a particular process running on the
| computer, from a Windows Service to do a Windows group membership of the
| user running that process. I was planning to use a API call to
| OpenProcessToken and use the Tokenhandle retrieved to build a
| WindowsIdentity object and do a access check on.
|
| Has anyone done this before, and can advise if this would work, and if
so
| possible post a sample on how to do the API call and get the Token
handle
?
|
| Many thanks
|
| Niclas
|
|
Yes, it's possible provided you are running this with appropriate
privileges, that is as SYSTEM to begin with.
Herewith a small sample that shows how to do.
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Diagnostics;
using System.Security;
using System.Security.Principal;
namespace TestSecurity
{
class Tester
{
[DllImport("advapi32", SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern int OpenProcessToken(
System.IntPtr ProcessHandle, // handle to process
int DesiredAccess, // desired access to process
ref IntPtr TokenHandle // handle to open access token
);
[DllImport("kernel32", SetLastError=true),
SuppressUnmanagedCodeSecurityAttribute]
static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
public const int TOKEN_DUPLICATE = 2;
public const int TOKEN_QUERY = 0X00000008;
public const int TOKEN_IMPERSONATE = 0X00000004;
static void Main()
{
IntPtr hToken = IntPtr.Zero;
IntPtr dupeTokenHandle = IntPtr.Zero;
// For simplicity I'm using the PID of System here
Process proc = Process.GetProcessById(4);
if (OpenProcessToken(proc.Handle,
TOKEN_QUERY|TOKEN_IMPERSONATE|TOKEN_DUPLICATE,
ref hToken) != 0)
{
WindowsIdentity newId = new WindowsIdentity(hToken);
Console.WriteLine(newId.Owner );
try
{
const int SecurityImpersonation = 2;
dupeTokenHandle = DupeToken(hToken,
SecurityImpersonation);
if(IntPtr.Zero == dupeTokenHandle)
{
string s = String.Format("Dup failed {0}, privilege not held",
Marshal.GetLastWin32Error());
throw new Exception(s);
}
WindowsImpersonationContext impersonatedUser =
newId.Impersonate();
IntPtr accountToken = WindowsIdentity.GetCurrent().Token;
Console.WriteLine( "Token number is: " +
accountToken.ToString());
Console.WriteLine( "Windows ID Name is: " +
WindowsIdentity.GetCurrent().Name);
}
finally
{
CloseHandle(hToken);
}
}
else
{
string s = String.Format("OpenProcess Failed {0}, privilege not
held", Marshal.GetLastWin32Error());
throw new Exception(s);
}
}
static IntPtr DupeToken(IntPtr token, int Level)
{
IntPtr dupeTokenHandle = IntPtr.Zero;
bool retVal = DuplicateToken(token, Level, ref dupeTokenHandle);
return dupeTokenHandle;
}
}
}
Willy.