passwd_rs/lib.rs
1//! # passwd-rs
2//! Crate/Library providing a functions to get information about groups, users and shadow passwords.
3//!
4//! ## Example
5//! ```rust
6//! use passwd_rs::{Group, User, Shadow, AccountStatus};
7//!
8//! fn main() -> std::io::Result<()> {
9//! let user = User::current_user()?;
10//! let password;
11//! if user.passwd.as_ref().unwrap().eq("x") {
12//! // WARN! This works only if program is executed as root
13//! let shadow = match Shadow::new_from_username(&user.name.clone()) {
14//! Err(e) => {
15//! if e.kind() == std::io::ErrorKind::PermissionDenied {
16//! println!("Must be run as root to access shadow passwords");
17//! }
18//! else { return Err(e) };
19//!
20//! return Ok(());
21//! },
22//! Ok(o) => o,
23//! };
24//! if let AccountStatus::Active(passwd) = shadow.passwd {
25//! password = passwd;
26//! } else {
27//! password = shadow.passwd.to_string();
28//! }
29//! } else {
30//! password = user.passwd.unwrap();
31//! }
32//!
33//! let group = Group::new_from_gid(user.gid.clone())?;
34//!
35//! println!("Group details:");
36//! println!("Name: {}", group.name);
37//! println!("ID: {}", group.gid);
38//! println!("Members: {}", group.display_members());
39//! println!();
40//! println!("User details:");
41//! println!("Name: {}", user.name);
42//! println!("ID: {}", user.uid);
43//! println!("Password: {}", password);
44//!
45//! Ok(())
46//! }
47//! ```
48
49pub mod group;
50pub mod shadow;
51pub mod user;
52
53use std::os::raw::*;
54pub use group::Group;
55pub use shadow::AccountStatus;
56pub use shadow::Shadow;
57pub use user::User;
58
59#[cfg(test)]
60mod tests {
61 use crate::Group;
62 use crate::Shadow;
63 use crate::User;
64 use std::io;
65
66 #[test]
67 fn user_from_name() -> std::io::Result<()> {
68 let passwd = User::new_from_name("root")?;
69
70 assert!(passwd.name.eq("root"));
71
72 Ok(())
73 }
74
75 #[test]
76 fn user_from_uid() -> std::io::Result<()> {
77 let passwd = User::new_from_uid(0)?;
78
79 assert_eq!(passwd.uid, 0);
80
81 Ok(())
82 }
83
84 #[test]
85 fn group_from_name() -> std::io::Result<()> {
86 let grp = Group::new_from_groupname("root")?;
87
88 assert!(grp.name.eq("root"));
89
90 Ok(())
91 }
92
93 #[test]
94 fn group_from_gid() -> std::io::Result<()> {
95 let grp = Group::new_from_gid(0)?;
96
97 assert_eq!(grp.gid, 0);
98
99 Ok(())
100 }
101
102 // Need to be run as root
103 #[test]
104 fn shadow_from_username() -> std::io::Result<()> {
105 let shadow = Shadow::new_from_username("root");
106 if let Err(e) = shadow {
107 if e.kind() == io::ErrorKind::PermissionDenied {
108 eprintln!("Shadow test must be run as root");
109 return Ok(());
110 }
111
112 return Err(e);
113 }
114
115 assert!(shadow.as_ref().unwrap().name.eq("root"));
116
117 Ok(())
118 }
119}
120
121extern "C" {
122 fn getuid() -> c_uint;
123}
124
125/// Get current user's ID
126pub fn whoami_uid() -> c_uint {
127 unsafe { getuid() }
128}
129
130/// Get current user's username
131pub fn whoami() -> std::io::Result<String> {
132 let user = User::current_user()?;
133 Ok(user.name)
134}