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}