Установить владельца файла для несуществующего пользователя / SID в Windows

Я пытаюсь написать инструмент для резервного копирования и восстановления. Я запускаю свой код на компакт-диске WinPE (http://en.wikipedia.org/wiki/Windows_Preinstallation_Environment). Я пытаюсь прочитать весь раздел C: и записать его в сеть. Так же, как команда tar, но для конкретных окон. У меня все работает, кроме настройки владельца файла. Кажется, что Windows действительно нетерпима к файлам, принадлежащим неизвестным идентификаторам безопасности. Поскольку я работаю в WinPE, большинство пользователей, определенных на C:, не находятся в локальной базе данных пользователей.

Вот некоторые из функций, которые я пробовал:

  • SetFileSecurity (возвращает 1307)
  • SetSecurityInfo (возвращает 1307)
  • SetNamedSecurityInfo (возвращает 1307)
  • BackupWrite (возвращает 1307)
  • NtSetSecurityObject (возвращает 0xC000005A)

Я знаю, что это можно сделать. SetACL (http://helgeklein.com/setacl/) умеет это делать.

Итак, вопрос. Как мне установить владельца файла на несуществующего пользователя / SID? Любая помощь очень ценится!

Вот пример кода, который я пробовал:

#define _WIN32_WINNT 0x0500

#include <windows.h>
#include <sddl.h>
#include <aclapi.h>
#include <tchar.h>

INT _tmain(){

PSECURITY_DESCRIPTOR psdOwner = LocalAlloc(LPTR,SECURITY_DESCRIPTOR_MIN_LENGTH);

if (InitializeSecurityDescriptor(psdOwner,SECURITY_DESCRIPTOR_REVISION)){

PSID psOwner = (PSID)0;

if (ConvertStringSidToSid(TEXT("S-1-5-21-3626571138-2175758104-1447827851-1013"),&psOwner)){

if (SetSecurityDescriptorOwner(psdOwner,psOwner,FALSE)){

DWORD dwError = SetNamedSecurityInfo(TEXT("test.txt"),SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,psdOwner,NULL,NULL,NULL);

if (dwError == ERROR_SUCCESS){

_tprintf(TEXT("Success!\n"));

}else{

_tprintf(TEXT("Failed to set owner: %u\n"),dwError);

}

}else{

_tprintf(TEXT("Failed to set owner into SD: %u\n"),GetLastError());

}

}else{

_tprintf(TEXT("Failed to covnert Sid string to Sid: %u\n"),GetLastError());

}

if (psOwner) LocalFree(psOwner);

}else{

_tprintf(TEXT("Failed to initialize SD: %u\n"),GetLastError());

}

if (psdOwner) LocalFree(psdOwner);

return 0;

}

2

Решение

Оказывается, вам нужна привилегия токена SE_RESTORE_NAME. Вы можете настроить свой токен процесса следующим образом:

BOOL TakeSecurityPriv(LPCTSTR szPriv){

BOOL bReturn = FALSE;

HANDLE hProcToken = (HANDLE)0;

if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hProcToken)){

TOKEN_PRIVILEGES tpTokPriv;

if (LookupPrivilegeValue(NULL,szPriv,&tpTokPriv.Privileges[0].Luid)){

tpTokPriv.PrivilegeCount = 1;
tpTokPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if (AdjustTokenPrivileges(hProcToken,FALSE,&tpTokPriv,0,NULL,0)){

bReturn = TRUE;

}

}

}

return bReturn;

}

Затем вы можете добавить следующее в начало main в моем примере:

if (TakeSecurityPriv(SE_RESTORE_NAME)){

Это избавляет от ошибки 1307. К сожалению, в моем примере есть еще одна ошибка, потому что владелец не настроен на правильный SID. Однако когда я переключаюсь обратно на BackupRead / BackupWrite, мне не нужно создавать SID или SECURITY_DESCRIPTOR. Я размышлял над тем, что может быть проблемой некоторое время без удачи. Возможно, кто-то еще может ответить на эту часть.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]