ZeBriD
asked on
Delphi7 SetEntriesInAcl Error 87
Hi all.
For several day I try to set new permissions to file in Windows 7 / XP. (Allow All to Everyone)
I do it in Delphi 7.
In theory - everything is not so difficult:
But, function SetEntriesInAcl always return 87 error (ERROR_INVALID_PARAMETER).
Can anybody say to me what am i doing wrong?
P.S. This code perfectly works on Delphi 2010 without any errors. But I need to make it work in Delphi 7
For several day I try to set new permissions to file in Windows 7 / XP. (Allow All to Everyone)
I do it in Delphi 7.
In theory - everything is not so difficult:
const
SECURITY_WORLD_SID_AUTHORITY: SID_IDENTIFIER_AUTHORITY = (Value: (0, 0, 0, 0, 0, 1));
SECURITY_WORLD_RID = $0;
var
ExplicitAccess: EXPLICIT_ACCESS_A;
psidEveryOne: PSID;
pSD: PSECURITY_DESCRIPTOR;
ptACL: PACL;
ErrNo: Cardinal;
begin
psidEveryOne := nil;
pSD := nil;
ptACL := nil;
try
win32check(AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY,
1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, psidEveryone));
try
ZeroMemory(@ExplicitAccess, SizeOf(ExplicitAccess));
with ExplicitAccess do
begin
grfAccessPermissions:= GENERIC_ALL;
grfAccessMode:= GRANT_ACCESS;
grfInheritance:= NO_INHERITANCE;
Trustee.TrusteeForm:= TRUSTEE_IS_SID;
Trustee.TrusteeType:= TRUSTEE_IS_WELL_KNOWN_GROUP;
Trustee.ptstrName:= psidEveryone;
end;
ErrNo := SetEntriesInAcl(1, @ExplicitAccess, nil, ptACL);
if ErrNo <> ERROR_SUCCESS then
raise Exception.Create(Format('Error ¿ %u', [ErrNo]))
// And so on....
But, function SetEntriesInAcl always return 87 error (ERROR_INVALID_PARAMETER).
Can anybody say to me what am i doing wrong?
P.S. This code perfectly works on Delphi 2010 without any errors. But I need to make it work in Delphi 7
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
>{$MINENUMSIZE 4} <------------------------- --------- this line
Already tried. Still not working.
Already tried. Still not working.
>> Already tried. Still not working.
I've checked it under D7. It works.
Make sure that SizeOf(ExplicitAccess) is 32.
I've checked it under D7. It works.
Make sure that SizeOf(ExplicitAccess) is 32.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>> modules AccAPI.pas & AccCtrl.pas attached.
sas31, there is no sense to add {$MINENUMSIZE 4} to AccAPI, because there is not any enumeration type there.
sas31, there is no sense to add {$MINENUMSIZE 4} to AccAPI, because there is not any enumeration type there.
ASKER
>Make sure that SizeOf(ExplicitAccess) is 32.
Checked. It is 32.
>modules AccAPI.pas & AccCtrl.pas attached
I've tried use your units. Now there is no error.
BUT now there is no access rights (look at image bellow. it is in russian, but I hope you will understand the error)
dLjX2Maj31.png
Checked. It is 32.
>modules AccAPI.pas & AccCtrl.pas attached
I've tried use your units. Now there is no error.
BUT now there is no access rights (look at image bellow. it is in russian, but I hope you will understand the error)
dLjX2Maj31.png
where is function "SetNamedSecurityInfo" which set security object ptACL after call "SetEntriesInAcl"?
see may example above (function "TakeOwnership").
see may example above (function "TakeOwnership").
ASKER
Well... I set permissions to crypto container.
Full current code in attach.
Full current code in attach.
const
SECURITY_WORLD_SID_AUTHORITY: SID_IDENTIFIER_AUTHORITY = (Value: (0, 0, 0, 0, 0, 1));
SECURITY_WORLD_RID = $0;
var
ExplicitAccess: EXPLICIT_ACCESS;
psidEveryOne: PSID;
pSD: PSECURITY_DESCRIPTOR;
ptACL: PACL;
ErrFunc: String;
ErrNo: Cardinal;
lpName,lpDomain : PAnsiChar;
cbName,cbDomain : Cardinal;
peUse : Cardinal;
begin
psidEveryOne := nil;
pSD := nil;
ptACL := nil;
try
win32check(AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY,
1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, psidEveryone));
cbName:=64;
cbDomain:=64;
GetMem(lpName,cbName*SizeOf(WideChar));
GetMem(lpDomain,cbDomain*SizeOf(WideChar));
if not LookupAccountSid(nil, psidEveryOne, lpName, cbName, lpDomain, cbDomain, peUse)
and (GetLastError=122) then
begin
ReAllocMem(lpName,cbName*SizeOf(WideChar));
ReAllocMem(lpDomain,cbDomain*SizeOf(WideChar));
if not LookupAccountSid(nil, psidEveryOne, lpName, cbName, lpDomain, cbDomain, peUse) then
raise Exception.Create(SysErrorMessage(GetLastError));
end;
ZeroMemory(@ExplicitAccess, SizeOf(ExplicitAccess));
//BuildExplicitAccessWithNameW(@ExplicitAccess, PAnsiChar(WideCharToString(lpName)), GENERIC_ALL, SET_ACCESS, NO_INHERITANCE);
BuildExplicitAccessWithName(@ExplicitAccess, lpName, GENERIC_ALL, SET_ACCESS, NO_INHERITANCE);
try
ErrNo := SetEntriesInAcl(1, @ExplicitAccess, nil, ptACL);
if ErrNo <> ERROR_SUCCESS then
raise Exception.Create(Format('SetEntriesInAcl error: %s', [SysErrorMessage(ErrNo)]));
try
pSD:= Pointer(LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH));
try
win32check(InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION));
win32check(SetSecurityDescriptorDacl(pSD, false, ptACL, false));
win32check(CryptSetProvParam(AhProv, PP_KEYSET_SEC_DESCR, pSD, DACL_SECURITY_INFORMATION));
finally
LocalFree(Cardinal(pSD));
end;
finally
LocalFree(Cardinal(ptACL));
end;
finally
FreeSid(psidEveryOne);
end;
ASKER
I've tryed to create ExplicitAccess by two ways:
BuildExplicitAccessWithNam e(@Explici tAccess, lpName, GENERIC_ALL, SET_ACCESS, NO_INHERITANCE);
and
with ExplicitAccess do
begin
grfAccessPermissions := GENERIC_ALL;
grfAccessMode := SET_ACCESS;
grfInheritance := NO_INHERITANCE;
Trustee.TrusteeForm := TRUSTEE_IS_SID;
Trustee.TrusteeType := TRUSTEE_IS_GROUP;
Trustee.ptstrName := psidEveryone;
end;
BuildExplicitAccessWithNam
and
with ExplicitAccess do
begin
grfAccessPermissions := GENERIC_ALL;
grfAccessMode := SET_ACCESS;
grfInheritance := NO_INHERITANCE;
Trustee.TrusteeForm := TRUSTEE_IS_SID;
Trustee.TrusteeType := TRUSTEE_IS_GROUP;
Trustee.ptstrName := psidEveryone;
end;
sorry, i didnt work with crypto containers.
i can expect what problem might be in "CryptSetProvParam" function, may be some parameter is invalid or something else.
try to change some parameters...
may be AhProv opened with restrictions to change security...
i can expect what problem might be in "CryptSetProvParam" function, may be some parameter is invalid or something else.
try to change some parameters...
may be AhProv opened with restrictions to change security...
>>modules AccAPI.pas & AccCtrl.pas attached
>I've tried use your units. Now there is no error.
It's interesting. Those are the Delphi's unit with {$MINENUMSIZE 4} added. But as I said before there is no sense to add {$MINENUMSIZE 4} to AccAPI.
>I've tried use your units. Now there is no error.
It's interesting. Those are the Delphi's unit with {$MINENUMSIZE 4} added. But as I said before there is no sense to add {$MINENUMSIZE 4} to AccAPI.
btw, It would be better to ask one question per thread
https://www.experts-exchange.com/help.jsp#hs=23&hi=23
https://www.experts-exchange.com/help.jsp#hs=23&hi=23
ASKER
yippee
It's work. Error was in func SetSecurityDescriptorDacl( pSD, false, ptACL, false).
Second parametr needs to be 'true'.
So, what was done.
Since the user can use not only in eng windows version, user group named 'Everyone' may be called differently, such as '¿¿¿' for russian version. But the SID of the group is always the same. Thats why I get SID at first. Then, using the function LookupAccountSid I get the name of this group. And only then, with the name of group 'Everyone', I create object ExplicitAccess and set these new rights to crypto-container.
I attached the working code below.
Thanks everyone.
It's work. Error was in func SetSecurityDescriptorDacl(
Second parametr needs to be 'true'.
So, what was done.
Since the user can use not only in eng windows version, user group named 'Everyone' may be called differently, such as '¿¿¿' for russian version. But the SID of the group is always the same. Thats why I get SID at first. Then, using the function LookupAccountSid I get the name of this group. And only then, with the name of group 'Everyone', I create object ExplicitAccess and set these new rights to crypto-container.
I attached the working code below.
Thanks everyone.
procedure TInetSession.SetProvPermiss(AhProv: HCRYPTPROV);
const
SECURITY_WORLD_SID_AUTHORITY: SID_IDENTIFIER_AUTHORITY = (Value: (0, 0, 0, 0, 0, 1));
SECURITY_WORLD_RID = $0;
var
ExplicitAccess: EXPLICIT_ACCESS;
psidEveryOne: PSID;
pSD: PSECURITY_DESCRIPTOR;
ptACL: PACL;
ErrNo: Cardinal;
lpName,lpDomain : PAnsiChar;
cbName,cbDomain : Cardinal;
peUse : Cardinal;
begin
psidEveryOne := nil;
pSD := nil;
ptACL := nil;
cbName := 0;
cbDomain := 0;
try
win32check(AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY,
1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, psidEveryone));
LookupAccountSid(nil, psidEveryOne, nil, cbName, nil, cbDomain, peUse);
GetMem(lpName,cbName*SizeOf(WideChar));
GetMem(lpDomain,cbDomain*SizeOf(WideChar));
try
win32check(LookupAccountSid(nil, psidEveryOne, lpName, cbName, lpDomain, cbDomain, peUse));
finally
FreeMem(lpName);
FreeMem(lpDomain);
end;
ZeroMemory(@ExplicitAccess, SizeOf(ExplicitAccess));
BuildExplicitAccessWithName(@ExplicitAccess, lpName, GENERIC_ALL, SET_ACCESS, NO_INHERITANCE);
try
ErrFunc := 'SetEntriesInAcl';
ErrNo := SetEntriesInAcl(1, @ExplicitAccess, nil, ptACL);
if ErrNo <> ERROR_SUCCESS then
raise Exception.Create(Format('System Error. Code: %u'#13#10'%s', [ErrNo, SysErrorMessage(ErrNo)]));
try
pSD:= Pointer(LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH));
try
win32check(InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION));
win32check(SetSecurityDescriptorDacl(pSD, true, ptACL, false));
win32check(CryptSetProvParam(AhProv, PP_KEYSET_SEC_DESCR, pSD, DACL_SECURITY_INFORMATION));
finally
LocalFree(Cardinal(pSD));
end;
finally
LocalFree(Cardinal(ptACL));
end;
finally
FreeSid(psidEveryOne);
end;
except
on E: Exception do
begin
do something...
Exit;
end;
end;
end;
ASKER
Only one problem was solved by experts.
Second I solved by my self.
Second I solved by my self.
Open in new window