Created
November 27, 2024 18:02
-
-
Save rolandshoemaker/21a04f56111c61da439f5b5a8def3275 to your computer and use it in GitHub Desktop.
acl.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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