Skip to content

Instantly share code, notes, and snippets.

@rolandshoemaker
Created November 27, 2024 18:02
Show Gist options
  • Save rolandshoemaker/21a04f56111c61da439f5b5a8def3275 to your computer and use it in GitHub Desktop.
Save rolandshoemaker/21a04f56111c61da439f5b5a8def3275 to your computer and use it in GitHub Desktop.
acl.cpp
#include <windows.h>
#include <stdio.h>
#include <aclapi.h>
#include <tchar.h>
#include <sddl.h>
#define S_IRWXU 0000700 /* RWX mask for owner */
#define S_IRUSR 0000400 /* R for owner */
#define S_IWUSR 0000200 /* W for owner */
#define S_IXUSR 0000100 /* X for owner */
#define S_IRWXG 0000070 /* RWX mask for group */
#define S_IRGRP 0000040 /* R for group */
#define S_IWGRP 0000020 /* W for group */
#define S_IXGRP 0000010 /* X for group */
#define S_IRWXO 0000007 /* RWX mask for other */
#define S_IROTH 0000004 /* R for other */
#define S_IWOTH 0000002 /* W for other */
#define S_IXOTH 0000001 /* X for other */
int main()
{
UINT32 unixMode;
DWORD dwRes, dwDisposition;
PSID pOwnerSID = NULL, pOwnerGroupSID = NULL, pEveryoneSID = NULL;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea[3];
SID_IDENTIFIER_AUTHORITY SIDAuthOwner = SECURITY_CREATOR_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIDAuthOwnerGroup = SECURITY_CREATOR_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
// Take unix octal and split it into: owner, group, everyone, using the three well known SIDs:
// * SECURITY_CREATOR_OWNER_RID (owner)
// * SECURITY_CREATOR_GROUP_RID (owner group)
// * SECURITY_WORLD_RID (everyone)
// This... mostly maps to the unix semantics.
ZeroMemory(&ea, 3 * sizeof(EXPLICIT_ACCESS));
// Create a well-known SID for the owner.
if(!AllocateAndInitializeSid(&SIDAuthOwner, 1,
SECURITY_CREATOR_OWNER_RID,
0, 0, 0, 0, 0, 0, 0,
&pOwnerSID))
{
_tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
goto Cleanup;
}
ACCESS_MASK ownerMode;
if (unixMode&S_IRUSR) {
ownerMode |= GENERIC_READ;
}
if (unixMode&S_IWUSR) {
ownerMode |= GENERIC_WRITE;
}
if (unixMode&S_IXUSR) {
ownerMode |= GENERIC_EXECUTE;
}
ea[0].grfAccessPermissions = ownerMode;
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) pOwnerSID;
// Create a well-known SID for the owner group.
if(!AllocateAndInitializeSid(&SIDAuthOwnerGroup, 1,
SECURITY_CREATOR_GROUP_RID,
0, 0, 0, 0, 0, 0, 0,
&pOwnerGroupSID))
{
_tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
goto Cleanup;
}
ACCESS_MASK ownerGroupMode;
if (unixMode&S_IRGRP) {
ownerGroupMode |= GENERIC_READ;
}
if (unixMode&S_IWGRP) {
ownerGroupMode |= GENERIC_WRITE;
}
if (unixMode&S_IXGRP) {
ownerGroupMode |= GENERIC_EXECUTE;
}
ea[1].grfAccessPermissions = ownerGroupMode;
ea[1].grfAccessMode = SET_ACCESS;
ea[1].grfInheritance= NO_INHERITANCE;
ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[1].Trustee.ptstrName = (LPTSTR) pOwnerGroupSID;
// Create a well-known SID for the Everyone group.
if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&pEveryoneSID))
{
_tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
goto Cleanup;
}
ACCESS_MASK everyoneMode;
if (unixMode&S_IROTH) {
everyoneMode |= GENERIC_READ;
}
if (unixMode&S_IWOTH) {
everyoneMode |= GENERIC_WRITE;
}
if (unixMode&S_IXOTH) {
everyoneMode |= GENERIC_EXECUTE;
}
ea[2].grfAccessPermissions = everyoneMode;
ea[2].grfAccessMode = SET_ACCESS;
ea[2].grfInheritance= NO_INHERITANCE;
ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[2].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[2].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
// Create a new ACL that contains the new ACEs.
dwRes = SetEntriesInAcl(3, ea, NULL, &pACL);
if (ERROR_SUCCESS != dwRes)
{
_tprintf(_T("SetEntriesInAcl Error %u\n"), GetLastError());
goto Cleanup;
}
// 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
pACL,
FALSE)) // not a default DACL
{
_tprintf(_T("SetSecurityDescriptorDacl Error %u\n"),
GetLastError());
goto Cleanup;
}
LPSTR sdStr;
PULONG sdLen;
if (!ConvertSecurityDescriptorToStringSecurityDescriptorA(
pSD,
SECURITY_DESCRIPTOR_REVISION, // SDDL_REVISION_1 ?
0, // SecurityInformation
&sdStr,
sdLen)) {
_tprintf(_T("ConvertSecurityDescriptorToStringSecurityDescriptorA Error %u\n"),
GetLastError());
goto Cleanup;
}
_tprintf(_T("%s %d\n"), sdStr, IsValidSecurityDescriptor(pSD));
Cleanup:
if (pOwnerSID)
FreeSid(pOwnerSID);
if (pOwnerGroupSID)
FreeSid(pOwnerGroupSID);
if (pEveryoneSID)
FreeSid(pEveryoneSID);
if (pACL)
LocalFree(pACL);
if (pSD)
LocalFree(pSD);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment