Skip to content

Commit 34f8f6e

Browse files
committed
Fix bug when using sync when daemon is running, that could result in ~/.config/vopono being owned by root
1 parent 59646e6 commit 34f8f6e

File tree

3 files changed

+26
-6
lines changed

3 files changed

+26
-6
lines changed

src/daemon.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ fn handle_client(mut conn: LocalSocketStream) -> anyhow::Result<()> {
150150
})
151151
.unwrap_or_else(|| user.dir.join(".config"));
152152
vopono_core::util::set_config_dir_override(Some(override_base));
153+
vopono_core::util::set_config_owner_override(Some((uid, gid)));
153154
exec_command.user = Some(user.name);
154155
exec_command.group = Some(group.name);
155156

@@ -377,6 +378,7 @@ fn handle_client(mut conn: LocalSocketStream) -> anyhow::Result<()> {
377378
}
378379
// Clear any thread-local override before exiting the handler
379380
vopono_core::util::set_config_dir_override(None);
381+
vopono_core::util::set_config_owner_override(None);
380382
Ok(())
381383
}
382384

vopono_core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ base64 = "0.22"
4646
x25519-dalek = { version = "3.0.0-pre.0", features = ["static_secrets"] }
4747
strum = "0.27"
4848
strum_macros = "0.27"
49-
zip = "5"
49+
zip = "6"
5050
maplit = "1"
5151
webbrowser = "1"
5252
serde_json = "1"

vopono_core/src/util/mod.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use anyhow::{Context, anyhow};
1414
use directories_next::BaseDirs;
1515
use ipnet::Ipv4Net;
1616
use log::{debug, info, warn};
17-
use nix::unistd::{Group, User};
17+
use nix::unistd::{Gid, Group, Uid, User};
1818
pub use open_hosts::open_hosts;
1919
pub use open_ports::open_ports;
2020
use rand::prelude::IndexedRandom;
@@ -33,6 +33,8 @@ use which::which;
3333

3434
thread_local! {
3535
static CONFIG_DIR_OVERRIDE: std::cell::RefCell<Option<PathBuf>> = const { std::cell::RefCell::new(None) };
36+
static CONFIG_OWNER_OVERRIDE: std::cell::RefCell<Option<(Uid, Gid)>> =
37+
const {std::cell::RefCell::new(None) };
3638
}
3739

3840
static DAEMON_MODE: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
@@ -52,6 +54,10 @@ pub fn set_config_dir_override(path: Option<PathBuf>) {
5254
CONFIG_DIR_OVERRIDE.with(|ov| *ov.borrow_mut() = path);
5355
}
5456

57+
pub fn set_config_owner_override(owner: Option<(Uid, Gid)>) {
58+
CONFIG_OWNER_OVERRIDE.with(|ov| *ov.borrow_mut() = owner);
59+
}
60+
5561
pub fn config_dir() -> anyhow::Result<PathBuf> {
5662
// Respect thread-local override first (used by daemon to select the connecting user's config).
5763
if let Some(override_path) = CONFIG_DIR_OVERRIDE.with(|ov| ov.borrow().clone())
@@ -176,14 +182,26 @@ pub fn set_config_permissions() -> anyhow::Result<()> {
176182
use std::os::unix::fs::PermissionsExt;
177183

178184
let check_dir = vopono_dir()?;
179-
let username = get_username()?;
180-
let group = get_group(&username)?;
185+
let (user, group) = CONFIG_OWNER_OVERRIDE
186+
.with(|ov| *ov.borrow())
187+
.map_or_else(
188+
|| -> anyhow::Result<(Option<Uid>, Option<Gid>)> {
189+
let username = get_username()?;
190+
let group_name = get_group(&username)?;
191+
let user = User::from_name(&username)?
192+
.map(|x| x.uid)
193+
.ok_or_else(|| anyhow!("Failed to resolve uid for user '{username}'"))?;
194+
let group = Group::from_name(&group_name)?
195+
.map(|x| x.gid)
196+
.ok_or_else(|| anyhow!("Failed to resolve gid for group '{group_name}'"))?;
197+
Ok((Some(user), Some(group)))
198+
},
199+
|(uid, gid)| Ok((Some(uid), Some(gid))),
200+
)?;
181201

182202
let file_permissions = Permissions::from_mode(0o640);
183203
let dir_permissions = Permissions::from_mode(0o750);
184204

185-
let group = nix::unistd::Group::from_name(&group)?.map(|x| x.gid);
186-
let user = nix::unistd::User::from_name(&username)?.map(|x| x.uid);
187205
for entry in WalkDir::new(check_dir).into_iter().filter_map(|e| e.ok()) {
188206
let path = entry.path();
189207
nix::unistd::chown(path, user, group)?;

0 commit comments

Comments
 (0)