93 lines
3.1 KiB
Rust
93 lines
3.1 KiB
Rust
//! Redox OS user and group utilities.
|
|
//!
|
|
//! The `userutils` crate contains the utilities for dealing with users and groups in Redox OS.
|
|
//! They are heavily influenced by UNIX and are, when needed, tailored to specific Redox use cases.
|
|
//!
|
|
//! These implementations strive to be as simple as possible drawing particular
|
|
//! inspiration by BSD systems. They are indeed small, by choice.
|
|
//!
|
|
//! The included utilities are:
|
|
//!
|
|
//! - `getty`: Used by `init(8)` to open and initialize the TTY line, read a login name and invoke `login(1)`.
|
|
//! - `id`: Displays user identity.
|
|
//! - `login`: Allows users to into the system.
|
|
//! - `passwd`: Allows users to modify their passwords.
|
|
//! - `su`: Allows users to substitute identity.
|
|
//! - `sudo`: Enables users to execute a command as another user.
|
|
//! - `whoami`: Display effective user ID.
|
|
|
|
use std::io::Result as IoResult;
|
|
|
|
use libredox::call::{fchown, open};
|
|
use libredox::error::Result as SysResult;
|
|
use libredox::flag::{O_CLOEXEC, O_CREAT, O_DIRECTORY};
|
|
use redox_users::{All, AllGroups, Error, Result, User, auth};
|
|
|
|
const DEFAULT_MODE: u16 = 0o700;
|
|
|
|
// Not the prettiest thing in the world, but some functionality here makes
|
|
// some of the utils much less gross
|
|
pub trait AllGroupsExt {
|
|
fn add_user_to_groups(&mut self, login: &str, groups: Vec<&str>) -> Result<()>;
|
|
fn remove_user_from_all_groups(&mut self, login: &str);
|
|
}
|
|
|
|
impl AllGroupsExt for AllGroups {
|
|
// new_groups is a comma separated list of groupnames
|
|
fn add_user_to_groups(&mut self, login: &str, new_groups: Vec<&str>) -> Result<()> {
|
|
for groupname in new_groups {
|
|
let group = match self.get_mut_by_name(groupname) {
|
|
Some(group) => group,
|
|
None => return Err(Error::UserNotFound),
|
|
};
|
|
group.users.push(login.to_string());
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Remove a user from all groups of which they are a member
|
|
fn remove_user_from_all_groups(&mut self, login: &str) {
|
|
for group in self.iter_mut() {
|
|
let op_pos = group.users.iter().position(|username| username == login);
|
|
if let Some(indx) = op_pos {
|
|
group.users.remove(indx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Spawns a shell for the given `User`.
|
|
///
|
|
/// This function wraps the shell_cmd function of the User struct
|
|
/// from redox_users and manages the child process. It is a blocking
|
|
/// operation.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use redox_users::AllUsers;
|
|
///
|
|
/// let sys_users = AllUsers::new().unwrap();
|
|
/// let user = sys_users.get_by_name("goyox86");
|
|
/// spawn_shell(user).unwrap();
|
|
/// ```
|
|
pub fn spawn_shell<T: Default>(user: &User<T>) -> IoResult<i32> {
|
|
let mut command = user.shell_cmd();
|
|
|
|
let mut child = command.spawn()?;
|
|
match child.wait()?.code() {
|
|
Some(code) => Ok(code),
|
|
None => Ok(1),
|
|
}
|
|
}
|
|
|
|
/// Creates a directory with 700 user:user permissions
|
|
pub fn create_user_dir<T>(user: &User<auth::Full>, dir: T) -> SysResult<()>
|
|
where
|
|
T: AsRef<str> + std::convert::AsRef<[u8]>,
|
|
{
|
|
let fd = open(dir, O_CREAT | O_DIRECTORY | O_CLOEXEC, DEFAULT_MODE)?;
|
|
fchown(fd, user.uid as u32, user.gid as u32)?;
|
|
Ok(())
|
|
}
|