在“本地服务”下运行Windows服务并正确委派GPO创建

时间:2012-02-01 16:04:18

标签: c# windows-services impersonation delegation gpo

我有以下工作:使用GPMC,我可以在以下情况下在域控制器上创建GPO:

  1. 我的应用程序作为控制台应用程序运行,以域用户身份登录。
  2. 我已将我的应用程序安装为域用户帐户Windows服务。
  3. 但是,当我将服务作为“本地服务”运行时,我在尝试创建GPO时遇到访问被拒绝的异常:

    System.UnauthorizedAccessException:访问被拒绝。 (HRESULT异常:0x80070005(E_ACCESSDENIED))    在Microsoft.GroupPolicy.IGPMDomain.CreateGPO()

    我使用LogonUser API代码委派创建:

    public Impersonate(ILogManager logManager, IWindowsCredentials windowsCredentials)
    {
        logManager.WriteDebug("Current User: {0}", WindowsIdentity.GetCurrent().Name);
    
        const int impersonationLevel = LOGON32_LOGON_INTERACTIVE;
    
        if (!RevertToSelf())
            throw new ImpersonateException("Impersonation failed to RevertToSelf.");
    
        if (LogonUser(windowsCredentials.Username, windowsCredentials.Domain,
                      windowsCredentials.Password.ConvertToReadableString(), impersonationLevel,
                      LOGON32_PROVIDER_DEFAULT, ref _token) != 0)
        {
            if (DuplicateToken(_token, impersonationLevel, ref _tokenDuplicate) != 0)
            {
                var tempWindowsIdentity = new WindowsIdentity(_tokenDuplicate);
                _impersonationContext = tempWindowsIdentity.Impersonate();
                logManager.WriteDebug("Impersonation User: {0}", WindowsIdentity.GetCurrent().Name);
                logManager.WriteDebug("Impersonation Level: {0}", tempWindowsIdentity.ImpersonationLevel);
            }
            else
            {
                if (_token != IntPtr.Zero)
                    CloseHandle(_token);
                if (_tokenDuplicate != IntPtr.Zero)
                    CloseHandle(_tokenDuplicate);
    
                throw new ImpersonateException(string.Format("Impersonation failed due to duplicateToken '{0}'.",
                                                             windowsCredentials.Username));
            }
    
            logManager.WriteDebug("Successfully impersonated: {0}", windowsCredentials.Username);
        }
        else
        {
            if (_token != IntPtr.Zero)
                CloseHandle(_token);
    
            throw new ImpersonateException(string.Format("Impersonation failed due to LogonUser '{0}'.",
                                                         windowsCredentials.Username));
        }
    }
    

    实际上我打印输出:

      

    2012-02-01 09:58:55 [9]调试 - 使用DisplayName'Test222'创建新的GPO。

         

    2012-02-01 09:58:55 [9]调查 - 当前用户:NT AUTHORITY \ SYSTEM

         

    2012-02-01 09:58:55 [9]调查 - 假冒用户:ABC \ joebob

         

    2012-02-01 09:58:55 [9]调查 - 假冒等级:假冒

    我觉得我正确的做法,但也许你不能通过授权创建GPO,但我找不到支持这一点的证据。有什么想法吗?

0 个答案:

没有答案