Incorporate rosapps. 0.3.15 was branched somewhat incorrectly so rosapps is not synce...
[reactos.git] / modules / rosapps / applications / sysutils / regexpl / SecurityDescriptor.cpp
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 }