From 9a9a8197aec79ba97229127bfb3310c38d414da6 Mon Sep 17 00:00:00 2001 From: fufesou Date: Mon, 17 Oct 2022 07:55:14 -0700 Subject: [PATCH] fix linux uid username mismatch Signed-off-by: fufesou --- libs/hbb_common/src/platform/linux.rs | 40 ++++++++++++++-------- src/platform/linux.rs | 49 ++++++++++++++++++--------- src/server/connection.rs | 9 ++++- 3 files changed, 66 insertions(+), 32 deletions(-) diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index 0473a3bbc..1a20ed0e1 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -27,7 +27,18 @@ impl Disto { } pub fn get_display_server() -> String { - let session = get_value_of_seat0(0); + let mut session = get_values_of_seat0([0].to_vec())[0].clone(); + if session.is_empty() { + // loginctl has not given the expected output. try something else. + if let Ok(sid) = std::env::var("XDG_SESSION_ID") { + // could also execute "cat /proc/self/sessionid" + session = sid.to_owned(); + } + if session.is_empty() { + session = run_cmds("cat /proc/self/sessionid".to_owned()).unwrap_or_default(); + } + } + get_display_server_of_session(&session) } @@ -77,15 +88,16 @@ fn get_display_server_of_session(session: &str) -> String { } } -pub fn get_value_of_seat0(i: usize) -> String { +pub fn get_values_of_seat0(indices: Vec) -> Vec { if let Ok(output) = run_loginctl(None) { for line in String::from_utf8_lossy(&output.stdout).lines() { if line.contains("seat0") { if let Some(sid) = line.split_whitespace().nth(0) { if is_active(sid) { - if let Some(uid) = line.split_whitespace().nth(i) { - return uid.to_owned(); - } + return indices + .into_iter() + .map(|idx| line.split_whitespace().nth(idx).unwrap_or("").to_owned()) + .collect::>(); } } } @@ -98,21 +110,19 @@ pub fn get_value_of_seat0(i: usize) -> String { if let Some(sid) = line.split_whitespace().nth(0) { let d = get_display_server_of_session(sid); if is_active(sid) && d != "tty" { - if let Some(uid) = line.split_whitespace().nth(i) { - return uid.to_owned(); - } + return indices + .into_iter() + .map(|idx| line.split_whitespace().nth(idx).unwrap_or("").to_owned()) + .collect::>(); } } } } - // loginctl has not given the expected output. try something else. - if let Ok(sid) = std::env::var("XDG_SESSION_ID") { - // could also execute "cat /proc/self/sessionid" - return sid.to_owned(); - } - - return "".to_owned(); + return indices + .iter() + .map(|_x| "".to_owned()) + .collect::>(); } fn is_active(sid: &str) -> bool { diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 2efe06faf..b72c15f54 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -219,15 +219,15 @@ fn stop_rustdesk_servers() { fn should_start_server( try_x11: bool, uid: &mut String, + cur_uid: String, cm0: &mut bool, last_restart: &mut std::time::Instant, server: &mut Option, ) -> bool { let cm = get_cm(); - let tmp = get_active_userid(); let mut start_new = false; - if tmp != *uid && !tmp.is_empty() { - *uid = tmp; + if cur_uid != *uid && !cur_uid.is_empty() { + *uid = cur_uid; if try_x11 { set_x11_env(&uid); } @@ -267,7 +267,6 @@ fn should_start_server( pub fn start_os_service() { stop_rustdesk_servers(); - start_uinput_service(); let running = Arc::new(AtomicBool::new(true)); @@ -284,13 +283,20 @@ pub fn start_os_service() { let mut cm0 = false; let mut last_restart = std::time::Instant::now(); while running.load(Ordering::SeqCst) { - let username = get_active_username(); + let (cur_uid, cur_user) = get_active_user_id_name(); let is_wayland = current_is_wayland(); - if username == "root" || !is_wayland { + if cur_user == "root" || !is_wayland { stop_server(&mut user_server); // try start subprocess "--server" - if should_start_server(true, &mut uid, &mut cm0, &mut last_restart, &mut server) { + if should_start_server( + true, + &mut uid, + cur_uid, + &mut cm0, + &mut last_restart, + &mut server, + ) { match crate::run_me(vec!["--server"]) { Ok(ps) => server = Some(ps), Err(err) => { @@ -298,8 +304,8 @@ pub fn start_os_service() { } } } - } else if username != "" { - if username != "gdm" { + } else if cur_user != "" { + if cur_user != "gdm" { // try kill subprocess "--server" stop_server(&mut server); @@ -307,11 +313,12 @@ pub fn start_os_service() { if should_start_server( false, &mut uid, + cur_uid.clone(), &mut cm0, &mut last_restart, &mut user_server, ) { - match run_as_user("--server") { + match run_as_user("--server", Some((cur_uid, cur_user))) { Ok(ps) => user_server = ps, Err(err) => { log::error!("Failed to start server: {}", err); @@ -335,8 +342,13 @@ pub fn start_os_service() { log::info!("Exit"); } +pub fn get_active_user_id_name() -> (String, String) { + let vec_id_name = get_values_of_seat0([1, 2].to_vec()); + (vec_id_name[0].clone(), vec_id_name[1].clone()) +} + pub fn get_active_userid() -> String { - get_value_of_seat0(1) + get_values_of_seat0([1].to_vec())[0].clone() } fn get_cm() -> bool { @@ -513,7 +525,7 @@ fn _get_display_manager() -> String { } pub fn get_active_username() -> String { - get_value_of_seat0(2) + get_values_of_seat0([2].to_vec())[0].clone() } pub fn get_active_user_home() -> Option { @@ -545,12 +557,17 @@ fn is_opensuse() -> bool { false } -pub fn run_as_user(arg: &str) -> ResultType> { - let uid = get_active_userid(); +pub fn run_as_user( + arg: &str, + user: Option<(String, String)>, +) -> ResultType> { + let (uid, username) = match user { + Some(id_name) => id_name, + None => get_active_user_id_name(), + }; let cmd = std::env::current_exe()?; let xdg = &format!("XDG_RUNTIME_DIR=/run/user/{}", uid) as &str; - let username = &get_active_username(); - let mut args = vec![xdg, "-u", username, cmd.to_str().unwrap_or(""), arg]; + let mut args = vec![xdg, "-u", &username, cmd.to_str().unwrap_or(""), arg]; // -E required for opensuse if is_opensuse() { args.insert(0, "-E"); diff --git a/src/server/connection.rs b/src/server/connection.rs index e865a8b4f..4f122b59d 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1514,7 +1514,14 @@ async fn start_ipc( if crate::platform::is_root() { let mut res = Ok(None); for _ in 0..10 { - res = crate::platform::run_as_user("--cm"); + #[cfg(not(target_os = "linux"))] + { + res = crate::platform::run_as_user("--cm"); + } + #[cfg(target_os = "linux")] + { + res = crate::platform::run_as_user("--cm", None); + } if res.is_ok() { break; }