Я пытаюсь установить владельца файла для другого пользователя программно в C ++.
Я определенно включил SeRestorePrivilege
для моего процесса. Я могу подтвердить это с помощью Process Explorer. Я запускаю процесс, он отключен, я запускаю свой код, чтобы включить его, ProcExp сообщает об этом как о включенном, я просто подхожу к точке, где должен быть установлен владелец, и он все еще включен (то есть я не случайно отключаю Это).
Что еще может быть вызвано для этого сообщения об отказе в доступе? Что я не учел?
std::wstring fileSystemObject = L"C:\test.txt";
*status_code = SetNamedSecurityInfo((wchar_t*)fileSystemObject.c_str(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, pSID, NULL, NULL, NULL);
if (*status_code == ERROR_SUCCESS)
{
Log(L"Successfully set owner for " + fileSystemObject);
return true;
}
else
{
Log(L"Failed to set owner for " + fileSystemObject + L". Error code: ", *status_code);
return false;
}
Спасибо.
РЕДАКТИРОВАТЬ: Большое спасибо за вашу постоянную помощь. Это очень ценится.
Я использовал ваш код для всех следующих тестов. По сути, я также получаю сообщения «Отказано в доступе» из вашего кода, однако отслеживаю его немного подробнее.
Во-первых, «C: \ test.txt» не был моим настоящим кодом, и, к сожалению, отсутствие обратной косой черты не является причиной моей проблемы. Спасибо за ваши острые глаза, хотя 🙂
Кроме того, я использую учетную запись администратора с отключенным контролем учетных записей, и в моей программе в манифесте установлен параметр requireAdministrator.
Однако я заметил, что и мой код, и ваш код работают с простыми файлами. После большого тестирования я обнаружил, что я получаю сообщения AccessDenied только в следующих сценариях:
1: я не владелец, и для разрешения «Взять на себя» установлено значение «Запретить», например. Каждый.
2: я владелец, и для разрешения «Взять на себя» установлено значение «Запретить», например. Каждый. Любопытно, что во втором случае, несмотря на код ошибки, смена владельца действительно происходит.
Я не понимаю, почему это происходит. Я и вы установили SE_RESTORE_NAME в токене процесса. Мне должно быть позволено произвольно установить владельца SID. Но, похоже, я не могу.
Похоже, что любой отказ от DACL в TakeOwnership отвергает мою способность стать владельцем. Тем не менее, я не могу изменить разрешения, пока не смогу стать владельцем! вздох.
Я мог бы попытаться установить SeTakeOwnershipPrivilege, как вы изначально рекомендовали, взяв на себя владение, изменив разрешения, установив владение внешним. Какая боль. И я даже не уверен, что это сработает.
Я также нашел это: http://us.generation-nt.com/setnamedsecurityinfo-failing-rc-1307-help-59729462.html
Кажется, он находится в аналогичной ситуации (я получаю 1307, если я не настроил токен процесса должным образом). Но CreatePrivateObjectSecurityEx требует гораздо больше настроек.
Хммм. Спасибо за ваше время.
Проблема здесь в том, что подсистема и модель безопасности защищают объект от необоснованных изменений владельца, и даже имея разрешения администратора, необходимо правильно преодолеть препятствия.
Есть две привилегии, связанные с владением файлом: SE_TAKE_OWNERSHIP_NAME
а также SE_RESTORE_NAME
, Первый позволяет взять чей-то объект, а второй позволяет установить владельца, который не является самим сеттером.
Это может выглядеть как SE_RESTORE_NAME
является более мощной привилегией и достаточной для выполнения задачи, однако, похоже, что это не так. Да, это позволяет установить чью-либо собственность, как говорится в MSDN:
Если у вызывающей стороны нет константы SeRestorePrivilege (см.
Константы привилегий), этот SID должен содержаться в
токен и должен иметь разрешение SE_GROUP_OWNER.
Параметр SecurityInfo должен включать OWNER_SECURITY_INFORMATION
флаг. Чтобы установить владельца, вызывающий должен иметь доступ WRITE_OWNER к
объект или активировать привилегию SE_TAKE_OWNERSHIP_NAME.
Однако это не позволяет вам преодолеть элемент DACL, который явно предотвращает изменение владельца. В этом случае вам также понадобятся и другие привилегии (то есть, вам нужно включить обе), что позволит вам получить право собственности у кого-то до того, как вы решите, кому вы собираетесь его передать.
Я копирую ссылку на исходный код C ++ / ATL из комментария выше: SetFileOwner.cpp. Когда permissions / DACL имеет элемент Deny, возникает исключение, и включение второй привилегии решает проблему.
Других решений пока нет …