I presume this is something to do with the profile for that user not being
loaded.
Q1: What's the recommended way to do this such that it's independent of
whoever might be logged on interactive (i.e. not dependent on them, or
affecting them), and independent of any other Service or Component doing the
same thing under a different Windows account?
Q2: In the specific case of IIS, how can I do this for the base account in
which the worker process has been configured to run, as opposed to any
impersonated account when handling a client request?
Q3: Are the associated Regional Settings handled in a similar way. Does the
user profile have be loaded in order for them to be effective?
Tony Proctor
Run as a specific account. Speaking for COM+ objects, you can use
LoadUserProfile if you need the profile settings associated with the
account. You should avoid calling this more than once since it is a
relatively expensive operation.
> Q2: In the specific case of IIS, how can I do this for the base account in
> which the worker process has been configured to run, as opposed to any
> impersonated account when handling a client request?
>
I'm not sure what you mean by "worker process". You are talking about the
ASP interpreter or ASP.NET? These are two different animals. In the case of
the ASP Interpreter, by default it is impersonating the calling user. If the
user is "Anonymous", then the IUSR_<computer> account is used. You can
always stop impersonating momentarily by calling CoRevertToSelf().
Brian
Re Q2: Sorry Brian, I meant as ASP environment, and by 'worker process' I
meant the DLLHOST (IIS5) or w3wp (IIS6). With anonymous authentication, I
know it could be running as the IUSR or IWAM account (depending on the
running mode), or a specific account set in the Directory Security tab. I
wasn't sure how to ensure the profile is loaded for _that_ account as
opposed to any that might be being impersonated on the current thread. For
instance, if the token passed to LoadUserProfile was returned by
OpenProcessToken, would that do what I expect?
Tony Proctor
"Brian Muth" <bm...@mvps.org> wrote in message
news:OQN1$aO7GH...@TK2MSFTNGP04.phx.gbl...
I really don't know, although it would be a simple matter to set up an
experiment and find out. Why not try it and let us know? My suspicion is it
is still costly. After all, it was deliberately left out as part of the
startup of a COM+ application for a reason.
>
> Re Q2: Sorry Brian, I meant as ASP environment, and by 'worker process' I
> meant the DLLHOST (IIS5) or w3wp (IIS6). With anonymous authentication, I
> know it could be running as the IUSR or IWAM account (depending on the
> running mode), or a specific account set in the Directory Security tab. I
> wasn't sure how to ensure the profile is loaded for _that_ account as
> opposed to any that might be being impersonated on the current thread. For
> instance, if the token passed to LoadUserProfile was returned by
> OpenProcessToken, would that do what I expect?
You would expect the user profile associated with the IUSR_<computer> or
IWAM_<computer> account. If you used OpenThreadToken you would get the user
profile of the impersonated user account.
HTH
Brian
At the moment, my worker process is configured to run under a specific local
admin account (i.e. not IUSR/IWAM). I have called LoadUserProfile using a
token from OpenProcessToken, but there are no user-level environment
variables loaded for that account, only system ones. Do I have to do
something special to get them into the current environment?
Tony Proctor
"Brian Muth" <bm...@mvps.org> wrote in message
news:um8a03U7...@TK2MSFTNGP02.phx.gbl...
See the steps outlined here: http://tinyurl.com/gwnny
Brian
If I open the process token then I get no user variables at all. It could be
that using the process token is equivalent to looking at the IUSR/IWAM
account, rather than the dedicated local account I have configured it to run
under. I know you said that the thread token, rather than the process token,
would return the impersonated account, but I didn't realise that the account
configured for the virtual directory's security ended up being impersonated.
If I open the thread token instead then I still don't get any user-level
environment variables, and HKEY_CURRENT_USER doesn't point to my account.
However, if I use the profile handle to look in the registry then I see all
the variables inside the KEY_USERS area.
...I know I've done something silly, somewhere
Tony Proctor
"Brian Muth" <bm...@mvps.org> wrote in message
news:eZ4lPlW7...@TK2MSFTNGP03.phx.gbl...
1) Using a process token from:
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY Or TOKEN_DUPLICATE Or
TOKEN_IMPERSONATE, hToken)
This fails with 'Access Denied' (=5)
2) Using a thread token from:
OpenThreadToken(GetCurrentThread(), TOKEN_QUERY Or TOKEN_DUPLICATE Or
TOKEN_IMPERSONATE, 1, hToken)
Irrespective of whether OpenAsSelf is 0 or 1, this works insomuch as I get a
profile handle back that shows me the user's hive. However,
HKEY_CURRENT_USER isn't pointing to the same place, and the
GetEnvironmentVariable API doesn't see my User Environment Variables.
In both cases, I was using the token to load the user's profile as follows:
Private Function LoadProfileFromToken(sUserName As String, hToken As Long)
As Long
Dim tPI As PROFILEINFO
Dim lpPI As Long
tPI.dwSize = LenB(tPI)
tPI.dwFlags = PI_NOUI
tPI.dwFlags = 0
tPI.lpUserName = StrPtr(sUserName)
tPI.lpProfilePath = 0
tPI.lpDefaultPath = 0
tPI.lpServerName = 0
tPI.lpPolicyPath = 0
lpPI = VarPtr(tPI)
If LoadUserProfile(hToken, lpPI) Then
LoadProfileFromToken = tPI.hProfile
...etc...
This code is all in a DLL accessed by an ASP page.
[Many thanks for staying with me on this]
Tony Proctor
"Brian Muth" <bm...@mvps.org> wrote in message
news:eZ4lPlW7...@TK2MSFTNGP03.phx.gbl...
Tony, I just don't follow your language. It's not clear you are following
all the steps. After you open the thread token, do you call LoadUserProfile?
Do you correctly use the last parameter returned (hProfile) as the parameter
to RegOpenKeyEx?
When you say "HKEY_CURRENT_USER doesn't point to my account" I have no clue
what you mean. Who's account is "my account"?
Brian
The earlier post I'd sent today showed some code that already answers the
question about my calls to LoadUserProfile. So, yes I do call it, and I do
extract a valid hProfile handle afterwards.
What I was trying to say in my last post - which I admit was a bit hurried -
was that when using the thread token, I got back a valid hProfile pointing
to my hive, and I could see my User environment variables under there.
However, when using HKEY_CURRENT_USER instead of hProfile then I didn't see
the same hive. I sort of assumed that since the thread was running as (or
impersonating) this local admin account that HKEY_CURRENT_USER would be
pointing to the relevant hive, or at least after calling LoadUserProfile. In
effect, I don't know which hive it happens to be pointing to but the
contents are not the same as the ones under hProfile. Also, the
GetEnvironmentVariable API doesn't find my User variables.
Tony Proctor
"Brian Muth" <bm...@mvps.org> wrote in message
news:OQWBFFj...@TK2MSFTNGP05.phx.gbl...
Thanks for the clarification. I can't fault anything that you have done.
Just be sure that the OpenAsSelf parameter is set to TRUE so you don't get
the impersonated token. Also, I would go into Component Services and look at
the identity of the COM+ application representing the IIS web site you have
set up, just to confirm you are seeing the chosen local admin account. (It
will probably look like: IIS--{Default Web Site//Root/MySite})
Other than that, I'm at a loss as to further suggestions.
Brian
It appears the difference between using HKEY_CURRENT_ROOT and hProfile to
look at the hive was a bug on my part (I had a old key kept open). Hence, I
can see the user environment variables using both keys now.
However, GetEnvironmentVariable still refuses to show the same variables to
me. I wonder if this is because it's using an older edition of the active
environment block, and that isn't changed by the LoadProfile call.
Interestingly, ExpandEnvironmentStringsForUser _does_ use these variables,
and I can easily use that as alternative to Get EnvironmentVariable. I just
whish I understood why it was necessary :-(
I also found that OpenThreadToken fails with error 1008 if you're in the
IDE. I did a Google and found a few people reporting this, but no
explanation there either
On the subject of performance, LoadUserProfile is definitely a _lot_ quicker
if the profile is already loaded, e.g. if that user is currently logged on
interactive, or another thread has called LoadUserProfile and not called
UnloadUserProfile.
Tony Proctor
P.S. I'm using W2K here so I couldn't check Component Services
"Brian Muth" <bm...@mvps.org> wrote in message
news:%237q$I%23k7GH...@TK2MSFTNGP04.phx.gbl...
Tony Proctor
"Brian Muth" <bm...@mvps.org> wrote in message
news:%237q$I%23k7GH...@TK2MSFTNGP04.phx.gbl...
Tony Proctor
"Brian Muth" <bm...@mvps.org> wrote in message
news:%237q$I%23k7GH...@TK2MSFTNGP04.phx.gbl...
No, I believe it's because your app gets an independent copy of the
environment, "Process Environment Block", when it starts. Changes to
environment variables with e.g. putenv are process-local. However, I think
you should be able to spawn a new process that has the updated environment.
You can see the same behavior if you have a command prompt open and you use
the System control panel to change environment variables. The new values
are only visible to command prompts opened after the change was made.
Tony Proctor
"Ben Voigt" <r...@nospam.nospam> wrote in message
news:eIBaCmi8...@TK2MSFTNGP05.phx.gbl...
My point was that, to enable local modifications to the environment block,
your copy is disassociated from the environment settings during process
startup. So anything you do to change the settings, like edit the registry,
load a user profile, etc, won't be reflected in your copy.
You could however load the user profile and then modify your local
environment to match.
Tony Proctor
"Ben Voigt" <r...@nospam.nospam> wrote in message
news:eh0xGft8...@TK2MSFTNGP02.phx.gbl...