Re: User access rights within process on Vista



If you try to open it and it fails with ERROR_ACCESS_DENIED, you do not have
access and you can go ahead and disable stuff.

Paul

"Milan Tomes" <MilanTomes@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:61DD7D81-C9F9-49CE-9C56-93D65CDF136B@xxxxxxxxxxxxxxxx
Paul,

I really need to know if my application have rights for creating specific
key in the registry (eg. HKU\.DEFAULT\Software) because if not I'll
disable
some functions in my application. Is a bit more complex problem, but I
still
need to know if I have that rights.

"Paul Baker [MVP, Windows - SDK]" wrote:

Milan,

I haven't used AccessCheck myself in a long time. I am still not
understanding why you don't call RegOpenKey. If it returns True, the
access
you requested was granted and it opened the key. If it returns False, it
did
not open the key. If GetLastError returns ERROR_ACCESS_DENIED, the reason
it
did not open the key was that that the access you requested was not
granted.
Is that different from what you need to know?

Or, do you simply want to know if the process is running elevated? I
think
you can call GetTokenInformation with TokenElevation for that. The MSDN
documentation say it requires Windows Server 2008 but I would be suprised
if
that's true.

Paul

"Milan Tomes" <MilanTomes@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:9153C533-3227-4305-9FAB-BED6F7A3761A@xxxxxxxxxxxxxxxx
For now I've solved my problem with following function. That only
problem
was
in a processing group SIDs where I've not tested
SE_GROUP_USE_FOR_DENY_ONLY
attribute. If you still have any opinion / advice how to use
AccessCheck
I'll
appreciate it.

function GetNTAccessRights(AObject: PChar; AObjectType:
SE_OBJECT_TYPE):
ACCESS_MASK;

procedure ApplyAllowMask(Mask: ACCESS_MASK; var Result: ACCESS_MASK);
begin
Result := Result or Mask;
end;

procedure ApplyDenyMask(Ace: TAce; var Result: ACCESS_MASK);
var
Mask: ACCESS_MASK;
i: byte;
BoolArray: TBooleanArray;
begin
case Ace.AceType of
ACCESS_ALLOWED_ACE_TYPE: Mask := Ace.AccessAllowedAce.Mask;
ACCESS_DENIED_ACE_TYPE: Mask := Ace.AccessDeniedAce.Mask;
else
exit;
end;
BitsToBooleans(Mask, BoolArray, true);
for i := 0 to 31 do
if BoolArray[i] then
ClearBit(Integer(Result), i);
end;

procedure ProcessAce(Ace: TAce; var Result: ACCESS_MASK);
begin
case Ace.AceType of
ACCESS_ALLOWED_ACE_TYPE: ApplyAllowMask(Ace.AccessAllowedAce.Mask,
Result);
ACCESS_DENIED_ACE_TYPE: ApplyDenyMask(Ace, Result);
end;
end;

var
SD: Pointer;
DACL: PACL;
Err: Cardinal;
GetNamedSecurityInfo: TGetNamedSecurityInfoProc;
DllHnd: HModule;

