1 /* $Id: ShellCommandDACL.cpp,v 1.5 2004/10/11 01:24:22 sedwards 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 // ShellCommandDACL.cpp: implementation of the CShellCommandDACL class.
25 //////////////////////////////////////////////////////////////////////
28 #include "ShellCommandDACL.h"
29 #include "RegistryExplorer.h"
30 #include "SecurityDescriptor.h"
32 #define DACL_CMD _T("DACL")
33 #define DACL_CMD_LENGTH COMMAND_LENGTH(DACL_CMD)
34 #define DACL_CMD_SHORT_DESC DACL_CMD _T(" command is used to view")/*"/edit"*/_T(" key's DACL.\n")
36 //////////////////////////////////////////////////////////////////////
37 // Construction/Destruction
38 //////////////////////////////////////////////////////////////////////
40 CShellCommandDACL::CShellCommandDACL(CRegistryTree
& rTree
):m_rTree(rTree
)
45 CShellCommandDACL::~CShellCommandDACL()
50 BOOL
CShellCommandDACL::Match(const TCHAR
*pchCommand
)
52 if (_tcsicmp(pchCommand
,DACL_CMD
) == 0)
54 if (_tcsnicmp(pchCommand
,DACL_CMD
_T(".."),DACL_CMD_LENGTH
+2*sizeof(TCHAR
)) == 0)
56 if (_tcsnicmp(pchCommand
,DACL_CMD
_T("/") ,DACL_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
58 if (_tcsnicmp(pchCommand
,DACL_CMD
_T("\\"),DACL_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
63 int CShellCommandDACL::Execute(CConsole
&rConsole
, CArgumentParser
& rArguments
)
65 rArguments
.ResetArgumentIteration();
67 const TCHAR
*pszKey
= NULL
;
69 BOOL blnBadParameter
= FALSE
;
71 const TCHAR
*pchParameter
;
72 const TCHAR
*pchCommandItself
= rArguments
.GetNextArgument();
75 if ((_tcsnicmp(pchCommandItself
,DACL_CMD
_T(".."),DACL_CMD_LENGTH
+2*sizeof(TCHAR
)) == 0)||
76 (_tcsnicmp(pchCommandItself
,DACL_CMD
_T("\\"),DACL_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0))
78 pszKey
= pchCommandItself
+ DACL_CMD_LENGTH
;
80 else if (_tcsnicmp(pchCommandItself
,DACL_CMD
_T("/"),DACL_CMD_LENGTH
+1*sizeof(TCHAR
)) == 0)
82 pchParameter
= pchCommandItself
+ DACL_CMD_LENGTH
;
83 goto CheckDACLArgument
;
86 while((pchParameter
= rArguments
.GetNextArgument()) != NULL
)
89 blnBadParameter
= FALSE
;
90 if ((_tcsicmp(pchParameter
,_T("/?")) == 0)
91 ||(_tcsicmp(pchParameter
,_T("-?")) == 0))
94 blnDo
= pszKey
!= NULL
;
98 pszKey
= pchParameter
;
103 blnBadParameter
= TRUE
;
107 rConsole
.Write(_T("Bad parameter: "));
108 rConsole
.Write(pchParameter
);
109 rConsole
.Write(_T("\n"));
115 if (!m_rTree
.GetKey(pszKey
?pszKey
:_T("."),KEY_QUERY_VALUE
|READ_CONTROL
,Key
))
117 rConsole
.Write(m_rTree
.GetLastErrorDescription());
123 rConsole
.Write(GetHelpString());
126 if (blnDo
&&blnHelp
) rConsole
.Write(_T("\n"));
133 rConsole
.Write(DACL_CMD COMMAND_NA_ON_ROOT
);
137 DWORD dwSecurityDescriptorLength
;
138 rConsole
.Write(_T("Key : "));
139 rConsole
.Write(_T("\\"));
140 rConsole
.Write(Key
.GetKeyName());
141 rConsole
.Write(_T("\n"));
142 PSECURITY_DESCRIPTOR pSecurityDescriptor
= NULL
;
143 TCHAR
*pchName
= NULL
, *pchDomainName
= NULL
;
146 nError
= Key
.GetSecurityDescriptorLength(&dwSecurityDescriptorLength
);
147 if (nError
!= ERROR_SUCCESS
)
150 pSecurityDescriptor
= (PSECURITY_DESCRIPTOR
) new unsigned char [dwSecurityDescriptorLength
];
151 DWORD dwSecurityDescriptorLength1
= dwSecurityDescriptorLength
;
152 nError
= Key
.GetSecurityDescriptor((SECURITY_INFORMATION
)DACL_SECURITY_INFORMATION
,pSecurityDescriptor
,&dwSecurityDescriptorLength1
);
153 if (nError
!= ERROR_SUCCESS
)
155 CSecurityDescriptor sd
;
156 sd
.AssociateDescriptor(pSecurityDescriptor
);
158 sd
.BeginDACLInteration();
159 ASSERT(sd
.DescriptorContainsDACL());
160 if (sd
.HasNULLDACL())
162 rConsole
.Write(_T("Key has not DACL.\n(This allows all access)\n"));
166 if (!sd
.HasValidDACL())
168 rConsole
.Write(_T("Invalid DACL.\n"));
172 DWORD nACECount
= sd
.GetDACLEntriesCount();
173 rConsole
.Write(_T("DACL has "));
175 rConsole
.Write(_itoa(nACECount
,Buffer
,10));
176 rConsole
.Write(_T(" ACEs.\n"));
179 rConsole
.Write(_T("(This denies all access)\n"));
183 for (DWORD i
= 0 ; i
< nACECount
; i
++)
185 rConsole
.Write(_T("\n"));
186 rConsole
.Write(_T("\tACE Index: "));
187 rConsole
.Write(_itoa(i
,Buffer
,10));
188 rConsole
.Write(_T("\n"));
189 rConsole
.Write(_T("\tACE Type: "));
190 switch (sd
.GetDACLEntry(i
))
192 case CSecurityDescriptor::AccessAlowed
:
193 rConsole
.Write(_T("Access-allowed\n"));
195 case CSecurityDescriptor::AccessDenied
:
196 rConsole
.Write(_T("Access-denied\n"));
199 rConsole
.Write(_T("Unknown.\nCannot continue dumping of the ACE list.\n"));
202 PSID pSID
= sd
.GetCurrentACE_SID();
203 if ((pSID
== NULL
)||(!IsValidSid(pSID
)))
205 rConsole
.Write(_T("\tInvalid SID.\n"));
209 DWORD dwSIDStringSize
= 0;
210 BOOL blnRet
= GetTextualSid(pSID
,NULL
,&dwSIDStringSize
);
212 ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER
);
213 TCHAR
*pchSID
= new TCHAR
[dwSIDStringSize
];
214 if(!GetTextualSid(pSID
,pchSID
,&dwSIDStringSize
))
216 DWORD dwError
= GetLastError();
217 ASSERT(dwError
!= ERROR_INSUFFICIENT_BUFFER
);
218 rConsole
.Write(_T("Error "));
220 rConsole
.Write(_itoa(dwError
,Buffer
,10));
221 rConsole
.Write(_T("\nGetting string representation of SID\n"));
225 rConsole
.Write(_T("\tSID: "));
226 rConsole
.Write(pchSID
);
227 rConsole
.Write(_T("\n"));
230 DWORD dwNameBufferLength
, dwDomainNameBufferLength
;
231 dwNameBufferLength
= 1024;
232 dwDomainNameBufferLength
= 1024;
233 pchName
= new TCHAR
[dwNameBufferLength
];
234 pchDomainName
= new TCHAR
[dwDomainNameBufferLength
];
235 DWORD dwNameLength
= dwNameBufferLength
, dwDomainNameLength
= dwDomainNameBufferLength
;
237 if (!LookupAccountSid(NULL
,pSID
,pchName
,&dwNameLength
,pchDomainName
,&dwDomainNameLength
,&Use
))
239 rConsole
.Write(_T("Error "));
241 rConsole
.Write(_itoa(GetLastError(),Buffer
,10));
242 rConsole
.Write(_T("\n"));
246 rConsole
.Write(_T("\tTrustee Domain: "));
247 rConsole
.Write(pchDomainName
);
248 rConsole
.Write(_T("\n"));
249 rConsole
.Write(_T("\tTrustee Name: "));
250 rConsole
.Write(pchName
);
251 rConsole
.Write(_T("\n\tSID type: "));
252 rConsole
.Write(GetSidTypeName(Use
));
253 rConsole
.Write(_T("\n"));
257 delete [] pchDomainName
;
258 pchDomainName
= NULL
;
262 sd
.GetCurrentACE_Flags(bFlags
);
263 wsprintf(Buffer
,_T("\tFlags: 0x%02lX\n"),bFlags
);
264 rConsole
.Write(Buffer
);
265 if (bFlags
& CONTAINER_INHERIT_ACE
)
267 rConsole
.Write(_T("\t\tCONTAINER_INHERIT_ACE\n"));
269 if (bFlags
& INHERIT_ONLY_ACE
)
271 rConsole
.Write(_T("\t\tINHERIT_ONLY_ACE\n"));
273 if (bFlags
& INHERITED_ACE
)
275 rConsole
.Write(_T("\t\tINHERITED_ACE\n"));
277 if (bFlags
& NO_PROPAGATE_INHERIT_ACE
)
279 rConsole
.Write(_T("\t\tNO_PROPAGATE_INHERIT_ACE\n"));
281 if (bFlags
& OBJECT_INHERIT_ACE
)
283 rConsole
.Write(_T("\t\tOBJECT_INHERIT_ACE\n"));
287 sd
.GetCurrentACE_AccessMask(dwAccessMask
);
288 wsprintf(Buffer
,_T("\tAccess Mask: 0x%08lX\n"),dwAccessMask
);
289 rConsole
.Write(Buffer
);
290 if (dwAccessMask
& GENERIC_READ
)
292 rConsole
.Write(_T("\t\tGENERIC_READ\n"));
294 if (dwAccessMask
& GENERIC_WRITE
)
296 rConsole
.Write(_T("\t\tGENERIC_WRITE\n"));
298 if (dwAccessMask
& GENERIC_EXECUTE
)
300 rConsole
.Write(_T("\t\tGENERIC_EXECUTE\n"));
302 if (dwAccessMask
& GENERIC_ALL
)
304 rConsole
.Write(_T("\t\tGENERIC_ALL\n"));
306 if (dwAccessMask
& SYNCHRONIZE
)
308 rConsole
.Write(_T("\t\tSYNCHRONIZE\n"));
310 if (dwAccessMask
& WRITE_OWNER
)
312 rConsole
.Write(_T("\t\tWRITE_OWNER\n"));
314 if (dwAccessMask
& WRITE_DAC
)
316 rConsole
.Write(_T("\t\tWRITE_DAC\n"));
318 if (dwAccessMask
& READ_CONTROL
)
320 rConsole
.Write(_T("\t\tREAD_CONTROL\n"));
322 if (dwAccessMask
& DELETE
)
324 rConsole
.Write(_T("\t\tDELETE\n"));
326 if (dwAccessMask
& KEY_CREATE_LINK
)
328 rConsole
.Write(_T("\t\tKEY_CREATE_LINK\n"));
330 if (dwAccessMask
& KEY_NOTIFY
)
332 rConsole
.Write(_T("\t\tKEY_NOTIFY\n"));
334 if (dwAccessMask
& KEY_ENUMERATE_SUB_KEYS
)
336 rConsole
.Write(_T("\t\tKEY_ENUMERATE_SUB_KEYS\n"));
338 if (dwAccessMask
& KEY_CREATE_SUB_KEY
)
340 rConsole
.Write(_T("\t\tKEY_CREATE_SUB_KEY\n"));
342 if (dwAccessMask
& KEY_SET_VALUE
)
344 rConsole
.Write(_T("\t\tKEY_SET_VALUE\n"));
346 if (dwAccessMask
& KEY_QUERY_VALUE
)
348 rConsole
.Write(_T("\t\tKEY_QUERY_VALUE\n"));
351 } // else (nACECount == 0)
352 } // else (!sd.HasValidDACL())
353 } // else (sd.HasNULLDACL())
355 delete [] pSecurityDescriptor
;
357 catch (DWORD dwError
)
359 rConsole
.Write(_T("Error "));
361 rConsole
.Write(_itoa(dwError
,Buffer
,10));
362 rConsole
.Write(_T("\n"));
363 if (pchName
) delete [] pchName
;
364 if (pchDomainName
) delete [] pchDomainName
;
365 if (pSecurityDescriptor
) delete [] pSecurityDescriptor
;
371 const TCHAR
* CShellCommandDACL::GetHelpString()
373 return DACL_CMD_SHORT_DESC
374 _T("Syntax: ") DACL_CMD
_T(" [<KEY>] [/?]\n\n")
375 _T(" <KEY> - Optional relative path of desired key.\n")
376 _T(" /? - This help.\n\n")
377 _T("Without parameters, command displays DACL of current key.\n");
380 const TCHAR
* CShellCommandDACL::GetHelpShortDescriptionString()
382 return DACL_CMD_SHORT_DESC
;