comparison src/libpam/conversation.rs @ 97:efe2f5f8b5b2

Implement "stateless" application-side PAM calls. This introduces `authenticate`, `account_management`, and `change_authtok`. These are the three PAM operations that are stateless (i.e., they don't start a session or modify global credentials).
author Paul Fisher <paul@pfish.zone>
date Mon, 23 Jun 2025 19:10:34 -0400
parents f3e260f9ddcb
children b87100c5eed4
comparison
equal deleted inserted replaced
96:f3e260f9ddcb 97:efe2f5f8b5b2
13 use std::iter; 13 use std::iter;
14 use std::marker::PhantomData; 14 use std::marker::PhantomData;
15 use std::result::Result as StdResult; 15 use std::result::Result as StdResult;
16 16
17 impl LibPamConversation<'_> { 17 impl LibPamConversation<'_> {
18 fn wrap<C: Conversation>(conv: &mut C) -> Self { 18 pub fn wrap<C: Conversation>(conv: &C) -> Self {
19 Self { 19 Self {
20 callback: Self::wrapper_callback::<C>, 20 callback: Self::wrapper_callback::<C>,
21 appdata: (conv as *mut C).cast(), 21 appdata: (conv as *const C).cast(),
22 life: PhantomData, 22 life: PhantomData,
23 _marker: Immovable(PhantomData), 23 _marker: Immovable(PhantomData),
24 } 24 }
25 } 25 }
26 26
29 /// PAM calls this, we compute answers, then send them back. 29 /// PAM calls this, we compute answers, then send them back.
30 unsafe extern "C" fn wrapper_callback<C: Conversation>( 30 unsafe extern "C" fn wrapper_callback<C: Conversation>(
31 count: c_int, 31 count: c_int,
32 questions: *const *const Question, 32 questions: *const *const Question,
33 answers: *mut *mut Answer, 33 answers: *mut *mut Answer,
34 me: *mut AppData, 34 me: *const AppData,
35 ) -> c_int { 35 ) -> c_int {
36 let internal = || { 36 let internal = || {
37 // Collect all our pointers 37 // Collect all our pointers
38 let conv = me 38 let conv = me
39 .cast::<C>() 39 .cast::<C>()
40 .as_mut() 40 .as_ref()
41 .ok_or(ErrorCode::ConversationError)?; 41 .ok_or(ErrorCode::ConversationError)?;
42 let indirect = Questions::borrow_ptr(questions, count as usize); 42 let indirect = Questions::borrow_ptr(questions, count as usize);
43 let answers_ptr = answers.as_mut().ok_or(ErrorCode::ConversationError)?; 43 let answers_ptr = answers.as_mut().ok_or(ErrorCode::ConversationError)?;
44 44
45 // Build our owned list of Q&As from the questions we've been asked 45 // Build our owned list of Q&As from the questions we've been asked