|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 1996.
//
// File: service.cxx
//
// Contents: Service support functions
//
// History: 8/94 davemont Created
//
//----------------------------------------------------------------------------
#include <aclpch.hxx>
#pragma hdrstop
//+---------------------------------------------------------------------------
//
// Function: OpenServiceObject
//
// Synopsis: Opens the specified service object
//
// Arguments: [IN pwszService] -- The name of the service to
// open
// [IN AccessMask] -- Flags indicating if the object
// is to be opened to read or write
// the DACL
// [OUT pHandle] -- Where the open handle is
// returned
//
// Returns: ERROR_SUCCESS -- Success
// ERROR_NOT_ENOUGH_MEMORY -- A memory allocation failed
// ERROR_INVALID_PARAMETER -- A bad name was given
//
//----------------------------------------------------------------------------
DWORD OpenServiceObject(IN LPWSTR pwszService, IN ACCESS_MASK AccessMask, OUT SC_HANDLE *pHandle) { acDebugOut((DEB_TRACE, "in OpenServiceObject \n"));
DWORD dwErr;
//
// Make sure the service functions are loaded
//
dwErr = LoadDLLFuncTable(); if(dwErr != ERROR_SUCCESS) { return(dwErr); }
if(pwszService != NULL) { WCHAR wszName[MAX_PATH + 1]; PWSTR pwszName; //
// save the object since we must crack it to go to remote machines
//
dwErr = AccGetBufferOfSizeW(pwszService, wszName, &pwszName); if(dwErr == ERROR_SUCCESS) { PWSTR pwszSvcName, pwszMachine;
//
// Separate the names
//
dwErr = ParseName(pwszName, &pwszMachine, &pwszSvcName);
//
// Go ahead and open the service control manager
//
if(dwErr == ERROR_SUCCESS) { SC_HANDLE hSC = OpenSCManager(pwszMachine, NULL, GENERIC_READ); if(hSC == NULL) { dwErr = GetLastError(); } else { //
// Open the service
//
*pHandle = OpenService(hSC, pwszSvcName, AccessMask); if(*pHandle == NULL) { dwErr = GetLastError(); }
//
// Close the handle to the scm
//
CloseServiceHandle(hSC); }
}
//
// Free our buffer
//
AccFreeBufferOfSizeW(wszName, pwszName); } } else { dwErr = ERROR_INVALID_PARAMETER; }
acDebugOut((DEB_TRACE, "Out OpenServiceObject: %lu\n", dwErr)); return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: ReadServicePropertyRights
//
// Synopsis: Gets the specified security info for the specified service
// object
//
// Arguments: [IN pwszService] -- The service to get the rights
// for
// [IN pRightsList] -- SecurityInfo to read based
// on properties
// [IN cRights] -- Number of items in rights list
// [IN AccessList] -- Access List to fill in
//
// Returns: ERROR_SUCCESS -- Success
// ERROR_INVALID_PARAMETER -- A bad property was encountered
// ERROR_NOT_ENOUGH_MEMORY -- A memory allocation failed
//
//----------------------------------------------------------------------------
DWORD ReadServicePropertyRights(IN LPWSTR pwszService, IN PACTRL_RIGHTS_INFO pRightsList, IN ULONG cRights, IN CAccessList& AccessList) { acDebugOut((DEB_TRACE, "in ReadServicePropertyRights\n")); DWORD dwErr = ERROR_SUCCESS; SC_HANDLE hSvc;
//
// For the moment, there is only service property itself...
//
ASSERT(cRights == 1 && pRightsList[0].pwszProperty == NULL); if(cRights != 1 || pRightsList[0].pwszProperty != NULL) { return(ERROR_INVALID_PARAMETER); }
//
// Open the service
//
dwErr = OpenServiceObject(pwszService, GetDesiredAccess(READ_ACCESS_RIGHTS, pRightsList[0].SeInfo), &hSvc);
if(dwErr == ERROR_SUCCESS) { dwErr = ReadServiceRights(hSvc, pRightsList, cRights, AccessList); //
// Close the object handle
//
CloseServiceHandle(hSvc); }
acDebugOut((DEB_TRACE, "Out ReadServicePropertyRights: %lu\n", dwErr)); return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: ReadServiceRights
//
// Synopsis: Gets the specified security info for the specified service
// object
//
// Arguments: [IN hSvc] -- Handle to the open service
// [IN pRightsList] -- SecurityInfo to read based
// on properties
// [IN cRights] -- Number of items in rights list
// [IN AccessList] -- Access List to fill in
//
// Returns: ERROR_SUCCESS -- Success
// ERROR_INVALID_PARAMETER -- A bad property was encountered
// ERROR_NOT_ENOUGH_MEMORY -- A memory allocation failed
//
//----------------------------------------------------------------------------
DWORD ReadServiceRights(IN SC_HANDLE hSvc, IN PACTRL_RIGHTS_INFO pRightsList, IN ULONG cRights, IN CAccessList& AccessList) { acDebugOut((DEB_TRACE, "in ReadServiceRights\n")); DWORD dwErr = ERROR_SUCCESS;
//
// For the moment, there is only service property itself...
//
ASSERT(cRights == 1 && pRightsList[0].pwszProperty == NULL); if(cRights != 1 || pRightsList[0].pwszProperty != NULL) { return(ERROR_INVALID_PARAMETER); }
//
// Get the service security...
//
UCHAR SDBuff[PSD_BASE_LENGTH]; PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SDBuff; ULONG cSize = 0;
//
// Get the size of the security descriptor from the service
//
if(QueryServiceObjectSecurity(hSvc, pRightsList[0].SeInfo, pSD, PSD_BASE_LENGTH, &cSize) == FALSE) { dwErr = GetLastError();
if(dwErr == ERROR_INSUFFICIENT_BUFFER) { dwErr = ERROR_SUCCESS; pSD = (PISECURITY_DESCRIPTOR)AccAlloc(cSize); if(pSD == NULL) { dwErr = ERROR_NOT_ENOUGH_MEMORY; } else { if(QueryServiceObjectSecurity(hSvc, pRightsList[0].SeInfo, pSD, cSize, &cSize) == FALSE) { dwErr = GetLastError(); } } } }
//
// If all that worked, we'll add our SD
//
if(dwErr == ERROR_SUCCESS) { dwErr = AccessList.AddSD(pSD, pRightsList->SeInfo, pRightsList->pwszProperty); }
//
// Free our memory if we allocated...
//
if(cSize > PSD_BASE_LENGTH) { AccFree(pSD); }
acDebugOut((DEB_TRACE, "Out ReadServiceRights: %lu\n", dwErr)); return(dwErr); }
//+---------------------------------------------------------------------------
//
// Function: GetServiceParentRights
//
// Synopsis: Determines who the parent is, and gets the access rights
// for it. It is used to aid in determining what the approriate
// inheritance bits are.
//
// This operation does not make sense for kernel objects
//
// Arguments: [IN pwszService] -- The service to get the parent
// for
// [IN pRightsList] -- The properties to get the
// rights for
// [IN cRights] -- Number of items in rights list
// [OUT ppDAcl] -- Where the DACL is returned
// [OUT ppSAcl] -- Where the SACL is returned
// [OUT ppSD] -- Where the Security Descriptor
// is returned
//
// Returns: ERROR_INVALID_FUNCTION -- Call doesn't make sense here
//
//----------------------------------------------------------------------------
DWORD GetServiceParentRights(IN LPWSTR pwszService, IN PACTRL_RIGHTS_INFO pRightsList, IN ULONG cRights, OUT PACL *ppDAcl, OUT PACL *ppSAcl, OUT PSECURITY_DESCRIPTOR *ppSD) { //
// This doesn't currently make sense for kernel objects, so simply
// return an error
//
return(ERROR_INVALID_FUNCTION); }
//+---------------------------------------------------------------------------
//
// Function: SetServiceSecurityInfo
//
// Synopsis: Sets the specified security info on the specified service
// object
//
// Arguments: [IN hService] -- The handle of the object
// [IN SeInfo] -- Flag indicating what security
// info to set
// [IN pwszProperty] -- The property on the object to
// set
// For kernel objects, this MBZ
// [IN pSD] -- The security descriptor to set
//
// Returns: ERROR_SUCCESS -- Success
// ERROR_INVALID_PARAMETER -- A bad property was given
//
//----------------------------------------------------------------------------
DWORD SetServiceSecurityInfo(IN SC_HANDLE hService, IN SECURITY_INFORMATION SeInfo, IN PWSTR pwszProperty, IN PSECURITY_DESCRIPTOR pSD) { acDebugOut((DEB_TRACE, "in SetServiceSecurityInfo\n"));
DWORD dwErr = ERROR_SUCCESS;
//
// Service don't have properties
//
if(pwszProperty != NULL) { dwErr = ERROR_INVALID_PARAMETER; } else { if(FLAG_ON(SeInfo, DACL_SECURITY_INFORMATION)) {
((PISECURITY_DESCRIPTOR)pSD)->Control |= SE_DACL_AUTO_INHERIT_REQ; }
if(FLAG_ON(SeInfo, SACL_SECURITY_INFORMATION)) {
((PISECURITY_DESCRIPTOR)pSD)->Control |= SE_SACL_AUTO_INHERIT_REQ; }
//
// set the security descriptor on the service
//
if(SetServiceObjectSecurity(hService, SeInfo, pSD) == FALSE) { dwErr = GetLastError(); } } acDebugOut((DEB_TRACE, "Out SetServiceSecurityInfo: %lu\n", dwErr));
return(dwErr); }
#if 0
//+---------------------------------------------------------------------------
//
// Function : GetServiceAccessMaskFromProviderIndependentRights
//
// Synopsis : translates the specified provider independent access rights into
// an access mask for a service
//
// Arguments: IN [AccessRights] - the input access rights
// OUT [AccessMask] - the returned NT access mask
//
//----------------------------------------------------------------------------
void GetServiceAccessMaskFromProviderIndependentRights(ULONG AccessRights, ACCESS_MASK *AccessMask) { if (PROV_OBJECT_READ & AccessRights) { *AccessMask |= SERVICE_READ; } if (PROV_OBJECT_WRITE & AccessRights) { *AccessMask |= SERVICE_WRITE; } if (PROV_OBJECT_EXECUTE & AccessRights) { *AccessMask |= SERVICE_EXECUTE; } } //+---------------------------------------------------------------------------
//
// Function : GetServiceProviderIndependentRightsFromAccessMask
//
// Synopsis : translates a service access mask into provider independent
// access rights
//
// Arguments: IN OUT [AccessMask] - the input NT access mask (modified)
// OUT [AccessRights] - the returned access rights
//
//----------------------------------------------------------------------------
ACCESS_RIGHTS GetServiceProviderIndependentRightsFromAccessMask( ACCESS_MASK AccessMask) { ACCESS_RIGHTS accessrights = 0;
if (GENERIC_ALL & AccessMask) { accessrights = PROV_ALL_ACCESS; } else { if (KEY_ALL_ACCESS == (KEY_ALL_ACCESS & AccessMask)) { accessrights = PROV_ALL_ACCESS; } else { if (WRITE_DAC & AccessMask) { accessrights |= PROV_EDIT_ACCESSRIGHTS; }
if (SERVICE_READ == (SERVICE_READ & AccessMask)) { accessrights |= PROV_OBJECT_READ; } if (SERVICE_WRITE == (SERVICE_WRITE & AccessMask)) { accessrights |= PROV_OBJECT_WRITE; } if (SERVICE_EXECUTE == (SERVICE_EXECUTE & AccessMask) ) { accessrights |= PROV_OBJECT_EXECUTE; } } } return(accessrights); } #endif
|