|
|
Регистрация | << Правила форума >> | 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; |