1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-09 08:58:35 +03:00

Add nss getpwent to the himmelblau daemon

Signed-off-by: David Mulder <dmulder@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
This commit is contained in:
David Mulder 2024-07-30 11:18:59 -06:00
parent e243b7c95f
commit 82d7208a85
4 changed files with 126 additions and 0 deletions

View File

@ -207,6 +207,7 @@ pub(crate) async fn handle_client(
} }
} }
} }
Request::NssAccounts => resolver.getpwent().await?,
_ => todo!(), _ => todo!(),
}; };
reqs.send(resp).await?; reqs.send(resp).await?;
@ -218,4 +219,5 @@ pub(crate) async fn handle_client(
Ok(()) Ok(())
} }
mod himmelblaud_getpwent;
mod himmelblaud_pam_auth; mod himmelblaud_pam_auth;

View File

@ -0,0 +1,92 @@
/*
Unix SMB/CIFS implementation.
Himmelblau daemon implementation for nss getpwent
Copyright (C) David Mulder 2024
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::himmelblaud::Resolver;
use crate::utils::split_username;
use dbg::DBG_ERR;
use ntstatus_gen::*;
use sock::{Passwd, Response};
impl Resolver {
pub(crate) async fn getpwent(&mut self) -> Result<Response, Box<NTSTATUS>> {
let user_entries = self.user_cache.fetch_all()?;
let template_homedir = self
.lp
.template_homedir()
.map_err(|e| {
DBG_ERR!("{:?}", e);
Box::new(NT_STATUS_NOT_A_DIRECTORY)
})?
.ok_or_else(|| {
DBG_ERR!("Failed to discover template homedir. Is it set?");
Box::new(NT_STATUS_NOT_A_DIRECTORY)
})?;
let shell = self
.lp
.template_shell()
.map_err(|e| {
DBG_ERR!("{:?}", e);
Box::new(NT_STATUS_NOT_A_DIRECTORY)
})?
.ok_or_else(|| {
DBG_ERR!("Failed to discover template shell. Is it set?");
Box::new(NT_STATUS_NOT_A_DIRECTORY)
})?;
let mut res = Vec::new();
for entry in user_entries {
let uid = self
.idmap
.gen_to_unix(&self.tenant_id, &entry.upn.to_lowercase())
.map_err(|e| {
DBG_ERR!("{:?}", e);
Box::new(NT_STATUS_INVALID_TOKEN)
})?;
let upn = entry.upn.clone();
let (cn, domain) = match split_username(&upn) {
Ok(res) => res,
Err(e) => {
DBG_ERR!(
"Failed to parse user upn '{}': {:?}",
&entry.upn,
e
);
return Err(Box::new(
NT_STATUS_INVALID_USER_PRINCIPAL_NAME,
));
}
};
let homedir = template_homedir
.clone()
.replace("%D", &domain)
.replace("%U", &cn);
let passwd = Passwd {
name: entry.upn.clone(),
passwd: "x".to_string(),
uid,
gid: uid,
gecos: entry.name,
dir: homedir,
shell: shell.clone(),
};
res.push(passwd);
}
Ok(Response::NssAccounts(res))
}
}

View File

@ -39,6 +39,7 @@ use constants::DEFAULT_ODC_PROVIDER;
mod cache; mod cache;
mod himmelblaud; mod himmelblaud;
use cache::{GroupCache, PrivateCache, UserCache}; use cache::{GroupCache, PrivateCache, UserCache};
mod utils;
#[tokio::main(flavor = "current_thread")] #[tokio::main(flavor = "current_thread")]
async fn main() -> ExitCode { async fn main() -> ExitCode {

31
himmelblaud/src/utils.rs Normal file
View File

@ -0,0 +1,31 @@
/*
Unix SMB/CIFS implementation.
Himmelblau daemon common utilities
Copyright (C) David Mulder 2024
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use ntstatus_gen::*;
pub fn split_username(
username: &str,
) -> Result<(String, String), Box<NTSTATUS>> {
let tup: Vec<&str> = username.split('@').collect();
if tup.len() == 2 {
return Ok((tup[0].to_string(), tup[1].to_string()));
}
Err(Box::new(NT_STATUS_INVALID_USER_PRINCIPAL_NAME))
}