MiTec/Common/MiTeC_AclApi.pas
2024-07-06 22:30:25 +02:00

373 lines
14 KiB
ObjectPascal

{*******************************************************}
{ MiTeC Common Routines }
{ Access Control API }
{ }
{ Copyright (c) 2009-2013 Michal Mutl }
{ }
{*******************************************************}
{$INCLUDE Compilers.inc}
unit MiTeC_AclApi;
interface
uses{$IFDEF RAD9PLUS}
WinAPI.Windows, System.SysUtils;
{$ELSE}
Windows, SysUtils;
{$ENDIF}
type
_SE_OBJECT_TYPE = (
SE_UNKNOWN_OBJECT_TYPE,
SE_FILE_OBJECT,
SE_SERVICE,
SE_PRINTER,
SE_REGISTRY_KEY,
SE_LMSHARE,
SE_KERNEL_OBJECT,
SE_WINDOW_OBJECT,
SE_DS_OBJECT,
SE_DS_OBJECT_ALL,
SE_PROVIDER_DEFINED_OBJECT,
SE_WMIGUID_OBJECT,
SE_REGISTRY_WOW64_32KEY);
SE_OBJECT_TYPE = _SE_OBJECT_TYPE;
TSeObjectType = SE_OBJECT_TYPE;
PPSID = ^PSID;
{PACL = ^ACL;
_ACL = record
AclRevision: Byte;
Sbz1: Byte;
AclSize: Word;
AceCount: Word;
Sbz2: Word;
end;
ACL = _ACL;
TAcl = ACL;}
PPACL = ^PAcl;
//
// Definition: TRUSTEE_TYPE
// This enumerated type specifies the type of trustee account for the trustee
// returned by the API described in this document.
// TRUSTEE_IS_UNKNOWN - The trustee is an unknown, but not necessarily invalid
// type. This field is not validated on input to the APIs
// that take Trustees.
// TRUSTEE_IS_USER The trustee account is a user account.
// TRUSTEE_IS_GROUP The trustee account is a group account.
//
_TRUSTEE_TYPE = (
TRUSTEE_IS_UNKNOWN,
TRUSTEE_IS_USER,
TRUSTEE_IS_GROUP,
TRUSTEE_IS_DOMAIN,
TRUSTEE_IS_ALIAS,
TRUSTEE_IS_WELL_KNOWN_GROUP,
TRUSTEE_IS_DELETED,
TRUSTEE_IS_INVALID,
TRUSTEE_IS_COMPUTER);
TRUSTEE_TYPE = _TRUSTEE_TYPE;
TTrusteeType = TRUSTEE_TYPE;
//
// Definition: TRUSTEE_FORM
// This enumerated type specifies the form the trustee identifier is in for a
// particular trustee.
// TRUSTEE_IS_SID The trustee is identified with a SID rather than with a name.
// TRUSTEE_IS_NAME The trustee is identified with a name.
//
_TRUSTEE_FORM = (
TRUSTEE_IS_SID,
TRUSTEE_IS_NAME,
TRUSTEE_BAD_FORM,
TRUSTEE_IS_OBJECTS_AND_SID,
TRUSTEE_IS_OBJECTS_AND_NAME);
TRUSTEE_FORM = _TRUSTEE_FORM;
TTrusteeForm = TRUSTEE_FORM;
//
// Definition: MULTIPLE_TRUSTEE_OPERATION
// If the trustee is a multiple trustee, this enumerated type specifies the type.
// TRUSTEE_IS_IMPERSONATE The trustee is an impersonate trustee and the multiple
// trustee field in the trustee points to another trustee
// that is a trustee for the server that will be doing the
// impersonation.
//
_MULTIPLE_TRUSTEE_OPERATION = (NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_IMPERSONATE);
MULTIPLE_TRUSTEE_OPERATION = _MULTIPLE_TRUSTEE_OPERATION;
TMultipleTrusteeOperation = MULTIPLE_TRUSTEE_OPERATION;
PTRUSTEE_A = ^TRUSTEE_A;
_TRUSTEE_A = packed record
pMultipleTrustee: PTRUSTEE_A;
MultipleTrusteeOperation: MULTIPLE_TRUSTEE_OPERATION;
TrusteeForm: TRUSTEE_FORM;
TrusteeType: TRUSTEE_TYPE;
ptstrName: LPSTR;
end;
TRUSTEE_A = _TRUSTEE_A;
TRUSTEEA = TRUSTEE_A;
PPTRUSTEE_A = ^PTRUSTEE_A;
TTrusteeA = TRUSTEE_A;
PTrusteeA = PTRUSTEE_A;
PTRUSTEE_W = ^TRUSTEE_W;
_TRUSTEE_W = packed record
pMultipleTrustee: PTRUSTEE_W;
MultipleTrusteeOperation: MULTIPLE_TRUSTEE_OPERATION;
TrusteeForm: TRUSTEE_FORM;
TrusteeType: TRUSTEE_TYPE;
ptstrName: LPWSTR;
end;
TRUSTEE_W = _TRUSTEE_W;
TRUSTEEW = TRUSTEE_W;
PPTRUSTEE_W = ^PTRUSTEE_W;
TTrusteeW = TRUSTEE_W;
PTrusteeW = PTRUSTEE_W;
{$IFDEF UNICODE}
TRUSTEE_ = TRUSTEE_W;
PTRUSTEE_ = PTRUSTEE_W;
TRUSTEE = TRUSTEEW;
PPTRUSTEE = ^PPTRUSTEE_W;
TTrustee = TTrusteeW;
PTrustee = PTrusteeW;
{$ELSE}
TRUSTEE_ = TRUSTEE_A;
PTRUSTEE_ = PTRUSTEE_A;
TRUSTEE = TRUSTEEA;
PPTRUSTEE = ^PPTRUSTEE_A;
TTrustee = TTrusteeA;
PTrustee = PTrusteeA;
{$ENDIF}
//
// Definition: ACCESS_MODE
// This enumerated type specifies how permissions are (requested)/to be applied
// for the trustee by the access control entry. On input this field can by any
// of the values, although it is not meaningful to mix access control and audit
// control entries. On output this field will be either SET_ACCESS, DENY_ACCESS,
// SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE.
// The following descriptions define how this type effects an explicit access
// request to apply access permissions to an object.
// GRANT_ACCESS - The trustee will have at least the requested permissions upon
// successful completion of the command. (If the trustee has
// additional permissions they will not be removed).
// SET_ACCESS - The trustee will have exactly the requested permissions upon
// successful completion of the command.
// DENY_ACCESS - The trustee will be denied the specified permissions.
// REVOKE_ACCESS - Any explicit access rights the trustee has will be revoked.
// SET_AUDIT_SUCCESS - The trustee will be audited for successful opens of the
// object using the requested permissions.
// SET_AUDIT_FAILURE - The trustee will be audited for failed opens of the object
// using the requested permissions.
//
_ACCESS_MODE = (
NOT_USED_ACCESS,
GRANT_ACCESS,
SET_ACCESS,
DENY_ACCESS,
REVOKE_ACCESS,
SET_AUDIT_SUCCESS,
SET_AUDIT_FAILURE);
ACCESS_MODE = _ACCESS_MODE;
TAccessMode = _ACCESS_MODE;
//
// Definition: Inheritance flags
// These bit masks are provided to allow simple application of inheritance in
// explicit access requests on containers.
// NO_INHERITANCE The specific access permissions will only be applied to
// the container, and will not be inherited by objects created
// within the container.
// SUB_CONTAINERS_ONLY_INHERIT The specific access permissions will be inherited
// and applied to sub containers created within the
// container, and will be applied to the container
// itself.
// SUB_OBJECTS_ONLY_INHERIT The specific access permissions will only be inherited
// by objects created within the specific container.
// The access permissions will not be applied to the
// container itself.
// SUB_CONTAINERS_AND_OBJECTS_INHERIT The specific access permissions will be
// inherited by containers created within the
// specific container, will be applied to
// objects created within the container, but
// will not be applied to the container itself.
//
const
NO_INHERITANCE = $0;
SUB_OBJECTS_ONLY_INHERIT = $1;
SUB_CONTAINERS_ONLY_INHERIT = $2;
SUB_CONTAINERS_AND_OBJECTS_INHERIT = $3;
INHERIT_NO_PROPAGATE = $4;
INHERIT_ONLY = $8;
type
PEXPLICIT_ACCESS_A = ^EXPLICIT_ACCESS_A;
_EXPLICIT_ACCESS_A = packed record
grfAccessPermissions: DWORD;
grfAccessMode: ACCESS_MODE;
grfInheritance: DWORD;
Trustee: TRUSTEE_A;
end;
EXPLICIT_ACCESS_A = _EXPLICIT_ACCESS_A;
EXPLICIT_ACCESSA = EXPLICIT_ACCESS_A;
PEXPLICIT_ACCESSA = PEXPLICIT_ACCESS_A;
TExplicitAccessA = EXPLICIT_ACCESS_A;
PExplicitAccessA = PEXPLICIT_ACCESS_A;
PEXPLICIT_ACCESS_W = ^EXPLICIT_ACCESS_W;
_EXPLICIT_ACCESS_W = packed record
grfAccessPermissions: DWORD;
grfAccessMode: ACCESS_MODE;
grfInheritance: DWORD;
Trustee: TRUSTEE_W;
end;
EXPLICIT_ACCESS_W = _EXPLICIT_ACCESS_W;
EXPLICIT_ACCESSW = EXPLICIT_ACCESS_W;
PEXPLICIT_ACCESSW = PEXPLICIT_ACCESS_W;
TExplicitAccessW = EXPLICIT_ACCESS_W;
PExplicitAccessW = PEXPLICIT_ACCESS_W;
{$IFDEF UNICODE}
EXPLICIT_ACCESS_ = EXPLICIT_ACCESS_W;
PEXPLICIT_ACCESS_ = PEXPLICIT_ACCESS_W;
EXPLICIT_ACCESS = EXPLICIT_ACCESSW;
PEXPLICIT_ACCESS = PEXPLICIT_ACCESSW;
TExplicitAccess = TExplicitAccessW;
PExplicitAccess = PExplicitAccessW;
{$ELSE}
EXPLICIT_ACCESS_ = EXPLICIT_ACCESS_A;
PEXPLICIT_ACCESS_ = PEXPLICIT_ACCESS_A;
EXPLICIT_ACCESS = EXPLICIT_ACCESSA;
PEXPLICIT_ACCESS = PEXPLICIT_ACCESSA;
TExplicitAccess = TExplicitAccessA;
PExplicitAccess = PExplicitAccessA;
{$ENDIF}
TGetNamedSecurityInfoA = function (pObjectName: LPSTR; ObjectType: SE_OBJECT_TYPE;
SecurityInfo: SECURITY_INFORMATION; ppsidOwner, ppsidGroup: PPSID; ppDacl,
ppSacl: PPACL; var ppSecurityDescriptor: PSECURITY_DESCRIPTOR): DWORD; stdcall;
TGetNamedSecurityInfoW = function (pObjectName: LPWSTR; ObjectType: SE_OBJECT_TYPE;
SecurityInfo: SECURITY_INFORMATION; ppsidOwner, ppsidGroup: PPSID; ppDacl,
ppSacl: PPACL; var ppSecurityDescriptor: PSECURITY_DESCRIPTOR): DWORD; stdcall;
TGetNamedSecurityInfo = function (pObjectName: LPTSTR; ObjectType: SE_OBJECT_TYPE;
SecurityInfo: SECURITY_INFORMATION; ppsidOwner, ppsidGroup: PPSID; ppDacl,
ppSacl: PPACL; var ppSecurityDescriptor: PSECURITY_DESCRIPTOR): DWORD; stdcall;
TGetSecurityInfo = function(handle: THANDLE; ObjectType: SE_OBJECT_TYPE;
SecurityInfo: SECURITY_INFORMATION; ppsidOwner: PPSID; ppsidGroup: PPSID;
ppDacl, ppSacl: PPACL; var ppSecurityDescriptor: PSECURITY_DESCRIPTOR): DWORD; stdcall;
TBuildExplicitAccessWithNameA = procedure (pExplicitAccess: PEXPLICIT_ACCESS_A;
pTrusteeName: LPSTR; AccessPermissions: DWORD; AccessMode: ACCESS_MODE;
Inheritance: DWORD); stdcall;
TBuildExplicitAccessWithNameW = procedure (pExplicitAccess: PEXPLICIT_ACCESS_W;
pTrusteeName: LPWSTR; AccessPermissions: DWORD; AccessMode: ACCESS_MODE;
Inheritance: DWORD); stdcall;
TBuildExplicitAccessWithName = procedure (pExplicitAccess: PEXPLICIT_ACCESS;
pTrusteeName: LPTSTR; AccessPermissions: DWORD; AccessMode: ACCESS_MODE;
Inheritance: DWORD); stdcall;
TSetEntriesInAclA = function (cCountOfExplicitEntries: ULONG;
pListOfExplicitEntries: PEXPLICIT_ACCESS_A; OldAcl: PACL;
var NewAcl: PACL): DWORD; stdcall;
TSetEntriesInAclW = function (cCountOfExplicitEntries: ULONG;
pListOfExplicitEntries: PEXPLICIT_ACCESS_W; OldAcl: PACL;
var NewAcl: PACL): DWORD; stdcall;
TSetEntriesInAcl = function (cCountOfExplicitEntries: ULONG;
pListOfExplicitEntries: PEXPLICIT_ACCESS; OldAcl: PACL;
var NewAcl: PACL): DWORD; stdcall;
TSetNamedSecurityInfoA = function (pObjectName: LPSTR; ObjectType: SE_OBJECT_TYPE;
SecurityInfo: SECURITY_INFORMATION; psidOwner, psidGroup: PSID;
pDacl, pSacl: PACL): DWORD; stdcall;
TSetNamedSecurityInfoW = function (pObjectName: LPWSTR; ObjectType: SE_OBJECT_TYPE;
SecurityInfo: SECURITY_INFORMATION; psidOwner, psidGroup: PSID;
pDacl, pSacl: PACL): DWORD; stdcall;
TSetNamedSecurityInfo = function (pObjectName: LPTSTR; ObjectType: SE_OBJECT_TYPE;
SecurityInfo: SECURITY_INFORMATION; psidOwner, psidGroup: PSID;
pDacl, pSacl: PACL): DWORD; stdcall;
var
GetNamedSecurityInfoA: TGetNamedSecurityInfoA;
GetNamedSecurityInfoW: TGetNamedSecurityInfoW;
GetNamedSecurityInfo: TGetNamedSecurityInfo;
GetSecurityInfo: TGetSecurityInfo;
BuildExplicitAccessWithNameA: TBuildExplicitAccessWithNameA = nil;
BuildExplicitAccessWithNameW: TBuildExplicitAccessWithNameW = nil;
BuildExplicitAccessWithName: TBuildExplicitAccessWithName = nil;
SetEntriesInAclA: TSetEntriesInAclA = nil;
SetEntriesInAclW: TSetEntriesInAclW = nil;
SetEntriesInAcl: TSetEntriesInAcl = nil;
SetNamedSecurityInfoW: TSetNamedSecurityInfoW;
SetNamedSecurityInfoA: TSetNamedSecurityInfoA;
SetNamedSecurityInfo: TSetNamedSecurityInfo = nil;
implementation
const
AclAPI_DLL = 'advapi32.dll';
var
AclAPIHandle: THandle;
UnloadAclAPI: Boolean;
function InitAclAPI: Boolean;
begin
AclAPIHandle:=GetModuleHandle(AclAPI_DLL);
UnloadAclAPI:=AclAPIHandle=0;
if AclAPIHandle=0 then
AclAPIHandle:=loadlibrary(AclAPI_DLL);
if AclAPIHandle<>0 then begin
@GetNamedSecurityInfoA:=GetProcAddress(AclAPIHandle,PChar('GetNamedSecurityInfoA'));
@GetNamedSecurityInfoW:=GetProcAddress(AclAPIHandle,PChar('GetNamedSecurityInfoW'));
GetNamedSecurityInfo:={$IFDEF UNICODE}GetNamedSecurityInfoW{$ELSE}GetNamedSecurityInfoA{$ENDIF};
@GetSecurityInfo:=GetProcAddress(AclAPIHandle,PChar('GetSecurityInfo'));
@BuildExplicitAccessWithNameA:=GetProcAddress(AclAPIHandle,PChar('BuildExplicitAccessWithNameA'));
@BuildExplicitAccessWithNameW:=GetProcAddress(AclAPIHandle,PChar('BuildExplicitAccessWithNameW'));
BuildExplicitAccessWithName:={$IFDEF UNICODE}BuildExplicitAccessWithNameW{$ELSE}BuildExplicitAccessWithNameA{$ENDIF};
@SetEntriesInAclA:=GetProcAddress(AclAPIHandle,PChar('SetEntriesInAclA'));
@SetEntriesInAclW:=GetProcAddress(AclAPIHandle,PChar('SetEntriesInAclW'));
SetEntriesInAcl:={$IFDEF UNICODE}SetEntriesInAclW{$ELSE}SetEntriesInAclA{$ENDIF};
@SetNamedSecurityInfoA:=GetProcAddress(AclAPIHandle,PChar('SetNamedSecurityInfoA'));
@SetNamedSecurityInfoW:=GetProcAddress(AclAPIHandle,PChar('SetNamedSecurityInfoW'));
SetNamedSecurityInfo:={$IFDEF UNICODE}SetNamedSecurityInfoW{$ELSE}SetNamedSecurityInfoA{$ENDIF};
end;
result:=(AclAPIHandle<>0) and Assigned(GetNamedSecurityInfo);
end;
procedure FreeAclAPI;
begin
if (AclAPIHandle<>0) and UnloadAclAPI then begin
if not FreeLibrary(AclAPIHandle) then
raise Exception.Create(Format('Unload Error: %s - 0x%x',[AclAPI_DLL,GetModuleHandle(AclAPI_DLL)]))
else
AclAPIHandle:=0;
end;
end;
initialization
InitACLAPI;
end.