Mercurial > crates > nonstick
changeset 105:13b4d2a19674
Support Rust v1.75.0.
This is the version included in Ubuntu 24.04 LTS and Debian Trixie,
so it's old enough to have wide penetration without being too old
to get new features (Debian Stable, I love you but v1.63 is just
not going to work out).
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 26 Jun 2025 00:48:51 -0400 |
parents | a2676475e86b |
children | 49d9e2b5c189 |
files | Cargo.toml build.rs src/_doc.rs src/libpam/environ.rs src/libpam/handle.rs src/libpam/memory.rs src/libpam/question.rs testharness/Cargo.toml testharness/tests/end2end.rs |
diffstat | 9 files changed, 74 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/Cargo.toml Wed Jun 25 16:56:56 2025 -0400 +++ b/Cargo.toml Thu Jun 26 00:48:51 2025 -0400 @@ -1,38 +1,46 @@ [workspace] members = ["testharness"] -resolver = "3" +resolver = "2" [workspace.package] version = "0.0.8-alpha0" authors = ["Paul Fisher <paul@pfish.zone>"] repository = "https://hg.pfish.zone/crates/nonstick/" edition = "2021" +rust-version = "1.75.0" [package] name = "nonstick" description = "PAM bindings for Rust" -version.workspace = true -authors.workspace = true readme = "README.md" keywords = ["pam", "ffi", "linux", "authentication"] license = "MIT" +version.workspace = true +authors.workspace = true edition.workspace = true +rust-version.workspace = true [features] default = ["link"] + # Enable this to actually link against your system's PAM library. # # This will fail if you have extensions enabled that are not compatible # with your system's PAM. link = [] + # Enable this to get access to Linux-PAM extensions. linux-pam-extensions = [] # Enable this to get access to OpenPAM extensions. openpam-extensions = [] +# This feature exists only for testing. +test-install = [] + [dependencies] bitflags = "2.9.0" libc = "0.2.97" +memoffset = "0.9.1" num_enum = "0.7.3" [dev-dependencies]
--- a/build.rs Wed Jun 25 16:56:56 2025 -0400 +++ b/build.rs Thu Jun 26 00:48:51 2025 -0400 @@ -4,8 +4,8 @@ fn main() { if cfg!(feature = "link") { - println!("cargo::rustc-link-lib=pam"); - println!("cargo::rustc-check-cfg=cfg(pam_impl, values(\"linux-pam\",\"openpam\"))"); + println!("cargo:rustc-link-lib=pam"); + println!("cargo:rustc-check-cfg=cfg(pam_impl, values(\"linux-pam\",\"openpam\"))"); let common_builder = bindgen::Builder::default() .merge_extern_blocks(true) .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) @@ -64,7 +64,7 @@ panic!("unrecognized PAM implementation") } }; - println!("cargo::rustc-cfg=pam_impl={pam_impl:?}"); + println!("cargo:rustc-cfg=pam_impl={pam_impl:?}"); let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings .write_to_file(out_path.join("bindings.rs"))
--- a/src/_doc.rs Wed Jun 25 16:56:56 2025 -0400 +++ b/src/_doc.rs Thu Jun 26 00:48:51 2025 -0400 @@ -7,11 +7,15 @@ /// # Examples /// /// ``` +/// # use nonstick::{_linklist, _stdlinks}; +/// /// Here is a list of links: +/// /// /// #[doc = _linklist!(pam_get_authtok: man7, manbsd)] /// /// -/// /// ...use it with link references, like the below... +/// /// The links are defined in the `stdlinks!` invocation below: /// /// /// #[doc = _stdlinks!(3 pam_get_authtok)] +/// # fn do_whatever() {} /// ``` #[macro_export] #[doc(hidden)] @@ -57,7 +61,11 @@ /// # Examples /// /// ``` +/// # use nonstick::{_guide}; +/// /// See [the guide][mwg]. +/// /// /// #[doc = _guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_get_user")] +/// # fn do_whatever() {} /// ``` #[macro_export] #[doc(hidden)] @@ -77,11 +85,17 @@ /// # Examples /// /// ``` -/// // Both of these formulations create a link reference named `man7`. -/// #[doc = _man7!(3 fn_name)] -/// #[doc = _man7!(5 thing_name "SECTION")] -/// // This one creates a link reference named `link_name`. -/// #[doc = _man7!(link_name: 1 prog_name "SECTION")] +/// # use nonstick::_man7; +/// /// This contains a [link to the man page for malloc][man7]. +/// #[doc = _man7!(3 malloc)] +/// # fn do_whatever() {} +/// +/// /// This contains both a link to the ["structure" section of `hgrc`][man7] +/// /// and a link to the ["environment" section of `systemd`][sysd_env]. +/// /// +/// #[doc = _man7!(5 hgrc "STRUCTURE")] +/// #[doc = _man7!(sysd_env: 1 systemd "ENVIRONMENT")] +/// # fn do_whatever2() {} /// ``` #[macro_export] #[doc(hidden)] @@ -103,11 +117,13 @@ /// # Examples /// /// ``` +/// # use nonstick::_manbsd; /// // Both of these formulations create a link named `manbsd`. /// #[doc = _manbsd!(3 fn_name)] /// #[doc = _manbsd!(5 thing_name "SECTION")] /// // This one creates a link named `link_name`. /// #[doc = _manbsd!(link_name: 1 prog_name "SECTION")] +/// # fn do_whatever() {} /// ``` #[macro_export] #[doc(hidden)] @@ -128,14 +144,18 @@ /// # Examples /// /// ``` -/// // Both of these formulations create a link reference named `xsso`. -/// // A link to the X/SSO specification for the `pam_set_item` function. +/// # use nonstick::_xsso; +/// /// This docstring will [link to the X/SSO spec for `pam_set_item`][xsso]. +/// /// /// #[doc = _xsso!(pam_set_item)] -/// // A link to the HTML page with the given name. +/// # fn link_one() {} +/// +/// /// This docstring will link to [`some_page`][xsso]. +/// /// I can also link to [the table of contents][spec_toc]. +/// /// /// #[doc = _xsso!("some_page.htm#section-id")] -/// -/// // This one creates a link reference named `spec_toc`. /// #[doc = _xsso!(spec_toc: "toc.htm")] +/// # fn do_whatever() {} /// ``` #[macro_export] #[doc(hidden)] @@ -154,7 +174,11 @@ /// # Examples /// /// ``` +/// # use nonstick::_stdlinks; +/// /// Check out [this][man7], [that][manbsd], or [the other][xsso]. +/// /// /// #[doc = _stdlinks!(3 pam_get_item)] +/// # fn do_whatever() {} /// ``` #[macro_export] #[doc(hidden)]
--- a/src/libpam/environ.rs Wed Jun 25 16:56:56 2025 -0400 +++ b/src/libpam/environ.rs Thu Jun 26 00:48:51 2025 -0400 @@ -139,6 +139,7 @@ } } } + impl Iterator for EnvList<'_> { type Item = (OsString, OsString); @@ -152,7 +153,7 @@ // SAFETY: We know we're still pointing to a valid pointer, // and advancing it one more is allowed. unsafe { - self.current = self.current.add(1); + self.current = advance(self.current); ptr::drop_in_place(item as *mut EnvVar); } Some(ret) @@ -167,14 +168,18 @@ // either an item we haven't used, or to the None end. unsafe { while let Some(var_ref) = self.current.as_mut() { + self.current = advance(self.current); ptr::drop_in_place(var_ref as *mut EnvVar); - self.current = self.current.add(1); } memory::free(self.start.as_ptr()) } } } +unsafe fn advance<T>(nn: NonNull<T>) -> NonNull<T> { + NonNull::new_unchecked(nn.as_ptr().offset(1)) +} + struct EnvVar(CHeapString); impl EnvVar { @@ -217,11 +222,11 @@ unsafe { for (idx, &text) in strings.iter().enumerate() { ptr::write( - ptrs.add(idx).as_ptr(), + ptrs.as_ptr().add(idx), Some(CHeapString::new(text).unwrap()), ) } - ptr::write(ptrs.add(strings.len()).as_ptr(), None); + ptr::write(ptrs.as_ptr().add(strings.len()), None); EnvList::from_ptr(ptrs.cast()) } }
--- a/src/libpam/handle.rs Wed Jun 25 16:56:56 2025 -0400 +++ b/src/libpam/handle.rs Thu Jun 26 00:48:51 2025 -0400 @@ -199,14 +199,14 @@ { // SAFETY: We're calling this function with a known value. unsafe { - pam_ffi::pam_syslog(self, level as c_int, c"%s".as_ptr().cast(), entry.as_ptr()) + pam_ffi::pam_syslog(self, level as c_int, "%s\0".as_ptr().cast(), entry.as_ptr()) } } #[cfg(pam_impl = "openpam")] { // SAFETY: We're calling this function with a known value. unsafe { - pam_ffi::openpam_log(self, level as c_int, c"%s".as_ptr().cast(), entry.as_ptr()) + pam_ffi::openpam_log(self, level as c_int, "%s\0".as_ptr().cast(), entry.as_ptr()) } } }
--- a/src/libpam/memory.rs Wed Jun 25 16:56:56 2025 -0400 +++ b/src/libpam/memory.rs Thu Jun 26 00:48:51 2025 -0400 @@ -6,11 +6,12 @@ use std::ffi::{c_char, CStr, CString}; use std::fmt::{Display, Formatter, Result as FmtResult}; use std::marker::{PhantomData, PhantomPinned}; -use std::mem::{offset_of, ManuallyDrop}; +use std::mem::{ManuallyDrop}; use std::ops::{Deref, DerefMut}; use std::ptr::NonNull; use std::result::Result as StdResult; use std::{mem, ptr, slice}; +use memoffset::offset_of; /// Raised from `calloc` when you have no memory! #[derive(Debug)] @@ -34,7 +35,7 @@ #[inline] pub fn calloc<T>(count: usize) -> StdResult<NonNull<T>, NoMem> { // SAFETY: it's always safe to allocate! Leaking memory is fun! - NonNull::new(unsafe { libc::calloc(count, size_of::<T>()) }.cast()).ok_or(NoMem) + NonNull::new(unsafe { libc::calloc(count, mem::size_of::<T>()) }.cast()).ok_or(NoMem) } /// Wrapper for [`libc::free`] to make debugging calls/frees easier.
--- a/src/libpam/question.rs Wed Jun 25 16:56:56 2025 -0400 +++ b/src/libpam/question.rs Thu Jun 26 00:48:51 2025 -0400 @@ -1,5 +1,6 @@ //! Data and types dealing with PAM messages. +use std::cell::Cell; #[cfg(feature = "linux-pam-extensions")] use crate::conv::{BinaryQAndA, RadioQAndA}; use crate::conv::{ErrorMsg, InfoMsg, MaskedQAndA, Message, QAndA}; @@ -12,7 +13,7 @@ use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::ffi::{c_void, CStr}; use std::pin::Pin; -use std::slice; +use std::{ptr, slice}; /// Abstraction of a collection of questions to be sent in a PAM conversation. /// @@ -91,7 +92,7 @@ /// Points to the memory address where the meat of `questions` is. /// **The memory layout of Vec is not specified**, and we need to return /// a pointer to the pointer, hence we have to store it here. - pointer: *const Question, + pointer: Cell<*const Question>, questions: Vec<Question>, _marker: Immovable, } @@ -110,14 +111,16 @@ let questions: Result<Vec<_>> = messages.iter().map(Question::try_from).collect(); let questions = questions?; Ok(Self { - pointer: questions.as_ptr(), + pointer: Cell::new(ptr::null()), questions, _marker: Default::default(), }) } fn ptr(self: Pin<&Self>) -> *const *const Question { - &self.pointer as *const *const Question + let me = self.get_ref(); + me.pointer.set(self.questions.as_ptr()); + me.pointer.as_ptr() } unsafe fn borrow_ptr<'a>(
--- a/testharness/Cargo.toml Wed Jun 25 16:56:56 2025 -0400 +++ b/testharness/Cargo.toml Thu Jun 26 00:48:51 2025 -0400 @@ -5,6 +5,7 @@ version.workspace = true authors.workspace = true edition.workspace = true +rust-version.workspace = true [lib] crate-type = ["cdylib"] @@ -12,6 +13,7 @@ [features] linux-pam-extensions = ["nonstick/linux-pam-extensions"] openpam-extensions = ["nonstick/openpam-extensions"] +test-install = [] [dependencies] nonstick = { path = ".." }