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