4e006d23cf48764f8264d869568c8d781298edce
[reactos.git] / rosapps / sysutils / regexpl / ShellCommandDACL.cpp
1 /* $Id: ShellCommandDACL.cpp,v 1.1 2000/10/04 21:04:30 ea Exp $
2 *
3 * regexpl - Console Registry Explorer
4 *
5 * Copyright (c) 1999-2000 Nedko Arnaoudov <nedkohome@atia.com>
6 *
7 * License: GNU GPL
8 *
9 */
10
11 // ShellCommandDACL.cpp: implementation of the CShellCommandDACL class.
12 //
13 //////////////////////////////////////////////////////////////////////
14
15 #include "ph.h"
16 #include "ShellCommandDACL.h"
17 #include "RegistryExplorer.h"
18 #include "SecurityDescriptor.h"
19
20 #define DACL_CMD _T("DACL")
21 #define DACL_CMD_LENGTH COMMAND_LENGTH(DACL_CMD)
22 #define DACL_CMD_SHORT_DESC DACL_CMD _T(" command is used to view")/*"/edit"*/_T(" key's DACL.\n")
23
24 //////////////////////////////////////////////////////////////////////
25 // Construction/Destruction
26 //////////////////////////////////////////////////////////////////////
27
28 CShellCommandDACL::CShellCommandDACL(CRegistryTree& rTree):m_rTree(rTree)
29 {
30
31 }
32
33 CShellCommandDACL::~CShellCommandDACL()
34 {
35
36 }
37
38 BOOL CShellCommandDACL::Match(const TCHAR *pchCommand)
39 {
40 if (_tcsicmp(pchCommand,DACL_CMD) == 0)
41 return TRUE;
42 if (_tcsnicmp(pchCommand,DACL_CMD _T(".."),DACL_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
43 return TRUE;
44 if (_tcsnicmp(pchCommand,DACL_CMD _T("/") ,DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
45 return TRUE;
46 if (_tcsnicmp(pchCommand,DACL_CMD _T("\\"),DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
47 return TRUE;
48 return FALSE;
49 }
50
51 int CShellCommandDACL::Execute(CConsole &rConsole, CArgumentParser& rArguments)
52 {
53 rArguments.ResetArgumentIteration();
54
55 const TCHAR *pchKey = NULL;
56 BOOL blnDo = TRUE;
57 BOOL blnBadParameter = FALSE;
58 BOOL blnHelp = FALSE;
59 const TCHAR *pchParameter;
60 const TCHAR *pchCommandItself = rArguments.GetNextArgument();
61 DWORD dwError;
62
63 if ((_tcsnicmp(pchCommandItself,DACL_CMD _T(".."),DACL_CMD_LENGTH+2*sizeof(TCHAR)) == 0)||
64 (_tcsnicmp(pchCommandItself,DACL_CMD _T("\\"),DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0))
65 {
66 pchKey = pchCommandItself + DACL_CMD_LENGTH;
67 }
68 else if (_tcsnicmp(pchCommandItself,DACL_CMD _T("/"),DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
69 {
70 pchParameter = pchCommandItself + DACL_CMD_LENGTH;
71 goto CheckDACLArgument;
72 }
73
74 while((pchParameter = rArguments.GetNextArgument()) != NULL)
75 {
76 CheckDACLArgument:
77 blnBadParameter = FALSE;
78 if ((_tcsicmp(pchParameter,_T("/?")) == 0)
79 ||(_tcsicmp(pchParameter,_T("-?")) == 0))
80 {
81 blnHelp = TRUE;
82 blnDo = pchKey != NULL;
83 }
84 else if (!pchKey)
85 {
86 pchKey = pchParameter;
87 blnDo = TRUE;
88 }
89 else
90 {
91 blnBadParameter = TRUE;
92 }
93 if (blnBadParameter)
94 {
95 rConsole.Write(_T("Bad parameter: "));
96 rConsole.Write(pchParameter);
97 rConsole.Write(_T("\n"));
98 }
99 }
100
101 CRegistryTree *pTree = NULL;
102 CRegistryKey *pKey = NULL;
103 if (pchKey)
104 {
105 pTree = new CRegistryTree(m_rTree);
106 if ((_tcscmp(pTree->GetCurrentPath(),m_rTree.GetCurrentPath()) != 0)||(!pTree->ChangeCurrentKey(pchKey)))
107 {
108 rConsole.Write(_T("Cannot open key "));
109 rConsole.Write(pchKey);
110 rConsole.Write(_T("\n"));
111 //blnHelp = TRUE;
112 blnDo = FALSE;
113 }
114 else
115 {
116 pKey = pTree->GetCurrentKey();
117 }
118 }
119 else
120 {
121 pKey = m_rTree.GetCurrentKey();
122 }
123
124 if (blnHelp)
125 {
126 rConsole.Write(GetHelpString());
127 }
128
129 if (blnDo&&blnHelp) rConsole.Write(_T("\n"));
130
131 if (blnDo)
132 {
133 if (pKey == NULL)
134 { // root key
135 rConsole.Write(DACL_CMD COMMAND_NA_ON_ROOT);
136 }
137 else
138 {
139 DWORD dwSecurityDescriptorLength;
140 rConsole.Write(_T("Key : "));
141 rConsole.Write(_T("\\"));
142 rConsole.Write(pTree?pTree->GetCurrentPath():m_rTree.GetCurrentPath());
143 rConsole.Write(_T("\n"));
144 PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
145 TCHAR *pchName = NULL, *pchDomainName = NULL;
146 try
147 {
148 dwError = pKey->GetSecurityDescriptorLength(&dwSecurityDescriptorLength);
149 if (dwError != ERROR_SUCCESS) throw dwError;
150
151 pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new unsigned char [dwSecurityDescriptorLength];
152 DWORD dwSecurityDescriptorLength1 = dwSecurityDescriptorLength;
153 dwError = pKey->GetSecurityDescriptor((SECURITY_INFORMATION)DACL_SECURITY_INFORMATION,pSecurityDescriptor,&dwSecurityDescriptorLength1);
154 if (dwError != ERROR_SUCCESS) throw dwError;
155 CSecurityDescriptor sd;
156 sd.AssociateDescriptor(pSecurityDescriptor);
157
158 sd.BeginDACLInteration();
159 ASSERT(sd.DescriptorContainsDACL());
160 if (sd.HasNULLDACL())
161 {
162 rConsole.Write(_T("Key has not DACL.\n(This allows all access)\n"));
163 }
164 else
165 {
166 if (!sd.HasValidDACL())
167 {
168 rConsole.Write(_T("Invalid DACL.\n"));
169 }
170 else
171 {
172 DWORD nACECount = sd.GetDACLEntriesCount();
173 rConsole.Write(_T("DACL has "));
174 TCHAR Buffer[256];
175 rConsole.Write(_itot(nACECount,Buffer,10));
176 rConsole.Write(_T(" ACEs.\n"));
177 if (nACECount == 0)
178 {
179 rConsole.Write(_T("(This denies all access)\n"));
180 }
181 else
182 {
183 for (DWORD i = 0 ; i < nACECount ; i++)
184 {
185 rConsole.Write(_T("\n"));
186 rConsole.Write(_T("\tACE Index: "));
187 rConsole.Write(_itot(i,Buffer,10));
188 rConsole.Write(_T("\n"));
189 rConsole.Write(_T("\tACE Type: "));
190 switch (sd.GetDACLEntry(i))
191 {
192 case CSecurityDescriptor::AccessAlowed:
193 rConsole.Write(_T("Access-allowed\n"));
194 break;
195 case CSecurityDescriptor::AccessDenied:
196 rConsole.Write(_T("Access-denied\n"));
197 break;
198 default:
199 rConsole.Write(_T("Unknown.\nCannot continue dumping of the ACE list.\n"));
200 goto AbortDumpDACL;
201 }
202 PSID pSID = sd.GetCurrentACE_SID();
203 if ((pSID == NULL)||(!IsValidSid(pSID)))
204 {
205 rConsole.Write(_T("\tInvalid SID.\n"));
206 }
207 else
208 {
209 DWORD dwSIDStringSize = 0;
210 BOOL blnRet = GetTextualSid(pSID,NULL,&dwSIDStringSize);
211 ASSERT(!blnRet);
212 ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
213 TCHAR *pchSID = new TCHAR[dwSIDStringSize];
214 if(!GetTextualSid(pSID,pchSID,&dwSIDStringSize))
215 {
216 dwError = GetLastError();
217 ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER);
218 rConsole.Write(_T("Error "));
219 TCHAR Buffer[256];
220 rConsole.Write(_itot(dwError,Buffer,10));
221 rConsole.Write(_T("\nGetting string representation of SID\n"));
222 }
223 else
224 {
225 rConsole.Write(_T("\tSID: "));
226 rConsole.Write(pchSID);
227 rConsole.Write(_T("\n"));
228 }
229 delete pchSID;
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;
236 SID_NAME_USE Use;
237 if (!LookupAccountSid(NULL,pSID,pchName,&dwNameLength,pchDomainName,&dwDomainNameLength,&Use))
238 {
239 rConsole.Write(_T("Error "));
240 TCHAR Buffer[256];
241 rConsole.Write(_itot(GetLastError(),Buffer,10));
242 rConsole.Write(_T("\n"));
243 }
244 else
245 {
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"));
254 }
255 delete [] pchName;
256 pchName = NULL;
257 delete [] pchDomainName;
258 pchDomainName = NULL;
259 }
260 DWORD dwAccessMask;
261 sd.GetCurrentACE_AccessMask(dwAccessMask);
262 wsprintf(Buffer,_T("\tAccess Mask: 0x%08lX\n"),dwAccessMask);
263 rConsole.Write(Buffer);
264 if (dwAccessMask & GENERIC_READ)
265 {
266 rConsole.Write(_T("\t\tGENERIC_READ\n"));
267 }
268 if (dwAccessMask & GENERIC_WRITE)
269 {
270 rConsole.Write(_T("\t\tGENERIC_WRITE\n"));
271 }
272 if (dwAccessMask & GENERIC_EXECUTE)
273 {
274 rConsole.Write(_T("\t\tGENERIC_EXECUTE\n"));
275 }
276 if (dwAccessMask & GENERIC_ALL)
277 {
278 rConsole.Write(_T("\t\tGENERIC_ALL\n"));
279 }
280 if (dwAccessMask & SYNCHRONIZE)
281 {
282 rConsole.Write(_T("\t\tSYNCHRONIZE\n"));
283 }
284 if (dwAccessMask & WRITE_OWNER)
285 {
286 rConsole.Write(_T("\t\tWRITE_OWNER\n"));
287 }
288 if (dwAccessMask & WRITE_DAC)
289 {
290 rConsole.Write(_T("\t\tWRITE_DAC\n"));
291 }
292 if (dwAccessMask & READ_CONTROL)
293 {
294 rConsole.Write(_T("\t\tREAD_CONTROL\n"));
295 }
296 if (dwAccessMask & DELETE)
297 {
298 rConsole.Write(_T("\t\tDELETE\n"));
299 }
300 if (dwAccessMask & KEY_CREATE_LINK)
301 {
302 rConsole.Write(_T("\t\tKEY_CREATE_LINK\n"));
303 }
304 if (dwAccessMask & KEY_NOTIFY)
305 {
306 rConsole.Write(_T("\t\tKEY_NOTIFY\n"));
307 }
308 if (dwAccessMask & KEY_ENUMERATE_SUB_KEYS)
309 {
310 rConsole.Write(_T("\t\tKEY_ENUMERATE_SUB_KEYS\n"));
311 }
312 if (dwAccessMask & KEY_CREATE_SUB_KEY)
313 {
314 rConsole.Write(_T("\t\tKEY_CREATE_SUB_KEY\n"));
315 }
316 if (dwAccessMask & KEY_SET_VALUE)
317 {
318 rConsole.Write(_T("\t\tKEY_SET_VALUE\n"));
319 }
320 if (dwAccessMask & KEY_QUERY_VALUE)
321 {
322 rConsole.Write(_T("\t\tKEY_QUERY_VALUE\n"));
323 }
324 } // for
325 } // else (nACECount == 0)
326 } // else (!sd.HasValidDACL())
327 } // else (sd.HasNULLDACL())
328 AbortDumpDACL:
329 delete [] pSecurityDescriptor;
330 } // try
331 catch (DWORD dwError)
332 {
333 rConsole.Write(_T("Error "));
334 TCHAR Buffer[256];
335 rConsole.Write(_itot(dwError,Buffer,10));
336 rConsole.Write(_T("\n"));
337 if (pchName) delete [] pchName;
338 if (pchDomainName) delete [] pchDomainName;
339 if (pSecurityDescriptor) delete [] pSecurityDescriptor;
340 }
341 } // else (pKey == NULL)
342 } // if (blnDo)
343
344 if (pTree)
345 delete pTree;
346
347 return 0;
348 }
349
350 const TCHAR * CShellCommandDACL::GetHelpString()
351 {
352 return DACL_CMD_SHORT_DESC
353 _T("Syntax: ") DACL_CMD _T(" [<KEY>] [/?]\n\n")
354 _T(" <KEY> - Optional relative path of desired key.\n")
355 _T(" /? - This help.\n\n")
356 _T("Without parameters, command displays DACL of current key.\n");
357 }
358
359 const TCHAR * CShellCommandDACL::GetHelpShortDescriptionString()
360 {
361 return DACL_CMD_SHORT_DESC;
362 }