Требуемая привилегия не удерживается, возвращаемая CreateFile - PullRequest
0 голосов
/ 28 июня 2018

При попытке открыть файл на Samba из приложения Win32, работающего на Windows Server, функция CreateFiles возвращает недопустимый дескриптор, а код ошибки - 0x522 (ERROR_PRIVILEGE_NOT_HELD), есть ли способ запросить систему, в которой для этого отсутствует Provilege? конкретный файл?

Я включил некоторые привилегии безопасности после олицетворения зарегистрированного пользователя (которым должен быть администратор): SE_SECURITY_NAME, SE_BACKUP_NAME и SE_RESTORE_NAME, но это не работает.

Мне просто нужно чтение привилегированного файла, и я отправляю в CreateFile следующие параметры:

 hSrcFile = CreateFile (sourcePath, READ_CONTROL | ACCESS_SYSTEM_SECURITY, 0, NULL, OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS, NULL);

Некоторая другая, вероятно, не очень полезная информация:

  • Зарегистрированный пользователь может открыть файл с помощью любого случайного приложения, например блокнот.
  • Если процесс создает новый файл в папке samba, он также может откройте его без проблем, проблема, кажется, затрагивает файлы уже создан до запуска программы.

Есть предложения? Спасибо

РЕДАКТИРОВАТЬ 1

Чтобы настроить флаг SE_SECURITY_NAME, я беру токен процесса с OpenProcessToken, затем использую эту функцию из MSDN для включения привилегий.

Я также пытался использовать токен из LogonUser при входе в систему в качестве администратора для установки привилегии, но в этом случае функция MSDN , похоже, не работает с ошибкой ACCESS_DENIED. То же самое после дублирования токена с DuplicateToken (и флагом SecurityDelegation) также не работает.

Я проверил возвращаемое значение AdjustTokenPrivileges при установке SE_SECURITY_NAME, и функция не завершилась. Я могу вызвать CreateFile, чтобы открыть файл без флага ACCESS_SYSTEM_SECURITY, но тогда я не могу использовать дескриптор файла для вызова GetFileInformationByHandleEx, так как функция завершается ошибкой с ACCESS DENIED, не уверенный, связано ли это с ACCESS_SYSTEM_SECURITY или нет.

РЕДАКТИРОВАТЬ 2

Я выполняю следующие шаги, чтобы включить SE_SECURITY_NAME, а затем использую CreateFile:

  • Получите токен процесса с помощью OpenProcessToken (помечает TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY) и вызовите AdjustTokenPrivileges с SE_SECURITY_NAME, SE_BACKUP_NAME и SE_RESTORE_NAME. (После получения правильного LUID с LookupPrivilegeValue). Код ошибки, возвращаемый функцией: 0x0.

  • Получите токен потока с помощью OpenThreadToken (помечает TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY) и вызовите AdjustTokenPrivileges с SE_SECURITY_NAME, SE_BACKUP_NAME и SE_RESTORE_NAME. (После получения правильного LUID с LookupPrivilegeValue). Код ошибки, возвращаемый функцией: 0x0.

  • Вызовите CreateFile с помощью CreateFile(pathTofile, READ_CONTROL | ACCESS_SYSTEM_SECURITY, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTIC,NULL), функция вернет 0x522: PRIVILEGE NOT HELDD. PathToFile имеет формат, такой как "\ 192.168.0.0 \ folder \ file.txt"

Надеюсь, это немного прояснит поток, код для включения привилегий:

bStatus = LookupPrivilegeValue (NULL, privilegeStr, &luid);
if (!bStatus)
{
    dwStatus = GetLastError();
   // do stuff
}

ZeroMemory (&tp, sizeof (tp));
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

/* Adjust Token privileges */
bStatus = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
    &oldtp, &dwSize);
dwStatus = GetLastError();
if (!bStatus || dwStatus != ERROR_SUCCESS )
{
    //do stuff, print error etc.
}

где privilegeStr, например, SE_SECURITY_NAME

РЕДАКТИРОВАТЬ 3

В надежде предоставить всеобъемлющий пример кода, который воспроизводит проблему и, таким образом, может получить возможное решение, я подготовил этот уродливый фрагмент кода:

HANDLE hToken;
bStatus = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES |
    TOKEN_QUERY, TRUE, &hToken);

LUID luid;
LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &luid);

TOKEN_PRIVILEGES    tp = { 0, };
TOKEN_PRIVILEGES    oldtp = { 0, };
DWORD               dwSize = sizeof(TOKEN_PRIVILEGES);

ZeroMemory(&tp, sizeof(tp));
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

/* Adjust Token privileges */
bStatus = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
    &oldtp, &dwSize);
dwStatus = GetLastError();
if (!bStatus || dwStatus != ERROR_SUCCESS)
{
    //Print error.
}

PRIVILEGE_SET privSet;
ZeroMemory(&privSet, sizeof(PRIVILEGE_SET));

privSet.PrivilegeCount = 1;
privSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
privSet.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
privSet.Privilege[0].Luid = luid;

BOOL bResult;
PrivilegeCheck(hToken, &privSet, &bResult);

fprintf(stderr,"Status bool: %d, attr value:0x%x, error code: 0x%x\n", 
    bResult,
    privSet.Privilege[0].Attributes,
    GetLastError());

hSrcFile = CreateFile (sourcePath, READ_CONTROL | ACCESS_SYSTEM_SECURITY, 0, NULL, OPEN_EXISTING,
    FILE_FLAG_BACKUP_SEMANTICS, NULL);

if( hSrcFile == INVALID_HANDLE_VALUE )
{
    fprintf(stderr,"CreateFile error 0x%x\n", GetLastError());
}

Вывод Status bool:1, attr value:0x80000002, error code: 0x0, за которым следует CreateFile error 0x522.

Подтверждает ли этот пример, что SE_SECURITY_NAME включен, но CreateFile все еще не работает? Что-нибудь еще нужно? Дополнительно:

  • Я могу открыть любой другой случайный файл на локальном диске с помощью ACCESS_SYSTEM_SECURITY
  • Файл, к которому не удается получить доступ, находится на SAMBA, как объяснялось в самой первой строке моего вопроса, имеет ли это какое-либо отношение к способу настройки этих атрибутов? Вроде так, но не знаю как.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...