mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Rebase against 1719aef8cbc99994ec93848ae6e9e29e5c4beb78.
This commit is contained in:
parent
ec3dd19d45
commit
9e265ac738
@ -1,149 +0,0 @@
|
||||
From 51cde3dff5de27d1aebc964a4802758534d56773 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 5 Aug 2017 03:39:55 +0200
|
||||
Subject: [PATCH] ntdll: Implement process token elevation through manifests.
|
||||
|
||||
---
|
||||
dlls/ntdll/loader.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
server/process.c | 8 ++++++++
|
||||
server/process.h | 1 +
|
||||
server/protocol.def | 7 +++++++
|
||||
server/token.c | 14 ++++++++++++++
|
||||
5 files changed, 67 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
|
||||
index 6290cbcb4e6..9a8f13901b2 100644
|
||||
--- a/dlls/ntdll/loader.c
|
||||
+++ b/dlls/ntdll/loader.c
|
||||
@@ -3489,6 +3489,32 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow
|
||||
}
|
||||
|
||||
|
||||
+/***********************************************************************
|
||||
+ * elevate_process
|
||||
+ */
|
||||
+static void elevate_process( void )
|
||||
+{
|
||||
+ NTSTATUS status;
|
||||
+ HANDLE token;
|
||||
+
|
||||
+ if (!(token = __wine_create_default_token( TRUE )))
|
||||
+ {
|
||||
+ ERR( "Failed to create admin token\n" );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ SERVER_START_REQ( replace_process_token )
|
||||
+ {
|
||||
+ req->token = wine_server_obj_handle( token );
|
||||
+ if ((status = wine_server_call( req )))
|
||||
+ ERR( "Failed to replace process token: %08x\n", status );
|
||||
+ }
|
||||
+ SERVER_END_REQ;
|
||||
+
|
||||
+ NtClose( token );
|
||||
+}
|
||||
+
|
||||
+
|
||||
/***********************************************************************
|
||||
* load_global_options
|
||||
*/
|
||||
@@ -3900,6 +3926,7 @@ void __wine_process_init(void)
|
||||
'k','e','r','n','e','l','3','2','.','d','l','l',0};
|
||||
void (WINAPI *kernel32_start_process)(LPTHREAD_START_ROUTINE,void*) = NULL;
|
||||
RTL_USER_PROCESS_PARAMETERS *params;
|
||||
+ ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION runlevel;
|
||||
WINE_MODREF *wm;
|
||||
NTSTATUS status;
|
||||
ANSI_STRING func_name;
|
||||
@@ -4021,6 +4048,16 @@ void __wine_process_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
+ /* elevate process if necessary */
|
||||
+ status = RtlQueryInformationActivationContext( 0, NULL, 0, RunlevelInformationInActivationContext,
|
||||
+ &runlevel, sizeof(runlevel), NULL );
|
||||
+ if (!status && (runlevel.RunLevel == ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE ||
|
||||
+ runlevel.RunLevel == ACTCTX_RUN_LEVEL_REQUIRE_ADMIN))
|
||||
+ {
|
||||
+ TRACE( "Application requested admin rights (run level %d)\n", runlevel.RunLevel );
|
||||
+ elevate_process(); /* FIXME: the process exists with a wrong token for a short time */
|
||||
+ }
|
||||
+
|
||||
/* the main exe needs to be the first in the load order list */
|
||||
RemoveEntryList( &wm->ldr.InLoadOrderLinks );
|
||||
InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderLinks );
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index fa8495511e0..df72efdecc8 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -1086,6 +1086,14 @@ int set_process_debug_flag( struct process *process, int flag )
|
||||
return write_process_memory( process, process->peb + 2, 1, &data );
|
||||
}
|
||||
|
||||
+/* replace the token of a process */
|
||||
+void replace_process_token( struct process *process, struct token *new_token )
|
||||
+{
|
||||
+ release_object(current->process->token);
|
||||
+ current->process->token = new_token;
|
||||
+ grab_object(new_token);
|
||||
+}
|
||||
+
|
||||
/* create a new process */
|
||||
DECL_HANDLER(new_process)
|
||||
{
|
||||
diff --git a/server/process.h b/server/process.h
|
||||
index 0fdf070b78e..43e8cc1ad7e 100644
|
||||
--- a/server/process.h
|
||||
+++ b/server/process.h
|
||||
@@ -129,6 +129,7 @@ extern void kill_console_processes( struct thread *renderer, int exit_code );
|
||||
extern void kill_debugged_processes( struct thread *debugger, int exit_code );
|
||||
extern void detach_debugged_processes( struct thread *debugger );
|
||||
extern void enum_processes( int (*cb)(struct process*, void*), void *user);
|
||||
+extern void replace_process_token( struct process *process, struct token *token );
|
||||
|
||||
/* console functions */
|
||||
extern obj_handle_t inherit_console( struct thread *parent_thread, obj_handle_t handle,
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index a9308904afc..8c40fba8d0a 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -3489,6 +3489,13 @@ struct handle_info
|
||||
@END
|
||||
|
||||
|
||||
+/* Create a new token */
|
||||
+@REQ(replace_process_token)
|
||||
+ obj_handle_t token; /* new process token */
|
||||
+@REPLY
|
||||
+@END
|
||||
+
|
||||
+
|
||||
/* Create I/O completion port */
|
||||
@REQ(create_completion)
|
||||
unsigned int access; /* desired access to a port */
|
||||
diff --git a/server/token.c b/server/token.c
|
||||
index 970ed1838da..1c1d49989b3 100644
|
||||
--- a/server/token.c
|
||||
+++ b/server/token.c
|
||||
@@ -1804,3 +1804,17 @@ DECL_HANDLER(create_token)
|
||||
release_object( token );
|
||||
}
|
||||
}
|
||||
+
|
||||
+/* Replaces the token of the current process */
|
||||
+DECL_HANDLER(replace_process_token)
|
||||
+{
|
||||
+ struct token *token;
|
||||
+
|
||||
+ if ((token = (struct token *)get_handle_obj( current->process, req->token,
|
||||
+ TOKEN_ASSIGN_PRIMARY,
|
||||
+ &token_ops )))
|
||||
+ {
|
||||
+ replace_process_token( current->process, token );
|
||||
+ release_object( token );
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,80 +0,0 @@
|
||||
From baff5c160cf7f1ac0011bf8f55d506bf0346e1fd Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Mon, 7 Aug 2017 02:53:06 +0200
|
||||
Subject: [PATCH] user32: Start explorer.exe using limited rights.
|
||||
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 4 ++--
|
||||
dlls/user32/win.c | 12 ++++++++++--
|
||||
2 files changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index f27642e7a7..0271cd72e0 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -7313,7 +7313,7 @@ static void test_token_security_descriptor(void)
|
||||
ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
|
||||
ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
|
||||
tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
|
||||
- todo_wine ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
|
||||
+ ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
|
||||
|
||||
size = 0;
|
||||
ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
|
||||
@@ -7768,7 +7768,7 @@ static void test_child_token_sd_medium(void)
|
||||
ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
|
||||
ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
|
||||
tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
|
||||
- todo_wine ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
|
||||
+ ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, sd);
|
||||
}
|
||||
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
|
||||
index cbfd8bb14a..8039f54fb0 100644
|
||||
--- a/dlls/user32/win.c
|
||||
+++ b/dlls/user32/win.c
|
||||
@@ -43,6 +43,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
|
||||
#define NB_USER_HANDLES ((LAST_USER_HANDLE - FIRST_USER_HANDLE + 1) >> 1)
|
||||
#define USER_HANDLE_TO_INDEX(hwnd) ((LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1)
|
||||
|
||||
+extern HANDLE CDECL __wine_create_default_token(BOOL admin);
|
||||
+
|
||||
static DWORD process_layout = ~0u;
|
||||
|
||||
static struct list window_surfaces = LIST_INIT( window_surfaces );
|
||||
@@ -2052,6 +2054,7 @@ HWND WINAPI GetDesktopWindow(void)
|
||||
WCHAR app[MAX_PATH + ARRAY_SIZE( explorer )];
|
||||
WCHAR cmdline[MAX_PATH + ARRAY_SIZE( explorer ) + ARRAY_SIZE( args )];
|
||||
WCHAR desktop[MAX_PATH];
|
||||
+ HANDLE token;
|
||||
void *redir;
|
||||
|
||||
SERVER_START_REQ( set_user_object_info )
|
||||
@@ -2084,9 +2087,12 @@ HWND WINAPI GetDesktopWindow(void)
|
||||
strcpyW( cmdline, app );
|
||||
strcatW( cmdline, args );
|
||||
|
||||
+ if (!(token = __wine_create_default_token( FALSE )))
|
||||
+ ERR( "Failed to create limited token\n" );
|
||||
+
|
||||
Wow64DisableWow64FsRedirection( &redir );
|
||||
- if (CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS,
|
||||
- NULL, windir, &si, &pi ))
|
||||
+ if (CreateProcessAsUserW( token, app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS,
|
||||
+ NULL, windir, &si, &pi ))
|
||||
{
|
||||
TRACE( "started explorer pid %04x tid %04x\n", pi.dwProcessId, pi.dwThreadId );
|
||||
WaitForInputIdle( pi.hProcess, 10000 );
|
||||
@@ -2096,6 +2102,8 @@ HWND WINAPI GetDesktopWindow(void)
|
||||
else WARN( "failed to start explorer, err %d\n", GetLastError() );
|
||||
Wow64RevertWow64FsRedirection( redir );
|
||||
|
||||
+ if (token) CloseHandle( token );
|
||||
+
|
||||
SERVER_START_REQ( get_desktop_window )
|
||||
{
|
||||
req->force = 1;
|
||||
--
|
||||
2.18.0
|
||||
|
@ -1,344 +0,0 @@
|
||||
From 5bf0baa79c46ec44dfd5e1340e96ff9289bc37f8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sun, 6 Aug 2017 03:15:34 +0200
|
||||
Subject: [PATCH] programs/runas: Basic implementation for starting processes
|
||||
with a different trustlevel.
|
||||
|
||||
---
|
||||
configure.ac | 1 +
|
||||
programs/runas/Makefile.in | 8 ++
|
||||
programs/runas/runas.c | 214 +++++++++++++++++++++++++++++++++++++
|
||||
programs/runas/runas.h | 26 +++++
|
||||
programs/runas/runas.rc | 39 +++++++
|
||||
5 files changed, 288 insertions(+)
|
||||
create mode 100644 programs/runas/Makefile.in
|
||||
create mode 100644 programs/runas/runas.c
|
||||
create mode 100644 programs/runas/runas.h
|
||||
create mode 100644 programs/runas/runas.rc
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 499c4f37ca..6f12614af1 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -3891,6 +3891,7 @@ WINE_CONFIG_MAKEFILE(programs/regedit/tests)
|
||||
WINE_CONFIG_MAKEFILE(programs/regsvcs)
|
||||
WINE_CONFIG_MAKEFILE(programs/regsvr32)
|
||||
WINE_CONFIG_MAKEFILE(programs/rpcss)
|
||||
+WINE_CONFIG_MAKEFILE(programs/runas)
|
||||
WINE_CONFIG_MAKEFILE(programs/rundll.exe16,enable_win16)
|
||||
WINE_CONFIG_MAKEFILE(programs/rundll32)
|
||||
WINE_CONFIG_MAKEFILE(programs/sc)
|
||||
diff --git a/programs/runas/Makefile.in b/programs/runas/Makefile.in
|
||||
new file mode 100644
|
||||
index 0000000000..33aa00ab03
|
||||
--- /dev/null
|
||||
+++ b/programs/runas/Makefile.in
|
||||
@@ -0,0 +1,8 @@
|
||||
+MODULE = runas.exe
|
||||
+APPMODE = -mconsole -municode -mno-cygwin
|
||||
+IMPORTS = advapi32 user32
|
||||
+
|
||||
+C_SRCS = \
|
||||
+ runas.c
|
||||
+
|
||||
+RC_SRCS = runas.rc
|
||||
diff --git a/programs/runas/runas.c b/programs/runas/runas.c
|
||||
new file mode 100644
|
||||
index 0000000000..412755afa0
|
||||
--- /dev/null
|
||||
+++ b/programs/runas/runas.c
|
||||
@@ -0,0 +1,214 @@
|
||||
+/*
|
||||
+ * runas.exe implementation
|
||||
+ *
|
||||
+ * Copyright 2017 Michael Müller
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#include <windows.h>
|
||||
+#include <wchar.h>
|
||||
+#include <wine/debug.h>
|
||||
+
|
||||
+#include "runas.h"
|
||||
+
|
||||
+WINE_DEFAULT_DEBUG_CHANNEL(runas);
|
||||
+
|
||||
+extern HANDLE CDECL __wine_create_default_token(BOOL admin);
|
||||
+
|
||||
+struct cmdinfo
|
||||
+{
|
||||
+ WCHAR *program;
|
||||
+ DWORD trustlevel;
|
||||
+};
|
||||
+
|
||||
+static void output_writeconsole(const WCHAR *str, DWORD wlen)
|
||||
+{
|
||||
+ DWORD count, ret;
|
||||
+
|
||||
+ ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, wlen, &count, NULL);
|
||||
+ if (!ret)
|
||||
+ {
|
||||
+ DWORD len;
|
||||
+ char *msgA;
|
||||
+
|
||||
+ /* On Windows WriteConsoleW() fails if the output is redirected. So fall
|
||||
+ * back to WriteFile(), assuming the console encoding is still the right
|
||||
+ * one in that case.
|
||||
+ */
|
||||
+ len = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, NULL, 0, NULL, NULL);
|
||||
+ msgA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
|
||||
+ if (!msgA) return;
|
||||
+
|
||||
+ WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, msgA, len, NULL, NULL);
|
||||
+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
|
||||
+ HeapFree(GetProcessHeap(), 0, msgA);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void output_formatstring(const WCHAR *fmt, __ms_va_list va_args)
|
||||
+{
|
||||
+ WCHAR *str;
|
||||
+ DWORD len;
|
||||
+
|
||||
+ SetLastError(NO_ERROR);
|
||||
+ len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
||||
+ fmt, 0, 0, (WCHAR *)&str, 0, &va_args);
|
||||
+ if (len == 0 && GetLastError() != NO_ERROR)
|
||||
+ {
|
||||
+ WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt));
|
||||
+ return;
|
||||
+ }
|
||||
+ output_writeconsole(str, len);
|
||||
+ LocalFree(str);
|
||||
+}
|
||||
+
|
||||
+static void WINAPIV output_message(unsigned int id, ...)
|
||||
+{
|
||||
+ WCHAR fmt[1024];
|
||||
+ __ms_va_list va_args;
|
||||
+
|
||||
+ if (!LoadStringW(GetModuleHandleW(NULL), id, fmt, sizeof(fmt)/sizeof(WCHAR)))
|
||||
+ {
|
||||
+ WINE_FIXME("LoadString failed with %d\n", GetLastError());
|
||||
+ return;
|
||||
+ }
|
||||
+ __ms_va_start(va_args, id);
|
||||
+ output_formatstring(fmt, va_args);
|
||||
+ __ms_va_end(va_args);
|
||||
+}
|
||||
+
|
||||
+static void show_usage(void)
|
||||
+{
|
||||
+ output_message(STRING_USAGE);
|
||||
+}
|
||||
+
|
||||
+static void show_trustlevels(void)
|
||||
+{
|
||||
+ output_message(STRING_TRUSTLEVELS);
|
||||
+ ExitProcess(0);
|
||||
+}
|
||||
+
|
||||
+static WCHAR *starts_with(WCHAR *str, const WCHAR *start)
|
||||
+{
|
||||
+ DWORD start_len = lstrlenW(start);
|
||||
+ if (lstrlenW(str) < start_len)
|
||||
+ return NULL;
|
||||
+ if (wcsncmp(str, start, start_len))
|
||||
+ return NULL;
|
||||
+ return str + start_len;
|
||||
+}
|
||||
+
|
||||
+static BOOL parse_command_line(int argc, WCHAR *argv[], struct cmdinfo *cmd)
|
||||
+{
|
||||
+ static const WCHAR showtrustlevelsW[] = {'/','s','h','o','w','t','r','u','s','t','l','e','v','e','l','s',0};
|
||||
+ static const WCHAR trustlevelW[] = {'/','t','r','u','s','t','l','e','v','e','l',':',0};
|
||||
+ int i;
|
||||
+
|
||||
+ memset(cmd, 0, sizeof(*cmd));
|
||||
+
|
||||
+ for (i = 1; i < argc; i++)
|
||||
+ {
|
||||
+ if (argv[i][0] == '/')
|
||||
+ {
|
||||
+ WCHAR *arg;
|
||||
+
|
||||
+ if ((arg = starts_with(argv[i], trustlevelW)))
|
||||
+ cmd->trustlevel = wcstoul(arg, NULL, 0);
|
||||
+ else if (!lstrcmpW(argv[i], showtrustlevelsW))
|
||||
+ show_trustlevels();
|
||||
+ else
|
||||
+ WINE_FIXME("Ignoring parameter %s\n", wine_dbgstr_w(argv[i]));
|
||||
+ }
|
||||
+ else if (argv[i][0])
|
||||
+ {
|
||||
+ if (cmd->program) return FALSE;
|
||||
+ cmd->program = argv[i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+static BOOL start_process(struct cmdinfo *cmd)
|
||||
+{
|
||||
+ PROCESS_INFORMATION info;
|
||||
+ STARTUPINFOW startup;
|
||||
+ HANDLE token = NULL;
|
||||
+ BOOL ret;
|
||||
+
|
||||
+ if (cmd->trustlevel == 0x20000)
|
||||
+ {
|
||||
+ if (!(token = __wine_create_default_token(FALSE)))
|
||||
+ ERR("Failed to create limited token\n");
|
||||
+ }
|
||||
+
|
||||
+ memset(&startup, 0, sizeof(startup));
|
||||
+ startup.cb = sizeof(startup);
|
||||
+ ret = CreateProcessAsUserW(token, NULL, cmd->program, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
|
||||
+ if (ret)
|
||||
+ {
|
||||
+ CloseHandle(info.hProcess);
|
||||
+ CloseHandle(info.hThread);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ DWORD error = GetLastError();
|
||||
+ WCHAR *str;
|
||||
+
|
||||
+ if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, 0, (WCHAR *)&str, 0, NULL))
|
||||
+ {
|
||||
+ output_message(STRING_START_ERROR, cmd->program, error, str);
|
||||
+ LocalFree(str);
|
||||
+ }
|
||||
+ else
|
||||
+ WINE_FIXME("Failed to format error: %u\n", error);
|
||||
+ }
|
||||
+
|
||||
+ if (token) CloseHandle(token);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int wmain(int argc, WCHAR *argv[])
|
||||
+{
|
||||
+ struct cmdinfo cmd;
|
||||
+
|
||||
+ if (argc <= 1)
|
||||
+ {
|
||||
+ show_usage();
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!parse_command_line(argc, argv, &cmd))
|
||||
+ {
|
||||
+ show_usage();
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (!cmd.program)
|
||||
+ {
|
||||
+ show_usage();
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (cmd.trustlevel && cmd.trustlevel != 0x20000)
|
||||
+ {
|
||||
+ output_message(STRING_UNHANDLED_TRUSTLEVEL, cmd.trustlevel);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return start_process(&cmd);
|
||||
+}
|
||||
diff --git a/programs/runas/runas.h b/programs/runas/runas.h
|
||||
new file mode 100644
|
||||
index 0000000000..40599a3b33
|
||||
--- /dev/null
|
||||
+++ b/programs/runas/runas.h
|
||||
@@ -0,0 +1,26 @@
|
||||
+/*
|
||||
+ * runas.exe implementation
|
||||
+ *
|
||||
+ * Copyright 2017 Michael Müller
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#include <windef.h>
|
||||
+
|
||||
+#define STRING_USAGE 101
|
||||
+#define STRING_UNHANDLED_TRUSTLEVEL 102
|
||||
+#define STRING_TRUSTLEVELS 103
|
||||
+#define STRING_START_ERROR 104
|
||||
diff --git a/programs/runas/runas.rc b/programs/runas/runas.rc
|
||||
new file mode 100644
|
||||
index 0000000000..f9297a4479
|
||||
--- /dev/null
|
||||
+++ b/programs/runas/runas.rc
|
||||
@@ -0,0 +1,39 @@
|
||||
+/*
|
||||
+ * runas.exe implementation
|
||||
+ *
|
||||
+ * Copyright 2017 Michael Müller
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#include "runas.h"
|
||||
+
|
||||
+#pragma makedep po
|
||||
+
|
||||
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
+
|
||||
+STRINGTABLE
|
||||
+{
|
||||
+ STRING_USAGE, "Usage of RUNAS:\n\n\
|
||||
+\RUNAS /trustlevel:<trustlevel> program\n\n\
|
||||
+\ /showtrustlevels Show possible trustlevels\n\
|
||||
+\ /trustlevel <trustlevel> should be listed in /showtrustlevels\n\
|
||||
+\ program Program to start\n\n"
|
||||
+ STRING_UNHANDLED_TRUSTLEVEL, "runas: Unhandled trustlevel 0x%1!x!\n"
|
||||
+ STRING_TRUSTLEVELS, "The following trustlevels are supported:\n\
|
||||
+0x20000 (standard user)\n"
|
||||
+ STRING_START_ERROR, "RUNAS-Error: %1 could not be started\n\
|
||||
+ %2!u!: %3\n"
|
||||
+}
|
||||
--
|
||||
2.23.0.rc1
|
||||
|
@ -1,27 +0,0 @@
|
||||
From 9804dd77fd8c0ec56963306f409fea6b910bb48d Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Sun, 7 Feb 2021 22:54:19 -0600
|
||||
Subject: [PATCH] server: Create processes using a limited administrator token
|
||||
by default.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
server/process.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index 15387a2affa..3a8bbdbfb2e 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -664,7 +664,7 @@ struct process *create_process( int fd, struct process *parent, unsigned int fla
|
||||
if (!parent)
|
||||
{
|
||||
process->handles = alloc_handle_table( process, 0 );
|
||||
- process->token = token_create_admin( TRUE, -1, TokenElevationTypeFull, default_session_id );
|
||||
+ process->token = token_create_admin( TRUE, -1, TokenElevationTypeLimited, default_session_id );
|
||||
process->affinity = ~0;
|
||||
}
|
||||
else
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,57 +0,0 @@
|
||||
From 643461bc989bd848363241dcfa04187e8d3a84d1 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Fri, 21 May 2021 21:52:06 -0500
|
||||
Subject: [PATCH] ntdll: Always start the initial process through start.exe.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/env.c | 26 +++-----------------------
|
||||
1 file changed, 3 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c
|
||||
index 30782a70eb0..959bafb28b7 100644
|
||||
--- a/dlls/ntdll/unix/env.c
|
||||
+++ b/dlls/ntdll/unix/env.c
|
||||
@@ -1909,6 +1909,7 @@ static void init_peb( RTL_USER_PROCESS_PARAMETERS *params, void *module )
|
||||
*/
|
||||
static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module )
|
||||
{
|
||||
+ static const char *args[] = { "start.exe", "/exec" };
|
||||
static const WCHAR valueW[] = {'1',0};
|
||||
static const WCHAR pathW[] = {'P','A','T','H'};
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
@@ -1937,29 +1938,8 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module )
|
||||
add_registry_environment( &env, &env_pos, &env_size );
|
||||
env[env_pos++] = 0;
|
||||
|
||||
- status = load_main_exe( NULL, main_argv[1], curdir, 0, &image, module );
|
||||
- if (!status)
|
||||
- {
|
||||
- char *loader;
|
||||
-
|
||||
- if (main_image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT;
|
||||
- /* if we have to use a different loader, fall back to start.exe */
|
||||
- if ((loader = get_alternate_wineloader( main_image_info.Machine )))
|
||||
- {
|
||||
- free( loader );
|
||||
- status = STATUS_INVALID_IMAGE_FORMAT;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (status) /* try launching it through start.exe */
|
||||
- {
|
||||
- static const char *args[] = { "start.exe", "/exec" };
|
||||
- free( image );
|
||||
- if (*module) NtUnmapViewOfSection( GetCurrentProcess(), *module );
|
||||
- load_start_exe( &image, module );
|
||||
- prepend_argv( args, 2 );
|
||||
- }
|
||||
- else rebuild_argv();
|
||||
+ load_start_exe( &image, module );
|
||||
+ prepend_argv( args, 2 );
|
||||
|
||||
main_wargv = build_wargv( get_dos_path( image ));
|
||||
cmdline = build_command_line( main_wargv );
|
||||
--
|
||||
2.40.1
|
||||
|
@ -1,110 +0,0 @@
|
||||
From 1eaa73714299df810d22a727e8053679d5e89f64 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Sun, 18 Apr 2021 17:46:35 -0500
|
||||
Subject: [PATCH] kernelbase: Elevate processes if requested in
|
||||
CreateProcessInternal().
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/kernelbase/process.c | 57 +++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 55 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c
|
||||
index 54a524abe04..7365bee9425 100644
|
||||
--- a/dlls/kernelbase/process.c
|
||||
+++ b/dlls/kernelbase/process.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "winnls.h"
|
||||
#include "wincontypes.h"
|
||||
#include "winternl.h"
|
||||
+#include "winuser.h"
|
||||
|
||||
#include "kernelbase.h"
|
||||
#include "wine/debug.h"
|
||||
@@ -431,6 +432,54 @@ BOOL WINAPI DECLSPEC_HOTPATCH CloseHandle( HANDLE handle )
|
||||
}
|
||||
|
||||
|
||||
+static BOOL image_needs_elevation( const WCHAR *path )
|
||||
+{
|
||||
+ ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION run_level;
|
||||
+ BOOL ret = FALSE;
|
||||
+ HANDLE handle;
|
||||
+ ACTCTXW ctx;
|
||||
+
|
||||
+ ctx.cbSize = sizeof(ctx);
|
||||
+ ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
|
||||
+ ctx.lpSource = path;
|
||||
+ ctx.lpResourceName = (const WCHAR *)CREATEPROCESS_MANIFEST_RESOURCE_ID;
|
||||
+
|
||||
+ if (RtlCreateActivationContext( &handle, &ctx )) return FALSE;
|
||||
+
|
||||
+ if (!RtlQueryInformationActivationContext( 0, handle, NULL, RunlevelInformationInActivationContext,
|
||||
+ &run_level, sizeof(run_level), NULL ))
|
||||
+ {
|
||||
+ TRACE( "image requested run level %#x\n", run_level.RunLevel );
|
||||
+ if (run_level.RunLevel == ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE
|
||||
+ || run_level.RunLevel == ACTCTX_RUN_LEVEL_REQUIRE_ADMIN)
|
||||
+ ret = TRUE;
|
||||
+ }
|
||||
+ RtlReleaseActivationContext( handle );
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static HANDLE get_elevated_token(void)
|
||||
+{
|
||||
+ TOKEN_ELEVATION_TYPE type;
|
||||
+ TOKEN_LINKED_TOKEN linked;
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ if ((status = NtQueryInformationToken( GetCurrentThreadEffectiveToken(),
|
||||
+ TokenElevationType, &type, sizeof(type), NULL )))
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (type == TokenElevationTypeFull) return NULL;
|
||||
+
|
||||
+ if ((status = NtQueryInformationToken( GetCurrentThreadEffectiveToken(),
|
||||
+ TokenLinkedToken, &linked, sizeof(linked), NULL )))
|
||||
+ return NULL;
|
||||
+
|
||||
+ return linked.LinkedToken;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/**********************************************************************
|
||||
* CreateProcessAsUserA (kernelbase.@)
|
||||
*/
|
||||
@@ -517,7 +566,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
|
||||
WCHAR *p, *tidy_cmdline = cmd_line;
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
RTL_USER_PROCESS_INFORMATION rtl_info;
|
||||
- HANDLE parent = 0, debug = 0;
|
||||
+ HANDLE parent = 0, debug = 0, elevated_token = NULL;
|
||||
ULONG nt_flags = 0;
|
||||
USHORT machine = 0;
|
||||
NTSTATUS status;
|
||||
@@ -629,6 +678,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
|
||||
if (flags & CREATE_BREAKAWAY_FROM_JOB) nt_flags |= PROCESS_CREATE_FLAGS_BREAKAWAY;
|
||||
if (flags & CREATE_SUSPENDED) nt_flags |= PROCESS_CREATE_FLAGS_SUSPENDED;
|
||||
|
||||
+ if (!token && image_needs_elevation( params->ImagePathName.Buffer ))
|
||||
+ token = elevated_token = get_elevated_token();
|
||||
+
|
||||
status = create_nt_process( token, debug, process_attr, thread_attr,
|
||||
nt_flags, params, &rtl_info, parent, machine, handle_list, job_list );
|
||||
switch (status)
|
||||
@@ -670,7 +722,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
|
||||
TRACE( "started process pid %04lx tid %04lx\n", info->dwProcessId, info->dwThreadId );
|
||||
}
|
||||
|
||||
- done:
|
||||
+done:
|
||||
+ if (elevated_token) NtClose( elevated_token );
|
||||
RtlDestroyProcessParameters( params );
|
||||
if (tidy_cmdline != cmd_line) HeapFree( GetProcessHeap(), 0, tidy_cmdline );
|
||||
return set_ntstatus( status );
|
||||
--
|
||||
2.40.1
|
||||
|
@ -1,129 +0,0 @@
|
||||
From 1754d90b8cc833d55e6d3f3de23cdf89dffd37aa Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Sun, 18 Apr 2021 17:46:44 -0500
|
||||
Subject: [PATCH] ntdll: Elevate processes if requested in
|
||||
RtlCreateUserProcess().
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/process.c | 81 +++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 76 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
|
||||
index dcdb26f81d1..ed1b2a20311 100644
|
||||
--- a/dlls/ntdll/process.c
|
||||
+++ b/dlls/ntdll/process.c
|
||||
@@ -37,6 +37,11 @@
|
||||
#include "wine/exception.h"
|
||||
|
||||
|
||||
+/* we don't want to include winuser.h */
|
||||
+#define CREATEPROCESS_MANIFEST_RESOURCE_ID ((ULONG_PTR)1)
|
||||
+
|
||||
+WINE_DEFAULT_DEBUG_CHANNEL(process);
|
||||
+
|
||||
/******************************************************************************
|
||||
* RtlGetCurrentPeb [NTDLL.@]
|
||||
*
|
||||
@@ -89,6 +94,63 @@ NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx( ULONG disable, ULONG *old_value )
|
||||
}
|
||||
|
||||
|
||||
+static BOOL image_needs_elevation( const UNICODE_STRING *path )
|
||||
+{
|
||||
+ ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION run_level;
|
||||
+ UNICODE_STRING path0;
|
||||
+ BOOL ret = FALSE;
|
||||
+ HANDLE handle;
|
||||
+ ACTCTXW ctx;
|
||||
+
|
||||
+ if (RtlDuplicateUnicodeString( 1, path, &path0 ))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ ctx.cbSize = sizeof(ctx);
|
||||
+ ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
|
||||
+ ctx.lpSource = path0.Buffer;
|
||||
+ ctx.lpResourceName = (const WCHAR *)CREATEPROCESS_MANIFEST_RESOURCE_ID;
|
||||
+
|
||||
+ if (RtlCreateActivationContext( &handle, &ctx ))
|
||||
+ {
|
||||
+ RtlFreeUnicodeString( &path0 );
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (!RtlQueryInformationActivationContext( 0, handle, NULL, RunlevelInformationInActivationContext,
|
||||
+ &run_level, sizeof(run_level), NULL ))
|
||||
+ {
|
||||
+ TRACE( "image requested run level %#x\n", run_level.RunLevel );
|
||||
+ if (run_level.RunLevel == ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE
|
||||
+ || run_level.RunLevel == ACTCTX_RUN_LEVEL_REQUIRE_ADMIN)
|
||||
+ ret = TRUE;
|
||||
+ }
|
||||
+ RtlReleaseActivationContext( handle );
|
||||
+ RtlFreeUnicodeString( &path0 );
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static HANDLE get_elevated_token(void)
|
||||
+{
|
||||
+ TOKEN_ELEVATION_TYPE type;
|
||||
+ TOKEN_LINKED_TOKEN linked;
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ if ((status = NtQueryInformationToken( GetCurrentThreadEffectiveToken(),
|
||||
+ TokenElevationType, &type, sizeof(type), NULL )))
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (type == TokenElevationTypeFull) return NULL;
|
||||
+
|
||||
+
|
||||
+ if ((status = NtQueryInformationToken( GetCurrentThreadEffectiveToken(),
|
||||
+ TokenLinkedToken, &linked, sizeof(linked), NULL )))
|
||||
+ return NULL;
|
||||
+
|
||||
+ return linked.LinkedToken;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/**********************************************************************
|
||||
* RtlWow64GetCurrentMachine (NTDLL.@)
|
||||
*/
|
||||
@@ -461,8 +523,15 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
|
||||
PS_CREATE_INFO create_info;
|
||||
ULONG_PTR buffer[offsetof( PS_ATTRIBUTE_LIST, Attributes[6] ) / sizeof(ULONG_PTR)];
|
||||
PS_ATTRIBUTE_LIST *attr = (PS_ATTRIBUTE_LIST *)buffer;
|
||||
+ HANDLE elevated_token = NULL;
|
||||
+ NTSTATUS status;
|
||||
UINT pos = 0;
|
||||
|
||||
+ /* It's not clear whether we should use path or ¶ms->ImagePathName here,
|
||||
+ * but Roblox Player tries to pass an empty string for the latter. */
|
||||
+ if (!token && image_needs_elevation( path ))
|
||||
+ token = elevated_token = get_elevated_token();
|
||||
+
|
||||
RtlNormalizeProcessParams( params );
|
||||
|
||||
attr->Attributes[pos].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
|
||||
@@ -509,11 +578,13 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
|
||||
InitializeObjectAttributes( &process_attr, NULL, 0, NULL, process_descr );
|
||||
InitializeObjectAttributes( &thread_attr, NULL, 0, NULL, thread_descr );
|
||||
|
||||
- return NtCreateUserProcess( &info->Process, &info->Thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS,
|
||||
- &process_attr, &thread_attr,
|
||||
- inherit ? PROCESS_CREATE_FLAGS_INHERIT_HANDLES : 0,
|
||||
- THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params,
|
||||
- &create_info, attr );
|
||||
+ status = NtCreateUserProcess( &info->Process, &info->Thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS,
|
||||
+ &process_attr, &thread_attr,
|
||||
+ inherit ? PROCESS_CREATE_FLAGS_INHERIT_HANDLES : 0,
|
||||
+ THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params, &create_info, attr );
|
||||
+
|
||||
+ if (elevated_token) NtClose( elevated_token );
|
||||
+ return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
--
|
||||
2.43.0
|
||||
|
@ -1,2 +0,0 @@
|
||||
Fixes: [40613] Multiple applications require UAC implementation to run installer/app as a normal user instead of administrator (WhatsApp Desktop, Smartflix, Squirrel Installers, OneDrive)
|
||||
Fixes: [39262] DiscordSetup.exe (.NET 4.5.2 app): Squirrell installer requires being run as unelevated process ('explorer.exe' should run unelevated by default with Vista+ setting)
|
@ -1 +1 @@
|
||||
934cfb86b5e2b485b4b90e1eeac4021733559591
|
||||
1719aef8cbc99994ec93848ae6e9e29e5c4beb78
|
||||
|
Loading…
Reference in New Issue
Block a user