ReactOS  0.4.14-dev-384-g5b37caa
ShellCommandDACL.cpp
Go to the documentation of this file.
1 /*
2  * regexpl - Console Registry Explorer
3  *
4  * Copyright (C) 2000-2005 Nedko Arnaudov <nedko@users.sourceforge.net>
5  *
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.
10  *
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.
15  *
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.
20  */
21 
22 // ShellCommandDACL.cpp: implementation of the CShellCommandDACL class.
23 //
25 
26 #include "ph.h"
27 #include "ShellCommandDACL.h"
28 #include "RegistryExplorer.h"
29 #include "SecurityDescriptor.h"
30 
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")
34 
36 // Construction/Destruction
38 
40 {
41 
42 }
43 
45 {
46 
47 }
48 
50 {
51  if (_tcsicmp(pchCommand,DACL_CMD) == 0)
52  return TRUE;
53  if (_tcsnicmp(pchCommand,DACL_CMD _T(".."),DACL_CMD_LENGTH+2*sizeof(TCHAR)) == 0)
54  return TRUE;
55  if (_tcsnicmp(pchCommand,DACL_CMD _T("/") ,DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
56  return TRUE;
57  if (_tcsnicmp(pchCommand,DACL_CMD _T("\\"),DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
58  return TRUE;
59  return FALSE;
60 }
61 
63 {
64  rArguments.ResetArgumentIteration();
65 
66  const TCHAR *pszKey = NULL;
67  BOOL blnDo = TRUE;
68  BOOL blnBadParameter = FALSE;
69  BOOL blnHelp = FALSE;
70  const TCHAR *pchParameter;
71  const TCHAR *pchCommandItself = rArguments.GetNextArgument();
72  LONG nError;
73 
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))
76  {
77  pszKey = pchCommandItself + DACL_CMD_LENGTH;
78  }
79  else if (_tcsnicmp(pchCommandItself,DACL_CMD _T("/"),DACL_CMD_LENGTH+1*sizeof(TCHAR)) == 0)
80  {
81  pchParameter = pchCommandItself + DACL_CMD_LENGTH;
82  goto CheckDACLArgument;
83  }
84 
85  while((pchParameter = rArguments.GetNextArgument()) != NULL)
86  {
87 CheckDACLArgument:
88  blnBadParameter = FALSE;
89  if ((_tcsicmp(pchParameter,_T("/?")) == 0)
90  ||(_tcsicmp(pchParameter,_T("-?")) == 0))
91  {
92  blnHelp = TRUE;
93  blnDo = pszKey != NULL;
94  }
95  else if (!pszKey)
96  {
97  pszKey = pchParameter;
98  blnDo = TRUE;
99  }
100  else
101  {
102  blnBadParameter = TRUE;
103  }
104  if (blnBadParameter)
105  {
106  rConsole.Write(_T("Bad parameter: "));
107  rConsole.Write(pchParameter);
108  rConsole.Write(_T("\n"));
109  }
110  }
111 
113 
114  if (!m_rTree.GetKey(pszKey?pszKey:_T("."),KEY_QUERY_VALUE|READ_CONTROL,Key))
115  {
117  blnDo = FALSE;
118  }
119 
120  if (blnHelp)
121  {
122  rConsole.Write(GetHelpString());
123  }
124 
125  if (blnDo&&blnHelp) rConsole.Write(_T("\n"));
126 
127  if (!blnDo)
128  return 0;
129 
130  if (Key.IsRoot())
131  { // root key
133  return 0;
134  }
135 
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;
143  try
144  {
145  nError = Key.GetSecurityDescriptorLength(&dwSecurityDescriptorLength);
146  if (nError != ERROR_SUCCESS)
147  throw nError;
148 
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)
153  throw nError;
155  sd.AssociateDescriptor(pSecurityDescriptor);
156 
157  sd.BeginDACLInteration();
158  ASSERT(sd.DescriptorContainsDACL());
159  if (sd.HasNULLDACL())
160  {
161  rConsole.Write(_T("Key has not DACL.\n(This allows all access)\n"));
162  }
163  else
164  {
165  if (!sd.HasValidDACL())
166  {
167  rConsole.Write(_T("Invalid DACL.\n"));
168  }
169  else
170  {
171  DWORD nACECount = sd.GetDACLEntriesCount();
172  rConsole.Write(_T("DACL has "));
173  TCHAR Buffer[256];
174  rConsole.Write(_itoa(nACECount,Buffer,10));
175  rConsole.Write(_T(" ACEs.\n"));
176  if (nACECount == 0)
177  {
178  rConsole.Write(_T("(This denies all access)\n"));
179  }
180  else
181  {
182  for (DWORD i = 0 ; i < nACECount ; i++)
183  {
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))
190  {
192  rConsole.Write(_T("Access-allowed\n"));
193  break;
195  rConsole.Write(_T("Access-denied\n"));
196  break;
197  default:
198  rConsole.Write(_T("Unknown.\nCannot continue dumping of the ACE list.\n"));
199  goto AbortDumpDACL;
200  }
201  PSID pSID = sd.GetCurrentACE_SID();
202  if ((pSID == NULL)||(!IsValidSid(pSID)))
203  {
204  rConsole.Write(_T("\tInvalid SID.\n"));
205  }
206  else
207  {
208  DWORD dwSIDStringSize = 0;
209  BOOL blnRet = GetTextualSid(pSID,NULL,&dwSIDStringSize);
210  ASSERT(!blnRet);
212  TCHAR *pchSID = new TCHAR[dwSIDStringSize];
213  if(!GetTextualSid(pSID,pchSID,&dwSIDStringSize))
214  {
215  DWORD dwError = GetLastError();
216  ASSERT(dwError != ERROR_INSUFFICIENT_BUFFER);
217  rConsole.Write(_T("Error "));
218  TCHAR Buffer[256];
219  rConsole.Write(_itoa(dwError,Buffer,10));
220  rConsole.Write(_T("\nGetting string representation of SID\n"));
221  }
222  else
223  {
224  rConsole.Write(_T("\tSID: "));
225  rConsole.Write(pchSID);
226  rConsole.Write(_T("\n"));
227  }
228  delete[] pchSID;
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;
235  SID_NAME_USE Use;
236  if (!LookupAccountSid(NULL,pSID,pchName,&dwNameLength,pchDomainName,&dwDomainNameLength,&Use))
237  {
238  rConsole.Write(_T("Error "));
239  TCHAR Buffer[256];
240  rConsole.Write(_itoa(GetLastError(),Buffer,10));
241  rConsole.Write(_T("\n"));
242  }
243  else
244  {
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"));
253  }
254  delete [] pchName;
255  pchName = NULL;
256  delete [] pchDomainName;
257  pchDomainName = NULL;
258  }
259 
260  BYTE bFlags;
261  sd.GetCurrentACE_Flags(bFlags);
262  wsprintf(Buffer,_T("\tFlags: 0x%02lX\n"),bFlags);
263  rConsole.Write(Buffer);
264  if (bFlags & CONTAINER_INHERIT_ACE)
265  {
266  rConsole.Write(_T("\t\tCONTAINER_INHERIT_ACE\n"));
267  }
268  if (bFlags & INHERIT_ONLY_ACE)
269  {
270  rConsole.Write(_T("\t\tINHERIT_ONLY_ACE\n"));
271  }
272  if (bFlags & INHERITED_ACE)
273  {
274  rConsole.Write(_T("\t\tINHERITED_ACE\n"));
275  }
276  if (bFlags & NO_PROPAGATE_INHERIT_ACE)
277  {
278  rConsole.Write(_T("\t\tNO_PROPAGATE_INHERIT_ACE\n"));
279  }
280  if (bFlags & OBJECT_INHERIT_ACE)
281  {
282  rConsole.Write(_T("\t\tOBJECT_INHERIT_ACE\n"));
283  }
284 
285  DWORD dwAccessMask;
286  sd.GetCurrentACE_AccessMask(dwAccessMask);
287  wsprintf(Buffer,_T("\tAccess Mask: 0x%08lX\n"),dwAccessMask);
288  rConsole.Write(Buffer);
289  if (dwAccessMask & GENERIC_READ)
290  {
291  rConsole.Write(_T("\t\tGENERIC_READ\n"));
292  }
293  if (dwAccessMask & GENERIC_WRITE)
294  {
295  rConsole.Write(_T("\t\tGENERIC_WRITE\n"));
296  }
297  if (dwAccessMask & GENERIC_EXECUTE)
298  {
299  rConsole.Write(_T("\t\tGENERIC_EXECUTE\n"));
300  }
301  if (dwAccessMask & GENERIC_ALL)
302  {
303  rConsole.Write(_T("\t\tGENERIC_ALL\n"));
304  }
305  if (dwAccessMask & SYNCHRONIZE)
306  {
307  rConsole.Write(_T("\t\tSYNCHRONIZE\n"));
308  }
309  if (dwAccessMask & WRITE_OWNER)
310  {
311  rConsole.Write(_T("\t\tWRITE_OWNER\n"));
312  }
313  if (dwAccessMask & WRITE_DAC)
314  {
315  rConsole.Write(_T("\t\tWRITE_DAC\n"));
316  }
317  if (dwAccessMask & READ_CONTROL)
318  {
319  rConsole.Write(_T("\t\tREAD_CONTROL\n"));
320  }
321  if (dwAccessMask & DELETE)
322  {
323  rConsole.Write(_T("\t\tDELETE\n"));
324  }
325  if (dwAccessMask & KEY_CREATE_LINK)
326  {
327  rConsole.Write(_T("\t\tKEY_CREATE_LINK\n"));
328  }
329  if (dwAccessMask & KEY_NOTIFY)
330  {
331  rConsole.Write(_T("\t\tKEY_NOTIFY\n"));
332  }
333  if (dwAccessMask & KEY_ENUMERATE_SUB_KEYS)
334  {
335  rConsole.Write(_T("\t\tKEY_ENUMERATE_SUB_KEYS\n"));
336  }
337  if (dwAccessMask & KEY_CREATE_SUB_KEY)
338  {
339  rConsole.Write(_T("\t\tKEY_CREATE_SUB_KEY\n"));
340  }
341  if (dwAccessMask & KEY_SET_VALUE)
342  {
343  rConsole.Write(_T("\t\tKEY_SET_VALUE\n"));
344  }
345  if (dwAccessMask & KEY_QUERY_VALUE)
346  {
347  rConsole.Write(_T("\t\tKEY_QUERY_VALUE\n"));
348  }
349  } // for
350  } // else (nACECount == 0)
351  } // else (!sd.HasValidDACL())
352  } // else (sd.HasNULLDACL())
353 AbortDumpDACL:
354  delete [] pSecurityDescriptor;
355  } // try
356  catch (DWORD dwError)
357  {
358  rConsole.Write(_T("Error "));
359  TCHAR Buffer[256];
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;
365  }
366 
367  return 0;
368 }
369 
371 {
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");
377 }
378 
380 {
381  return DACL_CMD_SHORT_DESC;
382 }
#define GENERIC_ALL
Definition: nt_native.h:92
virtual const TCHAR * GetHelpShortDescriptionString()
#define TRUE
Definition: types.h:120
#define DACL_CMD_LENGTH
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
Definition: fatprocs.h:2697
enum _SID_NAME_USE SID_NAME_USE
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_SET_VALUE
Definition: nt_native.h:1017
virtual const TCHAR * GetHelpString()
#define _tcsicmp
Definition: xmlstorage.h:205
CShellCommandDACL(CRegistryTree &rTree)
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define WRITE_OWNER
Definition: nt_native.h:60
#define NO_PROPAGATE_INHERIT_ACE
Definition: setypes.h:716
#define LookupAccountSid
Definition: winbase.h:3691
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL GetKey(const TCHAR *pchRelativePath, REGSAM DesiredAccess, CRegistryKey &rKey)
long LONG
Definition: pedump.c:60
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
#define _tcsnicmp
Definition: xmlstorage.h:207
#define GENERIC_WRITE
Definition: nt_native.h:90
TCHAR * GetNextArgument()
void ResetArgumentIteration()
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define DACL_CMD
_CRTIMP char *__cdecl _itoa(_In_ int _Value, _Pre_notnull_ _Post_z_ char *_Dest, _In_ int _Radix)
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:715
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WRITE_DAC
Definition: nt_native.h:59
#define DACL_CMD_SHORT_DESC
CRegistryTree & m_rTree
#define READ_CONTROL
Definition: nt_native.h:58
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR sd[]
Definition: suminfo.c:287
const TCHAR * GetLastErrorDescription()
virtual BOOL Match(const TCHAR *pchCommand)
unsigned char BYTE
Definition: mem.h:68
#define GENERIC_READ
Definition: compat.h:124
BOOL GetTextualSid(PSID pSid, LPTSTR TextualSid, LPDWORD lpdwBufferLen)
#define SYNCHRONIZE
Definition: nt_native.h:61
#define COMMAND_NA_ON_ROOT
BOOL Write(const TCHAR *p, DWORD dwChars=0)
Definition: Console.cpp:90
#define KEY_CREATE_LINK
Definition: nt_native.h:1021
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_NOTIFY
Definition: nt_native.h:1020
#define INHERITED_ACE
Definition: ph.h:47
virtual ~CShellCommandDACL()
virtual int Execute(CConsole &rConsole, CArgumentParser &rArguments)
BOOL WINAPI IsValidSid(PSID pSid)
Definition: security.c:698
#define INHERIT_ONLY_ACE
Definition: setypes.h:717
#define wsprintf
Definition: winuser.h:5766
#define GENERIC_EXECUTE
Definition: nt_native.h:91
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define OBJECT_INHERIT_ACE
Definition: setypes.h:714
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define DELETE
Definition: nt_native.h:57
const TCHAR * GetSidTypeName(SID_NAME_USE Use)
struct _SECURITY_DESCRIPTOR * PISECURITY_DESCRIPTOR
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10