fix: run GUI as user, use sudo for root operations only

pkexec cannot open display (no DISPLAY env). GUI runs as normal user,
rsync/restore/mkdir/rm use sudo. First sudo prompts for password,
then token is cached for ~15min.
This commit is contained in:
x3
2026-09-08 09:27:19 +00:00
parent e47ac11be1
commit 8488778cf0
3 changed files with 8 additions and 28 deletions
+2 -22
View File
@@ -6,7 +6,6 @@
#include <ctime>
#include <fstream>
#include <string>
#include <vector>
#include <unistd.h>
#include "config.h"
#include "rsync_manager.h"
@@ -20,24 +19,6 @@ static bool is_root() {
return getuid() == 0;
}
static void escalate_privileges(int argc, char* argv[]) {
if (is_root()) return;
g_print("x3-backup requires root privileges. Re-launching with pkexec...\n");
/* Build argv for exec: pkexec + original args + NULL */
std::vector<const char*> new_argv;
new_argv.push_back("pkexec");
for (int i = 0; i < argc; i++)
new_argv.push_back(argv[i]);
new_argv.push_back(nullptr);
execvp("pkexec", const_cast<char* const*>(new_argv.data()));
/* If execvp returns, it failed */
perror("execvp pkexec");
exit(1);
}
static std::string get_log_path() {
const char* home = getenv("HOME");
if (!home) home = ".";
@@ -124,13 +105,12 @@ int main(int argc, char* argv[]) {
g_print(" --log Print log to stdout\n");
g_print(" --help, -h Show this help\n\n");
g_print("Without options, x3-backup starts in GUI mode with system tray.\n\n");
g_print("Note: x3-backup requires root privileges and will prompt\n");
g_print(" for authentication via pkexec on startup.\n\n");
g_print("Note: Backups require root privileges. The first backup/restore\n");
g_print(" will prompt for your sudo password in the terminal.\n\n");
g_print("Log file: ~/.config/x3-backup/x3-backup.log\n");
return 0;
}
escalate_privileges(argc, argv);
gtk_init(&argc, &argv);
setup_logging(cli_mode);
+3 -3
View File
@@ -88,7 +88,7 @@ bool RsyncManager::create_snapshot(const std::string& snapshot_name,
rsync_flags += " \"" + source + "/\" \"" + target + "/\" 2>&1";
std::string cmd = "mkdir -p \"" + dest + "\" && " + rsync_flags;
std::string cmd = "mkdir -p \"" + dest + "\" && sudo " + rsync_flags;
/* Force line-buffered output so we get real-time progress from rsync */
std::string full_cmd = "stdbuf -oL " + cmd;
@@ -216,7 +216,7 @@ bool RsyncManager::restore_files(const std::string& snapshot_path,
std::string src = snapshot_path + "/" + f;
std::string dst = restore_dest + "/" + f;
std::string cmd = "rsync -aAX \"" + src + "\" \"" + dst + "\" 2>&1";
std::string cmd = "sudo rsync -aAX \"" + src + "\" \"" + dst + "\" 2>&1";
g_message("restore cmd: %s", cmd.c_str());
@@ -276,7 +276,7 @@ bool RsyncManager::restore_full_snapshot(const std::string& snapshot_path,
log_buffer_.clear();
}
std::string cmd = "rsync -aAX --delete \""
std::string cmd = "sudo rsync -aAX --delete \""
+ snapshot_path + "/\" \"" + restore_dest + "/\" 2>&1";
g_message("full restore cmd: %s", cmd.c_str());
+3 -3
View File
@@ -25,7 +25,7 @@ std::string SnapshotManager::create_snapshot(const std::string& description) {
std::string snapshots_dir = config_.snapshots_dir();
std::string metadata_dir = config_.metadata_dir();
std::string mkdir_cmd = "mkdir -p \"" + snapshots_dir + "\" && mkdir -p \"" + metadata_dir + "\"";
std::string mkdir_cmd = "sudo mkdir -p \"" + snapshots_dir + "\" && sudo mkdir -p \"" + metadata_dir + "\"";
system(mkdir_cmd.c_str());
/* Find latest snapshot for hardlink delta */
@@ -55,10 +55,10 @@ void SnapshotManager::delete_snapshot(const std::string& name) {
std::string path = config_.snapshots_dir() + "/" + name;
std::string meta = config_.metadata_dir() + "/" + name + ".json";
std::string cmd = "rm -rf \"" + path + "\"";
std::string cmd = "sudo rm -rf \"" + path + "\"";
system(cmd.c_str());
std::string meta_cmd = "rm -f \"" + meta + "\"";
std::string meta_cmd = "sudo rm -f \"" + meta + "\"";
system(meta_cmd.c_str());
}