Reactos
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
29BOOL 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
106const 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
135CSecurityDescriptor::CSecurityDescriptor()
136{
137 m_pSecurityDescriptor = NULL;
138 m_pCurrentACEHeader = NULL;
139}
140
141CSecurityDescriptor::~CSecurityDescriptor()
142{
143}
144
145void CSecurityDescriptor::AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor)
146{
147 m_pSecurityDescriptor = pSecurityDescriptor;
148}
149
150DWORD 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
159BOOL CSecurityDescriptor::DescriptorContainsDACL()
160{
161 return m_blnDACLPresent;
162}
163
164DWORD CSecurityDescriptor::BeginSACLInteration()
165{
166 if (!GetSecurityDescriptorSacl(m_pSecurityDescriptor,&m_blnSACLPresent,&m_pSACL,&m_blnSACLDefaulted))
167 throw GetLastError();
168 return ERROR_SUCCESS;
169}
170
171BOOL CSecurityDescriptor::DescriptorContainsSACL()
172{
173 return m_blnSACLPresent;
174}
175
176BOOL CSecurityDescriptor::HasNULLDACL()
177{
178 ASSERT(m_blnDACLPresent);
179 return (m_pDACL == NULL);
180}
181
182BOOL CSecurityDescriptor::HasValidDACL()
183{
184 ASSERT(m_blnDACLPresent);
185 ASSERT(m_pDACL != NULL);
186 return IsValidAcl(m_pDACL);
187}
188
189BOOL CSecurityDescriptor::HasNULLSACL()
190{
191 ASSERT(m_blnSACLPresent);
192 return (m_pSACL == NULL);
193}
194
195BOOL CSecurityDescriptor::HasValidSACL()
196{
197 ASSERT(m_blnSACLPresent);
198 ASSERT(m_pSACL != NULL);
199 return IsValidAcl(m_pSACL);
200}
201
202DWORD 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
210DWORD 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
218CSecurityDescriptor::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
234CSecurityDescriptor::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
248PSID 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
265void 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
285void CSecurityDescriptor::GetCurrentACE_Flags(BYTE& bFlags)
286{
287 ASSERT(m_pCurrentACEHeader != NULL);
288 bFlags = m_pCurrentACEHeader->AceFlags;
289}