Web Images Videos Maps News Shopping Gmail more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Message from discussion Service launching exe in security context of logged in user

View parsed - Show only message text

From: "Colin Wilson" <co...@wilsonc.demon.co.uk>
Subject: Re: Service launching exe in security context of logged in user
Newsgroups: borland.public.delphi.nativeapi.win32
References: <4165b2ba@newsgroups.borland.com> <4166E1CE.AEC9E17@no-spam.gmx.net> <416709e5@newsgroups.borland.com>
User-Agent: XanaNews/1.16.4.6
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
NNTP-Posting-Host: 217.44.213.140
Message-ID: <416a98a9$1@newsgroups.borland.com>
Date: 11 Oct 2004 07:28:57 -0700
X-Trace: newsgroups.borland.com 1097504937 217.44.213.140 (11 Oct 2004 07:28:57 -0700)
Lines: 220
Path: g2news1.google.com!news1.google.com!news.glorb.com!logbridge.uoregon.edu!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail

Steve McGrath wrote:

> Do you have working code sample for this.

You can use the code below.  People keep complaining that I forgot to
upload this to my website, so posting it here will kill two birds with
one stone!

It impersonates the logged on user, then loads their profile - so that
things like HKEY_CURRENT_USER work correctly in the context of the user
being impersonated.

You use it like this, from within your service's thread...

procedure TMyServiceThread.Execute;
var
  impersonator : TImpersonator;
begin
  impersonator := TImpersonator.CreateLoggedOn;
  try
    
    ...  Do whatever you like in the context of the logged on user ...

  finally
    impersonator.Free  // Revert to the SYSTEM account
  end
end;

-- 
Colin - using XanaNews HTTP Transport
e-mail :co...@wilsonc.demon.co.uk
web: http://www.wilsonc.demon.co.uk/delphi.htm

Posted with XanaNews 1.16.4.6

---  Here's the code...  ----

unit unitImpersonator;

interface

uses Windows, Classes, SysUtils;

type

TProfileInfo = record
  dwSize : DWORD;
  dwFlags : DWORD;
  lpUserName : PChar;
  lpProfilePath : PChar;
  lpDefaultPath : PChar;
  lpServerName : PChar;
  lpPolicyPath : PChar;
  hProfile : HKEY;
end;


TImpersonator = class
private
  fTokenHandle : THandle;
  fImpersonating: boolean;
  fProfileLoaded : boolean;
  fProfileInfo : TProfileInfo;
  procedure Impersonate;
  function GetImpersonating: boolean;
  function GetHKCURootKey: HKEY;
public
  constructor Create (const domain, user, password : string);
  constructor CreateLoggedOn;   // Impersonate the currently logged on
user.

  destructor Destroy; override;

  property Impersonating : boolean read GetImpersonating;
  property HKCURootKey : HKEY read GetHKCURootKey;
end;

const
  PI_NOUI        = 1;     // Prevents displaying of messages
  PI_APPLYPOLICY = 2;     // Apply NT4 style policy

function LoadUserProfile (hToken : THandle; var profileInfo :
TProfileInfo) : BOOL; stdcall;
function UnloadUserProfile (hToken, HKEY : THandle) : BOOL; stdcall;
function GetCurrentUserName : string;
function OpenProcessHandle (const process : string) : THandle;

implementation

uses psapi;

function LoadUserProfile (hToken : THandle; var profileInfo :
TProfileInfo) : BOOL; external 'userenv.dll' name 'LoadUserProfileA';
function UnLoadUserProfile (hToken, HKEY : THandle) : BOOL; external
'userenv.dll';

function OpenProcessHandle (const process : string) : THandle;
var
  buffer, pid : PDWORD;
  bufLen, cbNeeded : DWORD;
  hp : THandle;
  fileName : array [0..256] of char;
  i : Integer;
begin
  result := 0;
  bufLen := 65536;
  GetMem (buffer, bufLen);
  try
    if EnumProcesses (buffer, bufLen, cbNeeded) then
    begin
      pid := buffer;
      for i := 0 to cbNeeded div sizeof (DWORD) - 1 do
      begin
        hp := OpenProcess (PROCESS_VM_READ or
PROCESS_QUERY_INFORMATION, False, pid^);
        if hp <> 0 then
        try
          if (GetModuleBaseName (hp, 0, fileName, sizeof (fileName)) >
0) and
             (CompareText (fileName, process) = 0) then
          begin
            result := hp;
            break
          end
        finally
          if result = 0 then
            CloseHandle (hp)
        end;

        Inc (pid)
      end
    end
  finally
    FreeMem (buffer)
  end
end;

function GetExplorerProcessToken : THandle;
var
  explorerProcessHandle : THandle;
begin
  explorerProcessHandle := OpenProcessHandle ('explorer.exe');
  if explorerProcesshandle <> 0 then
  try
    if not OpenProcessToken (explorerProcessHandle, TOKEN_QUERY or
TOKEN_IMPERSONATE or TOKEN_DUPLICATE, result) then
      RaiseLastOSError;
  finally
    CloseHandle (explorerProcessHandle)
  end
  else
    result := INVALID_HANDLE_VALUE;
end;

function GetCurrentUserName : string;
var
  unLen : DWORD;
begin
  unLen := 512;
  SetLength (result, unLen);
  GetUserName (PChar (result), unLen);
  result := PChar (result);
end;

{ TImpersonator }

constructor TImpersonator.Create(const domain, user, password: string);
begin
  if LogonUser (PChar (user), PChar (domain), PChar (password),
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, fTokenHandle) then
    Impersonate;
end;

procedure TImpersonator.Impersonate;
var
  userName : string;
begin
  fImpersonating := ImpersonateLoggedOnUser (fTokenHandle);
  if fImpersonating then
  begin
    userName := GetCurrentUserName;

    ZeroMemory (@fProfileInfo, sizeof (fProfileInfo));
    fProfileInfo.dwSize := sizeof (fProfileInfo);
    fProfileInfo.lpUserName := PChar (userName);
    fProfileInfo.dwFlags := PI_APPLYPOLICY;
    fprofileLoaded := LoadUserProfile (fTokenHandle, fProfileInfo);
  end
end;

constructor TImpersonator.CreateLoggedOn;
begin
  fTokenHandle := GetExplorerProcessToken;

  if fTokenHandle <> INVALID_HANDLE_VALUE then
    Impersonate;
end;

destructor TImpersonator.Destroy;
begin
  if fProfileLoaded then
    UnloadUserProfile (fTokenHandle, fProfileInfo.hProfile);

  if fImpersonating then
    RevertToSelf;

  CloseHandle (fTokenHandle);
end;

function TImpersonator.GetImpersonating: boolean;
begin
  result := fImpersonating and fProfileLoaded;
end;

function TImpersonator.GetHKCURootKey: HKEY;
begin
  result := fProfileInfo.hProfile
end;

end.

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google