1use crate::unix_passwd::{EtcDb, EtcGroup, EtcUser};
2use kanidm_proto::internal::OperationError;
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, Debug)]
6pub struct NssUser {
7 pub name: String,
8 pub uid: u32,
9 pub gid: u32,
10 pub gecos: String,
11 pub homedir: String,
12 pub shell: String,
13}
14
15impl<T> From<&T> for NssUser
16where
17 T: AsRef<EtcUser>,
18{
19 fn from(etc_user: &T) -> Self {
20 let etc_user = etc_user.as_ref();
21 NssUser {
22 name: etc_user.name.clone(),
23 uid: etc_user.uid,
24 gid: etc_user.gid,
25 gecos: etc_user.gecos.clone(),
26 homedir: etc_user.homedir.clone(),
27 shell: etc_user.shell.clone(),
28 }
29 }
30}
31
32#[derive(Serialize, Deserialize, Debug)]
33pub struct NssGroup {
34 pub name: String,
35 pub gid: u32,
36 pub members: Vec<String>,
37}
38
39impl<T> From<&T> for NssGroup
40where
41 T: AsRef<EtcGroup>,
42{
43 fn from(etc_group: &T) -> Self {
44 let etc_group = etc_group.as_ref();
45 NssGroup {
46 name: etc_group.name.clone(),
47 gid: etc_group.gid,
48 members: etc_group.members.clone(),
49 }
50 }
51}
52
53#[derive(Serialize, Deserialize, Clone, Debug)]
55pub struct DeviceAuthorizationResponse {
56 pub device_code: String,
57 pub user_code: String,
58 pub verification_uri: String,
59 pub verification_uri_complete: Option<String>,
60 pub expires_in: u32,
61 pub interval: Option<u32>,
62 pub message: Option<String>,
65}
66
67#[derive(Serialize, Deserialize, Debug)]
68pub enum PamAuthResponse {
69 Unknown,
70 Success,
71 Denied,
72 Password,
73 DeviceAuthorizationGrant {
74 data: DeviceAuthorizationResponse,
75 },
76 MFACode {
78 msg: String,
79 },
80 MFAPoll {
82 msg: String,
84 polling_interval: u32,
86 },
87 MFAPollWait,
88 SetupPin {
90 msg: String,
91 },
92 Pin,
93 }
95
96#[derive(Serialize, Deserialize, Debug)]
97pub enum PamAuthRequest {
98 Password { cred: String },
99 DeviceAuthorizationGrant { data: DeviceAuthorizationResponse },
100 MFACode { cred: String },
101 MFAPoll,
102 SetupPin { pin: String },
103 Pin { cred: String },
104}
105
106#[derive(Serialize, Deserialize, Debug)]
107pub struct PamServiceInfo {
108 pub service: String,
109 pub tty: Option<String>,
111 pub rhost: Option<String>,
113}
114
115#[derive(Serialize, Deserialize, Debug)]
116pub enum ClientRequest {
117 SshKey(String),
118 NssAccounts,
119 NssAccountByUid(u32),
120 NssAccountByName(String),
121 NssGroups,
122 NssGroupByGid(u32),
123 NssGroupByName(String),
124 PamAuthenticateInit {
125 account_id: String,
126 info: PamServiceInfo,
127 },
128 PamAuthenticateStep(PamAuthRequest),
129 PamAccountAllowed(String),
130 PamAccountBeginSession(String),
131 InvalidateCache,
132 ClearCache,
133 Status,
134}
135
136impl ClientRequest {
137 pub fn as_safe_string(&self) -> String {
139 match self {
140 ClientRequest::SshKey(id) => format!("SshKey({})", id),
141 ClientRequest::NssAccounts => "NssAccounts".to_string(),
142 ClientRequest::NssAccountByUid(id) => format!("NssAccountByUid({})", id),
143 ClientRequest::NssAccountByName(id) => format!("NssAccountByName({})", id),
144 ClientRequest::NssGroups => "NssGroups".to_string(),
145 ClientRequest::NssGroupByGid(id) => format!("NssGroupByGid({})", id),
146 ClientRequest::NssGroupByName(id) => format!("NssGroupByName({})", id),
147 ClientRequest::PamAuthenticateInit { account_id, info } => format!(
148 "PamAuthenticateInit{{ account_id={} tty={} pam_secvice{} rhost={} }}",
149 account_id,
150 info.service,
151 info.tty.as_deref().unwrap_or(""),
152 info.rhost.as_deref().unwrap_or("")
153 ),
154 ClientRequest::PamAuthenticateStep(_) => "PamAuthenticateStep".to_string(),
155 ClientRequest::PamAccountAllowed(id) => {
156 format!("PamAccountAllowed({})", id)
157 }
158 ClientRequest::PamAccountBeginSession(_) => "PamAccountBeginSession".to_string(),
159 ClientRequest::InvalidateCache => "InvalidateCache".to_string(),
160 ClientRequest::ClearCache => "ClearCache".to_string(),
161 ClientRequest::Status => "Status".to_string(),
162 }
163 }
164}
165
166#[derive(Serialize, Deserialize, Debug)]
167pub struct ProviderStatus {
168 pub name: String,
169 pub online: bool,
170}
171
172#[derive(Serialize, Deserialize, Debug)]
173pub enum ClientResponse {
174 SshKeys(Vec<String>),
175 NssAccounts(Vec<NssUser>),
176 NssAccount(Option<NssUser>),
177 NssGroups(Vec<NssGroup>),
178 NssGroup(Option<NssGroup>),
179
180 PamStatus(Option<bool>),
181 PamAuthenticateStepResponse(PamAuthResponse),
182
183 ProviderStatus(Vec<ProviderStatus>),
184
185 Ok,
186 Error(OperationError),
187}
188
189impl From<PamAuthResponse> for ClientResponse {
190 fn from(par: PamAuthResponse) -> Self {
191 ClientResponse::PamAuthenticateStepResponse(par)
192 }
193}
194
195#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
196pub struct HomeDirectoryInfo {
197 pub uid: u32,
198 pub gid: u32,
199 pub name: String,
200 pub aliases: Vec<String>,
201}
202
203#[derive(Serialize, Deserialize, Debug, Clone)]
204pub struct TaskRequestFrame {
205 pub id: u64,
206 pub req: TaskRequest,
207}
208
209#[derive(Serialize, Deserialize, Debug, Clone)]
210pub enum TaskRequest {
211 HomeDirectory(HomeDirectoryInfo),
212}
213
214#[derive(Serialize, Deserialize, Debug)]
215pub enum TaskResponse {
216 Success(u64),
217 Error(String),
218 NotifyShadowChange(EtcDb),
219}
220
221#[test]
222fn test_clientrequest_as_safe_string() {
223 assert_eq!(
224 ClientRequest::NssAccounts.as_safe_string(),
225 "NssAccounts".to_string()
226 );
227 assert_eq!(
228 ClientRequest::SshKey("cheese".to_string()).as_safe_string(),
229 format!("SshKey({})", "cheese")
230 );
231}