Make the conten of shadow part of the user struct
This commit is contained in:
parent
9482e85821
commit
ffafa7e473
@ -11,7 +11,7 @@ use std::fmt::{self, Display};
|
|||||||
pub struct User {
|
pub struct User {
|
||||||
source: String,
|
source: String,
|
||||||
username: crate::Username, /* Username. */
|
username: crate::Username, /* Username. */
|
||||||
password: crate::Password, /* Hashed passphrase, if shadow database not in use (see shadow.h). */
|
pub(crate) password: crate::Password, /* Hashed passphrase, if shadow database not in use (see shadow.h). */
|
||||||
uid: crate::Uid, /* User ID. */
|
uid: crate::Uid, /* User ID. */
|
||||||
gid: crate::Gid, /* Group ID. */
|
gid: crate::Gid, /* Group ID. */
|
||||||
gecos: crate::Gecos, /* Real name. */
|
gecos: crate::Gecos, /* Real name. */
|
||||||
|
117
src/userlib.rs
117
src/userlib.rs
@ -8,14 +8,14 @@
|
|||||||
#![allow(clippy::non_ascii_literal)]
|
#![allow(clippy::non_ascii_literal)]
|
||||||
|
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufReader, Read};
|
use std::io::{BufReader, Read};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub struct UserDBLocal {
|
pub struct UserDBLocal {
|
||||||
source_files: Files,
|
source_files: Files,
|
||||||
pub passwd_entries: Vec<crate::User>,
|
pub users: HashMap<String, crate::User>,
|
||||||
pub shadow_entries: Vec<crate::Shadow>,
|
|
||||||
pub group_entries: Vec<crate::Group>,
|
pub group_entries: Vec<crate::Group>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,21 +42,30 @@ impl UserDBLocal {
|
|||||||
shadow_content: &str,
|
shadow_content: &str,
|
||||||
group_content: &str,
|
group_content: &str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let res = Self {
|
let shadow_entries: Vec<crate::Shadow> = shadow_content
|
||||||
|
.lines()
|
||||||
|
.filter_map(|line| {
|
||||||
|
if line.len() > 5 {
|
||||||
|
Some(crate::Shadow::new_from_string(line.to_owned()).expect("Parsing failed"))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let mut res = Self {
|
||||||
source_files: Files {
|
source_files: Files {
|
||||||
passwd: None,
|
passwd: None,
|
||||||
group: None,
|
group: None,
|
||||||
shadow: None,
|
shadow: None,
|
||||||
},
|
},
|
||||||
passwd_entries: passwd_content
|
users: passwd_content
|
||||||
.lines()
|
.lines()
|
||||||
.filter_map(|line| {
|
.filter_map(|line| {
|
||||||
if line.len() > 5 {
|
if line.len() > 5 {
|
||||||
println!("{}", line);
|
println!("{}", line);
|
||||||
Some(
|
let user = crate::User::new_from_string(line.to_owned())
|
||||||
crate::User::new_from_string(line.to_owned())
|
.expect("failed to read lines");
|
||||||
.expect("failed to read lines"),
|
Some((user.get_username().to_owned(), user))
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -74,60 +83,65 @@ impl UserDBLocal {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
shadow_entries: shadow_content
|
|
||||||
.lines()
|
|
||||||
.filter_map(|line| {
|
|
||||||
if line.len() > 5 {
|
|
||||||
Some(
|
|
||||||
crate::Shadow::new_from_string(line.to_owned())
|
|
||||||
.expect("Parsing failed"),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
};
|
};
|
||||||
|
for shadow in shadow_entries {
|
||||||
|
let user = res.users.get_mut(shadow.get_username()).expect(&format!(
|
||||||
|
"the user {} does not exist",
|
||||||
|
shadow.get_username()
|
||||||
|
));
|
||||||
|
user.password = crate::Password::Shadow(shadow);
|
||||||
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn load_files(files: Files) -> Self {
|
pub fn load_files(files: Files) -> Self {
|
||||||
let passwd_file = File::open(
|
let my_passwd_lines = file_to_string(files.passwd.as_ref());
|
||||||
files
|
let my_group_lines = file_to_string(files.group.as_ref());
|
||||||
.group
|
let my_shadow_lines = file_to_string(files.shadow.as_ref());
|
||||||
.clone()
|
|
||||||
.expect("passwd file path cannot be None"),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let mut passwd_reader = BufReader::new(passwd_file);
|
|
||||||
let mut my_passwd_lines = String::new();
|
|
||||||
passwd_reader.read_to_string(&mut my_passwd_lines).unwrap();
|
|
||||||
let group_file =
|
|
||||||
File::open(files.group.clone().expect("group file path cannot be None")).unwrap();
|
|
||||||
let mut group_reader = BufReader::new(group_file);
|
|
||||||
let mut my_group_lines = String::new();
|
|
||||||
group_reader.read_to_string(&mut my_group_lines).unwrap();
|
|
||||||
let shadow_file = File::open(
|
|
||||||
files
|
|
||||||
.shadow
|
|
||||||
.clone()
|
|
||||||
.expect("shadow file path cannot be None"),
|
|
||||||
)
|
|
||||||
.expect("Failed to read the shadow file. Most of the time root permissions are needed");
|
|
||||||
let mut shadow_reader = BufReader::new(shadow_file);
|
|
||||||
let mut my_shadow_lines = String::new();
|
|
||||||
shadow_reader.read_to_string(&mut my_shadow_lines).unwrap();
|
|
||||||
|
|
||||||
|
let mut users = user_vec_to_hashmap(string_to(&my_passwd_lines));
|
||||||
|
let passwds: Vec<crate::Shadow> = string_to(&my_shadow_lines);
|
||||||
|
shadow_to_users(&mut users, passwds);
|
||||||
Self {
|
Self {
|
||||||
source_files: files,
|
source_files: files,
|
||||||
passwd_entries: string_to(&my_passwd_lines),
|
users,
|
||||||
group_entries: string_to(&my_group_lines),
|
group_entries: string_to(&my_group_lines),
|
||||||
shadow_entries: string_to(&my_shadow_lines),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn file_to_string(path: Option<&PathBuf>) -> String {
|
||||||
|
let file = File::open(path.expect("Path cannot be None".into()))
|
||||||
|
.expect("Failed to read the file. Most of the time root permissions are needed".into());
|
||||||
|
let mut reader = BufReader::new(file);
|
||||||
|
let mut lines = String::new();
|
||||||
|
reader.read_to_string(&mut lines).unwrap();
|
||||||
|
lines
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Merge the Shadow passwords into the users.
|
||||||
|
fn shadow_to_users(
|
||||||
|
users: &mut HashMap<String, crate::User>,
|
||||||
|
shadow: Vec<crate::Shadow>,
|
||||||
|
) -> &mut HashMap<String, crate::User> {
|
||||||
|
for pass in shadow {
|
||||||
|
let user = users
|
||||||
|
.get_mut(pass.get_username())
|
||||||
|
.expect(&format!("the user {} does not exist", pass.get_username()));
|
||||||
|
user.password = crate::Password::Shadow(pass);
|
||||||
|
}
|
||||||
|
users
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a `Vec<crate::User>` to a `HashMap<String, crate::User>` where the username is used as key.
|
||||||
|
fn user_vec_to_hashmap(users: Vec<crate::User>) -> HashMap<String, crate::User> {
|
||||||
|
users
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| (x.get_username().to_owned(), x))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
/// Try to parse a String into some Object
|
/// Try to parse a String into some Object
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
@ -157,11 +171,8 @@ where
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_creator_user_db_local() {
|
fn test_creator_user_db_local() {
|
||||||
let data = UserDBLocal::import_from_strings("testuser:x:1001:1001:full Name,004,000342,001-2312,myemail@test.com:/home/test:/bin/test", "test:!!$6$/RotIe4VZzzAun4W$7YUONvru1rDnllN5TvrnOMsWUD5wSDUPAD6t6/Xwsr/0QOuWF3HcfAhypRkGa8G1B9qqWV5kZSnCb8GKMN9N61:18260:0:99999:7:::", "teste:x:1002:test,teste");
|
let data = UserDBLocal::import_from_strings("test:x:1001:1001:full Name,004,000342,001-2312,myemail@test.com:/home/test:/bin/test", "test:!!$6$/RotIe4VZzzAun4W$7YUONvru1rDnllN5TvrnOMsWUD5wSDUPAD6t6/Xwsr/0QOuWF3HcfAhypRkGa8G1B9qqWV5kZSnCb8GKMN9N61:18260:0:99999:7:::", "teste:x:1002:test,test");
|
||||||
assert_eq!(
|
assert_eq!(data.users.get("test").unwrap().get_username(), "test")
|
||||||
data.passwd_entries.get(0).unwrap().get_username(),
|
|
||||||
"testuser"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user