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 // ShellCommandDACL.cpp: implementation of the CShellCommandDACL class.
24 //////////////////////////////////////////////////////////////////////
27 #include "ShellCommandDACL.h"
28 #include "RegistryExplorer.h"
29 #include "SecurityDescriptor.h"
31 #define DACL_CMD _T("DACL")
32 #define DACL_CMD_LENGTH COMMAND_LENGTH(DACL_CMD)
33 #define DACL_CMD_SHORT_DESC DACL_CMD _T(" command is used to view")/*"/edit"*/_T(" key's DACL.\n")
35 //////////////////////////////////////////////////////////////////////
36 // Construction/Destruction
37 //////////////////////////////////////////////////////////////////////
39 CShellCommandDACL::CShellCommandDACL(CRegistryTree
& rTree
):m_rTree(rTree
)
44 CShellCommandDACL::~CShellCommandDACL()
49 BOOL
CShellCommandDACL::Match(const TCHAR
*pchCommand
)
51 if (_tcsicmp(pchCommand
,DACL_CMD
) == 0)
53 if (_tcsnicmp(pchCommand
,DACL_CMD
_T(".."),DACL_CMD_LENGTH
+2*sizeof(TCHAR
)) == 0)
55 if (_tcsnicmp(pchCommand
,DACL_CMD
_T("/") ,DACL_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
57 if (_tcsnicmp(pchCommand
,DACL_CMD
_T("\\"),DACL_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
62 int CShellCommandDACL::Execute(CConsole
&rConsole
, CArgumentParser
& rArguments
)
64 rArguments
.ResetArgumentIteration();
66 const TCHAR
*pszKey
= NULL
;
68 BOOL blnBadParameter
= FALSE
;
70 const TCHAR
*pchParameter
;
71 const TCHAR
*pchCommandItself
= rArguments
.GetNextArgument();
74 if ((_tcsnicmp(pchCommandItself
,DACL_CMD
_T(".."),DACL_CMD_LENGTH
+2*sizeof(TCHAR
)) == 0)||
75 (_tcsnicmp(pchCommandItself
,DACL_CMD
_T("\\"),DACL_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0))
77 pszKey
= pchCommandItself
+ DACL_CMD_LENGTH
;
79 else if (_tcsnicmp(pchCommandItself
,DACL_CMD
_T("/"),DACL_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
81 pchParameter
= pchCommandItself
+ DACL_CMD_LENGTH
;
82 goto CheckDACLArgument
;
85 while((pchParameter
= rArguments
.GetNextArgument()) != NULL
)
88 blnBadParameter
= FALSE
;
89 if ((_tcsicmp(pchParameter
,_T("/?")) == 0)
90 ||(_tcsicmp(pchParameter
,_T("-?")) == 0))
93 blnDo
= pszKey
!= NULL
;
97 pszKey
= pchParameter
;
102 blnBadParameter
= TRUE
;
106 rConsole
.Write(_T("Bad parameter: "));
107 rConsole
.Write(pchParameter
);
108 rConsole
.Write(_T("\n"));
114 if (!m_rTree
.GetKey(pszKey
?pszKey
:_T("."),KEY_QUERY_VALUE
|READ_CONTROL
,Key
))
116 rConsole
.Write(m_rTree
.GetLastErrorDescription());
122 rConsole
.Write(GetHelpString());
125 if (blnDo
&&blnHelp
) rConsole
.Write(_T("\n"));
132 rConsole
.Write(DACL_CMD COMMAND_NA_ON_ROOT
);
136 DWORD dwSecurityDescriptorLength
;
137 rConsole
.Write(_T("Key : "));
138 rConsole
.Write(_T("\\"));
139 rConsole
.Write(Key
.GetKeyName());
140 rConsole
.Write(_T("\n"));
141 PISECURITY_DESCRIPTOR pSecurityDescriptor
= NULL
;
142 TCHAR
*pchName
= NULL
, *pchDomainName
= NULL
;
145 nError
= Key
.GetSecurityDescriptorLength(&dwSecurityDescriptorLength
);
146 if (nError
!= ERROR_SUCCESS
)
149 pSecurityDescriptor
= (PISECURITY_DESCRIPTOR
) new unsigned char [dwSecurityDescriptorLength
];
150 DWORD dwSecurityDescriptorLength1
= dwSecurityDescriptorLength
;
151 nError
= Key
.GetSecurityDescriptor((SECURITY_INFORMATION
)DACL_SECURITY_INFORMATION
,pSecurityDescriptor
,&dwSecurityDescriptorLength1
);
152 if (nError
!= ERROR_SUCCESS
)
154 CSecurityDescriptor sd
;
155 sd
.AssociateDescriptor(pSecurityDescriptor
);
157 sd
.BeginDACLInteration();
158 ASSERT(sd
.DescriptorContainsDACL());
159 if (sd
.HasNULLDACL())
161 rConsole
.Write(_T("Key has not DACL.\n(This allows all access)\n"));
165 if (!sd
.HasValidDACL())
167 rConsole
.Write(_T("Invalid DACL.\n"));
171 DWORD nACECount
= sd
.GetDACLEntriesCount();
172 rConsole
.Write(_T("DACL has "));
174 rConsole
.Write(_itoa(nACECount
,Buffer
,10));
175 rConsole
.Write(_T(" ACEs.\n"));
178 rConsole
.Write(_T("(This denies all access)\n"));
182 for (DWORD i
= 0 ; i
< nACECount
; i
++)
184 rConsole
.Write(_T("\n"));
185 rConsole
.Write(_T("\tACE Index: "));
186 rConsole
.Write(_itoa(i
,Buffer
,10));
187 rConsole
.Write(_T("\n"));
188 rConsole
.Write(_T("\tACE Type: "));
189 switch (sd
.GetDACLEntry(i
))
191 case CSecurityDescriptor::AccessAlowed
:
192 rConsole
.Write(_T("Access-allowed\n"));
194 case CSecurityDescriptor::AccessDenied
:
195 rConsole
.Write(_T("Access-denied\n"));
198 rConsole
.Write(_T("Unknown.\nCannot continue dumping of the ACE list.\n"));
201 PSID pSID
= sd
.GetCurrentACE_SID();
202 if ((pSID
== NULL
)||(!IsValidSid(pSID
)))
204 rConsole
.Write(_T("\tInvalid SID.\n"));
208 DWORD dwSIDStringSize
= 0;
209 BOOL blnRet
= GetTextualSid(pSID
,NULL
,&dwSIDStringSize
);
211 ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER
);
212 TCHAR
*pchSID
= new TCHAR
[dwSIDStringSize
];
213 if(!GetTextualSid(pSID
,pchSID
,&dwSIDStringSize
))
215 DWORD dwError
= GetLastError();
216 ASSERT(dwError
!= ERROR_INSUFFICIENT_BUFFER
);
217 rConsole
.Write(_T("Error "));
219 rConsole
.Write(_itoa(dwError
,Buffer
,10));
220 rConsole
.Write(_T("\nGetting string representation of SID\n"));
224 rConsole
.Write(_T("\tSID: "));
225 rConsole
.Write(pchSID
);
226 rConsole
.Write(_T("\n"));
229 DWORD dwNameBufferLength
, dwDomainNameBufferLength
;
230 dwNameBufferLength
= 1024;
231 dwDomainNameBufferLength
= 1024;
232 pchName
= new TCHAR
[dwNameBufferLength
];
233 pchDomainName
= new TCHAR
[dwDomainNameBufferLength
];
234 DWORD dwNameLength
= dwNameBufferLength
, dwDomainNameLength
= dwDomainNameBufferLength
;
236 if (!LookupAccountSid(NULL
,pSID
,pchName
,&dwNameLength
,pchDomainName
,&dwDomainNameLength
,&Use
))
238 rConsole
.Write(_T("Error "));
240 rConsole
.Write(_itoa(GetLastError(),Buffer
,10));
241 rConsole
.Write(_T("\n"));
245 rConsole
.Write(_T("\tTrustee Domain: "));
246 rConsole
.Write(pchDomainName
);
247 rConsole
.Write(_T("\n"));
248 rConsole
.Write(_T("\tTrustee Name: "));
249 rConsole
.Write(pchName
);
250 rConsole
.Write(_T("\n\tSID type: "));
251 rConsole
.Write(GetSidTypeName(Use
));
252 rConsole
.Write(_T("\n"));
256 delete [] pchDomainName
;
257 pchDomainName
= NULL
;
261 sd
.GetCurrentACE_Flags(bFlags
);
262 wsprintf(Buffer
,_T("\tFlags: 0x%02lX\n"),bFlags
);
263 rConsole
.Write(Buffer
);
264 if (bFlags
& CONTAINER_INHERIT_ACE
)
266 rConsole
.Write(_T("\t\tCONTAINER_INHERIT_ACE\n"));
268 if (bFlags
& INHERIT_ONLY_ACE
)
270 rConsole
.Write(_T("\t\tINHERIT_ONLY_ACE\n"));
272 if (bFlags
& INHERITED_ACE
)
274 rConsole
.Write(_T("\t\tINHERITED_ACE\n"));
276 if (bFlags
& NO_PROPAGATE_INHERIT_ACE
)
278 rConsole
.Write(_T("\t\tNO_PROPAGATE_INHERIT_ACE\n"));
280 if (bFlags
& OBJECT_INHERIT_ACE
)
282 rConsole
.Write(_T("\t\tOBJECT_INHERIT_ACE\n"));
286 sd
.GetCurrentACE_AccessMask(dwAccessMask
);
287 wsprintf(Buffer
,_T("\tAccess Mask: 0x%08lX\n"),dwAccessMask
);
288 rConsole
.Write(Buffer
);
289 if (dwAccessMask
& GENERIC_READ
)
291 rConsole
.Write(_T("\t\tGENERIC_READ\n"));
293 if (dwAccessMask
& GENERIC_WRITE
)
295 rConsole
.Write(_T("\t\tGENERIC_WRITE\n"));
297 if (dwAccessMask
& GENERIC_EXECUTE
)
299 rConsole
.Write(_T("\t\tGENERIC_EXECUTE\n"));
301 if (dwAccessMask
& GENERIC_ALL
)
303 rConsole
.Write(_T("\t\tGENERIC_ALL\n"));
305 if (dwAccessMask
& SYNCHRONIZE
)
307 rConsole
.Write(_T("\t\tSYNCHRONIZE\n"));
309 if (dwAccessMask
& WRITE_OWNER
)
311 rConsole
.Write(_T("\t\tWRITE_OWNER\n"));
313 if (dwAccessMask
& WRITE_DAC
)
315 rConsole
.Write(_T("\t\tWRITE_DAC\n"));
317 if (dwAccessMask
& READ_CONTROL
)
319 rConsole
.Write(_T("\t\tREAD_CONTROL\n"));
321 if (dwAccessMask
& DELETE
)
323 rConsole
.Write(_T("\t\tDELETE\n"));
325 if (dwAccessMask
& KEY_CREATE_LINK
)
327 rConsole
.Write(_T("\t\tKEY_CREATE_LINK\n"));
329 if (dwAccessMask
& KEY_NOTIFY
)
331 rConsole
.Write(_T("\t\tKEY_NOTIFY\n"));
333 if (dwAccessMask
& KEY_ENUMERATE_SUB_KEYS
)
335 rConsole
.Write(_T("\t\tKEY_ENUMERATE_SUB_KEYS\n"));
337 if (dwAccessMask
& KEY_CREATE_SUB_KEY
)
339 rConsole
.Write(_T("\t\tKEY_CREATE_SUB_KEY\n"));
341 if (dwAccessMask
& KEY_SET_VALUE
)
343 rConsole
.Write(_T("\t\tKEY_SET_VALUE\n"));
345 if (dwAccessMask
& KEY_QUERY_VALUE
)
347 rConsole
.Write(_T("\t\tKEY_QUERY_VALUE\n"));
350 } // else (nACECount == 0)
351 } // else (!sd.HasValidDACL())
352 } // else (sd.HasNULLDACL())
354 delete [] pSecurityDescriptor
;
356 catch (DWORD dwError
)
358 rConsole
.Write(_T("Error "));
360 rConsole
.Write(_itoa(dwError
,Buffer
,10));
361 rConsole
.Write(_T("\n"));
362 if (pchName
) delete [] pchName
;
363 if (pchDomainName
) delete [] pchDomainName
;
364 if (pSecurityDescriptor
) delete [] pSecurityDescriptor
;
370 const TCHAR
* CShellCommandDACL::GetHelpString()
372 return DACL_CMD_SHORT_DESC
373 _T("Syntax: ") DACL_CMD
_T(" [<KEY>] [/?]\n\n")
374 _T(" <KEY> - Optional relative path of desired key.\n")
375 _T(" /? - This help.\n\n")
376 _T("Without parameters, command displays DACL of current key.\n");
379 const TCHAR
* CShellCommandDACL::GetHelpShortDescriptionString()
381 return DACL_CMD_SHORT_DESC
;