Search code examples
c#impersonationregistry

Impersonate admin account to edit registry key not working (C#)


I am using the following code to edit a registry key in the local machine hive ('SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\%SID%'). Everything seems to be fine until I actually try to open the registry key (with write permissions); a SecurityException is thrown with the message 'Requested registry access is not allowed.' I've checked and rechecked the permissions for the registry key and the user I'm impersonating and it all checks out. The code runs fine when logged into the impersonated user's account, but when logged in as a restricted user, it fails. It's as if the impersonation works all except for giving the thread administrative privileges. Any ideas about how to fix this would be greatly appreciated!

string KEY_STR = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\" + WindowsIdentity.GetCurrent().User.Value;
WindowsImpersonationContext adminContext = null;
IntPtr tokenHandle = new IntPtr(0);
try
{
    LogonUser(userName, domainName, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);
    if (tokenHandle.Equals(new IntPtr(0))) LogonUser(userName, computerName, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);
    WindowsIdentity adminIdentity = new WindowsIdentity(tokenHandle);
    adminContext = adminIdentity.Impersonate();
    RegistryKey key = Registry.LocalMachine.OpenSubKey(KEY_STR, true);
    key.SetValue("State", 0x60001);
    Console.Out.WriteLine("User profile changed to Mandatory.");
}
catch (Exception ex)
{
    Console.Out.WriteLine("\nUnable to set profile to Mandatory:\n\t" + ex.Message);
}
finally
{
    adminContext.Undo();
    if (tokenHandle != IntPtr.Zero) CloseHandle(tokenHandle);
}

Solution

  • The token I had was insufficient to get write access to the registry. I'm going to use a windows service running as system to accomplish this instead.