mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-30 04:34:27 +00:00
rustjail: get home dir using nix crate
Get user's home dir using `nix::unistd` crate instead of `utils` crate, and remove useless code from agent. Fixes: #4209 Signed-off-by: Xuewei Niu <justxuewei@apache.org>
This commit is contained in:
parent
2c238c8504
commit
6ecea84bc5
@ -42,7 +42,7 @@ use nix::pty;
|
|||||||
use nix::sched::{self, CloneFlags};
|
use nix::sched::{self, CloneFlags};
|
||||||
use nix::sys::signal::{self, Signal};
|
use nix::sys::signal::{self, Signal};
|
||||||
use nix::sys::stat::{self, Mode};
|
use nix::sys::stat::{self, Mode};
|
||||||
use nix::unistd::{self, fork, ForkResult, Gid, Pid, Uid};
|
use nix::unistd::{self, fork, ForkResult, Gid, Pid, Uid, User};
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
@ -64,8 +64,6 @@ use rlimit::{setrlimit, Resource, Rlim};
|
|||||||
use tokio::io::AsyncBufReadExt;
|
use tokio::io::AsyncBufReadExt;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
pub const EXEC_FIFO_FILENAME: &str = "exec.fifo";
|
pub const EXEC_FIFO_FILENAME: &str = "exec.fifo";
|
||||||
|
|
||||||
const INIT: &str = "INIT";
|
const INIT: &str = "INIT";
|
||||||
@ -665,12 +663,17 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the "HOME" env getting from "/etc/passwd", if
|
|
||||||
// there's no uid entry in /etc/passwd, set "/" as the
|
|
||||||
// home env.
|
|
||||||
if env::var_os(HOME_ENV_KEY).is_none() {
|
if env::var_os(HOME_ENV_KEY).is_none() {
|
||||||
let home_dir = utils::home_dir(guser.uid).unwrap_or_else(|_| String::from("/"));
|
// try to set "HOME" env by uid
|
||||||
env::set_var(HOME_ENV_KEY, home_dir);
|
if let Ok(Some(user)) = User::from_uid(Uid::from_raw(guser.uid)) {
|
||||||
|
if let Ok(user_home_dir) = user.dir.into_os_string().into_string() {
|
||||||
|
env::set_var(HOME_ENV_KEY, user_home_dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// set default home dir as "/" if "HOME" env is still empty
|
||||||
|
if env::var_os(HOME_ENV_KEY).is_none() {
|
||||||
|
env::set_var(HOME_ENV_KEY, String::from("/"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let exec_file = Path::new(&args[0]);
|
let exec_file = Path::new(&args[0]);
|
||||||
|
@ -41,7 +41,6 @@ pub mod seccomp;
|
|||||||
pub mod specconv;
|
pub mod specconv;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
pub mod sync_with_async;
|
pub mod sync_with_async;
|
||||||
pub mod utils;
|
|
||||||
pub mod validator;
|
pub mod validator;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
// Copyright (c) 2021 Ant Group
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
//
|
|
||||||
use anyhow::{anyhow, Context, Result};
|
|
||||||
use libc::gid_t;
|
|
||||||
use libc::uid_t;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{BufRead, BufReader};
|
|
||||||
|
|
||||||
const PASSWD_FILE: &str = "/etc/passwd";
|
|
||||||
|
|
||||||
// An entry from /etc/passwd
|
|
||||||
#[derive(Debug, PartialEq, PartialOrd)]
|
|
||||||
pub struct PasswdEntry {
|
|
||||||
// username
|
|
||||||
pub name: String,
|
|
||||||
// user password
|
|
||||||
pub passwd: String,
|
|
||||||
// user id
|
|
||||||
pub uid: uid_t,
|
|
||||||
// group id
|
|
||||||
pub gid: gid_t,
|
|
||||||
// user Information
|
|
||||||
pub gecos: String,
|
|
||||||
// home directory
|
|
||||||
pub dir: String,
|
|
||||||
// User's Shell
|
|
||||||
pub shell: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
// get an entry for a given `uid` from `/etc/passwd`
|
|
||||||
fn get_entry_by_uid(uid: uid_t, path: &str) -> Result<PasswdEntry> {
|
|
||||||
let file = File::open(path).with_context(|| format!("open file {}", path))?;
|
|
||||||
let mut reader = BufReader::new(file);
|
|
||||||
|
|
||||||
let mut line = String::new();
|
|
||||||
loop {
|
|
||||||
line.clear();
|
|
||||||
match reader.read_line(&mut line) {
|
|
||||||
Ok(0) => return Err(anyhow!(format!("file {} is empty", path))),
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(e) => {
|
|
||||||
return Err(anyhow!(format!(
|
|
||||||
"failed to read file {} with {:?}",
|
|
||||||
path, e
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if line.starts_with('#') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let parts: Vec<&str> = line.split(':').map(|part| part.trim()).collect();
|
|
||||||
if parts.len() != 7 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
match parts[2].parse() {
|
|
||||||
Err(_e) => continue,
|
|
||||||
Ok(new_uid) => {
|
|
||||||
if uid != new_uid {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let entry = PasswdEntry {
|
|
||||||
name: parts[0].to_string(),
|
|
||||||
passwd: parts[1].to_string(),
|
|
||||||
uid: new_uid,
|
|
||||||
gid: parts[3].parse().unwrap_or(0),
|
|
||||||
gecos: parts[4].to_string(),
|
|
||||||
dir: parts[5].to_string(),
|
|
||||||
shell: parts[6].to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
return Ok(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn home_dir(uid: uid_t) -> Result<String> {
|
|
||||||
get_entry_by_uid(uid, PASSWD_FILE).map(|entry| entry.dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use std::io::Write;
|
|
||||||
use tempfile::Builder;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_get_entry_by_uid() {
|
|
||||||
let tmpdir = Builder::new().tempdir().unwrap();
|
|
||||||
let tmpdir_path = tmpdir.path().to_str().unwrap();
|
|
||||||
let temp_passwd = format!("{}/passwd", tmpdir_path);
|
|
||||||
|
|
||||||
let mut tempf = File::create(temp_passwd.as_str()).unwrap();
|
|
||||||
let passwd_entries = "root:x:0:0:root:/root0:/bin/bash
|
|
||||||
root:x:1:0:root:/root1:/bin/bash
|
|
||||||
#root:x:1:0:root:/rootx:/bin/bash
|
|
||||||
root:x:2:0:root:/root2:/bin/bash
|
|
||||||
root:x:3:0:root:/root3
|
|
||||||
root:x:3:0:root:/root3:/bin/bash";
|
|
||||||
writeln!(tempf, "{}", passwd_entries).unwrap();
|
|
||||||
|
|
||||||
let entry = get_entry_by_uid(0, temp_passwd.as_str()).unwrap();
|
|
||||||
assert_eq!(entry.dir.as_str(), "/root0");
|
|
||||||
|
|
||||||
let entry = get_entry_by_uid(1, temp_passwd.as_str()).unwrap();
|
|
||||||
assert_eq!(entry.dir.as_str(), "/root1");
|
|
||||||
|
|
||||||
let entry = get_entry_by_uid(2, temp_passwd.as_str()).unwrap();
|
|
||||||
assert_eq!(entry.dir.as_str(), "/root2");
|
|
||||||
|
|
||||||
let entry = get_entry_by_uid(3, temp_passwd.as_str()).unwrap();
|
|
||||||
assert_eq!(entry.dir.as_str(), "/root3");
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user