Access denied on CreateFileMapping when run under different user accounts with runas - c++

This code gives me access denied errors when trying to open previously created file mapping. Help, help, help.
OS: WinXP SP3, no fast user switching.
Following code is run on 2 different user accounts using runas.
Both users have Administrator privileges.
test code:
SECURITY_DESCRIPTOR sd;
if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
printf("InitializeSecurityDescriptor failed %d\n", GetLastError());
if(!SetSecurityDescriptorDacl(&sd, true, 0, false))
printf("SetSecurityDescriptorDacl failed %d\n", GetLastError());
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = false;
HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 0x1000, "Global\\MyMap");
void* pMap = 0;
if(hMap) {
pMap = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0x1000);
} else {
printf("CreateFileMapping failed: %d\n", GetLastError());
hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, "Global\\MyMap");
if(hMap) {
printf("OpenFileMapping sucess!\n");
} else {
printf("OpenFileMapping failed: %d\n", GetLastError());
}
}
if(pMap) {
printf("Sucess!\n");
printf("DW: %X", *(DWORD*)pMap);
*(DWORD*)pMap = 0xDEADBEEF;
} else {
printf("MapViewOfFile failed: %d\n", GetLastError());
}
cin.ignore();
if(pMap)
UnmapViewOfFile(pMap);
if(hMap)
CloseHandle(hMap);

You forgot to pass the SECURITY_ATTRIBUTES struct to CreateFileMapping...

Related

How is an integrity level SID constructed?

