From 82d7208a85cd6ef6cddcf30b9b8b229580319d5b Mon Sep 17 00:00:00 2001 From: David Mulder Date: Tue, 30 Jul 2024 11:18:59 -0600 Subject: [PATCH] Add nss getpwent to the himmelblau daemon Signed-off-by: David Mulder Reviewed-by: Alexander Bokovoy --- himmelblaud/src/himmelblaud.rs | 2 + .../src/himmelblaud/himmelblaud_getpwent.rs | 92 +++++++++++++++++++ himmelblaud/src/main.rs | 1 + himmelblaud/src/utils.rs | 31 +++++++ 4 files changed, 126 insertions(+) create mode 100644 himmelblaud/src/himmelblaud/himmelblaud_getpwent.rs create mode 100644 himmelblaud/src/utils.rs diff --git a/himmelblaud/src/himmelblaud.rs b/himmelblaud/src/himmelblaud.rs index 96d5cc37628..169f3b1f767 100644 --- a/himmelblaud/src/himmelblaud.rs +++ b/himmelblaud/src/himmelblaud.rs @@ -207,6 +207,7 @@ pub(crate) async fn handle_client( } } } + Request::NssAccounts => resolver.getpwent().await?, _ => todo!(), }; reqs.send(resp).await?; @@ -218,4 +219,5 @@ pub(crate) async fn handle_client( Ok(()) } +mod himmelblaud_getpwent; mod himmelblaud_pam_auth; diff --git a/himmelblaud/src/himmelblaud/himmelblaud_getpwent.rs b/himmelblaud/src/himmelblaud/himmelblaud_getpwent.rs new file mode 100644 index 00000000000..b618c150643 --- /dev/null +++ b/himmelblaud/src/himmelblaud/himmelblaud_getpwent.rs @@ -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 . +*/ +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> { + 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)) + } +} diff --git a/himmelblaud/src/main.rs b/himmelblaud/src/main.rs index 74997fc0194..161191cd149 100644 --- a/himmelblaud/src/main.rs +++ b/himmelblaud/src/main.rs @@ -39,6 +39,7 @@ use constants::DEFAULT_ODC_PROVIDER; mod cache; mod himmelblaud; use cache::{GroupCache, PrivateCache, UserCache}; +mod utils; #[tokio::main(flavor = "current_thread")] async fn main() -> ExitCode { diff --git a/himmelblaud/src/utils.rs b/himmelblaud/src/utils.rs new file mode 100644 index 00000000000..932232eaec7 --- /dev/null +++ b/himmelblaud/src/utils.rs @@ -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 . +*/ +use ntstatus_gen::*; + +pub fn split_username( + username: &str, +) -> Result<(String, String), Box> { + 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)) +} -- 2.47.3