2004. október 9., szombat
Some useful Windows NT functions
Problem/Question/Abstract:
Some useful Windows NT functions
Answer:
{-----------------------------------------------------------------------------
Unit Name: unitNTFunctions
Author: StewartM
Documentation Date: 22 February, 2002 (11:04)
Version 1.0
-----------------------------------------------------------------------------
Purpose:
To provide a few handy Windows NT API functions.
Description:
Unit written by Stewart Moss (except where indicated)
Some of the functions are incomplete or not tested.
Copyright 2001 by Stewart Moss. All rights reserved.
-----------------------------------------------------------------------------}
unit unitNTFunctions;
// Unit written by Stewart Moss (except where indicated)
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
const
BSECURITY_NULL_SID_AUTHORITY = 0;
BSECURITY_WORLD_SID_AUTHORITY = 1;
BSECURITY_LOCAL_SID_AUTHORITY = 2;
BSECURITY_CREATOR_SID_AUTHORITY = 3;
BSECURITY_NT_AUTHORITY = 5;
SECURITY_INTERACTIVE_RID = $00000004;
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
ACL_REVISION = 2;
SECURITY_DESCRIPTOR_REVISION = 1;
type
PACE_Header = ^TACE_Header;
TACE_Header = record
AceType: BYTE;
AceFlags: BYTE;
AceSize: WORD;
end;
PAccess_Allowed_ACE = ^TAccess_Allowed_ACE;
TAccess_Allowed_ACE = record
Header: TACE_Header;
Mask: ACCESS_MASK;
SidStart: DWORD;
end;
const
SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
(Value: (0, 0, 0, 0, 0, 5));
function ISHandleAdministrator(UserToken: THandle): Boolean;
function IsAdmin: Boolean;
function ReturnUserHandle(Username: string): THandle;
function IsWinNT: boolean;
function TryToLoginAsUser(Username, Domain, Password: string): THandle;
implementation
function ISHandleAdministrator(UserToken: THandle): Boolean;
// this function written by Stewart Moss
var
tmpBuffer: array[0..1024] of char;
BufferPtr: Pointer;
ptgGroups: PTokenGroups;
dwInfoBufferSize: DWord;
PSIDAdministrators: PSID;
siaNTAuthority: SID_IDENTIFIER_AUTHORITY;
X: DWord;
bSuccess: Boolean;
begin
GetMem(PtgGroups, 1024);
bSuccess := GetTokenInformation(UserToken, TokenGroups, ptgGroups,
1024, dwInfoBufferSize);
result := false;
if not bsuccess then
exit;
if not AllocateAndInitializeSid(siaNtAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
psidAdministrators) then
exit;
for x := 0 to ptgGroups.GroupCount do
begin
if EqualSID(psidAdministrators, ptgGroups.Groups[x].SID) then
begin
result := true;
break;
end;
end;
freemem(PtgGroups);
Freemem(PsidAdministrators);
result := true;
end;
function IsAdmin: Boolean;
// This function written by somebody else
var
hAccessToken: THandle;
ptgGroups: PTokenGroups;
dwInfoBufferSize: DWORD;
psidAdministrators: PSID;
x: Integer;
bSuccess: BOOL;
begin
Result := False;
bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
hAccessToken);
if not bSuccess then
begin
if GetLastError = ERROR_NO_TOKEN then
bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
hAccessToken);
end;
if bSuccess then
begin
GetMem(ptgGroups, 1024);
bSuccess := GetTokenInformation(hAccessToken, TokenGroups,
ptgGroups, 1024, dwInfoBufferSize);
CloseHandle(hAccessToken);
if bSuccess then
begin
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, psidAdministrators);
{$R-}
for x := 0 to ptgGroups.GroupCount - 1 do
if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
begin
Result := True;
Break;
end;
{$R+}
FreeSid(psidAdministrators);
end;
FreeMem(ptgGroups);
end;
end;
function ReturnUserHandle(Username: string): THandle;
// Function written by Stewart Moss
begin
end;
function IsWinNT: boolean;
// Function Written by Stewart Moss
var
osv: TOSVERSIONINFO;
begin
result := false;
osv.dwOSVersionInfoSize := sizeOf(OSVERSIONINFO);
GetVersionEx(osv);
if (osv.dwPlatformId = VER_PLATFORM_WIN32_NT) then
result := true;
end;
function TryToLoginAsUser(Username, Domain, Password: string): THandle;
// Function written by Stewart Moss
// returns 0 if failed else User Handle
var
tmpstr: string;
hToken: THandle;
begin
result := 0;
if (UserName = '') or (Domain = '') then
exit;
if not LogonUser(PChar(Username), Pchar(Domain), PChar(Password),
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, hToken) then
exit;
result := hToken;
end;
(*function ApplySecurityDescriptorToRegistryKey(Key : Hkey): Boolean;
var lRv : longint;
siaNtAuthority : SID_IDENTIFIER_AUTHORITY;
psidSystem, psidAdministrators: PSID;
tmpACL : ACL;
pNewDACL : PACL;
dwACL : DWord;
ACLRevision : ACL_REVISION_INFORMATION;
begin
siaNtAuthority := SECURITY_NT_AUTHORITY;
result := false;
InitializeSid(psidAdministrators, siaNtAuthority,2);
InitializeSid(psidSystem, siaNtAuthority,1);
//*(GetSidSubAuthority(psidAdministrators,0)) = SECURITY_BUILTIN_DOMAIN_RID;
//*(GetSidSubAuthority(psidAdministrators,1)) = DOMAIN_ALIAS_RID_ADMINS;
//*(GetSidSubAuthority(psidSystem,0)) = SECURITY_LOCAL_SYSTEM_RID;
// getmem(pNewDACL, sizeof(PACL));
// pNewDACL := tmpAcl;
dwAcl := sizeof(PACL);
if not GETAclInformation(pnewAcl,
if (not InitializeAcl(pnewDACL,
dwACL,
ACL_REVISION)) then exit;
if (!AddAccessAllowedAce(pNewDACL,
ACL_REVISION,
KEY_ALL_ACCESS,
psidAdministrators)) return FALSE;
if (!AddAccessAllowedAce(pNewDACL,
ACL_REVISION,
KEY_ALL_ACCESS,
psidSystem)) return FALSE;
if (!InitializeSecurityDescriptor(psdAbsoluteSD,
SECURITY_DESCRIPTOR_REVISION)) return FALSE;
if (!SetSecurityDescriptorDacl(psdAbsoluteSD,
TRUE, // fDaclPresent flag
pNewDACL,
FALSE)) // not a default DACL
return FALSE;
if (!IsValidSecurityDescriptor(psdAbsoluteSD)) return FALSE;
lRv=RegSetKeySecurity(hKey,
(SECURITY_INFORMATION)(DACL_SECURITY_INFORMATION),
psdAbsoluteSD);
if (lRv!=ERROR_SUCCESS) return FALSE;
return TRUE;
}
*)
function do_SetRegACL: boolean;
var
sia: TSIDIdentifierAuthority;
pInteractiveSid, pAdministratorsSid: PSID;
sd: Windows.TSecurityDescriptor;
pDacl: PACL;
dwAclSize: DWORD;
aHKey: HKEY;
lRetCode: longint;
bSuccess: boolean;
begin
sia.Value[0] := 0;
sia.Value[1] := 0;
sia.Value[2] := 0;
sia.Value[3] := 0;
sia.Value[4] := 0;
sia.Value[5] := BSECURITY_NT_AUTHORITY;
pInteractiveSid := nil;
pAdministratorsSid := nil;
pDacl := nil;
bSuccess := false; // assume this function fails
//
// open the key for WRITE_DAC access
//
lRetCode := RegOpenKeyEx(
HKEY_CURRENT_USER,
'SOFTWARE\Test',
0,
WRITE_DAC,
aHKey
);
if (lRetCode <> ERROR_SUCCESS) then
begin
ShowMessage('Error in RegOpenKeyEx');
result := false;
end;
//
// prepare a Sid representing any Interactively logged-on user
//
if (not AllocateAndInitializeSid(
sia,
1,
SECURITY_INTERACTIVE_RID,
0, 0, 0, 0, 0, 0, 0,
pInteractiveSid
)) then
begin
ShowMessage('Error in: AllocateAndInitializeSid');
//goto cleanup;
end;
//
// prepare a Sid representing the well-known admin group
//
if (not AllocateAndInitializeSid(
sia,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
pAdministratorsSid
)) then
begin
ShowMessage('Error in: AllocateAndInitializeSid');
// goto cleanup;
end;
//
// compute size of new acl
//
dwAclSize := sizeof(TACL) +
2 * (sizeof(TAccess_Allowed_ACE) - sizeof(DWORD)) +
GetLengthSid(pInteractiveSid) +
GetLengthSid(pAdministratorsSid);
//
// allocate storage for Acl
//
pDacl := PACL(HeapAlloc(GetProcessHeap(), 0, dwAclSize));
//if(pDacl == nil) goto cleanup;
if (not InitializeAcl(pDacl^, dwAclSize, ACL_REVISION)) then
begin
ShowMessage('Error in: InitializeAcl');
//goto cleanup;
end;
//
// grant the Interactive Sid KEY_READ access to the perf key
//
if (not AddAccessAllowedAce(
pDacl^,
ACL_REVISION,
KEY_READ,
pInteractiveSid
)) then
begin
ShowMessage('Error in: AddAccessAllowedAce');
//goto cleanup;
end;
//
// grant the Administrators Sid KEY_ALL_ACCESS access to the perf key
//
if (not AddAccessAllowedAce(
pDacl^,
ACL_REVISION,
KEY_ALL_ACCESS,
pAdministratorsSid
)) then
begin
ShowMessage('Error in: AddAccessAllowedAce');
//goto cleanup;
end;
if (not InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION)) then
begin
ShowMessage('Error in: InitializeSecurityDescriptor');
//goto cleanup;
end;
if (not SetSecurityDescriptorDacl(@sd, TRUE, pDacl, FALSE)) then
begin
ShowMessage('Error in: SetSecurityDescriptorDacl');
//goto cleanup;
end;
//
// apply the security descriptor to the registry key
//
lRetCode := RegSetKeySecurity(
aHKey,
SECURITY_INFORMATION(DACL_SECURITY_INFORMATION),
@sd
);
if (lRetCode <> ERROR_SUCCESS) then
begin
ShowMessage('Error in: RegSetKeySecurity');
//goto cleanup;
end;
bSuccess := TRUE; // indicate success
end;
end.
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése