//+------------------------------------------------------------------ // // Copyright (C) 1995, Microsoft Corporation. // // File: DumpSec.cxx // // Contents: class to dump file security ACL // // Classes: CDumpSecurity // // History: Nov-93 DaveMont Created. // //------------------------------------------------------------------- #include //+--------------------------------------------------------------------------- // // Member: CDumpSecurity::CDumpSecurity, public // // Synopsis: initialized data members, constructor will not throw // // Arguments: IN [pfilename] - name of file to dump security for // //---------------------------------------------------------------------------- CDumpSecurity::CDumpSecurity(WCHAR *pfilename) : _psd(NULL), _pwfilename(pfilename), _pdacl(NULL), _pah(NULL), _psid(NULL), _cacethissid(0) { } //+--------------------------------------------------------------------------- // // Member: CDumpSecurity::Init, public // // Synopsis: Init must be called before any other methods - this // is not enforced. Init gets the security descriptor and // ACL for the file // // Arguments: none // //---------------------------------------------------------------------------- ULONG CDumpSecurity::Init() { ULONG ret; ULONG cpsd; // get the size of the security buffer if (!GetFileSecurity(_pwfilename, DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, NULL, 0, &cpsd) ) { if (ERROR_INSUFFICIENT_BUFFER == (ret = GetLastError())) { if ( NULL == ( _psd = (BYTE *)LocalAlloc(LMEM_FIXED, cpsd))) { return(ERROR_NOT_ENOUGH_MEMORY); } // actually get the buffer this time if ( GetFileSecurity(_pwfilename, DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, _psd, cpsd, &cpsd) ) { BOOL fdaclpresent; BOOL cod; // get the ACL if ( GetSecurityDescriptorDacl(_psd, &fdaclpresent, &_pdacl, &cod) ) { if (!fdaclpresent) { _pdacl = NULL; return(ERROR_NO_SECURITY_ON_OBJECT); } // save the ACL location _pah = (ACE_HEADER *)Add2Ptr(_pdacl, sizeof(ACL)); return(ERROR_SUCCESS); } else return(GetLastError()); } else return(GetLastError()); } } else return(ERROR_NO_SECURITY_ON_OBJECT); return(ret); } //+--------------------------------------------------------------------------- // // Member: Dtor, public // // Synopsis: frees the security descriptor // // Arguments: none // //---------------------------------------------------------------------------- CDumpSecurity::~CDumpSecurity() { if (_psd) { LocalFree(_psd); } } //+--------------------------------------------------------------------------- // // Member: CDumpSecurity::GetSDOwner, public // // Synopsis: returns the owner of the file // // Arguments: OUT [psid] - address of the returned sid // //---------------------------------------------------------------------------- ULONG CDumpSecurity::GetSDOwner(SID **psid) { BOOL cod; if ( GetSecurityDescriptorOwner(_psd, (void **)psid, &cod) ) return(0); else return(GetLastError()); } //+--------------------------------------------------------------------------- // // Member: CDumpSecurity::GetSDGroup, public // // Synopsis: returns the group from the file // // Arguments: OUT [pgsid] - address of the returned group sid // //---------------------------------------------------------------------------- ULONG CDumpSecurity::GetSDGroup(SID **pgsid) { BOOL cod; if ( GetSecurityDescriptorGroup(_psd, (void **)pgsid, &cod) ) return(0); else return(GetLastError()); } //+--------------------------------------------------------------------------- // // Member: CDumpSecurity::ResetAce, public // // Synopsis: sets the 'ace' index to the start of the DACL // // Arguments: IN - [psid] - the SID to find aces for // //---------------------------------------------------------------------------- VOID CDumpSecurity::ResetAce(SID *psid) { _psid = psid; _cacethissid = 0; if (_pdacl) _pah = (ACE_HEADER *)Add2Ptr(_pdacl, sizeof(ACL)); } //+--------------------------------------------------------------------------- // // Member: CDumpSecurity::GetNextAce, public // // Synopsis: gets the next ACE from the DACL for the specified SID // // Arguments: OUT [pace] - pointer to the next ace for the SID passed // in at the last reset. // // Returns: the number of the ACE // //---------------------------------------------------------------------------- LONG CDumpSecurity::GetNextAce(ACE_HEADER **paceh) { LONG ret = -1; if (_pdacl) { for (;_cacethissid < _pdacl->AceCount; _cacethissid++, _pah = (ACE_HEADER *)Add2Ptr(_pah, _pah->AceSize)) { if (!_psid || EqualSid(_psid,(SID *)&((ACCESS_ALLOWED_ACE *)_pah)->SidStart) ) { *paceh = _pah; ret = _cacethissid++; _pah = (ACE_HEADER *)Add2Ptr(_pah, _pah->AceSize); break; } } } return(ret); }