Prev: Mirror Driver Architecture
Next: LowLevelHooksTimeout?
From: Stefan Kuhr on 6 Mar 2006 09:41 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: Pavel Lebedinsky [MSFT] on 7 Mar 2006 16:57 Impersonating a client does not automatically give you the full token. You need to initiate elevation from the client side. -- This posting is provided "AS IS" with no warranties, and confers no rights. "Stefan Kuhr" wrote: > 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?
From: Stefan Kuhr on 7 Mar 2006 17:27 Hi Pavel, Pavel Lebedinsky [MSFT] 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? 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)? Thanks for the answer. Obviously I was told something else in class or my question was not clear enough there. -- Stefan Kuhr "Lesen schadet der Dummheit"
From: RossettoeCioccolato on 7 Mar 2006 17:48 Pavel, > You need to initiate elevation from the client side. < Could you be more explicit about how to do this? A better design would be to run the service as a network service and assume the client's administrative identity only within the context of a server thread. That way the client thread (on the server) will fault to the service's unprivileged identity. However, there is still a need for the server's client thread to assume the client's full identity (if the service's purpose is administrative). Regards, George.
From: RossettoeCioccolato on 7 Mar 2006 19:07
Pavel, Oh! I see that this is an LRPC interface. I guess that you must mean by clicking on Run As Administrator or opening an unrestricted command prompt. I was thinking of a remote interface and contemplating the prospect of having to station an admin at the server to click on some silly little dialog every time a client connects. That would be rediculous, wouldn't it? Regards, George. |