view libpam-sys/src/structs.rs @ 125:2b255c92417b

Introduce base PAM functions; use the real X/SSO PAM header for tests.
author Paul Fisher <paul@pfish.zone>
date Mon, 30 Jun 2025 17:47:32 -0400
parents 476a22db8639
children
line wrap: on
line source

//! Structs and wrappers that PAM is made of.
#![allow(non_camel_case_types)]

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(C)]
struct ExtremelyUnsafe {
    _value: (),
    _marker: 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 pam_handle_t(ExtremelyUnsafe);

impl fmt::Debug for pam_handle_t {
    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.
#[repr(C)]
pub struct AppData(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.
    msg: *const *const pam_message,
    // This is a &mut *mut because the caller sets the pointer in `resp`
    // but does not mess around outside its memory space.
    resp: &mut *mut pam_response,
    appdata: *const AppData,
) -> c_int;

/// Called to clean up data set using [`pam_set_data`](crate::pam_set_data).
pub type CleanupCallback = unsafe extern "C" fn(
    pamh: *mut pam_handle_t,
    data: *mut c_void,
    pam_end_status: c_int,
) -> c_int;

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

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

/// A response returned from a PAM conversation.
#[repr(C)]
pub struct pam_response {
    pub resp: *mut c_void,
    /// Completely unused.
    pub resp_retcode: c_int,
}