Skip to content

Commit

Permalink
win: ucrt64: fix non-admin shortcut launch on UCRT64 runtime
Browse files Browse the repository at this point in the history
1) On UCRT64, std::filesystem::exists() interprets the credentials folder to
not exist if the Users groups do not have folder read permissions, which
results in a subsequent failure to create the already existing folder.

2) Similarly, non-admin shortcut launches may also throw an exception in
boost::filesystem::create_directories() if the config folder has been
deleted by the user after installation. Steps to reproduce: install
Sunshine, quit Sunshine, delete config and then run launcher as non-admin.

Fix 1) by setting User read access to the folder - but not its
contents - so std::filesystem::exists() gives the expected result.

Fix 2) by allowing non-privileged process to start the service even
if no config was loaded, thus deferring config creation to service instance.
  • Loading branch information
psyke83 authored and tez011 committed Apr 4, 2024
1 parent 42619ca commit 673d972
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
10 changes: 9 additions & 1 deletion src/config.cpp
Expand Up @@ -1266,17 +1266,25 @@ namespace config {
BOOST_LOG(fatal) << "Failed to apply config: "sv << err.what();
}

if (!config_loaded) {
#ifdef _WIN32
// UCRT64 raises an access denied exception if launching from the shortcut
// as non-admin and the config folder is not yet present; we can defer
// so that service instance will do the work instead.

if (!config_loaded && !shortcut_launch) {
BOOST_LOG(fatal) << "To relaunch Sunshine successfully, use the shortcut in the Start Menu. Do not run Sunshine.exe manually."sv;
std::this_thread::sleep_for(10s);
#else
if (!config_loaded) {
#endif
return -1;
}

#ifdef _WIN32
// We have to wait until the config is loaded to handle these launches,
// because we need to have the correct base port loaded in our config.
// Exception: UCRT64 shortcut_launch instances may have no config loaded due to
// insufficient permissions to create folder; port defaults will be acceptable.
if (service_admin_launch) {
// This is a relaunch as admin to start the service
service_ctrl::start_service();
Expand Down
5 changes: 3 additions & 2 deletions src_assets/windows/misc/migration/migrate-config.bat
Expand Up @@ -38,10 +38,11 @@ if exist "%OLD_DIR%\credentials\" (
rem Create the credentials directory if it wasn't migrated or already existing
if not exist "%NEW_DIR%\credentials\" mkdir "%NEW_DIR%\credentials"

rem Disallow read access to the credentials directory for normal users
rem Note: We must use the SID directly because "Administrators" is localized
rem Disallow read access to the credentials directory contents for normal users
rem Note: We must use the SIDs directly because "Users" and "Administrators" are localized
icacls "%NEW_DIR%\credentials" /inheritance:r
icacls "%NEW_DIR%\credentials" /grant:r *S-1-5-32-544:(OI)(CI)(F)
icacls "%NEW_DIR%\credentials" /grant:r *S-1-5-32-545:(R)

rem Migrate the covers directory
if exist "%OLD_DIR%\covers\" (
Expand Down

0 comments on commit 673d972

Please sign in to comment.