В моей программе я должен установить настройку групповой политики для определенных файлов на ALL APPLICATION PACKAGES
, Для этого я использую следующую функцию, которая принимает FilePath
в файл и устанавливает ALL APPLICATION PACKAGES
групповая политика в этом файле:
DWORD AdjustGroupPolicy(std::wstring wstrFilePath)
{
PACL pOldDACL = NULL, pNewDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS eaAccess;
SECURITY_INFORMATION siInfo = DACL_SECURITY_INFORMATION;
DWORD dwResult = ERROR_SUCCESS;
dwResult = GetNamedSecurityInfo(wstrFilePath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD);
if (dwResult != ERROR_SUCCESS)
{
if (pSD != NULL)
LocalFree((HLOCAL)pSD);
}
ZeroMemory(&eaAccess, sizeof(EXPLICIT_ACCESS));
eaAccess.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
eaAccess.grfAccessMode = SET_ACCESS;
eaAccess.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
eaAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
eaAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
eaAccess.Trustee.ptstrName = L"ALL APPLICATION PACKAGES";
dwResult = SetEntriesInAcl(1, &eaAccess, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != dwResult)
{
if (pSD != NULL)
LocalFree((HLOCAL)pSD);
if (pNewDACL != NULL)
LocalFree((HLOCAL)pNewDACL);
}
dwResult = SetNamedSecurityInfo((LPWSTR)wstrFilePath.c_str(), SE_FILE_OBJECT, siInfo, NULL, NULL, pNewDACL, NULL);
if (ERROR_SUCCESS != dwResult)
{
if (pSD != NULL)
LocalFree((HLOCAL)pSD);
if (pNewDACL != NULL)
LocalFree((HLOCAL)pNewDACL);
}
return dwResult;
}
Проблема в том, что некоторые пользователи сообщают, что эта функция по какой-то причине не работает. Немного покопавшись в проблеме, я обнаружил, что на ПК с настройками языков, отличных от английского, функция не работает SetEntiresInAcl
с кодом ошибки 1332 (0x534). в Документация MSDN, код ошибки соответствует ошибке ERROR_NONE_MAPPED
, с описанием:
Нет сопоставления между именами учетных записей и идентификаторами безопасности.
Я думаю, что ошибка выбрасывается, потому что ALL APPLICATION PACKAGES
называется по-разному в зависимости от языковых настроек, поэтому Windows не может найти идентификатор безопасности для него; Однако я не уверен, как исправить эту ошибку. Как я могу исправить эту ошибку, чтобы функция работала надежно, независимо от языковых настроек пользователя?
Я относительно новичок в политике контроля доступа в Windows, и мне никогда не приходилось сталкиваться с ней до моего текущего проекта. Я усвоил урок, согласно которому я не должен назначать опекуна по имени, поскольку нельзя полагаться на одно и то же имя в разных системах, даже если это известная группа.
Я решил исправить это, добавив следующий код в функцию:
PSID pSID;
ConvertStringSidToSid(L"S-1-15-2-1", &pSID); // S-1-15-2 is the SID for ALL_APP_PACKAGES
Позже, когда я установил информацию об опекуне, я изменил код на:
eaAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
eaAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
eaAccess.Trustee.ptstrName = (LPTSTR)pSID;
ConvertStringSidToSid
принимает SID в формате строки и возвращает указатель на соответствующую структуру SID. Затем я могу использовать этот SID вместо его имени, что позволяет избежать проблем с переводом, которые у меня были раньше.
Других решений пока нет …