diff --git a/unix_integration/nss_kanidm/src/core.rs b/unix_integration/nss_kanidm/src/core.rs index d60ba9839..3b067a72e 100644 --- a/unix_integration/nss_kanidm/src/core.rs +++ b/unix_integration/nss_kanidm/src/core.rs @@ -285,6 +285,42 @@ pub fn get_group_entry_by_name(name: String, req_options: RequestOptions) -> Res } } +pub fn get_group_entries_by_member(member: String, req_options: RequestOptions) -> Response<Vec<Group>> { + match req_options.connect_to_daemon() { + Source::Daemon(mut daemon_client) => { + let req = ClientRequest::NssGroupsByMember(member); + daemon_client + .call_and_wait(&req, None) + .map(|r| match r { + ClientResponse::NssGroups(l) => { + l.into_iter().map(group_from_nssgroup).collect() + } + _ => Vec::new(), + }) + .map(Response::Success) + .unwrap_or_else(|_| Response::Success(vec![])) + } + Source::Fallback { users: _, groups } => { + if groups.is_empty() { + return Response::Unavail; + } + + let membergroups = groups + .into_iter() + .filter_map(|etcgroup| { + if etcgroup.members.contains(&member) { + Some(group_from_etcgroup(etcgroup)) + } else { + None + } + }) + .collect(); + + Response::Success(membergroups) + } + } +} + fn passwd_from_etcuser(etc: EtcUser) -> Passwd { Passwd { name: etc.name, diff --git a/unix_integration/nss_kanidm/src/hooks.rs b/unix_integration/nss_kanidm/src/hooks.rs index 62386c987..5b7968438 100644 --- a/unix_integration/nss_kanidm/src/hooks.rs +++ b/unix_integration/nss_kanidm/src/hooks.rs @@ -3,6 +3,7 @@ use kanidm_unix_common::constants::DEFAULT_CONFIG_PATH; use libnss::group::{Group, GroupHooks}; use libnss::interop::Response; use libnss::passwd::{Passwd, PasswdHooks}; +use libnss::initgroups::{InitgroupsHooks}; struct KanidmPasswd; libnss_passwd_hooks!(kanidm, KanidmPasswd); @@ -61,3 +62,16 @@ impl GroupHooks for KanidmGroup { core::get_group_entry_by_name(name, req_opt) } } + +struct KanidmInitgroups; +libnss_initgroups_hooks!(kanidm, KanidmInitgroups); + +impl InitgroupsHooks for KanidmInitgroups { + fn get_entries_by_user(user: String) -> Response<Vec<Group>> { + let req_opt = RequestOptions::Main { + config_path: DEFAULT_CONFIG_PATH, + }; + + core::get_group_entries_by_member(user, req_opt) + } +}