Added create_folder
method to MailStore
trait; Add code to set
restrictive permissions on mail account folders;
This commit is contained in:
parent
dcb182e4d0
commit
3a25914ec5
3 changed files with 56 additions and 1 deletions
|
@ -5,6 +5,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
digest = "0.10"
|
||||
libc = "0.2.146"
|
||||
rustls-pemfile = "1.0"
|
||||
sha2 = "0.10"
|
||||
time = "0.3"
|
||||
|
@ -12,6 +13,11 @@ x509-parser = "0.15"
|
|||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies.pw]
|
||||
git = "https://codeberg.org/jeang3nie/pw_rs.git"
|
||||
default-features = false
|
||||
features = [ "libc" ]
|
||||
|
||||
[dependencies.rustls]
|
||||
version = "0.21"
|
||||
features = [ "dangerous_configuration" ]
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use std::io::BufReader;
|
||||
use std::{
|
||||
ffi::CString,
|
||||
io::BufReader,
|
||||
os::{fd::AsRawFd, unix::prelude::OpenOptionsExt},
|
||||
};
|
||||
|
||||
use crate::prelude::Certificate;
|
||||
|
||||
|
@ -149,6 +153,21 @@ impl MailStore for Filesystem {
|
|||
Some(folder)
|
||||
}
|
||||
|
||||
fn create_folder(&self, user: &str, folder: &str) -> Result<(), io::Error> {
|
||||
if self.has_mailuser(user) {
|
||||
let user: Mailbox = user.parse().map_err(|e: ParseMailboxError| {
|
||||
io::Error::new(io::ErrorKind::Other, e.to_string())
|
||||
})?;
|
||||
let user: Mailuser = user.into();
|
||||
let mut path = self.path.clone();
|
||||
path.push(&user.host.to_string());
|
||||
path.push(&user.username);
|
||||
path.push(folder);
|
||||
fs::create_dir_all(&path)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_message(&self, user: &str, folder: &str, id: &str) -> Option<Message> {
|
||||
self.get_folder(user, folder)
|
||||
.and_then(|f| f.messages.get(id).cloned())
|
||||
|
@ -230,7 +249,22 @@ impl MailStore for Filesystem {
|
|||
.create(true)
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.mode(0o2770)
|
||||
.open(path)?;
|
||||
if let Some(pw) = pw::Passwd::getpw()
|
||||
.map_err(|e: pw::Error| io::Error::new(io::ErrorKind::Other, e.to_string()))?
|
||||
{
|
||||
let groups = pw
|
||||
.groups()
|
||||
.map_err(|e: pw::Error| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
|
||||
if let Some(gr) = groups.iter().find(|g| g.name == mb.username) {
|
||||
unsafe {
|
||||
if libc::fchown(fd.as_raw_fd(), pw.uid, gr.gid) != 0 {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut writer = BufWriter::new(fd);
|
||||
writer.write_all(blurb.as_bytes())?;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ pub trait MailStore {
|
|||
fn has_mailuser(&self, mailuser: &str) -> bool;
|
||||
/// Retreives all of the messages for this user
|
||||
fn get_folder(&self, user: &str, folder: &str) -> Option<Folder>;
|
||||
/// Creates a folder for the specified user, if it doesn't already exist
|
||||
fn create_folder(&self, user: &str, folder: &str) -> Result<(), Self::Error>;
|
||||
/// Checks whether this server has a message with the given title for this user and if so
|
||||
/// returns the message
|
||||
fn get_message(&self, user: &str, folder: &str, id: &str) -> Option<Message>;
|
||||
|
@ -97,6 +99,19 @@ impl MailStore for Domain {
|
|||
.and_then(|u| u.folders.get(folder).cloned())
|
||||
}
|
||||
|
||||
fn create_folder(&self, user: &str, folder: &str) -> Result<(), io::Error> {
|
||||
self.users.get(user).cloned().and_then(|mut u| {
|
||||
u.folders.insert(
|
||||
folder.to_string(),
|
||||
Folder {
|
||||
name: folder.to_string(),
|
||||
messages: HashMap::new(),
|
||||
},
|
||||
)
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_message(&self, user: &str, folder: &str, title: &str) -> Option<Message> {
|
||||
self.users
|
||||
.get(user)
|
||||
|
|
Loading…
Add table
Reference in a new issue