From: Pavel Lebedinsky [MSFT] on
"Stefan Kuhr" wrote:

>> Impersonating a client does not automatically give you the full
>> token. You need to initiate elevation from the client side.
>
> And that automatically involves the consent-UI beforehand, right? There
> really is no way to get the full token of a consent admin without an
> intermediate invocation of consent.exe?

I don't really know the details but it appears that you can either
run an app that has a manifest requesting elevation, or use
CoCreateInstanceAsAdmin.

The point is that UAP is designed to put the user in control. If
the user does not want to elevate, there's nothing your service
can do about this. (Of course, since you're running as
LocalSystem, you can technically do anything, and there's
probably some unsupported way get the user's full token, but
it is assumed that well-behaved services won't do this).

By the way, why do you need to impersonate an admin?
Since you run as system, you already have administrator
privileges in your service.

> If so, is there a way to make another administrator a non-consent-admin
> like the first administrator user that is auto-generated during
> installation (which apparently needs no consent ui)?


BUILTIN\Administrator is the only account that always runs elevated.
Other members of Administrators group get a limited token when
they log on.

--
This posting is provided "AS IS" with no warranties, and confers no
rights.


From: Skywing on
IIRC, any privileges that are in the token but not enabled get stripped away
across impersonation boundaries, so - you might try turning on all
privileges present before the security context is captured by impersonating,
transmitting the "real" privilege state with an RPC message or whatnot, then
restoring the original privilege state on the impersonating end when you get
the appropriate message.

(Note that I don't really know if this will do what you need to do in
Vista -- however I have succcessfully used techniques similar to this to get
the "important" parts of the token saved across an impersonation boundary in
<=Windows Server 2003. So it's probably worth a shot, at least.)

"Stefan Kuhr" <kustt110(a)gmx.li> wrote in message
news:440C4A01.E31D0B85(a)gmx.li...
> Hello everyone,
>
> I want a service running on Vista as LocalSystem to act like the
> elevated administrator by impersonating the client, which is an
> administrator running with the restricted token of a normal
> administrator on Vista.
>
> I followed the guidelines laid out in the section "Summary of Choices
> for Designing Administrative Applications"-"The Back-End Service Model"
> of the following document:
>
> http://msdn.microsoft.com/windowsvista/default.aspx?pull=/library/en-us/dnlong/html/AccProtVista.asp
>
> I created a Service running as LocalSystem, that exposes an RPC
> interface via LRPC to which a client app, marked with
> "requestedExecutionLevel" to be "asInvoker", then makes an Rpc call.
> However, when the server code impersonates the client, the token that
> the thread now uses is still the same restricted token that the client
> has. In one of the Vista Ascend Training classes that I attended, I was
> told that the service, when it impersonates the client, will receive the
> full token part of the client's split token, not the restricted token.
> What am I doing wrong?
>
> My code in the server part roughly looks like so and it runs without
> problems in an XP environment:
>
> /* [fault_status][comm_status] */ error_status_t StartCommandShell(
> /* [in] */ handle_t Binding)
> {
> if(!Binding)
> return ERROR_INVALID_PARAMETER;
>
> DWORD dwResult = RpcImpersonateClient(Binding);
> if(ERROR_SUCCESS!=dwResult)
> return dwResult;
>
> HANDLE hClientImpToken = NULL;
>
> if(!OpenThreadToken(GetCurrentThread(),
> TOKEN_READ|TOKEN_IMPERSONATE|TOKEN_DUPLICATE /*TOKEN_QUERY*/, TRUE,
> &hClientImpToken))
> {
> DWORD dwLastErr = GetLastError();
> VERIFY(ERROR_SUCCESS==RpcRevertToSelf());
> return dwLastErr;
> }
>
> VERIFY(ERROR_SUCCESS==RpcRevertToSelf());
>
> HANDLE hPrimaryToken = NULL;
>
>
> if(!DuplicateTokenEx(hClientImpToken, TOKEN_ALL_ACCESS, NULL,
> SecurityImpersonation, TokenPrimary, &hPrimaryToken))
> {
> DWORD dwLastErr = GetLastError();
> VERIFY(CloseHandle(hClientImpToken));
> return dwLastErr;
> }
>
> VERIFY(CloseHandle(hClientImpToken));
> ASSERT(hPrimaryToken);
>
> ///
> /// now we have the client's token as a primary token, ready for CPAU
> ///
> PROCESS_INFORMATION pi;
> STARTUPINFO si;
> ZeroMemory(&si, sizeof(STARTUPINFO));
> si.cb = sizeof(STARTUPINFO);
> si.dwFlags = STARTF_USESHOWWINDOW;
> si.wShowWindow = SW_SHOW;
> si.lpDesktop = CSTR2STR(_T("winsta0\\default"));
>
> if (!CreateProcessAsUser(hPrimaryToken, NULL, CSTR2STR(_T("cmd.exe")),
> NULL, NULL, FALSE,
> CREATE_NEW_CONSOLE|NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
> dwResult = GetLastError();
> else
> {
> VERIFY(CloseHandle(pi.hProcess));
> VERIFY(CloseHandle(pi.hThread));
> }
> VERIFY(CloseHandle(hPrimaryToken));
>
> return dwResult;
> }
>
>
> Any help appreciated. Ivan?
>
> --
> Stefan


From: Stefan Kuhr on
Hi Skywing,

Skywing wrote:
>
> IIRC, any privileges that are in the token but not enabled get stripped away
> across impersonation boundaries, so - you might try turning on all
> privileges present before the security context is captured by impersonating,
> transmitting the "real" privilege state with an RPC message or whatnot, then
> restoring the original privilege state on the impersonating end when you get
> the appropriate message.
>
> (Note that I don't really know if this will do what you need to do in
> Vista -- however I have succcessfully used techniques similar to this to get
> the "important" parts of the token saved across an impersonation boundary in
> <=Windows Server 2003. So it's probably worth a shot, at least.)
>

I am aware of the fact that those privileges that the client process has
not explicitely enabled before making the RPC are stripped from the
token that the impersonator gets. Actually, my test client tries to
enable all poossible privileges. However, privileges are not the primary
problem with admin elevation on Vista. The restricted token of a
non-elevated administrator manifests itself first and foremost in the
group sid of builtin\administrators being SE_GROUP_USE_FOR_DENY_ONLY (it
is SE_GROUP_OWNER in a full token) and two new SIDs of type label
(which apparently is not yet documented). These two label SIDs can
successfully be elevated to the values in a full admin token using
SetTokenInformation(..., TokenIntegrityLevel...) and (obviously)
well-known SID using the approach outlined here:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ProtectedMode.asp

but the group SID for builtin\administrators with
SE_GROUP_USE_FOR_DENY_ONLY cannot be replaced because
SetTokenInformation(..., TokenGroups, ) won't succeed (if that would
work, any service running as LocalSystem could masquerade as any user).

Anyway, thanks for helping.

--
Stefan
From: Stefan Kuhr on
Hi Pavel,

"Pavel Lebedinsky [MSFT]" wrote:
>
> "Stefan Kuhr" wrote:
>
> >> Impersonating a client does not automatically give you the full
> >> token. You need to initiate elevation from the client side.
> >
> > And that automatically involves the consent-UI beforehand, right? There
> > really is no way to get the full token of a consent admin without an
> > intermediate invocation of consent.exe?
>
> I don't really know the details but it appears that you can either
> run an app that has a manifest requesting elevation, or use
> CoCreateInstanceAsAdmin.

And as far as I can see, both variants require the consent UI.



>
>
> By the way, why do you need to impersonate an admin?
> Since you run as system, you already have administrator
> privileges in your service.

Good point. I have to elaborate a bit: We have a script language that
has a script command named "RunAs" which works like the command line app
runas. The point is, that on Vista, interactive tokens created by the
secondary logon are restricted tokens as well. Our customers expect that
they can use this runas command and pass it credentials of a local admin
(which usually is a domain user and thus a consent admin) and get
privileged things done on the otherwise unprivileged desktop of a normal
user. Please let us not talk about how insecure this all might be or how
we store passwords and so on, it is just the state of affairs right now.
If now this runas command only creates a restricted token of an admin,
probably most of the time the privileged actions that our customers want
to perform won't work anymore. So my idea was to create an intermediate
process of ours first, which then talks to our service via RPC to create
the process that the customer wants to run as the full admin.

Another point where we would need similar functionality is the usage of
the UpdateDriverForPlugAndPlayDevices API which requires full
administrative privileges but also desktop interaction in order for
installation of unsigned drivers (and IIRC also drivers with
CoInstallers that have UI) to succeed. In this case we also need a
privileged process with a full token, not running within some private
winsta\desktop of a non-interactive service but instead on a
non-privileged user's desktop. This will not work anymore with Vista's
implementation of CreateProcessWithLogonW.


--
Stefan
From: Pavel Lebedinsky [MSFT] on
I might be wrong, but I suspect that there is no supported way
to launch an elevated app without going through consent UI, and
this is probably by design.

You can try asking this question in the UAC team blog:

http://blogs.msdn.com/uac/default.aspx

--
This posting is provided "AS IS" with no warranties, and confers no
rights.

"Stefan Kuhr" wrote:

> In this case we also need a
> privileged process with a full token, not running within some private
> winsta\desktop of a non-interactive service but instead on a
> non-privileged user's desktop. This will not work anymore with Vista's
> implementation of CreateProcessWithLogonW.


First  |  Prev  | 
Pages: 1 2
Prev: Mirror Driver Architecture
Next: LowLevelHooksTimeout?