view libpam-sys/src/structs.rs @ 119:476a22db8639

Add PtrPtrVec to make it easy to pass pointer-to-pointers to PAM.
author Paul Fisher <paul@pfish.zone>
date Mon, 30 Jun 2025 01:40:28 -0400
parents 39760dfc9b3b
children
line wrap: on
line source

use std::ffi::{c_int, c_void};
use std::fmt;
use std::marker::{PhantomData, PhantomPinned};

/// A marker struct to make whatever it's in `!Sync`, `!Send`, and `!Unpin`.
#[derive(Default, PartialOrd, PartialEq, Ord, Eq)]
#[repr(transparent)]
struct ExtremelyUnsafe(PhantomData<(PhantomPinned, *mut c_void)>);

impl fmt::Debug for ExtremelyUnsafe {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("ExtremelyUnsafe")
    }
}

/// An opaque structure that PAM uses to communicate.
///
/// This is only ever returned in pointer form and cannot be constructed.
#[repr(C)]
pub struct PamHandle {
    _marker: ExtremelyUnsafe,
}

impl fmt::Debug for PamHandle {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "PamHandle({self:p}")
    }
}

/// An opaque structure that is passed through PAM in a conversation.
pub struct AppData {
    _marker: ExtremelyUnsafe,
}

impl fmt::Debug for AppData {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "AppData({self:p}")
    }
}

/// The callback that PAM uses to get information in a conversation.
///
/// For important details about the format of `messages`,
/// see the [`helpers`](crate::helpers) module.
pub type ConversationCallback = unsafe extern "C" fn(
    num_msg: c_int,
    // This is a *const *const because accessing memory from a reference
    // outside its bounds is undefined behavior, and *messages is an array
    // in X/SSO PAM impls.
    messages: *const *const Message,
    // This is a &mut *mut because the caller sets the pointer in `responses`
    // but does not mess around outside its memory space.
    responses: &mut *mut Response,
    appdata: *const AppData,
) -> c_int;

/// Used by PAM to communicate between the module and the application.
#[repr(C)]
pub struct Conversation {
    pub callback: ConversationCallback,
    pub appdata: *const AppData,
}

/// A message sent into a PAM conversation.
#[repr(C)]
pub struct Message {
    pub style: c_int,
    pub data: *const c_void,
}

/// A response returned from a PAM conversation.
#[repr(C)]
pub struct Response {
    pub data: *mut c_void,
    pub _unused: c_int,
}