diff --git a/README.md b/README.md index 7c927fd0..e9e15b2e 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,12 @@ Wine. All those differences are also documented on the Included bug fixes and improvements ----------------------------------- -**Bug fixes and features included in the next upcoming release [7]:** +**Bug fixes and features included in the next upcoming release [8]:** * Add partial implementation of ITfThreadMgrEx_ActivateEx ([Wine Bug #39564](https://bugs.winehq.org/show_bug.cgi?id=39564)) * Add stub kernel32.FreeUserPhysicalPages ([Wine Bug #39543](https://bugs.winehq.org/show_bug.cgi?id=39543)) * Add stubs for advapi32.RegCreateKeyTransacted[A/W] +* Do not require SeBackupPrivilege in load_registry and unload_registry ([Wine Bug #28729](https://bugs.winehq.org/show_bug.cgi?id=28729)) * Implement stub for hid.HidP_TranslateUsagesToI8042ScanCodes ([Wine Bug #39447](https://bugs.winehq.org/show_bug.cgi?id=39447)) * Implement support for "Purist Mode" (override for all dlls) * Properly handle multiple registry notifications per key diff --git a/debian/changelog b/debian/changelog index ae278344..1d16822c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,8 @@ wine-staging (1.7.55) UNRELEASED; urgency=low * Added patch to properly handle multiple registry notifications per key. * Added patch for stub of kernel32.FreeUserPhysicalPages. * Added patch for stubs of advapi32.RegCreateKeyTransacted[A/W]. + * Added patch to fix required privileges for load_registry and unload_registry + wineserver call. * Remove disabled shell32-Quoted_ShellExecute patchset (bug already fixed and all tests pass). * Remove disabled reg-Cleanup patchset (only cleanup and not actively diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index cf67fc49..b31df063 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -246,6 +246,7 @@ patch_enable_all () enable_server_Pipe_ObjectName="$1" enable_server_Realtime_Priority="$1" enable_server_Registry_Notifications="$1" + enable_server_Registry_Privileges="$1" enable_server_Shared_Memory="$1" enable_server_Signal_Thread="$1" enable_server_Stored_ACLs="$1" @@ -841,6 +842,9 @@ patch_enable () server-Registry_Notifications) enable_server_Registry_Notifications="$2" ;; + server-Registry_Privileges) + enable_server_Registry_Privileges="$2" + ;; server-Shared_Memory) enable_server_Shared_Memory="$2" ;; @@ -4940,6 +4944,21 @@ if test "$enable_server_Registry_Notifications" -eq 1; then ) >> "$patchlist" fi +# Patchset server-Registry_Privileges +# | +# | This patchset fixes the following Wine bugs: +# | * [#28729] Do not require SeBackupPrivilege in load_registry and unload_registry +# | +# | Modified files: +# | * dlls/advapi32/tests/registry.c, server/registry.c +# | +if test "$enable_server_Registry_Privileges" -eq 1; then + patch_apply server-Registry_Privileges/0001-server-Do-not-require-SeBackupPrivilege-in-load_regi.patch + ( + echo '+ { "Sebastian Lackner", "server: Do not require SeBackupPrivilege in load_registry and unload_registry.", 1 },'; + ) >> "$patchlist" +fi + # Patchset server-Signal_Thread # | # | Modified files: diff --git a/patches/server-Registry_Privileges/0001-server-Do-not-require-SeBackupPrivilege-in-load_regi.patch b/patches/server-Registry_Privileges/0001-server-Do-not-require-SeBackupPrivilege-in-load_regi.patch new file mode 100644 index 00000000..5297dd8b --- /dev/null +++ b/patches/server-Registry_Privileges/0001-server-Do-not-require-SeBackupPrivilege-in-load_regi.patch @@ -0,0 +1,187 @@ +From 71dfe4d8c48b19acb04773f769862b5a541cb4c9 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 14 Nov 2015 18:22:52 +0100 +Subject: server: Do not require SeBackupPrivilege in load_registry and + unload_registry. + +--- + dlls/advapi32/tests/registry.c | 107 ++++++++++++++++++++++++----------------- + server/registry.c | 20 +------- + 2 files changed, 65 insertions(+), 62 deletions(-) + +diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c +index 8808822..de32bd9 100644 +--- a/dlls/advapi32/tests/registry.c ++++ b/dlls/advapi32/tests/registry.c +@@ -1513,39 +1513,6 @@ static void test_reg_delete_key(void) + RegCloseKey(key); + } + +-static void test_reg_save_key(void) +-{ +- DWORD ret; +- +- ret = RegSaveKeyA(hkey_main, "saved_key", NULL); +- ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); +-} +- +-static void test_reg_load_key(void) +-{ +- DWORD ret; +- HKEY hkHandle; +- +- ret = RegLoadKeyA(HKEY_LOCAL_MACHINE, "Test", "saved_key"); +- ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); +- +- ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Test", &hkHandle); +- ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); +- +- RegCloseKey(hkHandle); +-} +- +-static void test_reg_unload_key(void) +-{ +- DWORD ret; +- +- ret = RegUnLoadKeyA(HKEY_LOCAL_MACHINE, "Test"); +- ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); +- +- DeleteFileA("saved_key"); +- DeleteFileA("saved_key.LOG"); +-} +- + static BOOL set_privileges(LPCSTR privilege, BOOL set) + { + TOKEN_PRIVILEGES tp; +@@ -1580,6 +1547,66 @@ static BOOL set_privileges(LPCSTR privilege, BOOL set) + return TRUE; + } + ++static void test_reg_save_key(void) ++{ ++ DWORD ret; ++ ++ if (!set_privileges(SE_BACKUP_NAME, TRUE) || ++ !set_privileges(SE_RESTORE_NAME, FALSE)) ++ { ++ win_skip("Failed to set SE_BACKUP_NAME privileges, skipping tests\n"); ++ return; ++ } ++ ++ ret = RegSaveKeyA(hkey_main, "saved_key", NULL); ++ ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); ++ ++ set_privileges(SE_BACKUP_NAME, FALSE); ++} ++ ++static void test_reg_load_key(void) ++{ ++ DWORD ret; ++ HKEY hkHandle; ++ ++ if (!set_privileges(SE_RESTORE_NAME, TRUE) || ++ !set_privileges(SE_BACKUP_NAME, FALSE)) ++ { ++ win_skip("Failed to set SE_RESTORE_NAME privileges, skipping tests\n"); ++ return; ++ } ++ ++ ret = RegLoadKeyA(HKEY_LOCAL_MACHINE, "Test", "saved_key"); ++ ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); ++ ++ set_privileges(SE_RESTORE_NAME, FALSE); ++ ++ ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Test", &hkHandle); ++ ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); ++ ++ RegCloseKey(hkHandle); ++} ++ ++static void test_reg_unload_key(void) ++{ ++ DWORD ret; ++ ++ if (!set_privileges(SE_RESTORE_NAME, TRUE) || ++ !set_privileges(SE_BACKUP_NAME, FALSE)) ++ { ++ win_skip("Failed to set SE_RESTORE_NAME privileges, skipping tests\n"); ++ return; ++ } ++ ++ ret = RegUnLoadKeyA(HKEY_LOCAL_MACHINE, "Test"); ++ ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); ++ ++ set_privileges(SE_RESTORE_NAME, FALSE); ++ ++ DeleteFileA("saved_key"); ++ DeleteFileA("saved_key.LOG"); ++} ++ + /* tests that show that RegConnectRegistry and + OpenSCManager accept computer names without the + \\ prefix (what MSDN says). */ +@@ -3276,17 +3303,9 @@ START_TEST(registry) + test_classesroot_enum(); + test_classesroot_mask(); + +- /* SaveKey/LoadKey require the SE_BACKUP_NAME privilege to be set */ +- if (set_privileges(SE_BACKUP_NAME, TRUE) && +- set_privileges(SE_RESTORE_NAME, TRUE)) +- { +- test_reg_save_key(); +- test_reg_load_key(); +- test_reg_unload_key(); +- +- set_privileges(SE_BACKUP_NAME, FALSE); +- set_privileges(SE_RESTORE_NAME, FALSE); +- } ++ test_reg_save_key(); ++ test_reg_load_key(); ++ test_reg_unload_key(); + + test_reg_delete_tree(); + test_rw_order(); +diff --git a/server/registry.c b/server/registry.c +index c95e103..a3c1390 100644 +--- a/server/registry.c ++++ b/server/registry.c +@@ -2182,17 +2182,9 @@ DECL_HANDLER(delete_key_value) + DECL_HANDLER(load_registry) + { + struct key *key, *parent; +- struct token *token = thread_get_impersonation_token( current ); + struct unicode_str name; + +- const LUID_AND_ATTRIBUTES privs[] = +- { +- { SeBackupPrivilege, 0 }, +- { SeRestorePrivilege, 0 }, +- }; +- +- if (!token || !token_check_privileges( token, TRUE, privs, +- sizeof(privs)/sizeof(privs[0]), NULL )) ++ if (!thread_single_check_privilege( current, &SeRestorePrivilege )) + { + set_error( STATUS_PRIVILEGE_NOT_HELD ); + return; +@@ -2214,16 +2206,8 @@ DECL_HANDLER(load_registry) + DECL_HANDLER(unload_registry) + { + struct key *key; +- struct token *token = thread_get_impersonation_token( current ); +- +- const LUID_AND_ATTRIBUTES privs[] = +- { +- { SeBackupPrivilege, 0 }, +- { SeRestorePrivilege, 0 }, +- }; + +- if (!token || !token_check_privileges( token, TRUE, privs, +- sizeof(privs)/sizeof(privs[0]), NULL )) ++ if (!thread_single_check_privilege( current, &SeRestorePrivilege )) + { + set_error( STATUS_PRIVILEGE_NOT_HELD ); + return; +-- +2.6.2 + diff --git a/patches/server-Registry_Privileges/definition b/patches/server-Registry_Privileges/definition new file mode 100644 index 00000000..521ae9ce --- /dev/null +++ b/patches/server-Registry_Privileges/definition @@ -0,0 +1 @@ +Fixes: [28729] Do not require SeBackupPrivilege in load_registry and unload_registry