| 58 | |
| 59 | #[cfg(unix)] |
| 60 | fn resolve_non_root_ids_for_openclaw() -> Result<(u32, u32), String> { |
| 61 | if let (Some(uid), Some(gid)) = (parse_env_u32("SUDO_UID"), parse_env_u32("SUDO_GID")) |
| 62 | && uid > 0 |
| 63 | && gid > 0 |
| 64 | { |
| 65 | return Ok((uid, gid)); |
| 66 | } |
| 67 | |
| 68 | if let Ok(user_name) = std::env::var("SUDO_USER") |
| 69 | && !user_name.trim().is_empty() |
| 70 | && user_name != "root" |
| 71 | { |
| 72 | match nix::unistd::User::from_name(&user_name) { |
| 73 | Ok(Some(user)) => { |
| 74 | let uid = user.uid.as_raw(); |
| 75 | let gid = user.gid.as_raw(); |
| 76 | if uid > 0 && gid > 0 { |
| 77 | return Ok((uid, gid)); |
| 78 | } |
| 79 | } |
| 80 | Ok(None) => {} |
| 81 | Err(error) => { |
| 82 | return Err(format!( |
| 83 | "failed to resolve SUDO_USER '{user_name}' for non-root openclaw execution: {error}" |
| 84 | )); |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | Err( |
| 90 | "refusing to run `openclaw` as root; please run clawshell with sudo from a regular user account." |
| 91 | .to_string(), |
| 92 | ) |
| 93 | } |
| 94 | |
| 95 | #[cfg(unix)] |
| 96 | fn parse_env_u32(name: &str) -> Option<u32> { |