Re: User access rights within process on Vista
- From: "Paul Baker [MVP, Windows - SDK]" <paulrichardbaker@xxxxxxxxxxxxxxxx>
- Date: Thu, 28 Feb 2008 09:23:00 -0500
One of us is certainly not understanding the other.
It seems to me that using RegOpenKeyEx on the parent key with
KEY_CREATE_SUB_KEY will tell you if you have access to create a subkey
without creating anything and with far less complexity. You can do this
during startup. Of course, there is always a chance that something will have
changed by the time you actually want to create the subkey, but that's fine
and that's what you want.
I do agree that *creating* a key, file, directory, etc. simply to check
access is poor programming style.
Paul
"Milan Tomes" <MilanTomes@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:E29F9B3F-36A5-47E1-8497-A414B705CD2F@xxxxxxxxxxxxxxxx
I've already solved it using some other API functions (not AccessCheck)
and I
want to use this function. My code is accepting user rights modification,
but
I guess AccessCheck function will provide up-to-date functionality so I
really want to use this function.
And in response to your question "Why not" I'll tell - I already told
enough
informations why I don't want use this style of programming. I need to
check
access rights to registry (file, dir etc.) without trying to write some
value
& test result. I want to read access rights and enable/disable some
functions
in my program. Thats it. Can/want you still help me ?
But I guess you didn't understand me - my program will not let user do
something and then get him a message like "You haven't enough access
rightsto
do this", but I want to check access rights in startup phase of my
application & disable functions that user can't do.
Milan Tomes
"Chris Becke" wrote:
Why not? Testing abstract access rights doesnt really help you as it is
technically possible for the permissions on each of those entities to be
individually modified.
A simple single test will merely provide a hint that the operation you
want
to do later, may or may not fail.
Now, waiting for the user to try and do an operation before you tell them
that the operation can't be done is - in some books - bad UI design.
So the option is to - up front - open the various parent resources that
you
may wish to create sub resources within - specifying the access flags
requesting child creation rights. If those fail - any one of them -
disable
the admin ui and run in viewer mode.
Chris.
"Milan Tomes" <MilanTomes@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:FB8EE439-08F6-41EC-A70A-2596F522AA72@xxxxxxxxxxxxxxxx
Hi Paul,
it's not only about registry. I need to know access rights to registry,
files, directories etc...
Trying to make that action & test result for something like
ERROR_ACCESS_DENIED isn't acceptable for me.
"Paul Baker [MVP, Windows - SDK]" wrote:
Oh, you want to know if you can create a key.
In that case, you use RegOpenKeyEx to try to open the parent key with
KEY_CREATE_SUB_KEY access.
Paul
"Paul Baker [MVP, Windows - SDK]" <paulrichardbaker@xxxxxxxxxxxxxxxx>
wrote
in message news:OIEzKQKeIHA.1204@xxxxxxxxxxxxxxxxxxxxxxx
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:
.
- Follow-Ups:
- Re: User access rights within process on Vista
- From: Milan Tomes
- Re: User access rights within process on Vista
- References:
- Re: User access rights within process on Vista
- From: Paul Baker [MVP, Windows - SDK]
- Re: User access rights within process on Vista
- From: Milan Tomes
- Re: User access rights within process on Vista
- From: Milan Tomes
- Re: User access rights within process on Vista
- From: Paul Baker [MVP, Windows - SDK]
- Re: User access rights within process on Vista
- From: Milan Tomes
- Re: User access rights within process on Vista
- From: Paul Baker [MVP, Windows - SDK]
- Re: User access rights within process on Vista
- From: Paul Baker [MVP, Windows - SDK]
- Re: User access rights within process on Vista
- From: Milan Tomes
- Re: User access rights within process on Vista
- From: Chris Becke
- Re: User access rights within process on Vista
- From: Milan Tomes
- Re: User access rights within process on Vista
- Prev by Date: Re: User access rights within process on Vista
- Next by Date: Re: User access rights within process on Vista
- Previous by thread: Re: User access rights within process on Vista
- Next by thread: Re: User access rights within process on Vista
- Index(es):
Relevant Pages
|
Loading