Skip to content

Instantly share code, notes, and snippets.

@drewchapin
Created February 3, 2017 03:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drewchapin/e55154f5d9474c5ee51435d5af5eb1c9 to your computer and use it in GitHub Desktop.
Save drewchapin/e55154f5d9474c5ee51435d5af5eb1c9 to your computer and use it in GitHub Desktop.
#pragma comment(lib,"advapi32.lib")
#include <Windows.h>
#include <WinSvc.h>
#include <AccCtrl.h>
#include <AclAPI.h>
#include <stdio.h>
int main( int argc, char* argv[] )
{
EXPLICIT_ACCESS ea;
SECURITY_DESCRIPTOR sd;
PSECURITY_DESCRIPTOR psd = NULL;
PACL pacl = NULL;
PACL pNewAcl = NULL;
BOOL bDaclPresent = FALSE;
BOOL bDaclDefaulted = FALSE;
DWORD dwError = 0;
DWORD dwSize = 0;
DWORD dwBytesNeeded = 0;
SC_HANDLE schSCManager = NULL;
SC_HANDLE schService = NULL;
char szSvcName[] = "spooler";
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)\n", GetLastError());
return -1;
}
// Get a handle to the service
schService = OpenService(
schSCManager, // SCManager database
szSvcName, // name of service
READ_CONTROL | WRITE_DAC); // access
if (schService == NULL)
{
printf("OpenService failed (%d)\n", GetLastError());
CloseServiceHandle(schSCManager);
return -1;
}
// Get the current security descriptor.
if (!QueryServiceObjectSecurity(schService,
DACL_SECURITY_INFORMATION,
&psd, // using NULL does not work on all versions
0,
&dwBytesNeeded))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
dwSize = dwBytesNeeded;
psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwSize);
if (psd == NULL)
{
// Note: HeapAlloc does not support GetLastError.
printf("HeapAlloc failed\n");
goto dacl_cleanup;
}
if (!QueryServiceObjectSecurity(schService,
DACL_SECURITY_INFORMATION, psd, dwSize, &dwBytesNeeded))
{
printf("QueryServiceObjectSecurity failed (%d)\n", GetLastError());
goto dacl_cleanup;
}
}
else
{
printf("QueryServiceObjectSecurity failed (%d)\n", GetLastError());
goto dacl_cleanup;
}
}
// Get the DACL.
if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
&bDaclDefaulted))
{
printf("GetSecurityDescriptorDacl failed(%d)\n", GetLastError());
goto dacl_cleanup;
}
// Build the ACE.
BuildExplicitAccessWithName(&ea, "tech1",
SERVICE_START | SERVICE_STOP | READ_CONTROL,
SET_ACCESS, NO_INHERITANCE);
dwError = SetEntriesInAcl(1, &ea, pacl, &pNewAcl);
if (dwError != ERROR_SUCCESS)
{
printf("SetEntriesInAcl failed(%d)\n", dwError);
goto dacl_cleanup;
}
// Initialize a new security descriptor.
if (!InitializeSecurityDescriptor(&sd,
SECURITY_DESCRIPTOR_REVISION))
{
printf("InitializeSecurityDescriptor failed(%d)\n", GetLastError());
goto dacl_cleanup;
}
// Set the new DACL in the security descriptor.
if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))
{
printf("SetSecurityDescriptorDacl failed(%d)\n", GetLastError());
goto dacl_cleanup;
}
// Set the new DACL for the service object.
if (!SetServiceObjectSecurity(schService,
DACL_SECURITY_INFORMATION, &sd))
{
printf("SetServiceObjectSecurity failed(%d)\n", GetLastError());
goto dacl_cleanup;
}
else printf("Service DACL updated successfully\n");
dacl_cleanup:
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
if(NULL != pNewAcl)
LocalFree((HLOCAL)pNewAcl);
if(NULL != psd)
HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment