При попытке открыть файл на 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, как объяснялось в самой первой строке моего вопроса, имеет ли это какое-либо отношение к способу настройки этих атрибутов? Вроде так, но не знаю как.