projects/aports·blob master · refs

141 lines · 5.7 KiB

1diff --git a/unix_integration/common/src/unix_proto.rs b/unix_integration/common/src/unix_proto.rs
2index 337f83acd..9ff949f8a 100644
3--- a/unix_integration/common/src/unix_proto.rs
4+++ b/unix_integration/common/src/unix_proto.rs
5@@ -121,6 +121,7 @@ pub enum ClientRequest {
6 NssGroups,
7 NssGroupByGid(u32),
8 NssGroupByName(String),
9+ NssGroupsByMember(String),
10 PamAuthenticateInit {
11 account_id: String,
12 info: PamServiceInfo,
13@@ -147,6 +148,7 @@ impl ClientRequest {
14 ClientRequest::NssGroups => "NssGroups".to_string(),
15 ClientRequest::NssGroupByGid(id) => format!("NssGroupByGid({id})"),
16 ClientRequest::NssGroupByName(id) => format!("NssGroupByName({id})"),
17+ ClientRequest::NssGroupsByMember(id) => format!("NssGroupsByMember({id})"),
18 ClientRequest::PamAuthenticateInit { account_id, info } => format!(
19 "PamAuthenticateInit{{ account_id={} tty={} pam_secvice{} rhost={} }}",
20 account_id,
21diff --git a/unix_integration/nss_sparkle_common/src/core.rs b/unix_integration/nss_sparkle_common/src/core.rs
22index 272f7e895..f409e1566 100644
23--- a/unix_integration/nss_sparkle_common/src/core.rs
24+++ b/unix_integration/nss_sparkle_common/src/core.rs
25@@ -313,6 +313,45 @@ pub fn get_group_entry_by_name(name: String, req_options: RequestOptions) -> Res
26 }
27 }
28
29+pub fn get_group_entries_by_member(
30+ member: String,
31+ req_options: RequestOptions,
32+) -> Response<Vec<Group>> {
33+ match req_options.connect_to_daemon() {
34+ Source::Daemon(daemon_client) => {
35+ let req = ClientRequest::NssGroupsByMember(member);
36+ daemon_client
37+ .call_and_wait(req, None)
38+ .map(|r| match r {
39+ ClientResponse::NssGroups(l) => {
40+ l.into_iter().map(group_from_nssgroup).collect()
41+ }
42+ _ => Vec::new(),
43+ })
44+ .map(Response::Success)
45+ .unwrap_or_else(|_| Response::Success(vec![]))
46+ }
47+ Source::Fallback { users: _, groups } => {
48+ if groups.is_empty() {
49+ return Response::Unavail;
50+ }
51+
52+ let membergroups = groups
53+ .into_iter()
54+ .filter_map(|etcgroup| {
55+ if etcgroup.members.contains(&member) {
56+ Some(group_from_etcgroup(etcgroup))
57+ } else {
58+ None
59+ }
60+ })
61+ .collect();
62+
63+ Response::Success(membergroups)
64+ }
65+ }
66+}
67+
68 fn passwd_from_etcuser(etc: EtcUser) -> Passwd {
69 Passwd {
70 name: etc.name,
71diff --git a/unix_integration/nss_sparkle_common/src/hooks.rs b/unix_integration/nss_sparkle_common/src/hooks.rs
72index 98de274d4..7bca5fd6e 100644
73--- a/unix_integration/nss_sparkle_common/src/hooks.rs
74+++ b/unix_integration/nss_sparkle_common/src/hooks.rs
75@@ -2,6 +2,7 @@ use crate::core::{self, RequestOptions};
76 use libnss::group::{Group, GroupHooks};
77 use libnss::interop::Response;
78 use libnss::passwd::{Passwd, PasswdHooks};
79+use libnss::initgroups::{InitgroupsHooks};
80 use sparkle_unix_common::constants::DEFAULT_CONFIG_PATH;
81
82 pub struct SparklePasswd;
83@@ -59,3 +60,16 @@ impl GroupHooks for SparkleGroup {
84 core::get_group_entry_by_name(name, req_opt)
85 }
86 }
87+
88+pub struct KanidmInitgroups;
89+libnss::libnss_initgroups_hooks!(kanidm, KanidmInitgroups);
90+
91+impl InitgroupsHooks for KanidmInitgroups {
92+ fn get_entries_by_user(user: String) -> Response<Vec<Group>> {
93+ let req_opt = RequestOptions::Main {
94+ config_path: DEFAULT_CONFIG_PATH,
95+ };
96+
97+ core::get_group_entries_by_member(user, req_opt)
98+ }
99+}
100diff --git a/unix_integration/resolver_common/src/cli/resolver.rs b/unix_integration/resolver_common/src/cli/resolver.rs
101index 7cdf0fbae..5e96361e9 100644
102--- a/unix_integration/resolver_common/src/cli/resolver.rs
103+++ b/unix_integration/resolver_common/src/cli/resolver.rs
104@@ -252,6 +252,14 @@ async fn handle_client(
105 error!("unable to load group, returning empty.");
106 ClientResponse::NssGroup(None)
107 }),
108+ ClientRequest::NssGroupsByMember(account_id) => cachelayer
109+ .get_nssgroups_member_name(account_id.as_str())
110+ .await
111+ .map(ClientResponse::NssGroups)
112+ .unwrap_or_else(|_| {
113+ error!("unable to enum groups");
114+ ClientResponse::NssGroups(Vec::new())
115+ }),
116 ClientRequest::PamAuthenticateInit { account_id, info } => {
117 #[allow(clippy::disallowed_methods)]
118 // Allowed as this is the time check for the remainder of the function and check.
119diff --git a/unix_integration/resolver_common/src/resolver.rs b/unix_integration/resolver_common/src/resolver.rs
120index 4a6c542a3..ae929cd1f 100644
121--- a/unix_integration/resolver_common/src/resolver.rs
122+++ b/unix_integration/resolver_common/src/resolver.rs
123@@ -908,6 +908,17 @@ impl Resolver {
124 Ok(r)
125 }
126
127+ pub async fn get_nssgroups_member_name(&self, account_id: &str) -> Result<Vec<NssGroup>, ()> {
128+ let account_name = account_id.to_string();
129+ Ok(self
130+ .get_nssgroups()
131+ .await
132+ .unwrap_or_default()
133+ .into_iter()
134+ .filter(|g| g.members.contains(&account_name))
135+ .collect())
136+ }
137+
138 #[instrument(level = "trace", skip_all)]
139 async fn get_nssgroup(&self, grp_id: Id) -> Result<Option<NssGroup>, ()> {
140 if let Some(mut nss_group) = self.system_provider.get_nssgroup(&grp_id).await {
141