I feel like I'm missing something obvious but I've been stuck on this for hours. I am attempting to call SetTokenInformation on a duplicate primary token of the current process, but it fails with 0x5 (Access denied).
I'm trying to create a child process with no privileges. Then I want to adjust the integrity level of the token to low.
Flow of execution in the minimal example:
We enable every single privilege. All of them.
We open the current process with PROCESS_ALL_ACCESS, and open the process token with TOKEN_ALL_ACCESS
We get a duplicate token for our current process.
We attempt to change the mandatory integrity level of the token, and we get Access denied.
Please note this is for a minimal example, I know the above would be very bad practice in production code. We are simply eliminating the possibility of permission issues.
Privileges:
Output:
What could I be missing here? I have tried everything I can think of:
Debugged it to verify the method being called is correct and the arguments on the stack are all valid
Verified arguments and return values for every function in the program
Tried every process and token access/duplication flag
Minimum 2 hours of Googling for random info with "StackOverflow ...
token" (this one is a joke, but I really did)
etc.
So I figure it has to be a problem with the SID itself. But I have been able to find nothing on the internet about how this SID is constructed.
MinimalMain.cpp:
// TokenMinimalExample.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include <windows.h>
#include <stdio.h>
#include "token_example.h"
int main()
{
// Enable every privilege under the sun.
if (!EnableEveryPrivilegeUnderTheSun())
{
printf("Failed to enable every privilege under the sun: %d\n", GetLastError());
return 1;
}
// Get a duplicate token for the current process
HANDLE hToken = GetCurrentProcessPrimaryToken();
if (hToken == INVALID_HANDLE_VALUE)
{
printf("Failed to get a duplicate token for the current process: %d\n", GetLastError());
return 1;
}
// Create a mandatory low integrity SID
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_MANDATORY_LABEL_AUTHORITY;
PSID pSid = NULL;
// Can be low, med, high, system, they're all 0x5
if(!AllocateAndInitializeSid(&SIDAuth, 1, SECURITY_MANDATORY_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSid))
{
printf("Failed to create a mandatory low integrity SID: %d\n", GetLastError());
system("PAUSE");
return 1;
}
// Change the integrity level of the duplicate token
TOKEN_MANDATORY_LABEL tml;
tml.Label.Attributes = SE_GROUP_INTEGRITY;
tml.Label.Sid = pSid;
if (!SetTokenInformation(hToken, TokenIntegrityLevel, &tml, sizeof(tml)))
{
// Access denied ??????
printf("Failed to set token information: %d\n", ::GetLastError());
system("PAUSE");
return 1;
}
system("PAUSE");
return 0;
}
token_example.h:
#pragma once
#include <Windows.h>
#include <stdio.h>
// Helper function to adjust our processes current privileges
bool SetThreadProcessPrivilege(LPCWSTR PrivilegeName, bool Enable)
{
HANDLE Token;
TOKEN_PRIVILEGES TokenPrivs;
LUID TempLuid;
bool Result;
if (!LookupPrivilegeValueW(NULL, PrivilegeName, &TempLuid)) return false;
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &Token))
{
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token)) return false;
}
TokenPrivs.PrivilegeCount = 1;
TokenPrivs.Privileges[0].Luid = TempLuid;
TokenPrivs.Privileges[0].Attributes = (Enable ? SE_PRIVILEGE_ENABLED : 0);
Result = (AdjustTokenPrivileges(Token, FALSE, &TokenPrivs, 0, NULL, NULL) && ::GetLastError() == ERROR_SUCCESS);
// Even if AdjustTokenPrivileges returns TRUE, it may not have succeeded
// check last error top confirm
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf(" Unable to set privilege: %S Error: %d \n", PrivilegeName, GetLastError());
CloseHandle(Token);
return FALSE;
}
CloseHandle(Token);
return Result;
}
// Test method, trying to figure out if I was missing any privileges
bool EnableEveryPrivilegeUnderTheSun()
{
if (!SetThreadProcessPrivilege(L"SeBackupPrivilege", true))
{
printf("Failed to enable SeBackupPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeRestorePrivilege", true))
{
printf("Failed to enable SeRestorePrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeIncreaseQuotaPrivilege", true))
{
printf("Failed to enable SeIncreaseQuotaPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeAssignPrimaryTokenPrivilege", true))
{
printf("Failed to enable SeAssignPrimaryTokenPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeTcbPrivilege", true))
{
printf("Failed to enable SeTcbPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeDebugPrivilege", true))
{
printf("Failed to enable SeTcbPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeSecurityPrivilege", true))
{
printf("Failed to enable SeTcbPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeSystemtimePrivilege", true))
{
printf("Failed to enable SeTcbPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeShutdownPrivilege", true))
{
printf("Failed to enable SeTcbPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeSystemEnvironmentPrivilege", true))
{
printf("Failed to enable SeTcbPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeTakeOwnershipPrivilege", true))
{
printf("Failed to enable SeTcbPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeLoadDriverPrivilege", true))
{
printf("Failed to enable SeTcbPrivilege: %d\n", GetLastError());
return false;
}
if (!SetThreadProcessPrivilege(L"SeManageVolumePrivilege", true))
{
printf("Failed to enable SeTcbPrivilege: %d\n", GetLastError());
return false;
}
return true;
}
// Helper function to get a duplicate primary token for the current process
HANDLE GetCurrentProcessPrimaryToken()
{
HANDLE tempproc;
HANDLE realtoken, duplicatetoken;
DWORD accessmode = TOKEN_ALL_ACCESS;
// Enable SeDebugPrivilege.
SetThreadProcessPrivilege(L"SeDebugPrivilege", true);
// Open a handle to the process.
tempproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
if (tempproc == NULL)
{
printf("OpenProcess failed with error %d\n", GetLastError());
return INVALID_HANDLE_VALUE;
}
if (!OpenProcessToken(tempproc, accessmode, &realtoken))
{
printf("OpenProcessToken failed with error %d\n", GetLastError());
CloseHandle(tempproc);
return INVALID_HANDLE_VALUE;
}
CloseHandle(tempproc);
SECURITY_ATTRIBUTES secattr = { 0 };
secattr.nLength = sizeof(secattr);
secattr.bInheritHandle = FALSE;
secattr.lpSecurityDescriptor = NULL;
if (!DuplicateTokenEx(realtoken, MAXIMUM_ALLOWED, &secattr, SecurityImpersonation, TokenPrimary, &duplicatetoken))
{
printf("DuplicateTokenEx failed with error %d\n", GetLastError());
CloseHandle(realtoken);
return INVALID_HANDLE_VALUE;
}
CloseHandle(realtoken);
return duplicatetoken;
}
Not sure why you cannot assign the system IL if you are running as System but the RID you are really looking for is SECURITY_MANDATORY_LOW_RID:
HANDLE hToken, hPrimTok = 0;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken))
{
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, 0, SecurityAnonymous, TokenPrimary, &hPrimTok)) hPrimTok = 0;
CloseHandle(hToken);
}
if (hPrimTok)
{
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_MANDATORY_LABEL_AUTHORITY;
TOKEN_MANDATORY_LABEL tml;
tml.Label.Attributes = SE_GROUP_INTEGRITY;
if (AllocateAndInitializeSid(&SIDAuth, 1, SECURITY_MANDATORY_LOW_RID, 0, 0, 0, 0, 0, 0, 0, &tml.Label.Sid))
{
if (!SetTokenInformation(hPrimTok, TokenIntegrityLevel, &tml, sizeof(tml)))
printf("SetTokenInformation failed, %u\n", GetLastError());
else
{
STARTUPINFOA si = { sizeof (STARTUPINFO) };
PROCESS_INFORMATION pi;
if (CreateProcessAsUserA(hPrimTok, 0, "Notepad.exe", 0, 0, FALSE, 0, 0, 0, &si, &pi))
{
// CloseHandle *2
}
}
FreeSid(tml.Label.Sid);
}
CloseHandle(hPrimTok);
}
Please note that you should also call CreateRestrictedToken to really restrict the new process. Disable all groups and privileges you don't need.

