|
![]() |
|
Registriert seit: 9. Jun 2006 Ort: Magdeburg 29 Beiträge Delphi 7 Professional |
#1
Hallo,
ich hatte ein ähnliches Problem (alle Rechte eines Registry Schlüssels bzw. Datei wurden gelöscht, wie setze ich die Rechte) und dieser Thread hat mir sehr geholfen. Die Antwort von Dezipaitor sollte man sich zweimal durchlesen. Für alle die ein ähnliches Problem haben und auf diesen Thread stoßen, will ich hier meinen Source posten. Problem: Ich erhalte bei Registry oder Dateizugriff ERROR_ACCESS_DENIED obwohl ich Owner oder Admin bin (siehe auch ![]()
Delphi-Quellcode:
SetRegPermission setzt die Zugriffsrechte des aktuellen Benutzers (bzw. Account meines Delphiprogramms).
if RegOpenKeyEx(HKEY_LOCAL_MACHINE, '...', 0, KEY_READ, Key)=ERROR_ACCESS_DENIED then begin
SetRegPermission(HKEY_LOCAL_MACHINE,'...', OldResetAccess); RegOpenKeyExW(HKEY_LOCAL_MACHINE, '...', 0, KEY_READ, Key); end;
Delphi-Quellcode:
Für Dateirechte sieht es so aus (SetNamedSecurityInfo kann man auch für Registry nutzen)
function SetRegPermission(Key:HKey; SubKeyName:WideString; var ResetAccess:string):boolean;
const SDDL_REVISION_1 = 1; SECURITY_DESCRIPTOR_REVISION = 1; var dwSize,RegResult:DWORD; pNewSD,pSD:Windows.PSECURITY_DESCRIPTOR; pSdStr:PChar; SvcKey:HKey; dwLength: DWORD; Token:THandle; pTokenUser:PTOKEN_USER; sNewSD:string; begin result:=false; sErr:=''; //*** Start Set Owner **** (see [url]http://support.microsoft.com/kb/111546[/url]) SetPrivilege('SeTakeOwnershipPrivilege', True); // SE_TAKE_OWNERSHIP_NAME try RegResult:=RegOpenKeyExW(Key, PWideChar(SubKeyName), 0, WRITE_OWNER, SvcKey); //TODO reset Owner? if RegResult=ERROR_SUCCESS then begin dwLength:=0; pTokenUser := nil; OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token); if not GetTokenInformation(Token, TokenUser, pTokenUser, 0, dwLength) then begin if GetLastError=ERROR_INSUFFICIENT_BUFFER then begin pTokenUser:=HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength); if pTokenUser<>nil then begin if GetTokenInformation(Token, TokenUser, pTokenUser, dwLength, dwLength) then begin GetMem(pSD,SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(pSD, True, Nil, False); // No ACL - all access granted SetSecurityDescriptorOwner(pSD, pTokenUser^.User.Sid, FALSE); SysErrorMessage( RegSetKeySecurity(SvcKey,OWNER_SECURITY_INFORMATION, pSD) ); FreeMem(pSD); end; HeapFree(GetProcessHeap, 0, pTokenUser); end; end; end; CloseHandle(Token); RegCloseKey(SvcKey); end; finally SetPrivilege('SeTakeOwnershipPrivilege', false); end; //*** End Set Owner **** RegResult:=RegOpenKeyExW(Key, PWideChar(SubKeyName), 0, READ_CONTROL or WRITE_DAC, SvcKey); if RegResult<>ERROR_SUCCESS then raise Exception.Create(SysErrorMessage(RegResult)); try pSD:=nil; dwSize:=0; RegResult:=RegGetKeySecurity(SvcKey,DACL_SECURITY_INFORMATION, pSD, dwSize); if RegResult<>ERROR_SUCCESS then raise Exception.Create(SysErrorMessage(RegResult)); GetMem(pSD,dwSize); InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); RegResult:=RegGetKeySecurity(SvcKey, DACL_SECURITY_INFORMATION, pSD, dwSize); if RegResult<>ERROR_SUCCESS then raise Exception.Create(SysErrorMessage(RegResult)); if ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION_1, DACL_SECURITY_INFORMATION, pSdStr, nil) then begin pNewSD:=nil; if ResetAccess<>'' then sNewSD:=ResetAccess else sNewSD:=StrPas(pSdStr)+'(A;OICI;GA;;;'+GetCurrentUserSIDString('BA')+')'; //AdminAccess='(A;OICI;GA;;;BA)'; //see "Security Descriptor String Format": [url]http://msdn2.microsoft.com/en-us/library/aa379570.aspx[/url] + "SID Strings" [url]http://msdn2.microsoft.com/en-us/library/aa379602.aspx[/url] + [url]http://msdn.microsoft.com/en-us/magazine/cc982153.aspx[/url] if ConvertStringSecurityDescriptorToSecurityDescriptor(PChar(sNewSD), SDDL_REVISION_1, pNewSD, nil) then if IsValidSecurityDescriptor(pNewSD) then begin RegResult:=RegSetKeySecurity(SvcKey, DACL_SECURITY_INFORMATION, pNewSD); if RegResult=ERROR_SUCCESS then begin ResetAccess:=StrPas(pSdStr); result:=true; end; end; if pNewSD<>nil then LocalFree(HLOCAL(pNewSD)); LocalFree(HLOCAL(pSdStr)); end; finally if pSD<>nil then FreeMem(pSD); RegCloseKey(SvcKey); end; end;
Delphi-Quellcode:
Hier noch die Hilfsfunktionen:
{SetFileAccessForAll: Set File Access for the current user}
procedure SetFileAccessForAll(FileName:string); var pSD:PSECURITY_DESCRIPTOR; Token:THandle; pTokenUser:PTOKEN_USER; r,dwLength: DWORD; sErr:string; pOldDACL,pDACL: PACL; EA: TExplicitAccess; begin sErr:=''; SetPrivilege('SeTakeOwnershipPrivilege', True); // SE_TAKE_OWNERSHIP_NAME try dwLength:=0; pTokenUser := nil; OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token); if not GetTokenInformation(Token, TokenUser, pTokenUser, 0, dwLength) then begin if GetLastError=ERROR_INSUFFICIENT_BUFFER then begin pTokenUser:=HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength); if pTokenUser<>nil then begin if GetTokenInformation(Token, TokenUser, pTokenUser, dwLength, dwLength) then begin SetNamedSecurityInfo(PChar(FileName), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, pTokenUser^.User.Sid, nil, nil, nil); // **** Start: grant all access to current User *** pSD:=nil; pOldDACL:=nil; GetNamedSecurityInfo(PChar(FileName), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, @pOldDACL, nil, pSD); ZeroMemory(@EA, SizeOf(EA)); BuildTrusteeWithSid(@EA.Trustee, pTokenUser^.User.Sid); EA.grfAccessPermissions := GENERIC_ALL; EA.grfAccessMode := SET_ACCESS; EA.grfInheritance := SUB_CONTAINERS_AND_OBJECTS_INHERIT; EA.Trustee.TrusteeForm := TRUSTEE_IS_SID; EA.Trustee.TrusteeType := TRUSTEE_IS_USER; r := SetEntriesInAcl(1, @EA, pOldDACL, pDACL); // Merges EA + pOldDACL = pDACL if r = ERROR_SUCCESS then begin SetNamedSecurityInfo(PAnsiChar(FileName), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, pDACL, nil); if pDACL<>nil then LocalFree(Cardinal(pDACL)); end; if pOldDACL<>nil then LocalFree(Cardinal(pOldDACL)); // **** Ende: *** end; HeapFree(GetProcessHeap, 0, pTokenUser); end; end; CloseHandle(Token); end; finally SetPrivilege('SeTakeOwnershipPrivilege', false); end; end;
Delphi-Quellcode:
Als Anregung auch mal hier angucken:
function ConvertSidToStringSid(Sid: PSID; var StringSid: LPSTR): BOOL; stdcall; external advapi32 name 'ConvertSidToStringSidA';
//function ConvertStringSidToSid(StringSid: LPCSTR; var Sid: PSID): BOOL; stdcall; external advapi32 name 'ConvertStringSidToSidA'; function GetCurrentUserSIDString(sDefault:string):string; //für SvcHostDlls var dwLength: DWORD; Token:THandle; pTokenUser:PTOKEN_USER; StringSid:PChar; begin result:=sDefault; dwLength:=0; pTokenUser := nil; OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, Token); if not GetTokenInformation(Token, TokenUser, pTokenUser, 0, dwLength) then begin if GetLastError=ERROR_INSUFFICIENT_BUFFER then begin pTokenUser:=HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength); if pTokenUser<>nil then begin if GetTokenInformation(Token, TokenUser, pTokenUser, dwLength, dwLength) then begin ConvertSidToStringSid(pTokenUser^.User.Sid, StringSid); result:=StrPas(StringSid); LocalFree(HLOCAL(StringSid)); end; HeapFree(GetProcessHeap, 0, pTokenUser); end; end; end; CloseHandle(Token); end; function ConvertSecurityDescriptorToStringSecurityDescriptor( SecurityDescriptor: PSECURITY_DESCRIPTOR; RequestedStringSDRevision: DWORD; SecurityInformation: SECURITY_INFORMATION; var StringSecurityDescriptor: LPSTR; StringSecurityDescriptorLen: PULONG): BOOL; stdcall; external advapi32 name 'ConvertSecurityDescriptorToStringSecurityDescriptorA'; function ConvertStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor: LPCSTR; StringSDRevision: DWORD; var SecurityDescriptor: Windows.PSECURITY_DESCRIPTOR; SecurityDescriptorSize: PULONG): BOOL; stdcall; external advapi32 name 'ConvertStringSecurityDescriptorToSecurityDescriptorA'; ![]() (Bitte nicht meckern, dass ich einen alten Thread ausgegraben habe - für die Delphiprogrammierer die nach Hilfe googeln ist doch nur wichtig, ob sie Hilfe finden oder nicht) |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |