MCPcopy Create free account
hub / github.com/NVIDIA/OpenShell / drop_privileges

Function drop_privileges

crates/openshell-supervisor-process/src/process.rs:1221–1371  ·  view source on GitHub ↗
(policy: &SandboxPolicy)

Source from the content-addressed store, hash-verified

1219#[cfg(unix)]
1220#[allow(clippy::similar_names)]
1221pub fn drop_privileges(policy: &SandboxPolicy) -> Result<()> {
1222 let user_name = match policy.process.run_as_user.as_deref() {
1223 Some(name) if !name.is_empty() => Some(name),
1224 _ => None,
1225 };
1226 let group_name = match policy.process.run_as_group.as_deref() {
1227 Some(name) if !name.is_empty() => Some(name),
1228 _ => None,
1229 };
1230
1231 // If no user/group is configured and we are running as root, fall back to
1232 // "sandbox:sandbox" instead of silently keeping root. This covers the
1233 // local/dev-mode path where policies are loaded from disk and never pass
1234 // through the server-side `ensure_sandbox_process_identity` normalization.
1235 // For non-root runtimes, the no-op is safe -- we are already unprivileged.
1236 if user_name.is_none() && group_name.is_none() {
1237 if nix::unistd::geteuid().is_root() {
1238 let mut fallback = policy.clone();
1239 fallback.process.run_as_user = Some("sandbox".into());
1240 fallback.process.run_as_group = Some("sandbox".into());
1241 return drop_privileges(&fallback);
1242 }
1243 return Ok(());
1244 }
1245
1246 // Resolve UID: numeric values are used directly; names resolve via passwd.
1247 let target_uid = match user_name {
1248 Some(name) if name.parse::<u32>().is_ok() => Uid::from_raw(name.parse().into_diagnostic()?),
1249 Some(name) => {
1250 User::from_name(name)
1251 .into_diagnostic()?
1252 .ok_or_else(|| miette::miette!("Sandbox user not found: {name}"))?
1253 .uid
1254 }
1255 None => nix::unistd::geteuid(),
1256 };
1257
1258 // Resolve group: if a numeric GID is configured use it directly.
1259 // Otherwise try name resolution, then fall back to current user's primary group.
1260 let target_gid = match group_name {
1261 Some(name) if name.parse::<u32>().is_ok() => Gid::from_raw(name.parse().into_diagnostic()?),
1262 Some(name) => {
1263 Group::from_name(name)
1264 .into_diagnostic()?
1265 .ok_or_else(|| miette::miette!("Sandbox group not found: {name}"))?
1266 .gid
1267 }
1268 None => match target_uid.as_raw() {
1269 0 => nix::unistd::getegid(),
1270 _ => Group::from_gid(
1271 User::from_uid(target_uid)
1272 .into_diagnostic()?
1273 .ok_or_else(|| miette::miette!("Failed to resolve user from UID {target_uid}"))?
1274 .gid,
1275 )
1276 .into_diagnostic()?
1277 .map_or_else(nix::unistd::getegid, |g| g.gid),
1278 },

Calls 3

is_emptyMethod · 0.45
parseMethod · 0.45