Как создать каталог со всеми правами, предоставленными каждому
Мне нужно программно создать каталог, который предоставляет "Полный доступ" группе "Все". Если я использую
CreateDirectory(path, NULL);
Это, в соответствии с документацией Win32 SDK, создаст каталог, который наследуется от его родительского каталога. Я не хочу наследовать права доступа родительского каталога, мне нужно, чтобы "Все" имели полный контроль над каталогом.
Очевидно, что это потребует настройки SECURITY_ATTRIBUTES
структура с соответствующим дескриптором безопасности. Как я могу это сделать?
3 ответа
Вот одна техника, которая, кажется, работает:
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
PSID everyone_sid = NULL;
AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0, &everyone_sid);
EXPLICIT_ACCESS ea;
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL;
ea.grfAccessMode = SET_ACCESS;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea.Trustee.ptstrName = (LPWSTR)everyone_sid;
PACL acl = NULL;
SetEntriesInAcl(1, &ea, NULL, &acl);
PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH);
InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = sd;
sa.bInheritHandle = FALSE;
CreateDirectory(path, &sa);
FreeSid(everyone_sid);
LocalFree(sd);
LocalFree(acl);
Обратите внимание, что в этом примере кода нет абсолютно никакой проверки ошибок - вам придется предоставить ее самостоятельно.
Я предпочитаю следующий фрагмент кода, поскольку он создает папку, наследующую права по умолчанию - что кажется правильным решением - другое программное обеспечение / пользователь может установить определенные наследуемые права на каталог по уважительной причине - затем добавляет запись полного доступа с полным доступом для встроенной группы "Пользователи".
BOOL CreateDirectoryWithUserFullControlACL(LPCTSTR lpPath)
{
if(!CreateDirectory(lpPath,NULL))
return FALSE;
HANDLE hDir = CreateFile(lpPath,READ_CONTROL|WRITE_DAC,0,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
if(hDir == INVALID_HANDLE_VALUE)
return FALSE;
ACL* pOldDACL;
SECURITY_DESCRIPTOR* pSD = NULL;
GetSecurityInfo(hDir, SE_FILE_OBJECT , DACL_SECURITY_INFORMATION,NULL, NULL, &pOldDACL, NULL, (void**)&pSD);
PSID pSid = NULL;
SID_IDENTIFIER_AUTHORITY authNt = SECURITY_NT_AUTHORITY;
AllocateAndInitializeSid(&authNt,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_USERS,0,0,0,0,0,0,&pSid);
EXPLICIT_ACCESS ea={0};
ea.grfAccessMode = GRANT_ACCESS;
ea.grfAccessPermissions = GENERIC_ALL;
ea.grfInheritance = CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE;
ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.ptstrName = (LPTSTR)pSid;
ACL* pNewDACL = 0;
DWORD err = SetEntriesInAcl(1,&ea,pOldDACL,&pNewDACL);
if(pNewDACL)
SetSecurityInfo(hDir,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL, pNewDACL, NULL);
FreeSid(pSid);
LocalFree(pNewDACL);
LocalFree(pSD);
LocalFree(pOldDACL);
CloseHandle(hDir);
return TRUE;
}
Посмотрите, можете ли вы использовать SetSecurityInfo()
В описании необязательного аргумента pDacl:
... Если значение параметра SecurityInfo включает флаг DACL-SECURITY-INFORMATION и значение этого параметра установлено в NULL, полный доступ к объекту предоставляется каждому.