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