Mercurial > crates > nonstick
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")); |