Token: THandle;
BufferLength: DWORD;
GroupsTokenInfo: PTokenGroups;
UserTokenInfo: PTokenUser;
Ace: PAce;
AceIndex: word;
AceSid: PSid;
i: cardinal;
begin
Result := $FFFFFFFF;
if not isWinNT then
exit;
DllHnd := 0;
Token := INVALID_HANDLE_VALUE;
UserTokenInfo := nil;
GroupsTokenInfo := nil;
try
Result := 0;
//Dynamicky nalinkuj potrebne funkce
DllHnd := LoadLibrary('ADVAPI32.DLL');
if DllHnd = 0 then
raise EG3OSError.Create('Nelze naèíst knihovnu AdvApi32.dll !!!');
@GetNamedSecurityInfo := GetProcAddress(DllHnd,
'GetNamedSecurityInfoA');
//Zjisti token
if not OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token) then
raise EG3OSError.Create('Nastala chyba pøi zjis?ování pøístupových
práv k objektu ' + AObject + ' (OpenProcessToken) !!!');
//Zjisti SID vlastnika procesu
if not GetTokenInformation(Token, TokenUser, nil, 0, BufferLength)
then
begin
Err := GetLastError;
if Err <> ERROR_INSUFFICIENT_BUFFER then
raise EG3OSError.CreateCode('Nastala chyba pøi zjis?ování
pøístupových práv k objektu ' + AObject + ' (GetTokenInformation - user
SID
buffer length) !!!', Err);
end;
UserTokenInfo := PTokenUser(AllocMem(BufferLength));
if not GetTokenInformation(Token, TokenUser, UserTokenInfo,
BufferLength, BufferLength) then
raise EG3OSError.Create('Nastala chyba pøi zjis?ování pøístupových
práv k objektu ' + AObject + ' (GetTokenInformation - user SID) !!!');
//Zjisti SIDy skupin, do kterych vlastnik procesu patri
if not GetTokenInformation(Token, TokenGroups, nil, 0, BufferLength)
then
begin
Err := GetLastError;
if Err <> ERROR_INSUFFICIENT_BUFFER then
raise EG3OSError.CreateCode('Nastala chyba pøi zjis?ování
pøístupových práv k objektu ' + AObject + ' (GetTokenInformation -
groups
buffer length) !!!', Err);
end;
GroupsTokenInfo := PTokenGroups(AllocMem(BufferLength));
if not GetTokenInformation(Token, TokenGroups, GroupsTokenInfo,
BufferLength, BufferLength) then
raise EG3OSError.Create('Nastala chyba pøi zjis?ování pøístupových
práv k objektu ' + AObject + ' (GetTokenInformation - groups) !!!');
//Zjisti DACL pro pozadovany prostredek
Err := GetNamedSecurityInfo(AObject, AObjectType,
DACL_SECURITY_INFORMATION, nil, nil, @DACL, nil, SD);
if Err <> ERROR_SUCCESS then
raise EG3OSError.CreateCode('Nastala chyba pøi zjis?ování
pøístupových
práv k objektu ' + AObject + ' (GetNamedSecurityInfo) !!!', Err)
else
begin
if DACL = nil then //Null DACL - nesmi byt
if AObjectType = SE_FILE_OBJECT then //Pokud se pozaduje DACL
souboru - na souborovem systemu FAT se ACL nevraci
begin
Result := $FFFFFFFF;
exit;
end
else
raise EG3OSError.CreateCode('Nastala chyba pøi zjis?ování
pøístupových práv k objektu ' + AObject + ' (GetNamedSecurityInfo -
Dacl =
nil) !!!', Err);
if not IsValidAcl(DACL^) then
raise EG3OSError.Create('Nastala chyba pøi zjis?ování
pøístupových
práv k objektu ' + AObject + ' (IsValidAcl) !!!');
for AceIndex := 0 to Pred(DACL^.AceCount) do
begin
GetAce(DACL^, AceIndex, Pointer(Ace));
AceSid := PSid(@Ace.AccessAllowedAce.SidStart);
if EqualSid(AceSid, UserTokenInfo^.User.Sid) then
ProcessAce(Ace^, Result)
else
begin
for i := 0 to Pred(GroupsTokenInfo^.GroupCount) do
begin
{$IFOPT R+}
{$DEFINE RANGECHECKS_ON}
{$ENDIF}
{$RANGECHECKS OFF} // Groups is an array [0..0] of TSIDAndAttributes,
ignore
ERangeError
if EqualSid(AceSid, GroupsTokenInfo^.Groups[i].Sid) then
if (GroupsTokenInfo^.Groups[i].Attributes and
SE_GROUP_USE_FOR_DENY_ONLY) = SE_GROUP_USE_FOR_DENY_ONLY then
ApplyDenyMask(Ace^, Result)
else
ProcessAce(Ace^, Result);
{$IFDEF RANGECHECKS_ON}
{$RANGECHECKS ON}
{$UNDEF RANGECHECKS_ON}
{$ENDIF}

end;
end;
end;
end;
finally
if Token <> INVALID_HANDLE_VALUE then
CloseHandle(Token);
if SD <> nil then
LocalFree(Cardinal(SD));
if DllHnd <> 0 then
FreeLibrary(DllHnd);
if UserTokenInfo <> nil then
FreeMem(UserTokenInfo);
if GroupsTokenInfo <> nil then
FreeMem(GroupsTokenInfo);
end;
end;

Milan Tomes

"Milan Tomes" wrote:

Hi Paul,

I need to know access rights not simply access denial. My application
will
disable some functions in non-elevated rights and enable them if there
are
elevated rights.
I've also tried AccessCheck, but I failed because I don't know much
about
impersonation etc. My testing code looks like:

Token := INVALID_HANDLE_VALUE;
DllHnd := 0;
if isWinNT then
begin
try
DllHnd := LoadLibrary('ADVAPI32.DLL');
if DllHnd = 0 then
raise EG3OSError.Create('Nelze naèíst knihovnu AdvApi32.dll
!!!');
@GetNamedSecurityInfo := GetProcAddress(DllHnd,
'GetNamedSecurityInfoA');
if not OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS,
Token)
then
raise EG3OSError.Create('OpenProcessToken failed !!!');
Err := GetNamedSecurityInfo('USERS\.DEFAULT\Software',
SE_REGISTRY_KEY, 0, nil, nil, nil, nil, SD);
if Err <> ERROR_SUCCESS then
raise EG3OSError.CreateCode('Nastala chyba pøi zjis?ování
pøístupových práv k objektu USERS\.DEFAULT\Software
(GetNamedSecurityInfo)
!!!', Err)
else
begin
GM.GenericRead := KEY_READ;
GM.GenericWrite := KEY_WRITE;
GM.GenericExecute := KEY_EXECUTE;
GM.GenericAll := KEY_ALL_ACCESS;
PSSize := SizeOf(_PRIVILEGE_SET);
if not AccessCheck(PSecurityDescriptor(SD), Token,
MAXIMUM_ALLOWED,
GM, PS, PSSize, Mask, AccessStatus) then
raise EG3OSError.Create('Chyba AccessCheck !!!');
if not AccessStatus then
raise EG3OSError.Create('Access denied !!!');
end;
finally
if Token <> INVALID_HANDLE_VALUE then
CloseHandle(Token);
if SD <> nil then
LocalFree(Cardinal(SD));
if DllHnd <> 0 then
FreeLibrary(DllHnd);
end;
end;

but calling AccessCheck failed with code 1309. Any help will be
appreciated.

Thanks

Milan Tomes


"Paul Baker [MVP, Windows - SDK]" wrote:

Are you asking simply because your application needs to be able to
handle
access denial? If so, the best practice would be to go ahead and try
to
open
the key (RegOpenKey) and see if you get ERROR_ACCESS_DENIED.

If you literally mean you need to know what access will be granted,
you
should use AccessCheck or one of the related APIs (the parameters
are a
quite complicated). You should not attempt to implement all the
rules
yourself, as you are quite likely to get it wrong and, even if you
don't,
fail to take into account new features in future versions of
Windows.

What do you mean it is not working in a non-elevated environment?
Are
you
aware of how that will affect your token and the access it gives
you?

Paul

"Milan Tomes" <Milan Tomes@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in
message
news:85DF5562-D0D9-4834-84AA-66BD0DB4E65D@xxxxxxxxxxxxxxxx
Hi,

how to determine user access rights for securable objects on Vista
?
I've
tried GetTokenInformation to get user & user groups SIDs and
GetNamedSecurityInfo to get ACL. Then I go through the ACL and
determine
access right. Unfortunately this is not working in non-elevated
environment.
So how to determine if my process have rights for e.g.
HKEY_USERS\.DEFAULT\Software registry key ???

Pls help me cause I'm already going crazy.

Thanks



.



Relevant Pages

  • Re: User access rights within process on Vista
    ... My code is accepting user rights modification, ... GroupsTokenInfo:= nil; ... raise EG3OSError.Create('Nelze naèíst knihovnu AdvApi32.dll ... BufferLength, BufferLength) then ...
    (microsoft.public.platformsdk.security)
  • Re: User access rights within process on Vista
    ... Testing abstract access rights doesnt really help you as it is ... GroupsTokenInfo:= nil; ... raise EG3OSError.Create('Nelze naèíst knihovnu AdvApi32.dll ... Err:= GetLastError; ...
    (microsoft.public.platformsdk.security)
  • Re: User access rights within process on Vista
    ... GroupsTokenInfo:= nil; ... if not GetTokenInformation(Token, TokenUser, nil, 0, BufferLength) ... Err:= GetLastError; ...
    (microsoft.public.platformsdk.security)
  • Re: User access rights within process on Vista
    ... If you still have any opinion / advice how to use AccessCheck ... GroupsTokenInfo:= nil; ... if not GetTokenInformation(Token, TokenUser, nil, 0, BufferLength) then ... Err:= GetLastError; ...
    (microsoft.public.platformsdk.security)
  • Re: User access rights within process on Vista
    ... I really need to know if my application have rights for creating specific ... GroupsTokenInfo:= nil; ... if not GetTokenInformation(Token, TokenUser, nil, 0, BufferLength) then ... Err:= GetLastError; ...
    (microsoft.public.platformsdk.security)