2 * regexpl - Console Registry Explorer
4 * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to
18 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 // SecurityDescriptor.cpp: implementation of the CSecurityDescriptor class.
24 //////////////////////////////////////////////////////////////////////
27 #include "SecurityDescriptor.h"
30 PSID pSid
, // binary Sid
31 LPTSTR TextualSid
, // buffer for Textual representation of Sid
32 LPDWORD lpdwBufferLen
// required/provided TextualSid buffersize
35 PSID_IDENTIFIER_AUTHORITY psia
;
36 DWORD dwSubAuthorities
;
37 DWORD dwSidRev
=SID_REVISION
;
41 // Validate the binary SID.
43 if(!IsValidSid(pSid
)) return FALSE
;
45 // Get the identifier authority value from the SID.
47 psia
= GetSidIdentifierAuthority(pSid
);
49 // Get the number of subauthorities in the SID.
51 dwSubAuthorities
= *GetSidSubAuthorityCount(pSid
);
53 // Compute the buffer length.
54 // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
56 dwSidSize
=(15 + 12 + (12 * dwSubAuthorities
) + 1) * sizeof(TCHAR
);
58 // Check input buffer length.
59 // If too small, indicate the proper size and set last error.
61 if (*lpdwBufferLen
< dwSidSize
)
63 *lpdwBufferLen
= dwSidSize
;
64 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
68 // Add 'S' prefix and revision number to the string.
70 dwSidSize
=wsprintf(TextualSid
, TEXT("S-%lu-"), dwSidRev
);
72 // Add SID identifier authority to the string.
74 if ( (psia
->Value
[0] != 0) || (psia
->Value
[1] != 0) )
76 dwSidSize
+=wsprintf(TextualSid
+ lstrlen(TextualSid
),
77 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
78 (USHORT
)psia
->Value
[0],
79 (USHORT
)psia
->Value
[1],
80 (USHORT
)psia
->Value
[2],
81 (USHORT
)psia
->Value
[3],
82 (USHORT
)psia
->Value
[4],
83 (USHORT
)psia
->Value
[5]);
87 dwSidSize
+=wsprintf(TextualSid
+ lstrlen(TextualSid
),
89 (ULONG
)(psia
->Value
[5] ) +
90 (ULONG
)(psia
->Value
[4] << 8) +
91 (ULONG
)(psia
->Value
[3] << 16) +
92 (ULONG
)(psia
->Value
[2] << 24) );
95 // Add SID subauthorities to the string.
97 for (dwCounter
=0 ; dwCounter
< dwSubAuthorities
; dwCounter
++)
99 dwSidSize
+=wsprintf(TextualSid
+ dwSidSize
, TEXT("-%lu"),
100 *GetSidSubAuthority(pSid
, dwCounter
) );
106 const TCHAR
* GetSidTypeName(SID_NAME_USE Use
)
111 return _T("User SID");
113 return _T("Group SID");
115 return _T("Domain SID");
117 return _T("Alias SID");
118 case SidTypeWellKnownGroup
:
119 return _T("SID for a well-known group");
120 case SidTypeDeletedAccount
:
121 return _T("SID for a deleted account");
123 return _T("Invalid SID");
125 return _T("Unknown SID type");
127 return _T("Error. Cannot recognize SID type.");
131 //////////////////////////////////////////////////////////////////////
132 // Construction/Destruction
133 //////////////////////////////////////////////////////////////////////
135 CSecurityDescriptor::CSecurityDescriptor()
137 m_pSecurityDescriptor
= NULL
;
138 m_pCurrentACEHeader
= NULL
;
141 CSecurityDescriptor::~CSecurityDescriptor()
145 void CSecurityDescriptor::AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
)
147 m_pSecurityDescriptor
= pSecurityDescriptor
;
150 DWORD
CSecurityDescriptor::BeginDACLInteration()
152 if (!GetSecurityDescriptorDacl(m_pSecurityDescriptor
,&m_blnDACLPresent
,&m_pDACL
,&m_blnDACLDefaulted
))
154 throw GetLastError();
156 return ERROR_SUCCESS
;
159 BOOL
CSecurityDescriptor::DescriptorContainsDACL()
161 return m_blnDACLPresent
;
164 DWORD
CSecurityDescriptor::BeginSACLInteration()
166 if (!GetSecurityDescriptorSacl(m_pSecurityDescriptor
,&m_blnSACLPresent
,&m_pSACL
,&m_blnSACLDefaulted
))
167 throw GetLastError();
168 return ERROR_SUCCESS
;
171 BOOL
CSecurityDescriptor::DescriptorContainsSACL()
173 return m_blnSACLPresent
;
176 BOOL
CSecurityDescriptor::HasNULLDACL()
178 ASSERT(m_blnDACLPresent
);
179 return (m_pDACL
== NULL
);
182 BOOL
CSecurityDescriptor::HasValidDACL()
184 ASSERT(m_blnDACLPresent
);
185 ASSERT(m_pDACL
!= NULL
);
186 return IsValidAcl(m_pDACL
);
189 BOOL
CSecurityDescriptor::HasNULLSACL()
191 ASSERT(m_blnSACLPresent
);
192 return (m_pSACL
== NULL
);
195 BOOL
CSecurityDescriptor::HasValidSACL()
197 ASSERT(m_blnSACLPresent
);
198 ASSERT(m_pSACL
!= NULL
);
199 return IsValidAcl(m_pSACL
);
202 DWORD
CSecurityDescriptor::GetDACLEntriesCount()
204 ACL_SIZE_INFORMATION SizeInfo
;
205 if (!GetAclInformation(m_pDACL
,&SizeInfo
,sizeof(SizeInfo
),AclSizeInformation
))
206 throw GetLastError();
207 return SizeInfo
.AceCount
;
210 DWORD
CSecurityDescriptor::GetSACLEntriesCount()
212 ACL_SIZE_INFORMATION SizeInfo
;
213 if (!GetAclInformation(m_pSACL
,&SizeInfo
,sizeof(SizeInfo
),AclSizeInformation
))
214 throw GetLastError();
215 return SizeInfo
.AceCount
;
218 CSecurityDescriptor::ACEntryType
CSecurityDescriptor::GetDACLEntry(DWORD nIndex
)
221 if (!GetAce(m_pDACL
,nIndex
,&pACE
)) throw GetLastError();
222 m_pCurrentACEHeader
= (PACE_HEADER
)pACE
;
223 if (m_pCurrentACEHeader
->AceType
== ACCESS_ALLOWED_ACE_TYPE
)
227 if (m_pCurrentACEHeader
->AceType
== ACCESS_DENIED_ACE_TYPE
)
234 CSecurityDescriptor::ACEntryType
CSecurityDescriptor::GetSACLEntry(DWORD nIndex
, BOOL
& blnFailedAccess
, BOOL
& blnSeccessfulAccess
)
237 if (!GetAce(m_pSACL
,nIndex
,&pACE
)) throw GetLastError();
238 m_pCurrentACEHeader
= (PACE_HEADER
)pACE
;
239 if (m_pCurrentACEHeader
->AceType
== SYSTEM_AUDIT_ACE_TYPE
)
241 blnFailedAccess
= m_pCurrentACEHeader
->AceFlags
& FAILED_ACCESS_ACE_FLAG
;
242 blnSeccessfulAccess
= m_pCurrentACEHeader
->AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
;
248 PSID
CSecurityDescriptor::GetCurrentACE_SID()
250 ASSERT(m_pCurrentACEHeader
!= NULL
);
251 switch(m_pCurrentACEHeader
->AceType
)
253 case ACCESS_ALLOWED_ACE_TYPE
:
254 return ((PSID
)&(((ACCESS_ALLOWED_ACE
*)m_pCurrentACEHeader
)->SidStart
));
255 case ACCESS_DENIED_ACE_TYPE
:
256 return ((PSID
)&(((ACCESS_DENIED_ACE
*)m_pCurrentACEHeader
)->SidStart
));
257 case SYSTEM_AUDIT_ACE_TYPE
:
258 return ((PSID
)&(((SYSTEM_AUDIT_ACE
*)m_pCurrentACEHeader
)->SidStart
));
260 ASSERT(FALSE
); // Do not call this function for unknown ACE types !!!
265 void CSecurityDescriptor::GetCurrentACE_AccessMask(DWORD
& dwMask
)
267 ASSERT(m_pCurrentACEHeader
!= NULL
);
268 switch(m_pCurrentACEHeader
->AceType
)
270 case ACCESS_ALLOWED_ACE_TYPE
:
271 dwMask
= (((ACCESS_ALLOWED_ACE
*)m_pCurrentACEHeader
)->Mask
);
273 case ACCESS_DENIED_ACE_TYPE
:
274 dwMask
= (((ACCESS_DENIED_ACE
*)m_pCurrentACEHeader
)->Mask
);
276 case SYSTEM_AUDIT_ACE_TYPE
:
277 dwMask
= (((SYSTEM_AUDIT_ACE
*)m_pCurrentACEHeader
)->Mask
);
280 ASSERT(FALSE
); // Do not call this function for unknown ACE types !!!
285 void CSecurityDescriptor::GetCurrentACE_Flags(BYTE
& bFlags
)
287 ASSERT(m_pCurrentACEHeader
!= NULL
);
288 bFlags
= m_pCurrentACEHeader
->AceFlags
;