Чтобы установить OWNER_SECURITY_INFORMATION
, вызывающий процесс должен иметь доступ WRITE_OWNER
, либо должен быть владельцем объекта, либо иметь включенную привилегию SE_TAKE_OWNERSHIP_NAME
, либо SE_RESTORE_NAME
, если вы не указали собственный SID в качестве владельца объекта. , И вам не нужно устанавливать SID владельца необходимого объекта. Следующий образец работает для меня:
#include <windows.h>
#include <iostream>
#include <sddl.h>
#include <aclapi.h>
#include <WinError.h>
#pragma comment(lib, "Advapi32.lib")
using namespace std;
int main(int argc, char* argv[])
{
// Fetch the security descriptor for "WdNisSvc" (Service name that corresponds to the display name of "Windows Security Service")
LPCWSTR serviceNameToGetSecurityInformationFrom = L"SecurityHealthService";
SC_HANDLE serviceManagerHandle = NULL, serviceHandle = NULL;
char securityDescriptorBuffer[1024];
DWORD lengthOfReturnedValue = 0;
LPSTR daclBuffer = nullptr, absoluteSecurityDescriptionBuffer = nullptr;
DWORD daclBufferSize = NULL, ownerSidBufferSize = NULL, absoluteSecurityDescriptionBufferSize = NULL, saclBufferSize = NULL, primaryGroupSidBufferSize = NULL;
WCHAR serviceName[] = L"MySampleService1";
DWORD securityInfoChangeOperationErrorValue = NULL;
BOOL securityDescriptorInAbsoluteFormatCreationErrorValue = NULL;
serviceManagerHandle = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
if (serviceManagerHandle == nullptr) {
cout << "Error opening Service Manager Handle (" << GetLastError() << ").\n";
}
else {
serviceHandle = OpenService(serviceManagerHandle, serviceNameToGetSecurityInformationFrom, READ_CONTROL); //| WRITE_OWNER | WRITE_DAC
if (serviceHandle == nullptr) {
cout << "Error opening service (" << GetLastError() << ").\n";
}
else {
if (!QueryServiceObjectSecurity(serviceHandle, DACL_SECURITY_INFORMATION, securityDescriptorBuffer, sizeof(securityDescriptorBuffer), &lengthOfReturnedValue)) {
cout << "Error obtaining service's security information (" << GetLastError() << ").\n";
}
else {
BOOL bDaclPresent = false, bDaclDefaulted = false;
PACL pDacl = NULL;
BOOL ret = GetSecurityDescriptorDacl(securityDescriptorBuffer, &bDaclPresent, &pDacl, &bDaclDefaulted);
if (bDaclPresent)
{
securityInfoChangeOperationErrorValue = SetNamedSecurityInfo(serviceName, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL);
}
else
{
cout << "The security descriptor doesn't contain a DACL" << endl;
}
//SC_HANDLE target_service = OpenService(serviceManagerHandle, serviceName, WRITE_DAC); //| WRITE_OWNER | WRITE_DAC
//if (serviceHandle == nullptr) {
// cout << "Error opening service (" << GetLastError() << ").\n";
//}
//else {
// BOOL ret = SetServiceObjectSecurity(target_service, DACL_SECURITY_INFORMATION, securityDescriptorBuffer);
// if (ret == 0) {
// cout << "Error SetServiceObjectSecurity (" << GetLastError() << ").\n";
// }
// CloseServiceHandle(target_service);
//}
}
CloseServiceHandle(serviceHandle);
}
CloseServiceHandle(serviceManagerHandle);
}
return 0;
}
Или просто используйте SetServiceObjectSecurity
:
#include <windows.h>
#include <iostream>
#include <sddl.h>
#include <aclapi.h>
#include <WinError.h>
#pragma comment(lib, "Advapi32.lib")
using namespace std;
int main(int argc, char* argv[])
{
// Fetch the security descriptor for "WdNisSvc" (Service name that corresponds to the display name of "Windows Security Service")
LPCWSTR serviceNameToGetSecurityInformationFrom = L"SecurityHealthService";
SC_HANDLE serviceManagerHandle = NULL, serviceHandle = NULL;
char securityDescriptorBuffer[1024];
DWORD lengthOfReturnedValue = 0;
LPSTR daclBuffer = nullptr, absoluteSecurityDescriptionBuffer = nullptr;
DWORD daclBufferSize = NULL, ownerSidBufferSize = NULL, absoluteSecurityDescriptionBufferSize = NULL, saclBufferSize = NULL, primaryGroupSidBufferSize = NULL;
WCHAR serviceName[] = L"MySampleService1";
DWORD securityInfoChangeOperationErrorValue = NULL;
BOOL securityDescriptorInAbsoluteFormatCreationErrorValue = NULL;
serviceManagerHandle = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
if (serviceManagerHandle == nullptr) {
cout << "Error opening Service Manager Handle (" << GetLastError() << ").\n";
}
else {
serviceHandle = OpenService(serviceManagerHandle, serviceNameToGetSecurityInformationFrom, READ_CONTROL); //| WRITE_OWNER | WRITE_DAC
if (serviceHandle == nullptr) {
cout << "Error opening service (" << GetLastError() << ").\n";
}
else {
if (!QueryServiceObjectSecurity(serviceHandle, DACL_SECURITY_INFORMATION, securityDescriptorBuffer, sizeof(securityDescriptorBuffer), &lengthOfReturnedValue)) {
cout << "Error obtaining service's security information (" << GetLastError() << ").\n";
}
else {
//securityDescriptorInAbsoluteFormatCreationErrorValue = MakeAbsoluteSD(securityDescriptorBuffer, NULL, &absoluteSecurityDescriptionBufferSize, (PACL)daclBuffer, &daclBufferSize, NULL, &saclBufferSize, NULL, &ownerSidBufferSize, NULL, &primaryGroupSidBufferSize);
//if ((!securityDescriptorInAbsoluteFormatCreationErrorValue) && (ERROR_INSUFFICIENT_BUFFER) == GetLastError()) {
// // Induced error
// //cout << "ERROR: Inadequate size of the buffers implemented.\n";
// absoluteSecurityDescriptionBuffer = new CHAR[absoluteSecurityDescriptionBufferSize];
// daclBuffer = new CHAR[daclBufferSize];
// securityDescriptorInAbsoluteFormatCreationErrorValue = MakeAbsoluteSD(securityDescriptorBuffer, absoluteSecurityDescriptionBuffer, &absoluteSecurityDescriptionBufferSize, (PACL)daclBuffer, &daclBufferSize, NULL, &saclBufferSize, NULL, &ownerSidBufferSize, NULL, &primaryGroupSidBufferSize);
//}
//securityInfoChangeOperationErrorValue = SetNamedSecurityInfo(serviceName, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, NULL, (ACL*)daclBuffer, NULL);
//if (securityInfoChangeOperationErrorValue != ERROR_SUCCESS) {
// cout << "Error setting security info (" << securityInfoChangeOperationErrorValue << ").\n";
//}
//delete[] absoluteSecurityDescriptionBuffer;
//delete[] daclBuffer;
SC_HANDLE target_service = OpenService(serviceManagerHandle, serviceName, WRITE_DAC); //| WRITE_OWNER | WRITE_DAC
if (serviceHandle == nullptr) {
cout << "Error opening service (" << GetLastError() << ").\n";
}
else {
BOOL ret = SetServiceObjectSecurity(target_service, DACL_SECURITY_INFORMATION, securityDescriptorBuffer);
if (ret == 0) {
cout << "Error SetServiceObjectSecurity (" << GetLastError() << ").\n";
}
CloseServiceHandle(target_service);
}
}
CloseServiceHandle(serviceHandle);
}
CloseServiceHandle(serviceManagerHandle);
}
return 0;
}
Примечание:
[SetServiceObjectSecurity
доступно для использования в операционных системах, указанных в разделе «Требования». Это может быть изменено или недоступно в последующих версиях. Вместо этого используйте функцию SetNamedSecurityInfo
.]