comparison src/libpam/pam_ffi.rs @ 80:5aa1a010f1e8

Start using PAM headers; improve owned/borrowed distinction. - Uses bindgen to generate bindings (only if needed). - Gets the story together on owned vs. borrowed handles. - Reduces number of mutable borrows in handle operation (since `PamHandle` is neither `Send` nor `Sync`, we never have to worry about thread safety. - Improves a bunch of macros so we don't have our own special syntax for docs. - Implement question indirection for standard XSSO PAM implementations.
author Paul Fisher <paul@pfish.zone>
date Tue, 10 Jun 2025 01:09:30 -0400
parents
children a8f4718fed5d
comparison
equal deleted inserted replaced
79:2128123b9406 80:5aa1a010f1e8
1 //! The types that are directly represented in PAM function signatures.
2
3 #![allow(non_camel_case_types)]
4
5 use crate::libpam::memory::Immovable;
6 use std::ffi::{c_int, c_void};
7 use std::marker::PhantomData;
8 use num_enum::{IntoPrimitive, TryFromPrimitive};
9
10 /// An opaque structure that a PAM handle points to.
11 #[repr(C)]
12 pub struct LibPamHandle {
13 _data: (),
14 _marker: Immovable,
15 }
16
17 /// An opaque structure that is passed through PAM in a conversation.
18 #[repr(C)]
19 pub struct AppData {
20 _data: (),
21 _marker: Immovable,
22 }
23
24 /// Generic version of answer data.
25 ///
26 /// This has the same structure as [`BinaryAnswer`](crate::libpam::answer::BinaryAnswer)
27 /// and [`TextAnswer`](crate::libpam::answer::TextAnswer).
28 #[repr(C)]
29 #[derive(Debug)]
30 pub struct Answer {
31 /// Pointer to the data returned in an answer.
32 /// For most answers, this will be a [`CStr`](std::ffi::CStr),
33 /// but for [`BinaryQAndA`](crate::conv::BinaryQAndA)s (a Linux-PAM extension),
34 /// this will be [`CBinaryData`](crate::libpam::memory::CBinaryData)
35 pub data: *mut c_void,
36 /// Unused.
37 return_code: c_int,
38 _marker: Immovable,
39 }
40
41 /// The C enum values for messages shown to the user.
42 #[derive(Debug, PartialEq, TryFromPrimitive, IntoPrimitive)]
43 #[repr(i32)]
44 pub enum Style {
45 /// Requests information from the user; will be masked when typing.
46 PromptEchoOff = 1,
47 /// Requests information from the user; will not be masked.
48 PromptEchoOn = 2,
49 /// An error message.
50 ErrorMsg = 3,
51 /// An informational message.
52 TextInfo = 4,
53 /// Yes/No/Maybe conditionals. A Linux-PAM extension.
54 RadioType = 5,
55 /// For server–client non-human interaction.
56 ///
57 /// NOT part of the X/Open PAM specification.
58 /// A Linux-PAM extension.
59 BinaryPrompt = 7,
60 }
61
62 /// A question sent by PAM or a module to an application.
63 ///
64 /// PAM refers to this as a "message", but we call it a question
65 /// to avoid confusion with [`Message`](crate::Message).
66 ///
67 /// This question, and its internal data, is owned by its creator
68 /// (either the module or PAM itself).
69 #[repr(C)]
70 pub struct Question {
71 /// The style of message to request.
72 pub style: c_int,
73 /// A description of the data requested.
74 ///
75 /// For most requests, this will be an owned [`CStr`](std::ffi::CStr), but for requests
76 /// with [`Style::BinaryPrompt`], this will be [`CBinaryData`]
77 /// (a Linux-PAM extension).
78 pub data: *mut c_void,
79 pub _marker: Immovable,
80 }
81
82 /// The callback that PAM uses to get information in a conversation.
83 ///
84 /// - `num_msg` is the number of messages in the `pam_message` array.
85 /// - `questions` is a pointer to the [`Question`]s being sent to the user.
86 /// For information about its structure,
87 /// see [`GenericQuestions`](super::question::GenericQuestions).
88 /// - `answers` is a pointer to an array of [`Answer`]s,
89 /// which PAM sets in response to a module's request.
90 /// This is an array of structs, not an array of pointers to a struct.
91 /// There should always be exactly as many `answers` as `num_msg`.
92 /// - `appdata` is the `appdata` field of the [`LibPamConversation`] we were passed.
93 pub type ConversationCallback = unsafe extern "C" fn(
94 num_msg: c_int,
95 questions: *const *const Question,
96 answers: *mut *mut Answer,
97 appdata: *mut AppData,
98 ) -> c_int;
99
100 /// The type used by PAM to call back into a conversation.
101 #[repr(C)]
102 pub struct LibPamConversation<'a> {
103 /// The function that is called to get information from the user.
104 pub callback: ConversationCallback,
105 /// The pointer that will be passed as the last parameter
106 /// to the conversation callback.
107 pub appdata: *mut AppData,
108 pub life: PhantomData<&'a mut ()>,
109 pub _marker: Immovable,
110 }
111
112 type pam_handle = LibPamHandle;
113 type pam_conv = LibPamConversation<'static>;
114
115 include!(concat!(env!("OUT_DIR"), "/bindings.rs"));