3 * regexpl - Console Registry Explorer
5 * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net>
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.
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.
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.
23 // SecurityDescriptor.cpp: implementation of the CSecurityDescriptor class.
25 //////////////////////////////////////////////////////////////////////
28 #include "SecurityDescriptor.h"
30 // *** THIS SHOULD GO IN A MINGW/ROS HEADER - Begin
33 //#define SID_REVISION (1) // Current revision level
35 //typedef struct _ACE_HEADER {
40 typedef ACE_HEADER
* PACE_HEADER
;
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)
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)
53 //#define SUCCESSFUL_ACCESS_ACE_FLAG (0x40)
54 //#define FAILED_ACCESS_ACE_FLAG (0x80)
56 //typedef struct _SYSTEM_AUDIT_ACE {
63 // *** THIS SHOULD GO IN A MINGW/ROS HEADER - End
67 PSID pSid
, // binary Sid
68 LPTSTR TextualSid
, // buffer for Textual representation of Sid
69 LPDWORD lpdwBufferLen
// required/provided TextualSid buffersize
72 PSID_IDENTIFIER_AUTHORITY psia
;
73 DWORD dwSubAuthorities
;
74 DWORD dwSidRev
=SID_REVISION
;
78 // Validate the binary SID.
80 if(!IsValidSid(pSid
)) return FALSE
;
82 // Get the identifier authority value from the SID.
84 psia
= GetSidIdentifierAuthority(pSid
);
86 // Get the number of subauthorities in the SID.
88 dwSubAuthorities
= *GetSidSubAuthorityCount(pSid
);
90 // Compute the buffer length.
91 // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
93 dwSidSize
=(15 + 12 + (12 * dwSubAuthorities
) + 1) * sizeof(TCHAR
);
95 // Check input buffer length.
96 // If too small, indicate the proper size and set last error.
98 if (*lpdwBufferLen
< dwSidSize
)
100 *lpdwBufferLen
= dwSidSize
;
101 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
105 // Add 'S' prefix and revision number to the string.
107 dwSidSize
=wsprintf(TextualSid
, TEXT("S-%lu-"), dwSidRev
);
109 // Add SID identifier authority to the string.
111 if ( (psia
->Value
[0] != 0) || (psia
->Value
[1] != 0) )
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]);
124 dwSidSize
+=wsprintf(TextualSid
+ lstrlen(TextualSid
),
126 (ULONG
)(psia
->Value
[5] ) +
127 (ULONG
)(psia
->Value
[4] << 8) +
128 (ULONG
)(psia
->Value
[3] << 16) +
129 (ULONG
)(psia
->Value
[2] << 24) );
132 // Add SID subauthorities to the string.
134 for (dwCounter
=0 ; dwCounter
< dwSubAuthorities
; dwCounter
++)
136 dwSidSize
+=wsprintf(TextualSid
+ dwSidSize
, TEXT("-%lu"),
137 *GetSidSubAuthority(pSid
, dwCounter
) );
143 const TCHAR
* GetSidTypeName(SID_NAME_USE Use
)
148 return _T("User SID");
150 return _T("Group SID");
152 return _T("Domain SID");
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");
160 return _T("Invalid SID");
162 return _T("Unknown SID type");
164 return _T("Error. Cannot recognize SID type.");
168 //////////////////////////////////////////////////////////////////////
169 // Construction/Destruction
170 //////////////////////////////////////////////////////////////////////
172 CSecurityDescriptor::CSecurityDescriptor()
174 m_pSecurityDescriptor
= NULL
;
175 m_pCurrentACEHeader
= NULL
;
178 CSecurityDescriptor::~CSecurityDescriptor()
182 void CSecurityDescriptor::AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
)
184 m_pSecurityDescriptor
= pSecurityDescriptor
;
187 DWORD
CSecurityDescriptor::BeginDACLInteration()
189 if (!GetSecurityDescriptorDacl(m_pSecurityDescriptor
,&m_blnDACLPresent
,&m_pDACL
,&m_blnDACLDefaulted
))
191 throw GetLastError();
193 return ERROR_SUCCESS
;
196 BOOL
CSecurityDescriptor::DescriptorContainsDACL()
198 return m_blnDACLPresent
;
201 DWORD
CSecurityDescriptor::BeginSACLInteration()
203 if (!GetSecurityDescriptorSacl(m_pSecurityDescriptor
,&m_blnSACLPresent
,&m_pSACL
,&m_blnSACLDefaulted
))
204 throw GetLastError();
205 return ERROR_SUCCESS
;
208 BOOL
CSecurityDescriptor::DescriptorContainsSACL()
210 return m_blnSACLPresent
;
213 BOOL
CSecurityDescriptor::HasNULLDACL()
215 ASSERT(m_blnDACLPresent
);
216 return (m_pDACL
== NULL
);
219 BOOL
CSecurityDescriptor::HasValidDACL()
221 ASSERT(m_blnDACLPresent
);
222 ASSERT(m_pDACL
!= NULL
);
223 return IsValidAcl(m_pDACL
);
226 BOOL
CSecurityDescriptor::HasNULLSACL()
228 ASSERT(m_blnSACLPresent
);
229 return (m_pSACL
== NULL
);
232 BOOL
CSecurityDescriptor::HasValidSACL()
234 ASSERT(m_blnSACLPresent
);
235 ASSERT(m_pSACL
!= NULL
);
236 return IsValidAcl(m_pSACL
);
239 DWORD
CSecurityDescriptor::GetDACLEntriesCount()
241 ACL_SIZE_INFORMATION SizeInfo
;
242 if (!GetAclInformation(m_pDACL
,&SizeInfo
,sizeof(SizeInfo
),AclSizeInformation
))
243 throw GetLastError();
244 return SizeInfo
.AceCount
;
247 DWORD
CSecurityDescriptor::GetSACLEntriesCount()
249 ACL_SIZE_INFORMATION SizeInfo
;
250 if (!GetAclInformation(m_pSACL
,&SizeInfo
,sizeof(SizeInfo
),AclSizeInformation
))
251 throw GetLastError();
252 return SizeInfo
.AceCount
;
255 CSecurityDescriptor::ACEntryType
CSecurityDescriptor::GetDACLEntry(DWORD nIndex
)
258 if (!GetAce(m_pDACL
,nIndex
,&pACE
)) throw GetLastError();
259 m_pCurrentACEHeader
= (PACE_HEADER
)pACE
;
260 if (m_pCurrentACEHeader
->AceType
== ACCESS_ALLOWED_ACE_TYPE
)
264 if (m_pCurrentACEHeader
->AceType
== ACCESS_DENIED_ACE_TYPE
)
271 CSecurityDescriptor::ACEntryType
CSecurityDescriptor::GetSACLEntry(DWORD nIndex
, BOOL
& blnFailedAccess
, BOOL
& blnSeccessfulAccess
)
274 if (!GetAce(m_pSACL
,nIndex
,&pACE
)) throw GetLastError();
275 m_pCurrentACEHeader
= (PACE_HEADER
)pACE
;
276 if (m_pCurrentACEHeader
->AceType
== SYSTEM_AUDIT_ACE_TYPE
)
278 blnFailedAccess
= m_pCurrentACEHeader
->AceFlags
& FAILED_ACCESS_ACE_FLAG
;
279 blnSeccessfulAccess
= m_pCurrentACEHeader
->AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
;
285 PSID
CSecurityDescriptor::GetCurrentACE_SID()
287 ASSERT(m_pCurrentACEHeader
!= NULL
);
288 switch(m_pCurrentACEHeader
->AceType
)
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
));
297 ASSERT(FALSE
); // Do not call this function for unknown ACE types !!!
302 void CSecurityDescriptor::GetCurrentACE_AccessMask(DWORD
& dwMask
)
304 ASSERT(m_pCurrentACEHeader
!= NULL
);
305 switch(m_pCurrentACEHeader
->AceType
)
307 case ACCESS_ALLOWED_ACE_TYPE
:
308 dwMask
= (((ACCESS_ALLOWED_ACE
*)m_pCurrentACEHeader
)->Mask
);
310 case ACCESS_DENIED_ACE_TYPE
:
311 dwMask
= (((ACCESS_DENIED_ACE
*)m_pCurrentACEHeader
)->Mask
);
313 case SYSTEM_AUDIT_ACE_TYPE
:
314 dwMask
= (((SYSTEM_AUDIT_ACE
*)m_pCurrentACEHeader
)->Mask
);
317 ASSERT(FALSE
); // Do not call this function for unknown ACE types !!!
322 void CSecurityDescriptor::GetCurrentACE_Flags(BYTE
& bFlags
)
324 ASSERT(m_pCurrentACEHeader
!= NULL
);
325 bFlags
= m_pCurrentACEHeader
->AceFlags
;