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"
31 PSID pSid
, // binary Sid
32 LPTSTR TextualSid
, // buffer for Textual representation of Sid
33 LPDWORD lpdwBufferLen
// required/provided TextualSid buffersize
36 PSID_IDENTIFIER_AUTHORITY psia
;
37 DWORD dwSubAuthorities
;
38 DWORD dwSidRev
=SID_REVISION
;
42 // Validate the binary SID.
44 if(!IsValidSid(pSid
)) return FALSE
;
46 // Get the identifier authority value from the SID.
48 psia
= GetSidIdentifierAuthority(pSid
);
50 // Get the number of subauthorities in the SID.
52 dwSubAuthorities
= *GetSidSubAuthorityCount(pSid
);
54 // Compute the buffer length.
55 // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
57 dwSidSize
=(15 + 12 + (12 * dwSubAuthorities
) + 1) * sizeof(TCHAR
);
59 // Check input buffer length.
60 // If too small, indicate the proper size and set last error.
62 if (*lpdwBufferLen
< dwSidSize
)
64 *lpdwBufferLen
= dwSidSize
;
65 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
69 // Add 'S' prefix and revision number to the string.
71 dwSidSize
=wsprintf(TextualSid
, TEXT("S-%lu-"), dwSidRev
);
73 // Add SID identifier authority to the string.
75 if ( (psia
->Value
[0] != 0) || (psia
->Value
[1] != 0) )
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]);
88 dwSidSize
+=wsprintf(TextualSid
+ lstrlen(TextualSid
),
90 (ULONG
)(psia
->Value
[5] ) +
91 (ULONG
)(psia
->Value
[4] << 8) +
92 (ULONG
)(psia
->Value
[3] << 16) +
93 (ULONG
)(psia
->Value
[2] << 24) );
96 // Add SID subauthorities to the string.
98 for (dwCounter
=0 ; dwCounter
< dwSubAuthorities
; dwCounter
++)
100 dwSidSize
+=wsprintf(TextualSid
+ dwSidSize
, TEXT("-%lu"),
101 *GetSidSubAuthority(pSid
, dwCounter
) );
107 const TCHAR
* GetSidTypeName(SID_NAME_USE Use
)
112 return _T("User SID");
114 return _T("Group SID");
116 return _T("Domain SID");
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");
124 return _T("Invalid SID");
126 return _T("Unknown SID type");
128 return _T("Error. Cannot recognize SID type.");
132 //////////////////////////////////////////////////////////////////////
133 // Construction/Destruction
134 //////////////////////////////////////////////////////////////////////
136 CSecurityDescriptor::CSecurityDescriptor()
138 m_pSecurityDescriptor
= NULL
;
139 m_pCurrentACEHeader
= NULL
;
142 CSecurityDescriptor::~CSecurityDescriptor()
146 void CSecurityDescriptor::AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
)
148 m_pSecurityDescriptor
= pSecurityDescriptor
;
151 DWORD
CSecurityDescriptor::BeginDACLInteration()
153 if (!GetSecurityDescriptorDacl(m_pSecurityDescriptor
,&m_blnDACLPresent
,&m_pDACL
,&m_blnDACLDefaulted
))
155 throw GetLastError();
157 return ERROR_SUCCESS
;
160 BOOL
CSecurityDescriptor::DescriptorContainsDACL()
162 return m_blnDACLPresent
;
165 DWORD
CSecurityDescriptor::BeginSACLInteration()
167 if (!GetSecurityDescriptorSacl(m_pSecurityDescriptor
,&m_blnSACLPresent
,&m_pSACL
,&m_blnSACLDefaulted
))
168 throw GetLastError();
169 return ERROR_SUCCESS
;
172 BOOL
CSecurityDescriptor::DescriptorContainsSACL()
174 return m_blnSACLPresent
;
177 BOOL
CSecurityDescriptor::HasNULLDACL()
179 ASSERT(m_blnDACLPresent
);
180 return (m_pDACL
== NULL
);
183 BOOL
CSecurityDescriptor::HasValidDACL()
185 ASSERT(m_blnDACLPresent
);
186 ASSERT(m_pDACL
!= NULL
);
187 return IsValidAcl(m_pDACL
);
190 BOOL
CSecurityDescriptor::HasNULLSACL()
192 ASSERT(m_blnSACLPresent
);
193 return (m_pSACL
== NULL
);
196 BOOL
CSecurityDescriptor::HasValidSACL()
198 ASSERT(m_blnSACLPresent
);
199 ASSERT(m_pSACL
!= NULL
);
200 return IsValidAcl(m_pSACL
);
203 DWORD
CSecurityDescriptor::GetDACLEntriesCount()
205 ACL_SIZE_INFORMATION SizeInfo
;
206 if (!GetAclInformation(m_pDACL
,&SizeInfo
,sizeof(SizeInfo
),AclSizeInformation
))
207 throw GetLastError();
208 return SizeInfo
.AceCount
;
211 DWORD
CSecurityDescriptor::GetSACLEntriesCount()
213 ACL_SIZE_INFORMATION SizeInfo
;
214 if (!GetAclInformation(m_pSACL
,&SizeInfo
,sizeof(SizeInfo
),AclSizeInformation
))
215 throw GetLastError();
216 return SizeInfo
.AceCount
;
219 CSecurityDescriptor::ACEntryType
CSecurityDescriptor::GetDACLEntry(DWORD nIndex
)
222 if (!GetAce(m_pDACL
,nIndex
,&pACE
)) throw GetLastError();
223 m_pCurrentACEHeader
= (PACE_HEADER
)pACE
;
224 if (m_pCurrentACEHeader
->AceType
== ACCESS_ALLOWED_ACE_TYPE
)
228 if (m_pCurrentACEHeader
->AceType
== ACCESS_DENIED_ACE_TYPE
)
235 CSecurityDescriptor::ACEntryType
CSecurityDescriptor::GetSACLEntry(DWORD nIndex
, BOOL
& blnFailedAccess
, BOOL
& blnSeccessfulAccess
)
238 if (!GetAce(m_pSACL
,nIndex
,&pACE
)) throw GetLastError();
239 m_pCurrentACEHeader
= (PACE_HEADER
)pACE
;
240 if (m_pCurrentACEHeader
->AceType
== SYSTEM_AUDIT_ACE_TYPE
)
242 blnFailedAccess
= m_pCurrentACEHeader
->AceFlags
& FAILED_ACCESS_ACE_FLAG
;
243 blnSeccessfulAccess
= m_pCurrentACEHeader
->AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
;
249 PSID
CSecurityDescriptor::GetCurrentACE_SID()
251 ASSERT(m_pCurrentACEHeader
!= NULL
);
252 switch(m_pCurrentACEHeader
->AceType
)
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
));
261 ASSERT(FALSE
); // Do not call this function for unknown ACE types !!!
266 void CSecurityDescriptor::GetCurrentACE_AccessMask(DWORD
& dwMask
)
268 ASSERT(m_pCurrentACEHeader
!= NULL
);
269 switch(m_pCurrentACEHeader
->AceType
)
271 case ACCESS_ALLOWED_ACE_TYPE
:
272 dwMask
= (((ACCESS_ALLOWED_ACE
*)m_pCurrentACEHeader
)->Mask
);
274 case ACCESS_DENIED_ACE_TYPE
:
275 dwMask
= (((ACCESS_DENIED_ACE
*)m_pCurrentACEHeader
)->Mask
);
277 case SYSTEM_AUDIT_ACE_TYPE
:
278 dwMask
= (((SYSTEM_AUDIT_ACE
*)m_pCurrentACEHeader
)->Mask
);
281 ASSERT(FALSE
); // Do not call this function for unknown ACE types !!!
286 void CSecurityDescriptor::GetCurrentACE_Flags(BYTE
& bFlags
)
288 ASSERT(m_pCurrentACEHeader
!= NULL
);
289 bFlags
= m_pCurrentACEHeader
->AceFlags
;