From e27705b40fe35db8e267cbc5e56b68f79e270bde Mon Sep 17 00:00:00 2001 From: Antoine POPINEAU Date: Sun, 5 Nov 2023 13:00:16 +0100 Subject: [PATCH] Retrieve user list from NSS (#72). --- Cargo.lock | 10 ++++++++++ Cargo.toml | 2 ++ src/info.rs | 46 +++++++++++++--------------------------------- 3 files changed, 25 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa0ecc1..74f41ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1395,6 +1395,7 @@ dependencies = [ "textwrap", "tokio", "unic-langid", + "uzers", "zeroize", ] @@ -1456,6 +1457,15 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "uzers" +version = "0.11.3" +source = "git+https://github.com/rustadopt/uzers-rs?branch=main#9e5460cc69ba1b6146abdc4fc6254d4c61c7c4bb" +dependencies = [ + "libc", + "log", +] + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 61f9a90..5e9a475 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,8 @@ tokio = { version = "^1.2", default-features = false, features = [ ] } unic-langid = "^0.9" zeroize = "^1.3" +# TODO: Change to published version when a new release is out. +uzers = { git = "https://github.com/rustadopt/uzers-rs", branch = "main" } [profile.release] lto = true diff --git a/src/info.rs b/src/info.rs index f257156..eca952d 100644 --- a/src/info.rs +++ b/src/info.rs @@ -10,6 +10,7 @@ use std::{ use ini::Ini; use lazy_static::lazy_static; use nix::sys::utsname; +use uzers::os::unix::UserExt; use crate::{ ui::{ @@ -163,41 +164,20 @@ pub fn delete_last_user_session(username: &str) { } pub fn get_users(min_uid: u16, max_uid: u16) -> Vec { - match File::open("/etc/passwd") { - Err(_) => vec![], - Ok(file) => { - let file = BufReader::new(file); + let users = unsafe { uzers::all_users() }; - let users: Vec = file - .lines() - .filter_map(|line| { - line - .map(|line| { - let mut split = line.splitn(7, ':'); - let username = split.next(); - let uid = split.nth(1); - let name = split.nth(1); + let users: Vec = users + .filter(|user| user.uid() >= min_uid as u32 && user.uid() <= max_uid as u32) + .map(|user| User { + username: user.name().to_string_lossy().to_string(), + name: match user.gecos() { + name if name.is_empty() => None, + name => Some(name.to_string_lossy().to_string()), + }, + }) + .collect(); - match uid.map(|uid| uid.parse::()) { - Some(Ok(uid)) => match (username, name) { - (Some(username), Some("")) => Some((uid, username.to_string(), None)), - (Some(username), Some(name)) => Some((uid, username.to_string(), Some(name.to_string()))), - _ => None, - }, - - _ => None, - } - }) - .ok() - .flatten() - .filter(|(uid, _, _)| uid >= &min_uid && uid <= &max_uid) - .map(|(_, username, name)| User { username, name }) - }) - .collect(); - - users - } - } + users } pub fn get_min_max_uids(min_uid: Option, max_uid: Option) -> (u16, u16) {