Article ID: 180116
Article Last Modified on 11/21/2006
Access Description
---------------------------------------------------------------
SERVICE_CHANGE_CONFIG Change Service configuration
information
SERVICE_ENUMERATE_DEPENDENTS Enumerate all Services dependent
on the Service
SERVICE_INTERROGATE Ask the Service to report status
immediately
SERVICE_PAUSE_CONTINUE Pause or continue
SERVICE_QUERY_CONFIG Query Service configuration
information
SERVICE_QUERY_STATUS Query the status
SERVICE_START Start
SERVICE_STOP Stop
SERVICE_USER_DEFINED_CONTROL Send a user defined control
Other access types defined for a Service include READ_CONTROL, WRITE_OWNER,
WRITE_DAC, and DELETE. These access types apply to all securable objects.
Please refer to the Platform SDK Documentation for more information.
User or Group Access
---------------------------------------------------------------
The Everyone Group SERVICE_ENUMERATE_DEPENDENTS
SERVICE_INTERROGATE
SERVICE_QUERY_CONFIG
SERVICE_QUERY_STATUS
SERVICE_USER_DEFINED_CONTROL
READ_CONTROL
The Power Users Group SERVICE_ENUMERATE_DEPENDENTS
LocalSystem (System) SERVICE_INTERROGATE
SERVICE_PAUSE_CONTINUE
SERVICE_QUERY_CONFIG
SERVICE_QUERY_STATUS
SERVICE_START
SERVICE_STOP
SERVICE_USER_DEFINED_CONTROL
READ_CONTROL
The Administrators Group SERVICE_CHANGE_CONFIG
The Server Operators Group SERVICE_ENUMERATE_DEPENDENTS
SERVICE_INTERROGATE
SERVICE_PAUSE_CONTINUE
SERVICE_QUERY_CONFIG
SERVICE_QUERY_STATUS
SERVICE_START
SERVICE_STOP
SERVICE_USER_DEFINED_CONTROL
READ_CONTROL
WRITE_OWNER
WRITE_DAC
DELETE
#include <windows.h>
#include <aclapi.h>
#include <stdio.h>
#include <tchar.h>
void DisplayError(DWORD dwError, LPTSTR pszAPI)
{
LPVOID lpvMessageBuffer;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpvMessageBuffer, 0, NULL);
//Now display this string.
_tprintf(TEXT("ERROR: API = %s.\n"), pszAPI);
_tprintf(TEXT(" error code = %u.\n"), dwError);
_tprintf(TEXT(" message = %s.\n"),
(LPTSTR)lpvMessageBuffer);
// Free the buffer allocated by the system.
LocalFree(lpvMessageBuffer);
ExitProcess(dwError);
}
void _tmain(int argc, TCHAR *argv[])
{
BOOL bDaclPresent = FALSE;
BOOL bDaclDefaulted = FALSE;
DWORD dwError = 0;
DWORD dwSize = 0;
EXPLICIT_ACCESS ea;
PACL pacl = NULL;
PACL pNewAcl = NULL;
PSECURITY_DESCRIPTOR psd;
SC_HANDLE schManager = NULL;
SC_HANDLE schService = NULL;
SECURITY_DESCRIPTOR sd;
if (argc != 2){
_tprintf(TEXT("Usage: %s [service name]\n"), argv[0]);
return;
}
//
// Obtain a handle to the Service Controller.
//
schManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (schManager == NULL)
DisplayError(GetLastError(), TEXT("OpenSCManager"));
//
// Obtain a handle to the service.
//
schService = OpenService(schManager, argv[1],
READ_CONTROL | WRITE_DAC);
if (schService == NULL)
DisplayError(GetLastError(), TEXT("OpenService"));
//
// Get the current security descriptor.
//
if (!QueryServiceObjectSecurity(schService,
DACL_SECURITY_INFORMATION, psd, 0, &dwSize)){
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwSize);
if (psd == NULL){
DisplayError(0, TEXT("HeapAlloc"));
// note HeapAlloc does not support GetLastError()
}
if (!QueryServiceObjectSecurity(schService,
DACL_SECURITY_INFORMATION, psd, dwSize, &dwSize))
DisplayError(GetLastError(),
TEXT("QueryServiceObjectSecurity"));
}
else
DisplayError(GetLastError(),
TEXT("QueryServiceObjectSecurity"));
}
//
// Get the DACL.
//
if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
&bDaclDefaulted))
DisplayError(GetLastError(), TEXT("GetSecurityDescriptorDacl"));
//
// Build the ACE.
//
BuildExplicitAccessWithName(&ea, TEXT("GUEST"),
SERVICE_START | SERVICE_STOP | READ_CONTROL | DELETE,
SET_ACCESS, NO_INHERITANCE);
dwError = SetEntriesInAcl(1, &ea, pacl, &pNewAcl);
if (dwError != ERROR_SUCCESS)
DisplayError(dwError, TEXT("SetEntriesInAcl"));
//
// Initialize a NEW Security Descriptor.
//
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
DisplayError(GetLastError(),
TEXT("InitializeSecurityDescriptor"));
//
// Set the new DACL in the Security Descriptor.
//
if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))
DisplayError(GetLastError(), TEXT("SetSecurityDescriptorDacl"));
//
// Set the new DACL for the service object.
//
if (!SetServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION,
&sd))
DisplayError(GetLastError(), TEXT("SetServiceObjectSecurity"));
//
// Close the handles.
//
if (!CloseServiceHandle(schManager))
DisplayError(GetLastError(), TEXT("CloseServiceHandle"));
if (!CloseServiceHandle(schService))
DisplayError(GetLastError(), TEXT("CloseServiceHandle"));
//
// Free buffers.
//
LocalFree((HLOCAL)pNewAcl);
HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
}
Keywords: kbacl kbapi kbcode kbhowto kbkernbase kbsecurity kbservice KB180116