Impersonation and NLS

by Michael S. Kaplan, published on 2005/03/19 02:16 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2005/03/19/398994.aspx


There are a lot of people who get confused (and then subsequently complain in public fora or to product support or wherever!) about the topic of using impersonation and NLS functionality, so I thought it might be good to explain what is happening.

Common complaints go something like this:

An application uses IIS to provide an administrative interface to a terminal server. They use impersonation to run with the permission of the user and then they use the SetLocaleInfo API (or they modify the values under the HKCU\Control Panel\International key) to change user locale overrides. Code then run in VB or other languages seems to pick up the settings just fine while they run as the user. Yet the changes never seem to stick for that user and are gone for any subsequent login of them.

The same problems seems to only happen sometimes with the Win32 CreateProcessAsUser/CreateProcessWithLogonW APIs and .NET WindowsIdentity.Impersonate() method -- sometimes settings changes work, other times they do not. A clear pattern does not seem immediately evident....

The problem never seems to occur when the RunAs utility is used to start a process.

Believe it or not, there is a a single, simple explanation that covers all of these behaviors. You might even know what is after looking at all of the above cases, side by side.

The problem has to do with whether the the registry profile of the specified user is loaded and available!

When the profile is loaded and available, then any call to open subkeys under the HKEY_CURRENT_USER registry key will be mapped to the appropriate entry for that user. This is where the locale overrides in the registry referred to above happen to be currently located. These entries are the ones that the SetLocaleInfo API modifies when it is called. Life is easy and everything works.

However, when the profile is not loaded, or if the profile is not available to the impersonated token (due to the impersonation level permissions), then called to open subkeys under the HKEY_CURRENT_USER registry key will actually load the Subkey belonging to the user doing the impersonation. That user's settings will then be modified and thus even though you will see NLS functions like GetDateFormat or GetLocaleInfo seem to work with the changes, none of the changes will be persisted under the current user.

The issue is straightforward enough to work around -- just make sure that you have called the LoadUserProfile API prior to calling any of those non-RunAs methods. And then make sure that the impersonation method used gives enough permission to look at the registry subkey.

Of course this method comes with a price -- there is a performance hit to doing it. Which is one of the reasons why impersonation, which does not always need the profile to be loaded, does not always go through these extra steps.

Though I hope that one day this is clear enough in the documentation that people will not be so often confused by the results they see....

 

This post sponsored by "﴿" (U+fd3f, a.k.a. ORNATE RIGHT PARENTHESIS)


# Pavel Lebedinsky on 21 Mar 2005 12:27 AM:

> or they modify the values under the HKCU\Control Panel\International

People who are doing these things from a service are usually not aware of the fact that they have to call RegOpenCurrentUser instead of just using HKCU. This can also lead to all kinds of weird problems.

# Michael S. Kaplan on 22 Apr 2005 6:55 PM:

Pavel, this is an excellent point. People do not realize that this API is needed for the impersonation case (though not for the RunAs case).

referenced by

2010/03/19 Strange how unsympathetic I was, until I was suddenly quite sympathetic

2007/08/08 The user locale of the system account is not the system locale

go to newer or older post, or back to index or month or day