1 /* 2 * regexpl - Console Registry Explorer 3 * 4 * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; see the file COPYING. If not, write to 18 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 * Boston, MA 02111-1307, USA. 20 */ 21 22 // SecurityDescriptor.cpp: implementation of the CSecurityDescriptor class. 23 // 24 ////////////////////////////////////////////////////////////////////// 25 26 #include "ph.h" 27 #include "SecurityDescriptor.h" 28 29 BOOL GetTextualSid( 30 PSID pSid, // binary Sid 31 LPTSTR TextualSid, // buffer for Textual representation of Sid 32 LPDWORD lpdwBufferLen // required/provided TextualSid buffersize 33 ) 34 { 35 PSID_IDENTIFIER_AUTHORITY psia; 36 DWORD dwSubAuthorities; 37 DWORD dwSidRev=SID_REVISION; 38 DWORD dwCounter; 39 DWORD dwSidSize; 40 41 // Validate the binary SID. 42 43 if(!IsValidSid(pSid)) return FALSE; 44 45 // Get the identifier authority value from the SID. 46 47 psia = GetSidIdentifierAuthority(pSid); 48 49 // Get the number of subauthorities in the SID. 50 51 dwSubAuthorities = *GetSidSubAuthorityCount(pSid); 52 53 // Compute the buffer length. 54 // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL 55 56 dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR); 57 58 // Check input buffer length. 59 // If too small, indicate the proper size and set last error. 60 61 if (*lpdwBufferLen < dwSidSize) 62 { 63 *lpdwBufferLen = dwSidSize; 64 SetLastError(ERROR_INSUFFICIENT_BUFFER); 65 return FALSE; 66 } 67 68 // Add 'S' prefix and revision number to the string. 69 70 dwSidSize=wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev ); 71 72 // Add SID identifier authority to the string. 73 74 if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) 75 { 76 dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid), 77 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"), 78 (USHORT)psia->Value[0], 79 (USHORT)psia->Value[1], 80 (USHORT)psia->Value[2], 81 (USHORT)psia->Value[3], 82 (USHORT)psia->Value[4], 83 (USHORT)psia->Value[5]); 84 } 85 else 86 { 87 dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid), 88 TEXT("%lu"), 89 (ULONG)(psia->Value[5] ) + 90 (ULONG)(psia->Value[4] << 8) + 91 (ULONG)(psia->Value[3] << 16) + 92 (ULONG)(psia->Value[2] << 24) ); 93 } 94 95 // Add SID subauthorities to the string. 96 // 97 for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++) 98 { 99 dwSidSize+=wsprintf(TextualSid + dwSidSize, TEXT("-%lu"), 100 *GetSidSubAuthority(pSid, dwCounter) ); 101 } 102 103 return TRUE; 104 } 105 106 const TCHAR * GetSidTypeName(SID_NAME_USE Use) 107 { 108 switch(Use) 109 { 110 case SidTypeUser: 111 return _T("User SID"); 112 case SidTypeGroup: 113 return _T("Group SID"); 114 case SidTypeDomain: 115 return _T("Domain SID"); 116 case SidTypeAlias: 117 return _T("Alias SID"); 118 case SidTypeWellKnownGroup: 119 return _T("SID for a well-known group"); 120 case SidTypeDeletedAccount: 121 return _T("SID for a deleted account"); 122 case SidTypeInvalid: 123 return _T("Invalid SID"); 124 case SidTypeUnknown: 125 return _T("Unknown SID type"); 126 default: 127 return _T("Error. Cannot recognize SID type."); 128 } 129 } 130 131 ////////////////////////////////////////////////////////////////////// 132 // Construction/Destruction 133 ////////////////////////////////////////////////////////////////////// 134 135 CSecurityDescriptor::CSecurityDescriptor() 136 { 137 m_pSecurityDescriptor = NULL; 138 m_pCurrentACEHeader = NULL; 139 } 140 141 CSecurityDescriptor::~CSecurityDescriptor() 142 { 143 } 144 145 void CSecurityDescriptor::AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor) 146 { 147 m_pSecurityDescriptor = pSecurityDescriptor; 148 } 149 150 DWORD CSecurityDescriptor::BeginDACLInteration() 151 { 152 if (!GetSecurityDescriptorDacl(m_pSecurityDescriptor,&m_blnDACLPresent,&m_pDACL,&m_blnDACLDefaulted)) 153 { 154 throw GetLastError(); 155 } 156 return ERROR_SUCCESS; 157 } 158 159 BOOL CSecurityDescriptor::DescriptorContainsDACL() 160 { 161 return m_blnDACLPresent; 162 } 163 164 DWORD CSecurityDescriptor::BeginSACLInteration() 165 { 166 if (!GetSecurityDescriptorSacl(m_pSecurityDescriptor,&m_blnSACLPresent,&m_pSACL,&m_blnSACLDefaulted)) 167 throw GetLastError(); 168 return ERROR_SUCCESS; 169 } 170 171 BOOL CSecurityDescriptor::DescriptorContainsSACL() 172 { 173 return m_blnSACLPresent; 174 } 175 176 BOOL CSecurityDescriptor::HasNULLDACL() 177 { 178 ASSERT(m_blnDACLPresent); 179 return (m_pDACL == NULL); 180 } 181 182 BOOL CSecurityDescriptor::HasValidDACL() 183 { 184 ASSERT(m_blnDACLPresent); 185 ASSERT(m_pDACL != NULL); 186 return IsValidAcl(m_pDACL); 187 } 188 189 BOOL CSecurityDescriptor::HasNULLSACL() 190 { 191 ASSERT(m_blnSACLPresent); 192 return (m_pSACL == NULL); 193 } 194 195 BOOL CSecurityDescriptor::HasValidSACL() 196 { 197 ASSERT(m_blnSACLPresent); 198 ASSERT(m_pSACL != NULL); 199 return IsValidAcl(m_pSACL); 200 } 201 202 DWORD CSecurityDescriptor::GetDACLEntriesCount() 203 { 204 ACL_SIZE_INFORMATION SizeInfo; 205 if (!GetAclInformation(m_pDACL,&SizeInfo,sizeof(SizeInfo),AclSizeInformation)) 206 throw GetLastError(); 207 return SizeInfo.AceCount; 208 } 209 210 DWORD CSecurityDescriptor::GetSACLEntriesCount() 211 { 212 ACL_SIZE_INFORMATION SizeInfo; 213 if (!GetAclInformation(m_pSACL,&SizeInfo,sizeof(SizeInfo),AclSizeInformation)) 214 throw GetLastError(); 215 return SizeInfo.AceCount; 216 } 217 218 CSecurityDescriptor::ACEntryType CSecurityDescriptor::GetDACLEntry(DWORD nIndex) 219 { 220 void *pACE; 221 if (!GetAce(m_pDACL,nIndex,&pACE)) throw GetLastError(); 222 m_pCurrentACEHeader = (PACE_HEADER)pACE; 223 if (m_pCurrentACEHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) 224 { 225 return AccessAlowed; 226 } 227 if (m_pCurrentACEHeader->AceType == ACCESS_DENIED_ACE_TYPE) 228 { 229 return AccessDenied; 230 } 231 return Unknown; 232 } 233 234 CSecurityDescriptor::ACEntryType CSecurityDescriptor::GetSACLEntry(DWORD nIndex, BOOL& blnFailedAccess, BOOL& blnSeccessfulAccess) 235 { 236 void *pACE; 237 if (!GetAce(m_pSACL,nIndex,&pACE)) throw GetLastError(); 238 m_pCurrentACEHeader = (PACE_HEADER)pACE; 239 if (m_pCurrentACEHeader->AceType == SYSTEM_AUDIT_ACE_TYPE) 240 { 241 blnFailedAccess = m_pCurrentACEHeader->AceFlags & FAILED_ACCESS_ACE_FLAG; 242 blnSeccessfulAccess = m_pCurrentACEHeader->AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG; 243 return SystemAudit; 244 } 245 return Unknown; 246 } 247 248 PSID CSecurityDescriptor::GetCurrentACE_SID() 249 { 250 ASSERT(m_pCurrentACEHeader != NULL); 251 switch(m_pCurrentACEHeader->AceType) 252 { 253 case ACCESS_ALLOWED_ACE_TYPE: 254 return ((PSID)&(((ACCESS_ALLOWED_ACE *)m_pCurrentACEHeader)->SidStart)); 255 case ACCESS_DENIED_ACE_TYPE: 256 return ((PSID)&(((ACCESS_DENIED_ACE *)m_pCurrentACEHeader)->SidStart)); 257 case SYSTEM_AUDIT_ACE_TYPE: 258 return ((PSID)&(((SYSTEM_AUDIT_ACE *)m_pCurrentACEHeader)->SidStart)); 259 default: 260 ASSERT(FALSE); // Do not call this function for unknown ACE types !!! 261 return NULL; 262 } 263 } 264 265 void CSecurityDescriptor::GetCurrentACE_AccessMask(DWORD& dwMask) 266 { 267 ASSERT(m_pCurrentACEHeader != NULL); 268 switch(m_pCurrentACEHeader->AceType) 269 { 270 case ACCESS_ALLOWED_ACE_TYPE: 271 dwMask = (((ACCESS_ALLOWED_ACE *)m_pCurrentACEHeader)->Mask); 272 return; 273 case ACCESS_DENIED_ACE_TYPE: 274 dwMask = (((ACCESS_DENIED_ACE *)m_pCurrentACEHeader)->Mask); 275 return; 276 case SYSTEM_AUDIT_ACE_TYPE: 277 dwMask = (((SYSTEM_AUDIT_ACE *)m_pCurrentACEHeader)->Mask); 278 return; 279 default: 280 ASSERT(FALSE); // Do not call this function for unknown ACE types !!! 281 return; 282 } 283 } 284 285 void CSecurityDescriptor::GetCurrentACE_Flags(BYTE& bFlags) 286 { 287 ASSERT(m_pCurrentACEHeader != NULL); 288 bFlags = m_pCurrentACEHeader->AceFlags; 289 } 290