remove pw_prefix

This commit is contained in:
Dietrich 2020-09-22 13:08:15 +02:00
parent a68f0800cc
commit c9cba38f2f

View File

@ -3,22 +3,22 @@ use std::fmt::{self, Display};
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct Username<'a> { pub struct Username<'a> {
pw_name: &'a str, username: &'a str,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct Password<'a> { pub struct Password<'a> {
pw_passwd: &'a str, password: &'a str,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct Uid { pub struct Uid {
pw_uid: u32, uid: u32,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct Gid { pub struct Gid {
pw_gid: u32, gid: u32,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
@ -37,24 +37,24 @@ pub enum Gecos<'a> {
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct HomeDir<'a> { pub struct HomeDir<'a> {
pw_dir: &'a str, dir: &'a str,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct ShellDir<'a> { pub struct ShellDir<'a> {
pw_shell: &'a str, shell: &'a str,
} }
/// A record in the user database `/etc/passwd`. /// A record in the user database `/etc/passwd`.
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct Passwd<'a> { pub struct Passwd<'a> {
pw_name: Username<'a>, /* Username. */ username: Username<'a>, /* Username. */
pw_passwd: Password<'a>, /* Hashed passphrase, if shadow database not in use (see shadow.h). */ password: Password<'a>, /* Hashed passphrase, if shadow database not in use (see shadow.h). */
pw_uid: Uid, /* User ID. */ uid: Uid, /* User ID. */
pw_gid: Gid, /* Group ID. */ gid: Gid, /* Group ID. */
pw_gecos: Gecos<'a>, /* Real name. */ gecos: Gecos<'a>, /* Real name. */
pw_dir: HomeDir<'a>, /* Home directory. */ home_dir: HomeDir<'a>, /* Home directory. */
pw_shell: ShellDir<'a>, /* Shell program. */ shell_dir: ShellDir<'a>, /* Shell program. */
} }
impl<'a> Passwd<'a> { impl<'a> Passwd<'a> {
@ -64,24 +64,24 @@ impl<'a> Passwd<'a> {
return Err("Failed to parse: not enough elements"); return Err("Failed to parse: not enough elements");
} else { } else {
Ok(Passwd { Ok(Passwd {
pw_name: Username { username: Username {
pw_name: elements.get(0).unwrap(), username: elements.get(0).unwrap(),
}, },
pw_passwd: Password { password: Password {
pw_passwd: elements.get(1).unwrap(), password: elements.get(1).unwrap(),
}, },
pw_uid: Uid { uid: Uid {
pw_uid: elements.get(2).unwrap().parse::<u32>().unwrap(), uid: elements.get(2).unwrap().parse::<u32>().unwrap(),
}, },
pw_gid: Gid { gid: Gid {
pw_gid: elements.get(3).unwrap().parse::<u32>().unwrap(), gid: elements.get(3).unwrap().parse::<u32>().unwrap(),
}, },
pw_gecos: parse_gecos(elements.get(4).unwrap()).unwrap(), gecos: parse_gecos(elements.get(4).unwrap()).unwrap(),
pw_dir: HomeDir { home_dir: HomeDir {
pw_dir: elements.get(5).unwrap(), dir: elements.get(5).unwrap(),
}, },
pw_shell: ShellDir { shell_dir: ShellDir {
pw_shell: elements.get(6).unwrap(), shell: elements.get(6).unwrap(),
}, },
}) })
} }
@ -110,23 +110,21 @@ fn parse_gecos(source: &str) -> Result<Gecos, &str> {
impl Default for Passwd<'_> { impl Default for Passwd<'_> {
fn default() -> Self { fn default() -> Self {
Passwd { Passwd {
pw_name: Username { username: Username {
pw_name: "defaultuser", username: "defaultuser",
}, },
pw_passwd: Password { password: Password {
pw_passwd: "notencrypted", password: "notencrypted",
}, },
pw_uid: Uid { pw_uid: 1001 }, uid: Uid { uid: 1001 },
pw_gid: Gid { pw_gid: 1001 }, gid: Gid { gid: 1001 },
pw_gecos: Gecos::Simple { gecos: Gecos::Simple {
comment: "gecos default comment", comment: "gecos default comment",
}, },
pw_dir: HomeDir { home_dir: HomeDir {
pw_dir: "/home/default", dir: "/home/default",
},
pw_shell: ShellDir {
pw_shell: "/bin/bash",
}, },
shell_dir: ShellDir { shell: "/bin/bash" },
} }
} }
} }
@ -136,38 +134,38 @@ impl Display for Passwd<'_> {
write!( write!(
f, f,
"{}:{}:{}:{}:{}:{}:{}", "{}:{}:{}:{}:{}:{}:{}",
self.pw_name, self.username,
self.pw_passwd, self.password,
self.pw_uid, self.uid,
self.pw_gid, self.gid,
self.pw_gecos, self.gecos,
self.pw_dir, self.home_dir,
self.pw_shell self.shell_dir
) )
} }
} }
impl Display for Username<'_> { impl Display for Username<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.pw_name,) write!(f, "{}", self.username,)
} }
} }
impl Display for Password<'_> { impl Display for Password<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.pw_passwd,) write!(f, "{}", self.password,)
} }
} }
impl Display for Uid { impl Display for Uid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.pw_uid,) write!(f, "{}", self.uid,)
} }
} }
impl Display for Gid { impl Display for Gid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.pw_gid,) write!(f, "{}", self.gid,)
} }
} }
@ -192,13 +190,13 @@ impl Display for Gecos<'_> {
impl Display for HomeDir<'_> { impl Display for HomeDir<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.pw_dir,) write!(f, "{}", self.dir,)
} }
} }
impl Display for ShellDir<'_> { impl Display for ShellDir<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.pw_shell,) write!(f, "{}", self.shell,)
} }
} }
@ -206,14 +204,16 @@ impl Display for ShellDir<'_> {
#[test] #[test]
fn test_default_user() { fn test_default_user() {
// Check if a user can be created.
let pwd = Passwd::default(); let pwd = Passwd::default();
assert_eq!(pwd.pw_name.pw_name, "defaultuser"); assert_eq!(pwd.username.username, "defaultuser");
assert_eq!(pwd.pw_dir.pw_dir, "/home/default"); assert_eq!(pwd.home_dir.dir, "/home/default");
assert_eq!(pwd.pw_uid.pw_uid, 1001); assert_eq!(pwd.uid.uid, 1001);
} }
#[test] #[test]
fn test_parse_gecos() { fn test_parse_gecos() {
// test if the Gecos field can be parsed and the resulting struct is populated correctly.
let gcd = "Full Name,504,11345342,ä1-2312,myemail@test.com"; let gcd = "Full Name,504,11345342,ä1-2312,myemail@test.com";
let gcs = "A böring comment →"; let gcs = "A böring comment →";
let res_detail = parse_gecos(gcd).unwrap(); let res_detail = parse_gecos(gcd).unwrap();
@ -242,20 +242,21 @@ fn test_parse_gecos() {
#[test] #[test]
fn test_new_from_string() { fn test_new_from_string() {
// Test if a single line can be parsed and if the resulting struct is populated correctly.
let pwd = let pwd =
Passwd::new_from_string("testuser:testpassword:1001:1001:testcomment:/home/test:/bin/test") Passwd::new_from_string("testuser:testpassword:1001:1001:testcomment:/home/test:/bin/test")
.unwrap(); .unwrap();
let pwd2 = let pwd2 =
Passwd::new_from_string("testuser:testpassword:1001:1001:full Name,004,000342,001-2312,myemail@test.com:/home/test:/bin/test") Passwd::new_from_string("testuser:testpassword:1001:1001:full Name,004,000342,001-2312,myemail@test.com:/home/test:/bin/test")
.unwrap(); .unwrap();
assert_eq!(pwd.pw_name.pw_name, "testuser"); assert_eq!(pwd.username.username, "testuser");
assert_eq!(pwd.pw_dir.pw_dir, "/home/test"); assert_eq!(pwd.home_dir.dir, "/home/test");
assert_eq!(pwd.pw_uid.pw_uid, 1001); assert_eq!(pwd.uid.uid, 1001);
match pwd.pw_gecos { match pwd.gecos {
Gecos::Simple { comment } => assert_eq!(comment, "testcomment"), Gecos::Simple { comment } => assert_eq!(comment, "testcomment"),
_ => unreachable!(), _ => unreachable!(),
} }
match pwd2.pw_gecos { match pwd2.gecos {
Gecos::Detail { Gecos::Detail {
full_name, full_name,
room, room,
@ -275,7 +276,7 @@ fn test_new_from_string() {
#[test] #[test]
fn test_parse_passwd() { fn test_parse_passwd() {
/// Test wether the passwd file can be parsed and recreated without throwing an exception // Test wether the passwd file can be parsed and recreated without throwing an exception
use std::fs::File; use std::fs::File;
use std::io::{prelude::*, BufReader}; use std::io::{prelude::*, BufReader};
let file = File::open("/etc/passwd").unwrap(); let file = File::open("/etc/passwd").unwrap();