4
我使用Win32 API在C中測試以下代碼,該代碼旨在創建可供當前用戶訪問的新文件,但是私有(不可訪問)爲其他人。Win32 API:爲當前用戶創建公共文件但爲其他人私有
爲此,它拒絕所有人的SID權限,然後爲當前的用戶SID設置權限。
該文件已成功創建並且權限顯然已成功設置(請參見下面的截圖),但是當我嘗試用記事本打開文件時,它說「訪問被拒絕」(我的文件資源管理器正在運行會話),如果我打開命令提示符並執行「輸入file_created.txt」,則出現相同的「訪問被拒絕」。
我當然可以手動恢復權限,因爲我是管理員,但其想法是使其以編程方式工作。
代碼:
#include <windows.h>
#include <AccCtrl.h>
#include <aclapi.h>
#include <stdio.h>
#include <stdexcept>
#include <string>
#undef UNICODE
int GetCurrentUserSid(PSID* pSID)
{
const int MAX_NAME = 256;
DWORD i, dwSize = 0;
HANDLE hToken;
PTOKEN_USER user;
TOKEN_INFORMATION_CLASS TokenClass = TokenUser;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ | TOKEN_QUERY, &hToken))
return GetLastError();
else
wprintf(L"OpenProcessToken() - got the handle to the access token!\n");
if (!GetTokenInformation(hToken, TokenClass, NULL, 0, &dwSize))
{
DWORD dwResult = GetLastError();
if (dwResult != ERROR_INSUFFICIENT_BUFFER)
{
wprintf(L"GetTokenInformation() failed, error %u\n", dwResult);
return FALSE;
}
else
wprintf(L"GetTokenInformation() - have an ample buffer...\n");
}
else
wprintf(L"GetTokenInformation() - buffer for Token group is OK\n");
user = (PTOKEN_USER)LocalAlloc(GPTR, dwSize);
if (!GetTokenInformation(hToken, TokenClass, user, dwSize, &dwSize))
{
wprintf(L"GetTokenInformation() failed, error %u\n", GetLastError());
return FALSE;
}
else
wprintf(L"GetTokenInformation() for getting the TokenGroups is OK\n");
DWORD dw_sid_len = GetLengthSid(user->User.Sid);
*pSID = (SID*)LocalAlloc(GPTR, dw_sid_len);
CopySid(dw_sid_len, *pSID, user->User.Sid);
return 0;
}
DWORD set_file_security(LPSTR filename)
{
PACL pNewDACL = NULL;
PSID current_user = NULL;
DWORD sid_size = SECURITY_MAX_SID_SIZE;
SID everyone_sid;
DWORD dwRes;
if (CreateWellKnownSid(WinWorldSid, NULL, &everyone_sid, &sid_size) ==
FALSE) {
throw std::runtime_error("CreateWellKnownSid() failed: " +
std::to_string(GetLastError()));
}
GetCurrentUserSid(¤t_user);
EXPLICIT_ACCESSA ea[2];
ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESSA));
ea[0].grfAccessPermissions = ACCESS_SYSTEM_SECURITY | READ_CONTROL | WRITE_DAC | GENERIC_ALL;
ea[0].grfAccessMode = GRANT_ACCESS;
ea[0].grfInheritance = NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.ptstrName = reinterpret_cast<char*>(current_user);
ea[1].grfAccessPermissions = ACCESS_SYSTEM_SECURITY | READ_CONTROL | WRITE_DAC | GENERIC_ALL;
ea[1].grfAccessMode = DENY_ACCESS;
ea[1].grfInheritance = NO_INHERITANCE;
ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[1].Trustee.ptstrName = reinterpret_cast<char*>(&everyone_sid);
dwRes = SetEntriesInAclA(2, ea, NULL, &pNewDACL);
if (ERROR_SUCCESS != dwRes) {
printf("SetEntriesInAcl Error %u\n", dwRes);
//TODO: goto Cleanup;
}
PSECURITY_DESCRIPTOR pSD = NULL;
// Initialize a security descriptor.
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD)
{
_tprintf(_T("LocalAlloc Error %u\n"), GetLastError());
goto Cleanup;
}
if (!InitializeSecurityDescriptor(pSD,
SECURITY_DESCRIPTOR_REVISION))
{
_tprintf(_T("InitializeSecurityDescriptor Error %u\n"),
GetLastError());
goto Cleanup;
}
// Add the ACL to the security descriptor.
if (!SetSecurityDescriptorDacl(pSD,
TRUE, // bDaclPresent flag
pNewDACL,
FALSE)) // not a default DACL
{
_tprintf(_T("SetSecurityDescriptorDacl Error %u\n"),
GetLastError());
goto Cleanup;
}
SECURITY_ATTRIBUTES sa;
// Initialize a security attributes structure.
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;
HANDLE hFile = CreateFileA(filename, GENERIC_ALL, 0, &sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(hFile);
//dwRes = SetNamedSecurityInfoA(filename, SE_FILE_OBJECT,
// DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL);
//if (ERROR_SUCCESS != dwRes) {
// printf("SetNamedSecurityInfo Error %u\n", dwRes);
// //goto Cleanup;
//}
Cleanup:
if (pNewDACL != NULL)
LocalFree((HLOCAL)pNewDACL);
return dwRes;
}
int main()
{
//return 0;
// Create Everyone SID.
DWORD sid_size = SECURITY_MAX_SID_SIZE;
SID everyone_sid;
if (CreateWellKnownSid(WinWorldSid, NULL, &everyone_sid, &sid_size) ==
FALSE) {
throw std::runtime_error("CreateWellKnownSid() failed: " +
std::to_string(GetLastError()));
}
LPSTR filename = "created_file.txt";
set_file_security(filename);
return 0;
}
注:我實現了代碼有內存泄漏等問題,我只是在迅速地測試這個想法。
你的老闆是完全正確的,我刪除了代碼中的每個人的設置,現在按預期工作,謝謝! –