user_lookup/
lib.rs

1// Copyright 2022 Mattias Eriksson
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! `user_lookup` provides an easy way to lookup Linux/Unix user and group information
10//! from /etc/passwd and /etc/group. It will cache the information for a
11//! duration specified by the user. If no caching is desired, a Duration of 0.0 can be used.
12//!
13//!```rust,ignore
14//!use user_lookup::async_reader::PasswdReader;
15//!use std::time::Duration;
16//!
17//!#[tokio::main]
18//!async fn main() {
19//!   let mut reader = PasswdReader::new(Duration::new(0,0));
20//!
21//!   println!("User with uid 1000 is: {}",
22//!   reader.get_username_by_uid(1000).await.unwrap().unwrap());
23//!}
24//!
25//!```
26#[cfg(feature = "async")]
27pub mod async_reader;
28#[cfg(feature = "sync")]
29pub mod sync_reader;
30
31/// A passwd entry, representing one row in
32/// `/etc/passwd`
33#[derive(Debug, Clone, PartialEq, Eq)]
34pub struct PasswdEntry {
35    /// Username
36    pub username: String,
37    /// User password
38    pub passwd: String,
39    /// User ID
40    pub uid: u32,
41    /// Group ID
42    pub gid: u32,
43    /// User full name or comment
44    pub gecos: String,
45    /// Home directory
46    pub home_dir: String,
47    /// Shell
48    pub shell: String,
49}
50
51impl PasswdEntry {
52    ///Create a PasswdEntry from &str.
53    pub fn parse(s: &str) -> Option<PasswdEntry> {
54        let mut entries = s.splitn(7, ':');
55        Some(PasswdEntry {
56            username: match entries.next() {
57                None => return None,
58                Some(s) => s.to_string(),
59            },
60            passwd: match entries.next() {
61                None => return None,
62                Some(s) => s.to_string(),
63            },
64            uid: match entries.next().and_then(|s| s.parse().ok()) {
65                None => return None,
66                Some(s) => s,
67            },
68            gid: match entries.next().and_then(|s| s.parse().ok()) {
69                None => return None,
70                Some(s) => s,
71            },
72            gecos: match entries.next() {
73                None => return None,
74                Some(s) => s.to_string(),
75            },
76            home_dir: match entries.next() {
77                None => return None,
78                Some(s) => s.to_string(),
79            },
80            shell: match entries.next() {
81                None => return None,
82                Some(s) => s.to_string(),
83            },
84        })
85    }
86}
87
88/// A group entry, representing one row in
89/// ```/etc/group```
90#[derive(Debug, Clone, PartialEq, Eq)]
91pub struct GroupEntry {
92    //Username
93    pub name: String,
94    //Password
95    pub passwd: String,
96    //Group ID
97    pub gid: u32,
98    //List of users
99    pub users: Vec<String>,
100}
101
102impl GroupEntry {
103    ///Create a GroupEntry from &str.
104    pub fn parse(s: &str) -> Option<GroupEntry> {
105        let mut entries = s.splitn(4, ':');
106        Some(GroupEntry {
107            name: match entries.next() {
108                None => return None,
109                Some(s) => s.to_string(),
110            },
111            passwd: match entries.next() {
112                None => return None,
113                Some(s) => s.to_string(),
114            },
115            gid: match entries.next().and_then(|s| s.parse().ok()) {
116                None => return None,
117                Some(s) => s,
118            },
119            users: match entries.next() {
120                None => return None,
121                Some(s) => s.split(',').map(|p| p.to_string()).collect(),
122            },
123        })
124    }
125}