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:
+2
-22
@@ -6,7 +6,6 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "rsync_manager.h"
|
#include "rsync_manager.h"
|
||||||
@@ -20,24 +19,6 @@ static bool is_root() {
|
|||||||
return getuid() == 0;
|
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() {
|
static std::string get_log_path() {
|
||||||
const char* home = getenv("HOME");
|
const char* home = getenv("HOME");
|
||||||
if (!home) home = ".";
|
if (!home) home = ".";
|
||||||
@@ -124,13 +105,12 @@ int main(int argc, char* argv[]) {
|
|||||||
g_print(" --log Print log to stdout\n");
|
g_print(" --log Print log to stdout\n");
|
||||||
g_print(" --help, -h Show this help\n\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("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("Note: Backups require root privileges. The first backup/restore\n");
|
||||||
g_print(" for authentication via pkexec on startup.\n\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");
|
g_print("Log file: ~/.config/x3-backup/x3-backup.log\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
escalate_privileges(argc, argv);
|
|
||||||
gtk_init(&argc, &argv);
|
gtk_init(&argc, &argv);
|
||||||
|
|
||||||
setup_logging(cli_mode);
|
setup_logging(cli_mode);
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ bool RsyncManager::create_snapshot(const std::string& snapshot_name,
|
|||||||
|
|
||||||
rsync_flags += " \"" + source + "/\" \"" + target + "/\" 2>&1";
|
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 */
|
/* Force line-buffered output so we get real-time progress from rsync */
|
||||||
std::string full_cmd = "stdbuf -oL " + cmd;
|
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 src = snapshot_path + "/" + f;
|
||||||
std::string dst = restore_dest + "/" + 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());
|
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();
|
log_buffer_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string cmd = "rsync -aAX --delete \""
|
std::string cmd = "sudo rsync -aAX --delete \""
|
||||||
+ snapshot_path + "/\" \"" + restore_dest + "/\" 2>&1";
|
+ snapshot_path + "/\" \"" + restore_dest + "/\" 2>&1";
|
||||||
|
|
||||||
g_message("full restore cmd: %s", cmd.c_str());
|
g_message("full restore cmd: %s", cmd.c_str());
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ std::string SnapshotManager::create_snapshot(const std::string& description) {
|
|||||||
std::string snapshots_dir = config_.snapshots_dir();
|
std::string snapshots_dir = config_.snapshots_dir();
|
||||||
std::string metadata_dir = config_.metadata_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());
|
system(mkdir_cmd.c_str());
|
||||||
|
|
||||||
/* Find latest snapshot for hardlink delta */
|
/* 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 path = config_.snapshots_dir() + "/" + name;
|
||||||
std::string meta = config_.metadata_dir() + "/" + name + ".json";
|
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());
|
system(cmd.c_str());
|
||||||
|
|
||||||
std::string meta_cmd = "rm -f \"" + meta + "\"";
|
std::string meta_cmd = "sudo rm -f \"" + meta + "\"";
|
||||||
system(meta_cmd.c_str());
|
system(meta_cmd.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user