0

I have to create a folder or modify security attributes if folder already exist. I need to set permissions to folder so that only LocalAccount has full access and other user accounts should not have any access to this folder. As of now, I'm trying the below code,but couldn't achieve.

Updated: I guess, any existing ACEs causing problem(if folder exist) or Any ACEs which are inherited from parent directory causing problem?

DWORD dwRes;
PSID pEveryoneSID = NULL, pLocalSystemSID = NULL;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea[2];
SID_IDENTIFIER_AUTHORITY SIDAuthWorld =
    SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
SECURITY_ATTRIBUTES sa;

// Create a well-known SID for the Everyone group.
if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
    SECURITY_WORLD_RID,
    0, 0, 0, 0, 0, 0, 0,
    &pEveryoneSID))
{
    LOGERROR(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
    goto Cleanup;
}

// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will deny Everyone GENERIC_ALL to the folder.
ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
ea[0].grfAccessPermissions = GENERIC_ALL;   
ea[0].grfAccessMode = DENY_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)pEveryoneSID;

// Create a SID for the LocalSystem account(A special account used by the operating system) group.
if (!AllocateAndInitializeSid(&SIDAuthNT, 1,
    SECURITY_LOCAL_SYSTEM_RID,
    0, 0, 0, 0, 0, 0, 0,
    &pLocalSystemSID))
{
    LOGERROR(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
    goto Cleanup;
}

// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will allow the  LocalSystem full access to the folder
ea[1].grfAccessPermissions = GENERIC_ALL;
ea[1].grfAccessMode = GRANT_ACCESS;   // or SET_ACCESS ?
ea[1].grfInheritance = NO_INHERITANCE;
ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;     
ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;       //not sure what to use here for localAccount
ea[1].Trustee.ptstrName = (LPTSTR)pLocalSystemSID;

// Create a new ACL that contains the new ACEs.
dwRes = SetEntriesInAcl(2, ea, NULL, &pACL);
if (ERROR_SUCCESS != dwRes)
{
    LOGERROR(_T("SetEntriesInAcl Error %u\n"), GetLastError());
    goto Cleanup;
}

// Initialize a security descriptor.  
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
    SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD)
{
    LOGERROR(_T("LocalAlloc Error %u\n"), GetLastError());
    goto Cleanup;
}

if (!InitializeSecurityDescriptor(pSD,
    SECURITY_DESCRIPTOR_REVISION))
{
    LOGERROR(_T("InitializeSecurityDescriptor Error %u\n"),
        GetLastError());
    goto Cleanup;
}

// Add the ACL to the security descriptor. 
if (!SetSecurityDescriptorDacl(pSD,
    TRUE,     // bDaclPresent flag   
    pACL,
    FALSE))   // not a default DACL 
{
    LOGERROR(_T("SetSecurityDescriptorDacl Error %u\n"),
        GetLastError());
    goto Cleanup;
}

// Initialize a security attributes structure.
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;

int rVal = SHCreateDirectoryExW(NULL, m_tcProxyData, &sa);
Raj
  • 263
  • 1
  • 2
  • 14
  • What exactly isn't working? I tried to code you posted and it worked OK; a folder was created that had a deny for Everyone with a single allow for System. – Ralara Oct 05 '15 at 10:45
  • As of now, a normal user is able to access that folder. I mean it is not denying for access to normal user. – Raj Oct 05 '15 at 11:54
  • 1
    You aren't building the SYSTEM SID correctly; the second argument should be 1, not 2. And "deny to everybody but system" isn't actually a valid ACL - the deny overrides the allow, so the upshot is just "deny to everybody". But otherwise the code works fine for me, access is denied as expected. Are you sure the directory didn't already exist? – Harry Johnston Oct 06 '15 at 00:55
  • My understanding says, explict allow overrides group deny, here i guess everybody means a group. [to answer your question, directory is already exist, also i corrected those argument mistake from 2 to 1] – Raj Oct 06 '15 at 07:04
  • if folder is already exist, the existing ACLs may create problem. if so, how Can i clear existing ACLs before adding new ACLs. – Raj Oct 06 '15 at 09:13
  • You can't change the permissions on an existing directory using `SHCreateDirectoryExW`. Use `SetFileSecurity` instead. And no, it doesn't make any difference whether the ACE is for a group or a user, deny permissions still override allow permissions. – Harry Johnston Oct 07 '15 at 02:21
  • 1
    (The ACL should only contain the allow permission; the system will deny everybody else access by default. Make sure you use the `PROTECTED_DACL_SECURITY_INFORMATION` flag to disable inherited permissions.) – Harry Johnston Oct 07 '15 at 02:23

0 Answers0