Token impersonation on Windows requires administrator permission Why?

#include <windows.h>
#include <iostream>
#include <Lmcons.h>
#include <conio.h>
BOOL SetPrivilege(
HANDLE hToken, // access
token handle
LPCTSTR lpszPrivilege, // name of
privilege to enable/disable
BOOL bEnablePrivilege // to
enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(
NULL, // lookup
privilege on local system
lpszPrivilege, // privilege
to lookup
&luid)) // receives
LUID of privilege
{
printf("[-]
LookupPrivilegeValue error: %u\n",
GetLastError());
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes =
SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes =
0;
// Enable the privilege or disable
all privileges.
if (!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL))
{
printf("[-]
AdjustTokenPrivileges error:
%u\n",
GetLastError());
return FALSE;
}
if (GetLastError() ==
ERROR_NOT_ALL_ASSIGNED)
{
printf("[-] The token does not
have the specified privilege.
\n");
return FALSE;
}
return TRUE;
}
int main(int argc, char** argv) {
// Print whoami to compare to
thread later
printf("[+] Current user is:
%s\n"); //
(get_username()).c_str());
system("whoami");
// Grab PID from command line
argument
char *pid_c = argv[1];
DWORD PID_TO_IMPERSONATE = 900;
// Initialize variables and
structures
HANDLE tokenHandle = NULL;
HANDLE duplicateTokenHandle =
NULL;
STARTUPINFOW startupInfo;
PROCESS_INFORMATION
processInformation;
ZeroMemory(&startupInfo,
sizeof(STARTUPINFO));
ZeroMemory(&processInformation,
sizeof(PROCESS_INFORMATION));
startupInfo.cb =
sizeof(STARTUPINFO);
// Add SE debug privilege
HANDLE currentTokenHandle =
NULL;
BOOL getCurrentToken =
OpenProcessToken
(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES,
&currentTokenHandle);
if
(SetPrivilege
(currentTokenHandle,
"SeDebugPrivilege", TRUE))
{
printf("[+] SeDebugPrivilege
enabled!\n");
}
// Call OpenProcess(), print
return code and error code
HANDLE processHandle =
OpenProcess
(PROCESS_QUERY_INFORMATION,
true, PID_TO_IMPERSONATE);
if (GetLastError() == NULL)
printf("[+] OpenProcess()
success!\n");
else
{
printf("[-] OpenProcess()
Return Code: %i\n",
processHandle);
printf("[-] OpenProcess()
Error: %i\n",
GetLastError());
}
// Call OpenProcessToken(),
print return code and error
code
BOOL getToken =
OpenProcessToken
(processHandle,
TOKEN_DUPLICATE |
TOKEN_ASSIGN_PRIMARY |
TOKEN_QUERY, &tokenHandle);
if (GetLastError() == NULL)
printf("[+]
OpenProcessToken()
success!\n");
else
{
printf("[-]
OpenProcessToken() Return
Code: %i\n", getToken);
printf("[-] OpenProcessToken()
Error: %i\n",
GetLastError());
}
// Impersonate user in a
thread
BOOL impersonateUser =
ImpersonateLoggedOnUser
(tokenHandle);
if (GetLastError() == NULL)
{
printf("[+]
ImpersonatedLoggedOnUser()
success!\n");
// printf("[+] Current
user is: %s\n",
(get_username()).c_str());
system("whoami");
printf("[+] Reverting thread
to original user context\n");
RevertToSelf();
}
else
{
printf("[-]
ImpersonatedLoggedOnUser()
Return Code: %i\n", getToken);
printf("[-]
ImpersonatedLoggedOnUser()
Error: %i\n", GetLastError());
}
// Call DuplicateTokenEx(),
print return code and error
code
BOOL duplicateToken =
DuplicateTokenEx(tokenHandle,
TOKEN_ADJUST_DEFAULT |
TOKEN_ADJUST_SESSIONID |
TOKEN_QUERY | TOKEN_DUPLICATE
| TOKEN_ASSIGN_PRIMARY, NULL,
SecurityImpersonation,
TokenPrimary,
&duplicateTokenHandle);
if (GetLastError() == NULL)
printf("[+] DuplicateTokenEx()
success!\n");
else
{
printf("[-] DuplicateTokenEx()
Return Code: %i\n",
duplicateToken);
printf("[-] DupicateTokenEx()
Error: %i\n", GetLastError());
}
// Call
CreateProcessWithTokenW(),
print return code and error
code
BOOL createProcess =
CreateProcessWithTokenW
(duplicateTokenHandle,
LOGON_WITH_PROFILE,
L"C:\\Windows\
\System32\\cmd.exe", NULL,
0, NULL, NULL, &startupInfo,
&processInformation);
if (GetLastError() == NULL)
printf("[+] Process
spawned!\n");
else
{
printf("[-]
CreateProcessWithTokenW
Return Code: %i\n",
createProcess);
printf("[-]
CreateProcessWithTokenW Error:
%i\n", GetLastError());
}
getch();
return 0;
}
This is a code that impersonates Winlogon Access token on Windows to give me System rights but it requires me to run the program as administrator before I'm able to impersonate Winlogon...
I believe the reason is based on lack of privileges my program access token has.
If there's anyone that can give me an idea to do this without running as administrator first I'll appreciate.
What it actually requires is that the account holds the SE_IMPERSONATE_NAME privilege and the particular process having it enabled. Normally only highly trusted accounts (an elevated Administrator token or Local System used by default for services) have this privilege but you can assign it to others through the "Local Users and Groups" (or "Active Directory Users and Computers" if using AD) MMC snap-in.

Win32 API: Creating file public for current user but private for everyone else

I am testing the following code in C using Win32 API, which is intended to create a new file that is accessible for the current user but private (not accessible) for everyone else.
For this this a deny all permissions for everyone SID, then for current's user SID I set up the permissions.
The file is created successfully and the permissions are apparently set up successfully (see screenshots below), however when I try to open the file with notepad, it says "access is denied" (My file explorer is running under the same session), also if I open a command prompt and do "type file_created.txt" the same "access is denied" appear.
I can of course, restore manually the permissions since I am administrator, but the idea is to make it work programmatically.
Image with everyone permissions:
Image with current user permissions:
The code:
#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(&current_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;
}
NOTE: I realized the code has memory leaks and other issues, I was just quickly hacking to test the idea.
In the Windows OS explicit deny permissions have a precedence over explicit allow permissions. So since "Everyone" group includes your account, access to the file is denied, even if you enabled it for yourself. In fact you don't need deny rule altogether, if access rights are not set in the object ACL for some user, access will be denied by default.

in windows 10 SetNamedSecurityInfo() is failed to set permissions for files

I am trying to change file permissions in Windows 10 c:\program files(X86) using SetNamedSecurityInfo() from the MSDN API, but it is returning access denied. The same is wroking in Windows 7, but I am not able to do in Windows 10. Please help me to solve this.
bool GrantOwnership(const char *lpszOwnFile)
{
BOOL bRetval = FALSE;
HANDLE hToken = NULL;
PSID pSIDAdmin = NULL;
PSID pSIDEveryone = NULL;
PACL pACL = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld =
SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
const int NUM_ACES = 2;
EXPLICIT_ACCESS ea[NUM_ACES];
DWORD dwRes;
LPTSTR str = (LPTSTR)lpszOwnFile;
// Specify the DACL to use.
// Create a SID for the Everyone group.
if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
SECURITY_WORLD_RID,
0,
0, 0, 0, 0, 0, 0,
&pSIDEveryone))
{
printf("AllocateAndInitializeSid (Everyone) error %u\n",
GetLastError());
goto Cleanup;
}
// Create a SID for the BUILTIN\Administrators group.
if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pSIDAdmin))
{
printf("AllocateAndInitializeSid (Admin) error %u\n",
GetLastError());
goto Cleanup;
}
ZeroMemory(&ea, NUM_ACES * sizeof(EXPLICIT_ACCESS));
// Set read access for Everyone.
ea[0].grfAccessPermissions = GENERIC_READ;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance = NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR)pSIDEveryone;
// Set full control for Administrators.
ea[1].grfAccessPermissions = GENERIC_ALL;
ea[1].grfAccessMode = SET_ACCESS;
ea[1].grfInheritance = NO_INHERITANCE;
ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea[1].Trustee.ptstrName = (LPTSTR)pSIDAdmin;
if (ERROR_SUCCESS != SetEntriesInAcl(NUM_ACES,
ea,
NULL,
&pACL))
{
printf("Failed SetEntriesInAcl\n");
goto Cleanup;
}
// Try to modify the object's DACL.
dwRes = SetNamedSecurityInfo(
(LPTSTR)lpszOwnFile, // name of the object
SE_FILE_OBJECT, // type of object
DACL_SECURITY_INFORMATION, // change only the object's DACL
NULL, NULL, // do not change owner or group
pACL, // DACL specified
NULL); // do not change SACL
if (ERROR_SUCCESS == dwRes)
{
printf("Successfully changed DACL\n");
bRetval = TRUE;
// No more processing needed.
goto Cleanup;
}
if (dwRes != ERROR_ACCESS_DENIED)
{
printf("First SetNamedSecurityInfo call failed: %u\n",
dwRes);
goto Cleanup;
}
// If the preceding call failed because access was denied,
// enable the SE_TAKE_OWNERSHIP_NAME privilege, create a SID for
// the Administrators group, take ownership of the object, and
// disable the privilege. Then try again to set the object's DACL.
// Open a handle to the access token for the calling process.
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES,
&hToken))
{
printf("OpenProcessToken failed: %u\n", GetLastError());
goto Cleanup;
}
// Enable the SE_TAKE_OWNERSHIP_NAME privilege.
if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE))
{
printf("You must be logged on as Administrator.\n");
goto Cleanup;
}
// Set the owner in the object's security descriptor.
dwRes = SetNamedSecurityInfo(
(LPTSTR)lpszOwnFile, // name of the object
SE_FILE_OBJECT, // type of object
OWNER_SECURITY_INFORMATION, // change only the object's owner
pSIDAdmin, // SID of Administrator group
NULL,
NULL,
NULL);
if (dwRes != ERROR_SUCCESS)
{
printf("Could not set owner. Error: %u\n", dwRes);
goto Cleanup;
}
// Disable the SE_TAKE_OWNERSHIP_NAME privilege.
if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE))
{
printf("Failed SetPrivilege call unexpectedly.\n");
goto Cleanup;
}
// Try again to modify the object's DACL,
// now that we are the owner.
dwRes = SetNamedSecurityInfo(
(LPTSTR)lpszOwnFile, // name of the object
SE_FILE_OBJECT, // type of object
DACL_SECURITY_INFORMATION, // change only the object's DACL
NULL, NULL, // do not change owner or group
pACL, // DACL specified
NULL); // do not change SACL
if (dwRes == ERROR_SUCCESS)
{
printf("Successfully changed DACL\n");
bRetval = TRUE;
}
else
{
printf("Second SetNamedSecurityInfo call failed: %u\n",
dwRes);
}
Cleanup:
if (pSIDAdmin)
FreeSid(pSIDAdmin);
if (pSIDEveryone)
FreeSid(pSIDEveryone);
if (pACL)
LocalFree(pACL);
if (hToken)
CloseHandle(hToken);
return bRetval;
}

