|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1996.
//
// File: ACLAPI.C
//
// Contents: Implements the drt for MARTA and Win32Ex APIs
//
// History: 14-Sep-96 MacM Created
//
// Notes:
//
//----------------------------------------------------------------------------
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <aclapi.h>
#include <marta.h>
#include <seopaque.h>
#include <ntrtl.h>
#define EVERYONE L"EVERYONE"
#define EVERYONE_A "EVERYONE"
#define GUEST L"GUEST"
#define GUEST_A "GUEST"
#define GUEST_COMPARE L"GUEST"
#define SYSTEM L"SYSTEM"
#define SYSTEM_A "SYSTEM"
#define MAX_LINE 256
//
// Globals
//
BOOL fVerbose = FALSE;
//
// Function prototypes
//
DWORD Nt4BuildW(PACL *ppAcl); DWORD Nt4BuildA(PACL *ppAcl); DWORD Nt5BuildW(PACTRL_ACCESSW *ppAccess); DWORD Nt5BuildA(PACTRL_ACCESSA *ppAccess); DWORD Nt4DrtW(PACL pAcl, PSTR pszObject, SE_OBJECT_TYPE ObjType);
DWORD Nt4DrtA(PACL pAcl, PSTR pszObject, SE_OBJECT_TYPE ObjType);
DWORD Nt5DrtW(PACTRL_ACCESSW pAccess, PSTR pszObject, SE_OBJECT_TYPE ObjType);
DWORD Nt5DrtA(PACTRL_ACCESSA pAccess, PSTR pszObject, SE_OBJECT_TYPE ObjType);
VOID ConvertAccessMaskToAccessRight(IN ACCESS_MASK AccessMask, OUT PACCESS_RIGHTS pAccessRight); //+---------------------------------------------------------------------------
//
// Function: main
//
// Synopsis: The main
//
// Arguments: [IN argc] -- Count of arguments
// [IN argv] -- List of arguments
//
// Returns: 0 -- Success
// non-0 -- Failure
//
//----------------------------------------------------------------------------
__cdecl main(INT argc, CHAR *argv[]) {
DWORD dwErr = ERROR_SUCCESS; PACL pNt4AclW = NULL, pNt4AclA = NULL; PACTRL_ACCESSW pNt5AccessW = NULL; PACTRL_ACCESSA pNt5AccessA = NULL; FILE *fp = NULL; SE_OBJECT_TYPE ObjType; CHAR szBuff[MAX_LINE];
if (argc < 2 || argc > 3) { fprintf(stderr,"USAGE: aclexdrt input_file [verbose]\n"); exit(1); }
if(argc == 3) { fVerbose = TRUE; }
AccProvInit(dwErr);
//
// Do the Nt4 style build routines
//
if(dwErr == ERROR_SUCCESS) { dwErr = Nt4BuildW(&pNt4AclW); }
if(dwErr == ERROR_SUCCESS) { dwErr = Nt4BuildA(&pNt4AclA); }
if(dwErr == ERROR_SUCCESS) { dwErr = Nt5BuildW(&pNt5AccessW); }
if(dwErr == ERROR_SUCCESS) { dwErr = Nt5BuildA(&pNt5AccessA); }
//
// Now, open the file and process it...
//
if(dwErr == ERROR_SUCCESS) { fp = fopen(argv[1], "r"); if(fp == NULL) { fprintf(stderr, "File %s not found\n", argv[1]); dwErr = ERROR_FILE_NOT_FOUND; }
while(dwErr == ERROR_SUCCESS && fgets(szBuff, MAX_LINE, fp) != NULL) { BOOL fIsDSObj = FALSE; PSTR pszType; PSTR pszObject = strtok(szBuff, " "); if(pszObject != NULL) { pszType = strtok(NULL," \n\r\0"); }
if(pszObject == NULL && pszType == NULL) { continue; } else if(pszObject == NULL || pszType == NULL) { fprintf(stderr, "Invalid entry %s in input file %s\n", szBuff, argv[1]); dwErr = ERROR_INVALID_DATA; } else { if(_stricmp(pszType, "FILE") == 0) { ObjType = SE_FILE_OBJECT; } else if(_stricmp(pszType, "SERVICE") == 0) { ObjType = SE_SERVICE; } else if(_stricmp(pszType, "PRINTER") == 0) { ObjType = SE_PRINTER; } else if (_stricmp(pszType, "REGISTRY_KEY") == 0) { ObjType = SE_REGISTRY_KEY; } else if(_stricmp(pszType, "SHARE") == 0) { ObjType = SE_LMSHARE; } else if(_stricmp(pszType, "DSOBJ") == 0) { ObjType = SE_DS_OBJECT; fIsDSObj = TRUE; } else if(_stricmp(pszType, "DSOBJALL") == 0) { ObjType = SE_DS_OBJECT_ALL; fIsDSObj = TRUE; } else { fprintf(stderr, "Invalid object type %s\n", pszType); dwErr = ERROR_INVALID_DATA; } }
//
// If it worked, do the tests...
//
if(dwErr == ERROR_SUCCESS && fIsDSObj == FALSE) { dwErr = Nt4DrtW(pNt4AclW, pszObject, ObjType); }
if(dwErr == ERROR_SUCCESS && fIsDSObj == FALSE) { dwErr = Nt4DrtA(pNt4AclA, pszObject, ObjType); }
if(dwErr == ERROR_SUCCESS) { dwErr = Nt5DrtW(pNt5AccessW, pszObject, ObjType); }
if(dwErr == ERROR_SUCCESS) { dwErr = Nt5DrtA(pNt5AccessA, pszObject, ObjType); } }
if(fp != NULL) { fclose(fp); }
} LocalFree(pNt4AclW); LocalFree(pNt4AclA); LocalFree(pNt5AccessW); LocalFree(pNt5AccessA);
if(dwErr == ERROR_SUCCESS) { printf("Success\n"); } else { printf("Failure: %lu\n", dwErr); }
return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: CompareAcls
//
// Synopsis: Compares 2 acls for equality
//
// Arguments: [pAcl1] -- First ACL
// [pAcl2] -- Second ACL
//
// Returns: ERROR_SUCCESS -- They match
// ERROR_INVALID_DATA -- They don't match
//
//----------------------------------------------------------------------------
DWORD CompAcls(PACL pAcl1, PACL pAcl2) { DWORD dwErr = ERROR_SUCCESS;
ACL_SIZE_INFORMATION AclSize1, AclSize2; ACL_REVISION_INFORMATION AclRev1, AclRev2; PKNOWN_ACE pAce1, pAce2; PSID pSid1, pSid2; DWORD iIndex;
if(pAcl1 == NULL || pAcl2 == NULL) { if(pAcl1 != pAcl2) { if(fVerbose) { fprintf(stderr,"Acl %lu is NULL\n", pAcl1 == NULL ? 1 : 2); } dwErr = ERROR_INVALID_DATA; } } else { if(GetAclInformation(pAcl1, &AclRev1, sizeof(ACL_REVISION_INFORMATION), AclRevisionInformation) == FALSE || GetAclInformation(pAcl2, &AclRev2, sizeof(ACL_REVISION_INFORMATION), AclRevisionInformation) == FALSE) { return(ERROR_INVALID_DATA); }
if(GetAclInformation(pAcl1, &AclSize1, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) == FALSE || GetAclInformation(pAcl2, &AclSize2, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) == FALSE) { return(ERROR_INVALID_DATA); }
if(AclRev1.AclRevision != AclRev2.AclRevision) { if(fVerbose) { fprintf(stderr, "Revision mismatch: %lu %lu\n", AclRev1.AclRevision, AclRev2.AclRevision); } dwErr = ERROR_INVALID_DATA; }
if(AclSize1.AceCount != AclSize2.AceCount) { if(fVerbose) { fprintf(stderr, "AceCount mismatch: %lu %lu\n", AclSize1.AceCount, AclSize2.AceCount); } dwErr = ERROR_INVALID_DATA; }
if(AclSize1.AclBytesInUse != AclSize2.AclBytesInUse) { if(fVerbose) { fprintf(stderr, "BytesInUse mismatch: %lu %lu\n", AclSize1.AclBytesInUse, AclSize2.AclBytesInUse); } dwErr = ERROR_INVALID_DATA; }
if(pAcl1->Sbz1 != pAcl2->Sbz1) { if(fVerbose) { fprintf(stderr, "Acl flags mismatch: %lu %lu\n", pAcl1->Sbz1, pAcl2->Sbz1); } dwErr = ERROR_INVALID_DATA; }
if(dwErr != ERROR_SUCCESS) { return(dwErr); }
//
// Now, compare all of the aces
//
pAce1 = FirstAce(pAcl1); pAce2 = FirstAce(pAcl2); for(iIndex = 0; iIndex < pAcl1->AceCount && dwErr == ERROR_SUCCESS; iIndex++) { ACCESS_RIGHTS Rights1, Rights2;
if(fVerbose) { printf("Ace %lu\n", iIndex); }
if(pAce1->Header.AceType != pAce2->Header.AceType) { if(fVerbose) { fprintf(stderr, "\tAceType mismatch: %lu %lu\n", pAce1->Header.AceType, pAce2->Header.AceType); } dwErr = ERROR_INVALID_DATA; }
if(pAce1->Header.AceFlags != pAce2->Header.AceFlags) { if(fVerbose) { fprintf(stderr, "\tAceType mismatch: %lu %lu\n", pAce1->Header.AceFlags, pAce2->Header.AceFlags); } dwErr = ERROR_INVALID_DATA; }
if(pAce1->Header.AceSize != pAce2->Header.AceSize) { if(fVerbose) { fprintf(stderr, "\tAceType mismatch: %lu %lu\n", pAce1->Header.AceSize, pAce2->Header.AceSize); } dwErr = ERROR_INVALID_DATA; }
ConvertAccessMaskToAccessRight(pAce1->Mask, &Rights1); ConvertAccessMaskToAccessRight(pAce2->Mask, &Rights2); if(Rights1 != Rights1) { if(fVerbose) { fprintf(stderr, "\tAccessMask mismatch: %lu %lu\n", Rights1, Rights2); } dwErr = ERROR_INVALID_DATA; }
if(!RtlEqualSid((PSID)&(pAce1->SidStart), (PSID)&(pAce2->SidStart))) { if(fVerbose) { fprintf(stderr, "\tSids don't match\n"); } dwErr = ERROR_INVALID_DATA; }
pAce1 = NextAce(pAce1); pAce2 = NextAce(pAce2); } }
return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: CompStringsW
//
// Synopsis: Compares 2 string pointers for equality
//
// Arguments: [pwszStr1] -- First string
// [pwszStr2] -- Second string
//
// Returns: ERROR_SUCCESS -- They match
// ERROR_INVALID_DATA -- They don't match
//
//----------------------------------------------------------------------------
DWORD CompStringsW(PWSTR pwszStr1, PWSTR pwszStr2) { if(pwszStr1 != NULL && pwszStr2 != NULL) { if(_wcsicmp(pwszStr1, pwszStr2) == 0) { return(ERROR_SUCCESS); } } else { if(pwszStr1 == NULL) { return(ERROR_SUCCESS); } }
return(ERROR_INVALID_DATA); }
//+---------------------------------------------------------------------------
//
// Function: CompStringsA
//
// Synopsis: Compares 2 string pointers for equality
//
// Arguments: [pszStr1] -- First string
// [pszStr2] -- Second string
//
// Returns: ERROR_SUCCESS -- They match
// ERROR_INVALID_DATA -- They don't match
//
//----------------------------------------------------------------------------
DWORD CompStringsA(PSTR pszStr1, PSTR pszStr2) { if(pszStr1 != NULL && pszStr2 != NULL) { if(_stricmp(pszStr1, pszStr2) == 0) { return(ERROR_SUCCESS); } } else { if(pszStr1 == NULL) { return(ERROR_SUCCESS); } }
return(ERROR_INVALID_DATA); }
//+---------------------------------------------------------------------------
//
// Function: CompAccessW
//
// Synopsis: Compares 2 WIDE access lists for equality
//
// Arguments: [pAccess1] -- First list
// [pAccess2] -- Second list
//
// Returns: ERROR_SUCCESS -- They match
// ERROR_INVALID_DATA -- They don't match
//
//----------------------------------------------------------------------------
DWORD CompAccessW(PACTRL_ACCESSW pAccess1, PACTRL_ACCESSW pAccess2) { DWORD dwErr = ERROR_SUCCESS; ULONG iIndex = 0;
if(pAccess1 == NULL || pAccess2 == NULL) { if(pAccess1 != pAccess2) { if(fVerbose) { fprintf(stderr,"Access %lu is NULL\n", pAccess1 == NULL ? 1 : 2); } dwErr = ERROR_INVALID_DATA; } } else { PACTRL_ACCESS_ENTRY_LISTW pAAEL1; PACTRL_ACCESS_ENTRY_LISTW pAAEL2;
dwErr = CompStringsW((PWSTR)pAccess1->pPropertyAccessList[0].lpProperty, (PWSTR)pAccess2->pPropertyAccessList[0].lpProperty); if(dwErr != ERROR_SUCCESS) { return(dwErr); }
pAAEL1 = pAccess1->pPropertyAccessList[0].pAccessEntryList; pAAEL2 = pAccess2->pPropertyAccessList[0].pAccessEntryList; if(pAAEL1->cEntries != pAAEL2->cEntries) { dwErr = ERROR_INVALID_DATA; if(fVerbose) { fprintf(stderr, "cEntries: %lu %lu\n", pAAEL1->cEntries, pAAEL2->cEntries); } } else { //
// Compare all of the entries
//
for(iIndex = 0; iIndex < pAAEL1->cEntries; iIndex++) { if(_wcsicmp(pAAEL1->pAccessList[iIndex].Trustee.ptstrName, pAAEL1->pAccessList[iIndex].Trustee.ptstrName) != 0) { if(fVerbose) { fprintf(stderr, "Trustees: %ws %ws\n", pAAEL1->pAccessList[iIndex].Trustee.ptstrName, pAAEL2->pAccessList[iIndex].Trustee.ptstrName); } dwErr = ERROR_INVALID_DATA; continue; }
if(pAAEL1->pAccessList[iIndex].fAccessFlags != pAAEL1->pAccessList[iIndex].fAccessFlags) { if(fVerbose) { fprintf(stderr, "AccessFlags: %lu %lu\n", pAAEL1->pAccessList[iIndex].fAccessFlags, pAAEL2->pAccessList[iIndex].fAccessFlags); } dwErr = ERROR_INVALID_DATA; continue; }
if(pAAEL1->pAccessList[iIndex].Access != pAAEL1->pAccessList[iIndex].Access) { if(fVerbose) { fprintf(stderr, "Access: %lu %lu\n", pAAEL1->pAccessList[iIndex].Access, pAAEL2->pAccessList[iIndex].Access); } dwErr = ERROR_INVALID_DATA; continue; }
if(pAAEL1->pAccessList[iIndex].ProvSpecificAccess != pAAEL1->pAccessList[iIndex].ProvSpecificAccess) { if(fVerbose) { fprintf(stderr, "ProvSpecificAccess: %lu %lu\n", pAAEL1->pAccessList[iIndex].ProvSpecificAccess, pAAEL2->pAccessList[iIndex].ProvSpecificAccess); } dwErr = ERROR_INVALID_DATA; continue; }
if(pAAEL1->pAccessList[iIndex].Inheritance != pAAEL1->pAccessList[iIndex].Inheritance) { if(fVerbose) { fprintf(stderr, "AccessFlags: %lu %lu\n", pAAEL1->pAccessList[iIndex].Inheritance, pAAEL2->pAccessList[iIndex].Inheritance); } dwErr = ERROR_INVALID_DATA; continue; }
//
// The inheritance property
//
dwErr = CompStringsW( (PWSTR)pAAEL1->pAccessList[iIndex].lpInheritProperty, (PWSTR)pAAEL1->pAccessList[iIndex].lpInheritProperty);
if(dwErr == ERROR_SUCCESS && fVerbose) { printf("AccessEntry %lu\n", iIndex); } } } }
return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: CompAccessA
//
// Synopsis: Compares 2 ANSI access lists for equality
//
// Arguments: [pAccess1] -- First list
// [pAccess2] -- Second list
//
// Returns: ERROR_SUCCESS -- They match
// ERROR_INVALID_DATA -- They don't match
//
//----------------------------------------------------------------------------
DWORD CompAccessA(PACTRL_ACCESSA pAccess1, PACTRL_ACCESSA pAccess2) { DWORD dwErr = ERROR_SUCCESS; ULONG iIndex = 0;
if(pAccess1 == NULL || pAccess2 == NULL) { if(pAccess1 != pAccess2) { if(fVerbose) { fprintf(stderr,"Access %lu is NULL\n", pAccess1 == NULL ? 1 : 2); } dwErr = ERROR_INVALID_DATA; } } else { PACTRL_ACCESS_ENTRY_LISTA pAAEL1; PACTRL_ACCESS_ENTRY_LISTA pAAEL2;
dwErr = CompStringsA((PSTR)pAccess1->pPropertyAccessList[0].lpProperty, (PSTR)pAccess2->pPropertyAccessList[0].lpProperty); if(dwErr != ERROR_SUCCESS) { return(dwErr); }
pAAEL1 = pAccess1->pPropertyAccessList[0].pAccessEntryList; pAAEL2 = pAccess2->pPropertyAccessList[0].pAccessEntryList; if(pAAEL1->cEntries != pAAEL2->cEntries) { dwErr = ERROR_INVALID_DATA; if(fVerbose) { fprintf(stderr, "cEntries: %lu %lu\n", pAAEL1->cEntries, pAAEL2->cEntries); } } else { //
// Compare all of the entries
//
for(iIndex = 0; iIndex < pAAEL1->cEntries; iIndex++) { if(_stricmp(pAAEL1->pAccessList[iIndex].Trustee.ptstrName, pAAEL1->pAccessList[iIndex].Trustee.ptstrName) != 0) { if(fVerbose) { fprintf(stderr, "Trustees: %ws %ws\n", pAAEL1->pAccessList[iIndex].Trustee.ptstrName, pAAEL2->pAccessList[iIndex].Trustee.ptstrName); } dwErr = ERROR_INVALID_DATA; continue; }
if(pAAEL1->pAccessList[iIndex].fAccessFlags != pAAEL1->pAccessList[iIndex].fAccessFlags) { if(fVerbose) { fprintf(stderr, "AccessFlags: %lu %lu\n", pAAEL1->pAccessList[iIndex].fAccessFlags, pAAEL2->pAccessList[iIndex].fAccessFlags); } dwErr = ERROR_INVALID_DATA; continue; }
if(pAAEL1->pAccessList[iIndex].Access != pAAEL1->pAccessList[iIndex].Access) { if(fVerbose) { fprintf(stderr, "Access: %lu %lu\n", pAAEL1->pAccessList[iIndex].Access, pAAEL2->pAccessList[iIndex].Access); } dwErr = ERROR_INVALID_DATA; continue; }
if(pAAEL1->pAccessList[iIndex].ProvSpecificAccess != pAAEL1->pAccessList[iIndex].ProvSpecificAccess) { if(fVerbose) { fprintf(stderr, "ProvSpecificAccess: %lu %lu\n", pAAEL1->pAccessList[iIndex].ProvSpecificAccess, pAAEL2->pAccessList[iIndex].ProvSpecificAccess); } dwErr = ERROR_INVALID_DATA; continue; }
if(pAAEL1->pAccessList[iIndex].Inheritance != pAAEL1->pAccessList[iIndex].Inheritance) { if(fVerbose) { fprintf(stderr, "AccessFlags: %lu %lu\n", pAAEL1->pAccessList[iIndex].Inheritance, pAAEL2->pAccessList[iIndex].Inheritance); } dwErr = ERROR_INVALID_DATA; continue; }
//
// The inheritance property
//
dwErr = CompStringsA( (PSTR)pAAEL1->pAccessList[iIndex].lpInheritProperty, (PSTR)pAAEL1->pAccessList[iIndex].lpInheritProperty);
if(dwErr == ERROR_SUCCESS && fVerbose) { printf("AccessEntry %lu\n", iIndex); } } } }
return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: DumpAccessW
//
// Synopsis: Dumps an ACTRL_ACCESSW structure to the screen
//
// Arguments: [pAccess] -- Structure to dump
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID DumpAccessW(PACTRL_ACCESSW pAccess) { if(fVerbose) { ULONG iProp, iEnt; printf("\tEntries: %lu\n", pAccess->cEntries); for(iProp = 0; iProp < pAccess->cEntries; iProp++) { printf("\t\tProperty: %ws\n", pAccess->pPropertyAccessList[iProp].lpProperty == NULL ? L"NULL" : pAccess->pPropertyAccessList[iProp].lpProperty); printf("\t\tFlags: %lu\n", pAccess->pPropertyAccessList[iProp].fListFlags); if(pAccess->pPropertyAccessList[iProp].pAccessEntryList == NULL) { printf("\t\tpAccessEntryList: NULL\n"); } else { PACTRL_ACCESS_ENTRYW pAE= pAccess->pPropertyAccessList[iProp]. pAccessEntryList->pAccessList; printf("\t\t\tcEntries: %lu\n", pAccess->pPropertyAccessList[iProp].pAccessEntryList-> cEntries);
for(iEnt = 0; iEnt < pAccess->pPropertyAccessList[iProp]. pAccessEntryList->cEntries; iEnt++) { printf("\t\t\tEntry %lu:\n", iEnt); printf("\t\t\t\tTrustee.Name: %ws\n", pAE[iEnt].Trustee.ptstrName); printf("\t\t\t\tfAccessFlags: %lu\n", pAE[iEnt].fAccessFlags); printf("\t\t\t\tAccess: 0x%lx\n", pAE[iEnt].Access); printf("\t\t\t\tProvSpecificAccess: %lu\n", pAE[iEnt].ProvSpecificAccess); printf("\t\t\t\tInheritance: %lu\n", pAE[iEnt].Inheritance); printf("\t\t\t\tlpInheritProperty: %ws\n", pAE[iEnt].lpInheritProperty == NULL ? L"" : pAE[iEnt].lpInheritProperty); } } } } }
#define BUILD_COUNT 5
//+---------------------------------------------------------------------------
//
// Function: Nt4BuildW
//
// Synopsis: Builds an ACL using the NT4 API WIDE apis
//
// Arguments: [ppAcl] -- Acl to build
//
// Returns: ERROR_SUCCESS -- Everything worked
// ERROR_INVALID_DATA -- One of the compares failed
//
//----------------------------------------------------------------------------
DWORD Nt4BuildW(PACL *ppAcl) { DWORD dwErr = ERROR_SUCCESS; ULONG cCount; EXPLICIT_ACCESS_W EAW; PEXPLICIT_ACCESS_W pEAW; PACL pAcl = NULL, pNewAcl; ULONG iIndex, iVer;
PWSTR rgTrustees[BUILD_COUNT] = {EVERYONE, SYSTEM, GUEST, EVERYONE, SYSTEM};
DWORD rgAccess[BUILD_COUNT] = {GENERIC_ALL | 0x8, GENERIC_ALL, GENERIC_ALL | 0x8, GENERIC_ALL | 0x8, 0};
ACCESS_MODE rgMode[BUILD_COUNT] = {SET_ACCESS, DENY_ACCESS, SET_ACCESS, SET_ACCESS, REVOKE_ACCESS};
DWORD rgInherit[BUILD_COUNT] = {NO_INHERITANCE, NO_INHERITANCE, SUB_CONTAINERS_AND_OBJECTS_INHERIT, NO_INHERITANCE, SUB_CONTAINERS_AND_OBJECTS_INHERIT};
DWORD rgSrch[BUILD_COUNT][BUILD_COUNT + 1] = {{1, 0}, {2, 1, 0}, {3, 1, 2, 0}, {3, 1, 3, 2}, {2, 3, 2}}; if(fVerbose) { printf("Nt4BuildW\n"); }
//
// We'll do this in a loop, since we have BUILD_COUNT different builds to do
//
for(iIndex = 0; iIndex < BUILD_COUNT && dwErr == ERROR_SUCCESS; iIndex++) { //
// Build the new entry
//
BuildExplicitAccessWithNameW(&EAW, rgTrustees[iIndex], rgAccess[iIndex], rgMode[iIndex], rgInherit[iIndex]);
dwErr = SetEntriesInAclW(1, &EAW, pAcl, &pNewAcl);
if(dwErr == ERROR_SUCCESS) { LocalFree(pAcl); pAcl = pNewAcl;
//
// Get the explicit entries, and we'll verify them...
//
dwErr = GetExplicitEntriesFromAclW(pAcl, &cCount, &pEAW); if(dwErr == ERROR_SUCCESS) { PDWORD pSrch = rgSrch[iIndex]; ULONG cExpected = pSrch[0];
if(cCount != cExpected) { dwErr = ERROR_INVALID_DATA; if(fVerbose) { printf("\tCount mismatched: %lu, expected %lu\n", cCount, cExpected); } } else { //
// verify the rest of the data
//
for(iVer = 0; iVer < cExpected; iVer++) { ULONG iSrch = pSrch[iVer + 1]; if(_wcsicmp(pEAW[iVer].Trustee.ptstrName, rgTrustees[iSrch]) != 0) { dwErr = ERROR_INVALID_DATA; if(fVerbose) { printf("\tTrustee mismatch[%lu]: %ws, expected " "%ws\n", iVer, pEAW[iVer].Trustee.ptstrName, rgTrustees[iSrch]); } } } }
if(dwErr == ERROR_SUCCESS) { if(fVerbose) { printf("\tCount: %lu\n", cCount); } } LocalFree(pEAW); } else { fprintf(stderr, "\tNt4BuildW: SetEntriesInAclW failed with %lu\n", dwErr); } } else { fprintf(stderr,"\tNt4BuildW: SetEntriesInAclW failed with %lu\n", dwErr); }
}
if(dwErr == ERROR_SUCCESS) { *ppAcl = pAcl; } else { LocalFree(pAcl); }
return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: Nt4BuildA
//
// Synopsis: Builds an ACL using the NT4 API ANSI apis
//
// Arguments: [ppAcl] -- Acl to build
//
// Returns: ERROR_SUCCESS -- Everything worked
// ERROR_INVALID_DATA -- One of the compares failed
//
//----------------------------------------------------------------------------
DWORD Nt4BuildA(PACL *ppAcl) { DWORD dwErr = ERROR_SUCCESS; ULONG cCount; EXPLICIT_ACCESS_A EAA; PEXPLICIT_ACCESS_A pEAA; PACL pAcl = NULL, pNewAcl; ULONG iIndex, iVer;
PSTR rgTrustees[BUILD_COUNT] = {EVERYONE_A, SYSTEM_A, GUEST_A, EVERYONE_A, SYSTEM_A};
DWORD rgAccess[BUILD_COUNT] = {GENERIC_ALL | 0x8, GENERIC_ALL, GENERIC_ALL | 0x8, GENERIC_ALL | 0x8, 0};
ACCESS_MODE rgMode[BUILD_COUNT] = {SET_ACCESS, DENY_ACCESS, SET_ACCESS, SET_ACCESS, REVOKE_ACCESS};
DWORD rgInherit[BUILD_COUNT] = {NO_INHERITANCE, NO_INHERITANCE, SUB_CONTAINERS_AND_OBJECTS_INHERIT, NO_INHERITANCE, SUB_CONTAINERS_AND_OBJECTS_INHERIT};
DWORD rgSrch[BUILD_COUNT][BUILD_COUNT + 1] = {{1, 0}, {2, 1, 0}, {3, 1, 2, 0}, {3, 1, 3, 2}, {2, 3, 2}}; if(fVerbose) { printf("Nt4BuildA\n"); }
//
// We'll do this in a loop, since we have BUILD_COUNT different builds to do
//
for(iIndex = 0; iIndex < BUILD_COUNT && dwErr == ERROR_SUCCESS; iIndex++) { //
// Build the new entry
//
BuildExplicitAccessWithNameA(&EAA, rgTrustees[iIndex], rgAccess[iIndex], rgMode[iIndex], rgInherit[iIndex]);
dwErr = SetEntriesInAclA(1, &EAA, pAcl, &pNewAcl);
if(dwErr == ERROR_SUCCESS) { LocalFree(pAcl); pAcl = pNewAcl;
//
// Get the explicit entries, and we'll verify them...
//
dwErr = GetExplicitEntriesFromAclA(pAcl, &cCount, &pEAA); if(dwErr == ERROR_SUCCESS) { PDWORD pSrch = rgSrch[iIndex]; ULONG cExpected = pSrch[0];
if(cCount != cExpected) { dwErr = ERROR_INVALID_DATA; if(fVerbose) { printf("\tCount mismatched: %lu, expected %lu\n", cCount, cExpected); } } else { //
// verify the rest of the data
//
for(iVer = 0; iVer < cExpected; iVer++) { ULONG iSrch = pSrch[iVer + 1]; if(_stricmp(pEAA[iVer].Trustee.ptstrName, rgTrustees[iSrch]) != 0) { dwErr = ERROR_INVALID_DATA; if(fVerbose) { printf("\tTrustee mismatch[%lu]: %s, expected " "%s\n", iVer, pEAA[iVer].Trustee.ptstrName, rgTrustees[iSrch]); } } } }
if(dwErr == ERROR_SUCCESS) { if(fVerbose) { printf("\tCount: %lu\n", cCount); } }
LocalFree(pEAA); } else { fprintf(stderr, "\tNt4BuildA: SetEntriesInAclA failed with %lu\n", dwErr); } } else { fprintf(stderr,"\tNt4BuildA: SetEntriesInAclA failed with %lu\n", dwErr); }
}
if(dwErr == ERROR_SUCCESS) { *ppAcl = pAcl; } else { LocalFree(pAcl); }
return(dwErr); }
#undef BUILD_COUNT
#define BUILD_COUNT 6
//+---------------------------------------------------------------------------
//
// Function: Nt5BuildW
//
// Synopsis: Builds an ACL using the NT5 API WIDE apis
//
// Arguments: [ppAccess] -- Access list to build
//
// Returns: ERROR_SUCCESS -- Everything worked
// ERROR_INVALID_DATA -- One of the compares failed
//
//----------------------------------------------------------------------------
DWORD Nt5BuildW(PACTRL_ACCESSW *ppAccess) { DWORD dwErr = ERROR_SUCCESS;
PACTRL_ACCESSW pAccess = NULL, pNewAccess; ULONG iIndex, iVer;
PWSTR rgTrustees[BUILD_COUNT] = {SYSTEM, EVERYONE, SYSTEM, GUEST, EVERYONE, SYSTEM};
DWORD rgTypes[BUILD_COUNT] = {ACTRL_ACCESS_ALLOWED, ACTRL_ACCESS_ALLOWED, ACTRL_ACCESS_DENIED, ACTRL_ACCESS_ALLOWED, ACTRL_ACCESS_ALLOWED, ACTRL_ACCESS_DENIED};
DWORD rgAccess[BUILD_COUNT] = {ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_5, ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_1, ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_2, ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_3, ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_4, ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_2};
ACCESS_MODE rgMode[BUILD_COUNT] = {SET_ACCESS, SET_ACCESS, GRANT_ACCESS, GRANT_ACCESS, GRANT_ACCESS, REVOKE_ACCESS};
DWORD rgInherit[BUILD_COUNT] = {NO_INHERITANCE, NO_INHERITANCE, NO_INHERITANCE, NO_INHERITANCE, NO_INHERITANCE, NO_INHERITANCE};
DWORD rgSrch[BUILD_COUNT][BUILD_COUNT + 1] = {{1, 0}, {1, 1}, {2, 2, 1}, {3, 2, 3, 1}, {4, 2, 4, 3, 1}, {3, 4, 3, 1}}; if(fVerbose) { printf("Nt5BuildW\n"); }
//
// We'll do this in a loop, since we have BUILD_COUNT different builds to do
//
for(iIndex = 0; iIndex < BUILD_COUNT && dwErr == ERROR_SUCCESS; iIndex++) {
ACTRL_ACCESS_ENTRYW AAE;
BuildTrusteeWithNameW(&(AAE.Trustee), rgTrustees[iIndex]); AAE.fAccessFlags = rgTypes[iIndex]; AAE.Access = rgAccess[iIndex]; AAE.ProvSpecificAccess = 0; AAE.Inheritance = rgInherit[iIndex]; AAE.lpInheritProperty = NULL;
dwErr = SetEntriesInAccessListW(1, &AAE, rgMode[iIndex], NULL, pAccess, &pNewAccess); if(dwErr == ERROR_SUCCESS) { LocalFree(pAccess); pAccess = pNewAccess; }
if(dwErr == ERROR_SUCCESS) { //
// Now, verify the new entries...
//
PACTRL_ACCESS_ENTRY_LISTW pAAELW = pAccess->pPropertyAccessList[0].pAccessEntryList; PDWORD pSrch = rgSrch[iIndex]; ULONG cExpected = pSrch[0];
if(pAAELW->cEntries != cExpected) { dwErr = ERROR_INVALID_DATA; if(fVerbose) { printf("\tCount mismatched: %lu, expected %lu\n", pAAELW->cEntries, cExpected); } } else { //
// verify the rest of the data
//
for(iVer = 0; iVer < pAAELW->cEntries; iVer++) { ULONG iSrch = pSrch[iVer + 1]; if(_wcsicmp(pAAELW->pAccessList[iVer].Trustee.ptstrName, rgTrustees[iSrch]) != 0) { dwErr = ERROR_INVALID_DATA; if(fVerbose) { printf("\tTrustee mismatch[%lu]: %ws, expected " "%ws\n", iVer, pAAELW->pAccessList[iVer].Trustee.ptstrName, rgTrustees[iSrch]); } } } }
if(dwErr == ERROR_SUCCESS) { if(fVerbose) { printf("\tCount: %lu\n", cExpected); } } } else { fprintf(stderr,"\tNt5BuildW: SetEntriesInAccessListW failed " "with %lu\n", dwErr); }
}
if(dwErr == ERROR_SUCCESS) { *ppAccess = pAccess; } else { LocalFree(pAccess); }
return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: Nt5BuildA
//
// Synopsis: Builds an ACL using the NT5 API ANSI apis
//
// Arguments: [ppAccess] -- Access list to build
//
// Returns: ERROR_SUCCESS -- Everything worked
// ERROR_INVALID_DATA -- One of the compares failed
//
//----------------------------------------------------------------------------
DWORD Nt5BuildA(PACTRL_ACCESSA *ppAccess) { DWORD dwErr = ERROR_SUCCESS;
PACTRL_ACCESSA pAccess = NULL, pNewAccess; ULONG iIndex, iVer;
PSTR rgTrustees[BUILD_COUNT] = {SYSTEM_A, EVERYONE_A, SYSTEM_A, GUEST_A, EVERYONE_A, SYSTEM_A};
DWORD rgTypes[BUILD_COUNT] = {ACTRL_ACCESS_ALLOWED, ACTRL_ACCESS_ALLOWED, ACTRL_ACCESS_DENIED, ACTRL_ACCESS_ALLOWED, ACTRL_ACCESS_ALLOWED, ACTRL_ACCESS_DENIED};
DWORD rgAccess[BUILD_COUNT] = {ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_5, ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_1, ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_2, ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_3, ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_4, ACTRL_STD_RIGHTS_ALL | ACTRL_PERM_2};
ACCESS_MODE rgMode[BUILD_COUNT] = {SET_ACCESS, SET_ACCESS, GRANT_ACCESS, GRANT_ACCESS, GRANT_ACCESS, REVOKE_ACCESS};
DWORD rgInherit[BUILD_COUNT] = {NO_INHERITANCE, NO_INHERITANCE, NO_INHERITANCE, NO_INHERITANCE, NO_INHERITANCE, NO_INHERITANCE};
DWORD rgSrch[BUILD_COUNT][BUILD_COUNT + 1] = {{1, 0}, {1, 1}, {2, 2, 1}, {3, 2, 3, 1}, {4, 2, 4, 3, 1}, {3, 4, 3, 1}}; if(fVerbose) { printf("Nt5BuildA\n"); }
//
// We'll do this in a loop, since we have BUILD_COUNT different builds to do
//
for(iIndex = 0; iIndex < BUILD_COUNT && dwErr == ERROR_SUCCESS; iIndex++) {
ACTRL_ACCESS_ENTRYA AAE;
BuildTrusteeWithNameA(&(AAE.Trustee), rgTrustees[iIndex]); AAE.fAccessFlags = rgTypes[iIndex]; AAE.Access = rgAccess[iIndex]; AAE.ProvSpecificAccess = 0; AAE.Inheritance = rgInherit[iIndex]; AAE.lpInheritProperty = NULL;
dwErr = SetEntriesInAccessListA(1, &AAE, rgMode[iIndex], NULL, pAccess, &pNewAccess); if(dwErr == ERROR_SUCCESS) { LocalFree(pAccess); pAccess = pNewAccess; }
if(dwErr == ERROR_SUCCESS) { //
// Now, verify the new entries...
//
PACTRL_ACCESS_ENTRY_LISTA pAAELA = pAccess->pPropertyAccessList[0].pAccessEntryList; PDWORD pSrch = rgSrch[iIndex]; ULONG cExpected = pSrch[0];
if(pAAELA->cEntries != cExpected) { dwErr = ERROR_INVALID_DATA; if(fVerbose) { printf("\tCount mismatched: %lu, expected %lu\n", pAAELA->cEntries, cExpected); } } else { //
// verify the rest of the data
//
for(iVer = 0; iVer < pAAELA->cEntries; iVer++) { ULONG iSrch = pSrch[iVer + 1]; if(_stricmp(pAAELA->pAccessList[iVer].Trustee.ptstrName, rgTrustees[iSrch]) != 0) { dwErr = ERROR_INVALID_DATA; if(fVerbose) { printf("\tTrustee mismatch[%lu]: %s, expected " "%s\n", iVer, pAAELA->pAccessList[iVer].Trustee.ptstrName, rgTrustees[iSrch]); } } } }
if(dwErr == ERROR_SUCCESS) { if(fVerbose) { printf("\tCount: %lu\n", cExpected); } } } else { fprintf(stderr,"\tNt5BuildA: SetEntriesInAccessListA failed " "with %lu\n", dwErr); }
}
if(dwErr == ERROR_SUCCESS) { *ppAccess = pAccess; } else { LocalFree(pAccess); }
return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: Nt4DrtW
//
// Synopsis: Does the actual API drt. This involves reading the existing
// access, writing the new one, rereading the new one and
// verifing the results, and then restores the old one. This
// uses the WIDE version of the NT4 APIs
//
// Arguments: [pAcl] -- Acl to write on the object
// [pszObject] -- The object in question
// [ObjType] -- Type of the object
//
// Returns: ERROR_SUCCESS -- Success
// ERROR_INVALID_DATA -- One of the compares failed
//
//----------------------------------------------------------------------------
DWORD Nt4DrtW(PACL pAcl, PSTR pszObject, SE_OBJECT_TYPE ObjType) { DWORD dwErr = ERROR_SUCCESS; WCHAR wszPath[MAX_PATH + 1]; PACL pOldAcl = NULL; PSECURITY_DESCRIPTOR pSD = NULL;
mbstowcs(wszPath, pszObject, strlen(pszObject) + 1);
if(fVerbose) { printf("Nt4DrtW: Processing %ws [%lu]\n", wszPath, ObjType); }
//
// First, get the old acl
//
dwErr = GetNamedSecurityInfoW(wszPath, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldAcl, NULL, &pSD); if(dwErr == ERROR_SUCCESS) { //
// Set, get, and compare the new acl...
//
dwErr = SetNamedSecurityInfoW(wszPath, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, pAcl, NULL); if(dwErr == ERROR_SUCCESS) { PACL pNewAcl = NULL; PSECURITY_DESCRIPTOR pNewSD = NULL; dwErr = GetNamedSecurityInfoW(wszPath, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, &pNewAcl, NULL, &pNewSD); if(dwErr == ERROR_SUCCESS) { //
// Compare them...
//
dwErr = CompAcls(pAcl, pNewAcl); if(dwErr != ERROR_SUCCESS) { fprintf(stderr, "\tSet and old ACLs don't compare\n"); } LocalFree(pNewSD); } else { if(fVerbose) { printf("\tSecond GetNamedSecurityW on %ws failed with %lu\n", wszPath, dwErr); } } } else { if(fVerbose) { printf("\tSetNamedSecurityInfoW on %ws failed with %lu\n", wszPath, dwErr); } } } else { fprintf(stderr, "\tGetNamedSecurityInfoW failed on %ws: %lu\n", wszPath, dwErr); }
//
// Restore the objects security
//
if(pSD != NULL) { DWORD dwErr2 = SetNamedSecurityInfoW(wszPath, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, pOldAcl, NULL); if(dwErr2 != ERROR_SUCCESS) { fprintf(stderr, "Restoring access to %ws failed with %lu\n", wszPath, dwErr2);
}
if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; }
} LocalFree(pSD); return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: Nt4DrtA
//
// Synopsis: Does the actual API drt. This involves reading the existing
// access, writing the new one, rereading the new one and
// verifing the results, and then restores the old one. This
// uses the ANSI version of the NT4 APIs
//
// Arguments: [pAcl] -- Acl to write on the object
// [pszObject] -- The object in question
// [ObjType] -- Type of the object
//
// Returns: ERROR_SUCCESS -- Success
// ERROR_INVALID_DATA -- One of the compares failed
//
//----------------------------------------------------------------------------
DWORD Nt4DrtA(PACL pAcl, PSTR pszObject, SE_OBJECT_TYPE ObjType) { DWORD dwErr = ERROR_SUCCESS; PACL pOldAcl = NULL; PSECURITY_DESCRIPTOR pSD = NULL;
if(fVerbose) { printf("Nt4DrtA: Processing %s [%lu]\n", pszObject, ObjType); }
//
// First, get the old acl
//
dwErr = GetNamedSecurityInfoA(pszObject, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldAcl, NULL, &pSD); if(dwErr == ERROR_SUCCESS) { //
// Set, get, and compare the new acl...
//
dwErr = SetNamedSecurityInfoA(pszObject, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, pAcl, NULL); if(dwErr == ERROR_SUCCESS) { PACL pNewAcl = NULL; PSECURITY_DESCRIPTOR pNewSD = NULL; dwErr = GetNamedSecurityInfoA(pszObject, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, &pNewAcl, NULL, &pNewSD); if(dwErr == ERROR_SUCCESS) { //
// Compare them...
//
dwErr = CompAcls(pAcl, pNewAcl); if(dwErr != ERROR_SUCCESS) { fprintf(stderr, "\tSet and old ACLs don't compare\n"); } LocalFree(pNewSD); } else { if(fVerbose) { printf("\tSecond GetNamedSecurityA on %s failed with %lu\n", pszObject, dwErr); } } } else { if(fVerbose) { printf("\tSetNamedSecurityInfoA on %s failed with %lu\n", pszObject, dwErr); } } } else { fprintf(stderr, "\tGetNamedSecurityInfoA failed on %s: %lu\n", pszObject, dwErr); }
//
// Restore the objects security
//
if(pSD != NULL) { DWORD dwErr2 = SetNamedSecurityInfoA(pszObject, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, pOldAcl, NULL); if(dwErr2 != ERROR_SUCCESS) { fprintf(stderr, "Restoring access to %s failed with %lu\n", pszObject, dwErr2);
}
if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; }
} LocalFree(pSD); return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: Nt5DrtW
//
// Synopsis: Does the actual API drt. This involves reading the existing
// access, writing the new one, rereading the new one and
// verifing the results, and then restores the old one. This
// uses the WIDE version of the NT5 APIs
//
// Arguments: [pAccess] -- Access list to write on the object
// [pszObject] -- The object in question
// [ObjType] -- Type of the object
//
// Returns: ERROR_SUCCESS -- Success
// ERROR_INVALID_DATA -- One of the compares failed
//
//----------------------------------------------------------------------------
DWORD Nt5DrtW(PACTRL_ACCESSW pAccess, PSTR pszObject, SE_OBJECT_TYPE ObjType) { DWORD dwErr = ERROR_SUCCESS; WCHAR wszPath[MAX_PATH + 1]; PACTRL_ACCESSW pOldAccess = NULL;
mbstowcs(wszPath, pszObject, strlen(pszObject) + 1);
if(fVerbose) { printf("Nt5DrtW: Processing %ws [%lu]\n", wszPath, ObjType); }
//
// First, get the old acl
//
dwErr = GetNamedSecurityInfoExW(wszPath, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldAccess, NULL, NULL, NULL); if(dwErr == ERROR_SUCCESS) {
//
// Set, get, and compare the new value...
//
dwErr = SetNamedSecurityInfoExW(wszPath, ObjType, DACL_SECURITY_INFORMATION, NULL, pAccess, NULL, NULL, NULL, NULL); if(dwErr == ERROR_SUCCESS) { PACTRL_ACCESS pNewAccess = NULL; dwErr = GetNamedSecurityInfoExW(wszPath, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, &pNewAccess, NULL, NULL, NULL); if(dwErr == ERROR_SUCCESS) { //
// Compare them...
//
dwErr = CompAccessW(pAccess, pNewAccess); if(dwErr != ERROR_SUCCESS) { fprintf(stderr, "\tSet and old Accesses don't compare\n"); } } else { if(fVerbose) { printf("\tSecond GetNamedSecurityExW on %ws failed " "with %lu\n", wszPath, dwErr); } } } else { if(fVerbose) { printf("\tSetNamedSecurityInfoExW on %ws failed with %lu\n", wszPath, dwErr); } } } else { fprintf(stderr, "\tGetNamedSecurityInfoExW failed on %ws: %lu\n", wszPath, dwErr); }
//
// Restore the objects security
//
if(pOldAccess != NULL) { DWORD dwErr2 = SetNamedSecurityInfoExW(wszPath, ObjType, DACL_SECURITY_INFORMATION, NULL, pOldAccess, NULL, NULL, NULL, NULL); if(dwErr2 != ERROR_SUCCESS) { fprintf(stderr, "Restoring access to %ws failed with %lu\n", wszPath, dwErr2);
}
if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; }
}
LocalFree(pOldAccess);
return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: Nt5DrtA
//
// Synopsis: Does the actual API drt. This involves reading the existing
// access, writing the new one, rereading the new one and
// verifing the results, and then restores the old one. This
// uses the ANSI version of the NT5 APIs
//
// Arguments: [pAccess] -- Access list to write on the object
// [pszObject] -- The object in question
// [ObjType] -- Type of the object
//
// Returns: ERROR_SUCCESS -- Success
// ERROR_INVALID_DATA -- One of the compares failed
//
//----------------------------------------------------------------------------
DWORD Nt5DrtA(PACTRL_ACCESSA pAccess, PSTR pszObject, SE_OBJECT_TYPE ObjType) { DWORD dwErr = ERROR_SUCCESS; PACTRL_ACCESSA pOldAccess = NULL;
if(fVerbose) { printf("Nt5DrtA: Processing %s [%lu]\n", pszObject, ObjType); }
//
// First, get the old acl
//
dwErr = GetNamedSecurityInfoExA(pszObject, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldAccess, NULL, NULL, NULL); if(dwErr == ERROR_SUCCESS) { //
// Set, get, and compare the new value...
//
dwErr = SetNamedSecurityInfoExA(pszObject, ObjType, DACL_SECURITY_INFORMATION, NULL, pAccess, NULL, NULL, NULL, NULL); if(dwErr == ERROR_SUCCESS) { PACTRL_ACCESSA pNewAccess = NULL; dwErr = GetNamedSecurityInfoExA(pszObject, ObjType, DACL_SECURITY_INFORMATION, NULL, NULL, &pNewAccess, NULL, NULL, NULL); if(dwErr == ERROR_SUCCESS) { //
// Compare them...
//
dwErr = CompAccessA(pAccess, pNewAccess); if(dwErr != ERROR_SUCCESS) { fprintf(stderr, "\tSet and old Accesses don't compare\n"); } } else { if(fVerbose) { printf("\tSecond GetNamedSecurityExA on %s failed " "with %lu\n", pszObject, dwErr); } } } else { if(fVerbose) { printf("\tSetNamedSecurityInfoExA on %s failed with %lu\n", pszObject, dwErr); } } } else { fprintf(stderr, "\tGetNamedSecurityInfoExA failed on %s: %lu\n", pszObject, dwErr); }
//
// Restore the objects security
//
if(pOldAccess != NULL) { DWORD dwErr2 = SetNamedSecurityInfoExA(pszObject, ObjType, DACL_SECURITY_INFORMATION, NULL, pOldAccess, NULL, NULL, NULL, NULL); if(dwErr2 != ERROR_SUCCESS) { fprintf(stderr, "Restoring access to %s failed with %lu\n", pszObject, dwErr2);
}
if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; }
}
LocalFree(pOldAccess);
//
// Finally, try to convert to and from a security descriptor
//
if(dwErr == ERROR_SUCCESS) { PSECURITY_DESCRIPTOR pSD; dwErr = ConvertAccessToSecurityDescriptorA(pAccess, NULL, "ntds\\macm", NULL, &pSD); if(dwErr != ERROR_SUCCESS) { fprintf(stderr, "ConvertAccessToSecurityDescriptor failed with %lu\n", dwErr); } else { PACTRL_ACCESSA pNewAccess; PSTR pszName;
dwErr = ConvertSecurityDescriptorToAccessA(pszObject, ObjType, pSD, &pNewAccess, NULL, &pszName, NULL); if(dwErr == ERROR_SUCCESS) { AccFree(pszName); AccFree(pNewAccess); } else { fprintf(stderr, "ConvertSecurityDescriptorToAccessA failed with %lu\n", dwErr); }
LocalFree(pSD); }
}
return(dwErr); }
|