1#![cfg(target_family = "unix")]
2
3use async_trait::async_trait;
9use libunftp::auth::*;
10
11#[derive(Debug)]
16pub struct PamAuthenticator {
17 service: String,
18}
19
20impl PamAuthenticator {
21 pub fn new<S: Into<String>>(service: S) -> Self {
23 let service = service.into();
24 PamAuthenticator { service }
25 }
26}
27
28#[async_trait]
29impl Authenticator<DefaultUser> for PamAuthenticator {
30 #[allow(clippy::type_complexity)]
31 #[tracing_attributes::instrument]
32 async fn authenticate(&self, username: &str, creds: &Credentials) -> Result<DefaultUser, AuthenticationError> {
33 let username = username.to_string();
34 let password = creds.password.as_ref().ok_or(AuthenticationError::BadPassword)?;
35 let service = self.service.clone();
36
37 let mut auth = pam_auth::Authenticator::with_password(&service).map_err(|e| AuthenticationError::with_source("pam error", e))?;
38
39 auth.get_handler().set_credentials(&username, password);
40 auth.authenticate().map_err(|e| AuthenticationError::with_source("pam error", e))?;
41 Ok(DefaultUser {})
42 }
43}