SetNamedSecurityInfo execution restarts system

I'm trying to change audit settings of a folder.As i was testing my code on different machines i found that SetNamedSecurityInfo call restarts the system.This happened with some machines.A pop up generates which says "Windows has encountered a security issue and will restart in one minute".I'm not able to figure out the reason.Any help will be appreciated!
HANDLE hProcess = GetCurrentProcess();
HANDLE hToken;
DWORD val;
BOOL result;
result = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);
if (result == 0)
{
printf("\nBreak After open process");
return 0;
}
else{
printf("\ncontinue after open process");
}
// Used for reading SACL's
result = SetPrivilege(hToken, SE_SECURITY_NAME, TRUE);
if (result == 0)
{
printf("\nBreak After setprivilege");
return 0;
}
else{
printf("\ncontinue after open process");
}
CloseHandle(hToken);
retval = GetNamedSecurityInfo(file, SE_FILE_OBJECT, SACL_SECURITY_INFORMATION, &owner, NULL, NULL, &sacl, &psd);
if(retval != 0)
{
wcout << "GetNamedSecurityInfo failed with error: " << retval << endl;
return -1;
}
printf("\nBuilt trust successfully before");
BuildTrusteeWithSid(ptrust,psd);
printf("\nBuilt trust successfully");
printf("\ntrying to modify ...");
EXPLICIT_ACCESS ea;
PACL pNewSACL = NULL;
ACCESS_MODE AccessMode = SET_AUDIT_SUCCESS; //SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE
DWORD dwAccessRights = 0X410D0060;
DWORD dwInheritance = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = dwAccessRights;
ea.grfAccessMode = SET_AUDIT_SUCCESS;
ea.grfInheritance = dwInheritance;
ea.Trustee = *(ptrust);
DWORD dwRes = SetEntriesInAcl(1, &ea, sacl, &pNewSACL);
if(dwRes != ERROR_SUCCESS)
{
printf("SetEntriesInAcl() error %u\n", dwRes);
}
else
{
printf("SetEntriesInAcl() is OK\n");
}
dwRes = SetNamedSecurityInfo(file, SE_FILE_OBJECT, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, pNewSACL);
if(dwRes != ERROR_SUCCESS)
{
printf("SetNamedSecurityInfo() error %u\n", dwRes);
}
else
printf("SetNamedSecurityInfo() is OK\n\n");
LocalFree(psd);
There is an global policy entry that controls the shutdown if the system was unable to log security audits.
See:
"Computer Configuration\Windows Settings\Local Policies\Security Options"
"Audit: Shut down system immediately if unable to log security audits"
This could happen in combination with:
"Computer Configuration\Windows Settings\Local Policies\Security Options"
"Audit: Audit the accesss of global system objects"