![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Столкнулся с такой задачей: В реестре имеется ключ, который нужно удалить. Права доступа следующие: система - read, Администраторы - read, Пользователи - read, TrustedInstaller - Full. Как я понимаю нужно стать владельцем объекта, затем установить для своего пользователя права на запись и лишь после этого удалить нужный объект. Однако столкнулся с тем что при попытке выполнения следующего кода получаю сообщение об ошибке.
Код:
function ChangeRegKeySecurity(AUser, ADomain: String; AKey: HKEY;
APatch: String; AHideMessage: Boolean = True): Boolean;
var
Key: HKEY;
test: integer;
pOwnerSid: PSid;
lpDomain: PWideChar;
cbDomain, cbSid: Cardinal;
peUse: Cardinal;
pSecDescr: PSECURITY_DESCRIPTOR;
r: integer;
mybuff: PWideChar;
begin
Result := False;
pSecDescr := PSECURITY_DESCRIPTOR
(LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH));
LookupAccountName(PChar(ADomain), PChar(AUser), nil, cbSid, nil,
cbDomain, peUse);
GetMem(pOwnerSid, cbSid);
GetMem(lpDomain, cbDomain * SizeOf(WideChar));
if not LookupAccountNameW(PChar(ADomain), PChar(AUser), pOwnerSid, cbSid,
lpDomain, cbDomain, peUse) then
begin
if not AHideMessage then
MessageDlg('Указанный пользователь не найден!', mtError, [mbOK], 0);
Exit;
end;
if InitializeSecurityDescriptor(@pSecDescr, SECURITY_DESCRIPTOR_REVISION) then
begin
if SetSecurityDescriptorOwner(@pSecDescr, pOwnerSid, True) then
begin
//Вот тут получаем ошибку об Access Denied
r := RegOpenKeyEx(AKey, PWideChar(APatch), 1, KEY_ALL_ACCESS, Key);
if r = ERROR_SUCCESS then
begin
r := RegSetKeySecurity(Key, OWNER_SECURITY_INFORMATION, @pSecDescr);
if r <> ERROR_SUCCESS then
begin
if not AHideMessage then
MessageDlg(SysErrorMessage(r), mtError, [mbOK], 0);
Exit;
end;
RegCloseKey(Key);
Result := True;
end
else
begin
if not AHideMessage then
MessageDlg(SysErrorMessage(r), mtError, [mbOK], 0);
Exit;
end;
end;
end
else
begin
if not AHideMessage then
MessageDlg('Не могу инициализировать дескриптор безопасности!', mtError,
[mbOK], 0);
end;
end;
.....
ChangeRegKeySecurity('TestUser','TEST-PC',HKEY_CLASSES_ROOT,'AppID\{CDCBCFCA-3CDC-436f-A4E2-0E02075250C2}',False);TestUser - является администратором. Собственно вопрос с каким ключем прав доступа выполнить RegOpenKeyEx. Последний раз редактировалось Asmoday74, 29.10.2011 в 23:48. |
|
#2
|
|||
|
|||
|
Почитал справку от мелкософта нашел следующее:
When you call the RegOpenKeyEx function, the system checks the requested access rights against the key's security descriptor. If the user does not have the correct access to the registry key, the open operation fails. If an administrator needs access to the key, the solution is to enable the SE_TAKE_OWNERSHIP_NAME privilege and open the registry key with WRITE_OWNER access. For more information, see Enabling and Disabling Privileges. Пробую открыть нужный раздел с правами на смену владельца, все проходит удачно. Код:
r := RegOpenKeyEx(AKey, PWideChar(APatch), 1,WRITE_OWNER, Key); Функцию для установки SE_TAKE_OWNERSHIP_NAME использую такую: Код:
function SetPrivilege(privilegeName: string; enable: boolean): boolean;
var
tpPrev, tp: TTokenPrivileges;
token: THandle;
dwRetLen: DWord;
begin
result := False;
try
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
token); // ïполучаем маркер безопасности процесс- токен
tp.PrivilegeCount := 1;
if LookupPrivilegeValue(nil, pchar(privilegeName), tp.Privileges[0].LUID)
then // получаем идентификатор привилегии - LUID
begin
if enable then
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
// устанавливаем атрибуты привилегии
else
tp.Privileges[0].Attributes := 0;
dwRetLen := 0;
result := AdjustTokenPrivileges(token, False, tp, SizeOf(tpPrev), tpPrev,
dwRetLen); // включаем или отключаем привилегию
end;
finally
try
CloseHandle(token);
except
end;
end;
end; |
|
#3
|
|||
|
|||
|
Вобщем вопрос решил сам, выкладываю полностью рабочий код функций для смены прав доступа к ветке реестра. Поддержка начиная с Windows 2000.
Код:
function SetPrivilege(privilegeName: string; enable: boolean): boolean;
var
tpPrev, tp: TTokenPrivileges;
token: THandle;
dwRetLen: DWord;
begin
result := False;
try
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
token); // пполучаем маркер безопасности процесс- токен
tp.PrivilegeCount := 1;
if LookupPrivilegeValue(nil, pchar(privilegeName), tp.Privileges[0].LUID)
then // получаем идентификатор привилегии - LUID
begin
if enable then
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
// устанавливаем атрибуты привилегии
else
tp.Privileges[0].Attributes := 0;
dwRetLen := 0;
result := AdjustTokenPrivileges(token, False, tp, SizeOf(tpPrev), tpPrev,
dwRetLen); // включаем или отключаем привилегию
end;
finally
try
CloseHandle(token);
except
end;
end;
end;
function ChangeRegKeySecurity(AUser, ADomain: String; AKey: HKEY;
APatch: String; AHideMessage: boolean = True): boolean;
var
Key: HKEY;
pOwnerSid: PSid;
lpDomain: PWideChar;
cbDomain, cbSid: Cardinal;
peUse: Cardinal;
pSecDescr: PSECURITY_DESCRIPTOR;
r: integer;
begin
result := False;
pSecDescr := PSECURITY_DESCRIPTOR
(LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH));
LookupAccountName(pchar(ADomain), pchar(AUser), nil, cbSid, nil,
cbDomain, peUse);
GetMem(pOwnerSid, cbSid);
GetMem(lpDomain, cbDomain * SizeOf(WideChar));
if not LookupAccountNameW(pchar(ADomain), pchar(AUser), pOwnerSid, cbSid,
lpDomain, cbDomain, peUse) then
begin
if not AHideMessage then
MessageDlg('Указанный пользователь не найден!', mtError, [mbOK], 0);
Exit;
end;
if InitializeSecurityDescriptor(@pSecDescr, SECURITY_DESCRIPTOR_REVISION) then
begin
if SetSecurityDescriptorOwner(@pSecDescr, pOwnerSid, True) then
begin
r := RegOpenKeyEx(AKey, PWideChar(APatch), 1,WRITE_OWNER, Key);
if r = ERROR_SUCCESS then
begin
r := RegSetKeySecurity(Key, OWNER_SECURITY_INFORMATION, @pSecDescr);
if r <> ERROR_SUCCESS then
begin
if not AHideMessage then
MessageDlg(SysErrorMessage(r), mtError, [mbOK], 0);
Exit;
end;
RegCloseKey(Key);
result := True;
end
else
begin
if not AHideMessage then
MessageDlg(SysErrorMessage(r), mtError, [mbOK], 0);
Exit;
end;
end;
end
else
begin
if not AHideMessage then
MessageDlg('Не могу инициализировать дескриптор безопасности!', mtError,
[mbOK], 0);
end;
end;
//Использование
procedure TForm1.Button1Click(Sender: TObject);
begin
if not SetPrivilege('SeTakeOwnershipPrivilege', True) then
begin
MessageDlg('Не могу установить привилегию смены владельца!', mtError,
[mbOK], 0);
Exit;
end;
ChangeRegKeySecurity(
'user', //Имя влядельца объекта
'domain', //Домен или имя локального компьютера
HKEY_CLASSES_ROOT, //Ветка рееестра
'test', //Дополнительный путь
False //Скрыть сообщения об ошибках
);
end; |