From ede24db26773b5ce2c2d7e13bf12939b55124281 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Fri, 26 Feb 2021 22:31:19 -0600 Subject: [PATCH] shell32: Implement the "runas" verb. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on a patch by Michael Müller. Signed-off-by: Zebediah Figura --- dlls/shell32/shlexec.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c index 8c7e3cf0808..c9a996a13dd 100644 --- a/dlls/shell32/shlexec.c +++ b/dlls/shell32/shlexec.c @@ -292,6 +292,21 @@ static HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR psz return hr; } +static HANDLE get_admin_token(void) +{ + TOKEN_ELEVATION_TYPE type; + TOKEN_LINKED_TOKEN linked; + DWORD size; + + if (!GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenElevationType, &type, sizeof(type), &size) + || type == TokenElevationTypeFull) + return NULL; + + if (!GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenLinkedToken, &linked, sizeof(linked), &size)) + return NULL; + return linked.LinkedToken; +} + /************************************************************************* * SHELL_ExecuteW [Internal] * @@ -305,6 +320,7 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, UINT gcdret = 0; WCHAR curdir[MAX_PATH]; DWORD dwCreationFlags; + HANDLE token = NULL; TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory)); @@ -326,8 +342,12 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, dwCreationFlags = CREATE_UNICODE_ENVIRONMENT; if (!(psei->fMask & SEE_MASK_NO_CONSOLE)) dwCreationFlags |= CREATE_NEW_CONSOLE; - if (CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, dwCreationFlags, env, - NULL, &startup, &info)) + + if (psei->lpVerb && !wcsicmp(psei->lpVerb, L"runas")) + token = get_admin_token(); + + if (CreateProcessAsUserW(token, NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, + dwCreationFlags, env, NULL, &startup, &info)) { /* Give 30 seconds to the app to come up, if desired. Probably only needed when starting app immediately before making a DDE connection. */ @@ -347,6 +367,8 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, retval = ERROR_BAD_FORMAT; } + CloseHandle(token); + TRACE("returning %Iu\n", retval); psei_out->hInstApp = (HINSTANCE)retval; -- 2.34.1