title: How can I get elevated permissions (UAC) via impersonation under a non-interactive login?
body: <p>I have a class library that keeps system-wide configuration data in the registry (HKLM\Software\XXX). This library is used in various applications (services, windows forms, web apps, console apps) on various versions of Windows (XP, 2003, 7, 2008 R2). Because of this, the identity of the app is not consistent and may not even be a member of the machine's Administrators group. So I've created an AD domain admin user and do impersonation to gain write access to the registry. This works perfectly in XP/2003, but not in UAC-enabled systems (7/2008R2). It is my understanding that only interactive logins split the tokens which would imply that non-interactive logins (service identities, app pool identities, etc.) do not. I can't find anything to confirm that, but working from that assumption, the impersonation I'm doing should work.</p>
  
  <p>I wrote a wrapper class to do the impersonation using native LogonUser (network logontype, default provider) and DuplicateTokenEx (impersonation, primary token) then WindowsIdentity.Impersonate(). I get a reference to my root key:</p>
  
  <pre><code>using (ECR.Impersonator imp = new ECR.Impersonator("XXX", "XXX", "XXX"))
  {
      _root = Registry.LocalMachine.CreateSubKey("SOFTWARE\\XXX", RegistryKeyPermissionCheck.ReadWriteSubTree);
  }
  </code></pre>
  
  <p>According to <a href="http://msdn.microsoft.com/en-us/library/microsoft.win32.registrykeypermissioncheck(VS.90).aspx" rel="noreferrer">MSDN</a>, by using ReadWriteSubTree, this should be the ONLY time a security check is done. I can write values to that key, create sub-keys (also using ReadWriteSubTree) and writing values to those sub-keys without ever needing another security check. So I thought that I would only need to do the costly impersonation one time - getting the reference to my root key.</p>
  
  <p>I can write values to my root key just fine:</p>
  
  <pre><code>_root.SetValue("cachedDate", value.ToBinary(), RegistryValueKind.QWord); }
  </code></pre>
  
  <p>but when I create/open a sub-key with ReadWriteSubTree:</p>
  
  <pre><code>RegistryKey key = _root.CreateSubKey("XXX", RegistryKeyPermissionCheck.ReadWriteSubTree);
  </code></pre>
  
  <p>it bombs with <code>Access to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\XXX\XXX' is denied</code>.</p>
  
  <p>While I'm curious why a security check is done when MSDN says it shouldn't, my question is how can I get elevated permissions via impersonation for applications that may not be running under a interactive login?</p>