Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1804348
  • 博文数量: 290
  • 博客积分: 10653
  • 博客等级: 上将
  • 技术积分: 3178
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-24 23:08
文章存档

2013年(6)

2012年(15)

2011年(25)

2010年(86)

2009年(52)

2008年(66)

2007年(40)

分类: C/C++

2009-07-02 20:00:03

Modifying the DACL for a Service

An application can create or modify the DACL associated with a Service object in order to control access. To retrieve the DACL associated with a service object, use the QueryServiceObjectSecurity function. To set the DACL, use the SetServiceObjectSecurity function. Any changes made to the SECURITY_DESCRIPTOR associated with the service object are persistent until the service is removed from the system.

The following sample code creates and sets a new DACL for the service specified on the command line. The sample code merges one Access Control Entry (ACE) to the existing DACL for the service. The new ACE grants the Guest account start, stop, delete, and READ_CONTROL access to the specified service. Access to the service can be modified by the AccessPermissions parameter passed to the BuildExplicitAccessWithName function.

 

 

#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);

   // Display the 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);
}

阅读(1127) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-11-13 10:02:16

你好,如果我要把权限设给系统里所有的用户,而不是设给geust,是不是只要把BuildExplicitAccessWithName(&ea, TEXT("GUEST"), SERVICE_START | SERVICE_STOP | READ_CONTROL | DELETE, SET_ACCESS, NO_INHERITANCE); 里面的GUEST改为SYSTEM就可以了?谢谢。