From 97556cc77d3cfa6281fd5161135230efe0cc55b4 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 7 Jun 2016 21:51:37 +0000 Subject: [PATCH] [SC] Add the sdshow command. svn path=/trunk/; revision=71590 --- reactos/base/applications/sc/CMakeLists.txt | 1 + reactos/base/applications/sc/sc.c | 12 +++ reactos/base/applications/sc/sc.h | 3 + reactos/base/applications/sc/sdshow.c | 101 ++++++++++++++++++++ reactos/base/applications/sc/usage.c | 12 ++- 5 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 reactos/base/applications/sc/sdshow.c diff --git a/reactos/base/applications/sc/CMakeLists.txt b/reactos/base/applications/sc/CMakeLists.txt index 890964a4d07..9b1c70dc50c 100644 --- a/reactos/base/applications/sc/CMakeLists.txt +++ b/reactos/base/applications/sc/CMakeLists.txt @@ -8,6 +8,7 @@ list(APPEND SOURCE print.c query.c sc.c + sdshow.c start.c usage.c sc.h) diff --git a/reactos/base/applications/sc/sc.c b/reactos/base/applications/sc/sc.c index ba594757746..73876d0989b 100644 --- a/reactos/base/applications/sc/sc.c +++ b/reactos/base/applications/sc/sc.c @@ -179,6 +179,18 @@ ScControl(LPCTSTR Server, // remote machine name else ControlUsage(); } + else if (!lstrcmpi(Command, _T("sdshow"))) + { + if (ArgCount > 0) + { + ServiceName = *ServiceArgs++; + ArgCount--; + + SdShow(ServiceName); + } + else + SdShowUsage(); + } else { MainUsage(); diff --git a/reactos/base/applications/sc/sc.h b/reactos/base/applications/sc/sc.h index 3d00b5cacca..e195d290b80 100644 --- a/reactos/base/applications/sc/sc.h +++ b/reactos/base/applications/sc/sc.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #define SCDBG @@ -18,6 +19,7 @@ BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args, INT ArgCount); BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended); LPSERVICE_STATUS_PROCESS QueryService(LPCTSTR ServiceName); +BOOL SdShow(LPCTSTR ServiceName); /* print and error functions */ VOID PrintService(LPCTSTR ServiceName, LPSERVICE_STATUS_PROCESS pStatus, BOOL bExtended); @@ -35,5 +37,6 @@ VOID DescriptionUsage(VOID); VOID DeleteUsage(VOID); VOID CreateUsage(VOID); VOID ControlUsage(VOID); +VOID SdShowUsage(VOID); #endif /* _SC_PCH_ */ diff --git a/reactos/base/applications/sc/sdshow.c b/reactos/base/applications/sc/sdshow.c new file mode 100644 index 00000000000..f913bbf8e76 --- /dev/null +++ b/reactos/base/applications/sc/sdshow.c @@ -0,0 +1,101 @@ +/* + * PROJECT: ReactOS Services + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/sc/sdshow.c + * PURPOSE: Show a service security descriptor + * COPYRIGHT: Copyright 2016 Eric Kohl + * + */ + +#include "sc.h" + +BOOL SdShow(LPCTSTR ServiceName) +{ + SC_HANDLE hManager = NULL; + SC_HANDLE hService = NULL; + BOOL bResult = TRUE; + DWORD cbBytesNeeded = 0; + PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; + LPTSTR pStringBuffer = NULL; + +#ifdef SCDBG + _tprintf(_T("service to show sd - %s\n\n"), ServiceName); +#endif + + hManager = OpenSCManager(NULL, + NULL, + SC_MANAGER_CONNECT); + if (hManager == NULL) + { + bResult = FALSE; + goto done; + } + + hService = OpenService(hManager, ServiceName, READ_CONTROL); + if (hService == NULL) + { + bResult = FALSE; + goto done; + } + + if (!QueryServiceObjectSecurity(hService, + DACL_SECURITY_INFORMATION, + (PSECURITY_DESCRIPTOR)&pSecurityDescriptor, + sizeof(PSECURITY_DESCRIPTOR), + &cbBytesNeeded)) + { + if (cbBytesNeeded == 0) + { + bResult = FALSE; + goto done; + } + } + + pSecurityDescriptor = HeapAlloc(GetProcessHeap(), 0, cbBytesNeeded); + if (pSecurityDescriptor == NULL) + { + SetLastError(ERROR_OUTOFMEMORY); + bResult = FALSE; + goto done; + } + + if (!QueryServiceObjectSecurity(hService, + DACL_SECURITY_INFORMATION, + pSecurityDescriptor, + cbBytesNeeded, + &cbBytesNeeded)) + { + bResult = FALSE; + goto done; + } + + if (!ConvertSecurityDescriptorToStringSecurityDescriptor(pSecurityDescriptor, + SDDL_REVISION_1, + DACL_SECURITY_INFORMATION, + &pStringBuffer, + NULL)) + { + bResult = FALSE; + goto done; + } + + _tprintf(_T("\n%s\n"), pStringBuffer); + +done: + if (bResult == FALSE) + ReportLastError(); + + if (pStringBuffer != NULL) + LocalFree(pStringBuffer); + + if (pSecurityDescriptor != NULL) + HeapFree(GetProcessHeap(), 0, pSecurityDescriptor); + + if (hService) + CloseServiceHandle(hService); + + if (hManager) + CloseServiceHandle(hManager); + + return bResult; +} diff --git a/reactos/base/applications/sc/usage.c b/reactos/base/applications/sc/usage.c index f7e83ba7164..1f5b3233a54 100644 --- a/reactos/base/applications/sc/usage.c +++ b/reactos/base/applications/sc/usage.c @@ -41,8 +41,8 @@ VOID MainUsage(VOID) // "\t qfailure : Queries the actions taken by a service upon failure.\n" _T("\t delete : Deletes a service (from the registry).\n") _T("\t create : Creates a service. (adds it to the registry).\n") - _T("\t control : Sends a control to a service.\n")); -// "\t sdshow : Displays a service's security descriptor.\n") + _T("\t control : Sends a control to a service.\n") + _T("\t sdshow : Displays a service's security descriptor.\n")); // "\t sdset : Sets a service's security descriptor.\n") // "\t GetDisplayName : Gets the DisplayName for a service.\n") // "\t GetKeyName : Gets the ServiceKeyName for a service.\n") @@ -190,3 +190,11 @@ VOID ControlUsage(VOID) _T("USAGE:\n") _T(" sc control [service name] \n")); } + +VOID SdShowUsage(VOID) +{ + _tprintf(_T("DESCRIPTION:\n") + _T(" Displays a service's security descriptor in SDDL format.\n") + _T("USAGE:\n") + _T(" sc sdshow \n")); +}