1 /* $Id: SecurityDescriptor.cpp,v 1.4 2001/01/13 23:54:41 narnaoud Exp $
3 * regexpl - Console Registry Explorer
5 * Copyright (C) 2000,2001 Nedko Arnaoudov <nedkohome@atia.com>
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 //////////////////////////////////////////////////////////////////////
29 #include "SecurityDescriptor.h"
33 // *** THIS SHOULD GO IN A MINGW/ROS HEADER - Begin
36 #define SID_REVISION (1) // Current revision level
38 //typedef struct _ACE_HEADER {
43 typedef ACE_HEADER
* PACE_HEADER
;
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)
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)
56 //#define SUCCESSFUL_ACCESS_ACE_FLAG (0x40)
57 //#define FAILED_ACCESS_ACE_FLAG (0x80)
59 typedef struct _SYSTEM_AUDIT_ACE
{
66 // *** THIS SHOULD GO IN A MINGW/ROS HEADER - End
70 PSID pSid
, // binary Sid
71 LPTSTR TextualSid
, // buffer for Textual representation of Sid
72 LPDWORD lpdwBufferLen
// required/provided TextualSid buffersize
75 PSID_IDENTIFIER_AUTHORITY psia
;
76 DWORD dwSubAuthorities
;
77 DWORD dwSidRev
=SID_REVISION
;
81 // Validate the binary SID.
83 if(!IsValidSid(pSid
)) return FALSE
;
85 // Get the identifier authority value from the SID.
87 psia
= GetSidIdentifierAuthority(pSid
);
89 // Get the number of subauthorities in the SID.
91 dwSubAuthorities
= *GetSidSubAuthorityCount(pSid
);
93 // Compute the buffer length.
94 // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
96 dwSidSize
=(15 + 12 + (12 * dwSubAuthorities
) + 1) * sizeof(TCHAR
);
98 // Check input buffer length.
99 // If too small, indicate the proper size and set last error.
101 if (*lpdwBufferLen
< dwSidSize
)
103 *lpdwBufferLen
= dwSidSize
;
104 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
108 // Add 'S' prefix and revision number to the string.
110 dwSidSize
=wsprintf(TextualSid
, TEXT("S-%lu-"), dwSidRev
);
112 // Add SID identifier authority to the string.
114 if ( (psia
->Value
[0] != 0) || (psia
->Value
[1] != 0) )
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]);
127 dwSidSize
+=wsprintf(TextualSid
+ lstrlen(TextualSid
),
129 (ULONG
)(psia
->Value
[5] ) +
130 (ULONG
)(psia
->Value
[4] << 8) +
131 (ULONG
)(psia
->Value
[3] << 16) +
132 (ULONG
)(psia
->Value
[2] << 24) );
135 // Add SID subauthorities to the string.
137 for (dwCounter
=0 ; dwCounter
< dwSubAuthorities
; dwCounter
++)
139 dwSidSize
+=wsprintf(TextualSid
+ dwSidSize
, TEXT("-%lu"),
140 *GetSidSubAuthority(pSid
, dwCounter
) );
146 const TCHAR
* GetSidTypeName(SID_NAME_USE Use
)
151 return _T("User SID");
153 return _T("Group SID");
155 return _T("Domain SID");
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");
163 return _T("Invalid SID");
165 return _T("Unknown SID type");
167 return _T("Error. Cannot recognize SID type.");
171 //////////////////////////////////////////////////////////////////////
172 // Construction/Destruction
173 //////////////////////////////////////////////////////////////////////
175 CSecurityDescriptor::CSecurityDescriptor()
177 m_pSecurityDescriptor
= NULL
;
178 m_pCurrentACEHeader
= NULL
;
181 CSecurityDescriptor::~CSecurityDescriptor()
185 void CSecurityDescriptor::AssociateDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor
)
187 m_pSecurityDescriptor
= pSecurityDescriptor
;
190 DWORD
CSecurityDescriptor::BeginDACLInteration()
192 if (!GetSecurityDescriptorDacl(m_pSecurityDescriptor
,&m_blnDACLPresent
,&m_pDACL
,&m_blnDACLDefaulted
))
194 throw GetLastError();
196 return ERROR_SUCCESS
;
199 BOOL
CSecurityDescriptor::DescriptorContainsDACL()
201 return m_blnDACLPresent
;
204 DWORD
CSecurityDescriptor::BeginSACLInteration()
206 if (!GetSecurityDescriptorSacl(m_pSecurityDescriptor
,&m_blnSACLPresent
,&m_pSACL
,&m_blnSACLDefaulted
))
207 throw GetLastError();
208 return ERROR_SUCCESS
;
211 BOOL
CSecurityDescriptor::DescriptorContainsSACL()
213 return m_blnSACLPresent
;
216 BOOL
CSecurityDescriptor::HasNULLDACL()
218 ASSERT(m_blnDACLPresent
);
219 return (m_pDACL
== NULL
);
222 BOOL
CSecurityDescriptor::HasValidDACL()
224 ASSERT(m_blnDACLPresent
);
225 ASSERT(m_pDACL
!= NULL
);
226 return IsValidAcl(m_pDACL
);
229 BOOL
CSecurityDescriptor::HasNULLSACL()
231 ASSERT(m_blnSACLPresent
);
232 return (m_pSACL
== NULL
);
235 BOOL
CSecurityDescriptor::HasValidSACL()
237 ASSERT(m_blnSACLPresent
);
238 ASSERT(m_pSACL
!= NULL
);
239 return IsValidAcl(m_pSACL
);
242 DWORD
CSecurityDescriptor::GetDACLEntriesCount()
244 ACL_SIZE_INFORMATION SizeInfo
;
245 if (!GetAclInformation(m_pDACL
,&SizeInfo
,sizeof(SizeInfo
),AclSizeInformation
))
246 throw GetLastError();
247 return SizeInfo
.AceCount
;
250 DWORD
CSecurityDescriptor::GetSACLEntriesCount()
252 ACL_SIZE_INFORMATION SizeInfo
;
253 if (!GetAclInformation(m_pSACL
,&SizeInfo
,sizeof(SizeInfo
),AclSizeInformation
))
254 throw GetLastError();
255 return SizeInfo
.AceCount
;
258 CSecurityDescriptor::ACEntryType
CSecurityDescriptor::GetDACLEntry(DWORD nIndex
)
261 if (!GetAce(m_pDACL
,nIndex
,&pACE
)) throw GetLastError();
262 m_pCurrentACEHeader
= (PACE_HEADER
)pACE
;
263 if (m_pCurrentACEHeader
->AceType
== ACCESS_ALLOWED_ACE_TYPE
)
267 if (m_pCurrentACEHeader
->AceType
== ACCESS_DENIED_ACE_TYPE
)
274 CSecurityDescriptor::ACEntryType
CSecurityDescriptor::GetSACLEntry(DWORD nIndex
, BOOL
& blnFailedAccess
, BOOL
& blnSeccessfulAccess
)
277 if (!GetAce(m_pSACL
,nIndex
,&pACE
)) throw GetLastError();
278 m_pCurrentACEHeader
= (PACE_HEADER
)pACE
;
279 if (m_pCurrentACEHeader
->AceType
== SYSTEM_AUDIT_ACE_TYPE
)
281 blnFailedAccess
= m_pCurrentACEHeader
->AceFlags
& FAILED_ACCESS_ACE_FLAG
;
282 blnSeccessfulAccess
= m_pCurrentACEHeader
->AceFlags
& SUCCESSFUL_ACCESS_ACE_FLAG
;
288 PSID
CSecurityDescriptor::GetCurrentACE_SID()
290 ASSERT(m_pCurrentACEHeader
!= NULL
);
291 switch(m_pCurrentACEHeader
->AceType
)
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
));
300 ASSERT(FALSE
); // Do not call this function for unknown ACE types !!!
305 void CSecurityDescriptor::GetCurrentACE_AccessMask(DWORD
& dwMask
)
307 ASSERT(m_pCurrentACEHeader
!= NULL
);
308 switch(m_pCurrentACEHeader
->AceType
)
310 case ACCESS_ALLOWED_ACE_TYPE
:
311 dwMask
= (((ACCESS_ALLOWED_ACE
*)m_pCurrentACEHeader
)->Mask
);
313 case ACCESS_DENIED_ACE_TYPE
:
314 dwMask
= (((ACCESS_DENIED_ACE
*)m_pCurrentACEHeader
)->Mask
);
316 case SYSTEM_AUDIT_ACE_TYPE
:
317 dwMask
= (((SYSTEM_AUDIT_ACE
*)m_pCurrentACEHeader
)->Mask
);
320 ASSERT(FALSE
); // Do not call this function for unknown ACE types !!!
325 void CSecurityDescriptor::GetCurrentACE_Flags(BYTE
& bFlags
)
327 ASSERT(m_pCurrentACEHeader
!= NULL
);
328 bFlags
= m_pCurrentACEHeader
->AceFlags
;