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