diff src/handle.rs @ 103:dfcd96a74ac4 default tip

write a truly prodigious amount of documentation adds a bunch of links to the OpenPAM man pages and the XSSO spec as well as just a bunch of prose and stuff.
author Paul Fisher <paul@pfish.zone>
date Wed, 25 Jun 2025 00:59:24 -0400
parents 3f11b8d30f63
children
line wrap: on
line diff
--- a/src/handle.rs	Tue Jun 24 18:11:38 2025 -0400
+++ b/src/handle.rs	Wed Jun 25 00:59:24 2025 -0400
@@ -4,6 +4,7 @@
 use crate::conv::Conversation;
 use crate::environ::{EnvironMap, EnvironMapMut};
 use crate::logging::Level;
+use crate::{_guide, _linklist, _man7, _manbsd, _stdlinks};
 
 macro_rules! trait_item {
     ($(#[$md:meta])* get = $getter:ident, item = $item:literal $(, see = $see:path)?) => {
@@ -18,17 +19,18 @@
         /// The item is assumed to be valid UTF-8 text.
         /// If it is not, `ConversationError` is returned.
         ///
-        /// See the [`pam_get_item`][man] manual page,
-        /// [`pam_get_item` in the Module Writers' Guide][mwg], or
-        /// [`pam_get_item` in the Application Developers' Guide][adg].
+        /// # References
+        ///
+        #[doc = _linklist!(pam_get_item: mwg, adg, _std)]
         ///
-        /// [man]: https://www.man7.org/linux/man-pages/man3/pam_get_item.3.html
-        /// [adg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/adg-interface-by-app-expected.html#adg-pam_get_item
-        /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-by-module-item.html#mwg-pam_get_item
+        #[doc = _guide!(adg: "adg-interface-by-app-expected.html#adg-pam_get_item")]
+        #[doc = _guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_get_item")]
+        #[doc = _stdlinks!(3 pam_get_item)]
         fn $getter(&self) -> Result<Option<String>>;
     };
     ($(#[$md:meta])* set = $setter:ident, item = $item:literal $(, see = $see:path)?) => {
         $(#[$md])*
+        #[doc = ""]
         #[doc = concat!("Sets the `", $item, "` from the PAM handle.")]
         $(
             #[doc = concat!("See [`", stringify!($see), "`].")]
@@ -38,13 +40,13 @@
         /// If the string contains a null byte, this will return
         /// a `ConversationError`.
         ///
-        /// See the [`pam_set_item`][man] manual page,
-        /// [`pam_set_item` in the Module Writers' Guide][mwg], or
-        /// [`pam_set_item` in the Application Developers' Guide][adg].
+        /// # References
+        ///
+        #[doc = _linklist!(pam_set_item: mwg, adg, _std)]
         ///
-        /// [man]: https://www.man7.org/linux/man-pages/man3/pam_set_item.3.html
-        /// [adg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/adg-interface-by-app-expected.html#adg-pam_set_item
-        /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-by-module-item.html#mwg-pam_set_item
+        #[doc = _guide!(adg: "adg-interface-by-app-expected.html#adg-pam_set_item")]
+        #[doc = _guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_set_item")]
+        #[doc = _stdlinks!(3 pam_set_item)]
         fn $setter(&mut self, value: Option<&str>) -> Result<()>;
     };
 }
@@ -61,9 +63,14 @@
     /// Logs something via this PAM handle.
     ///
     /// You probably want to use one of the logging macros,
-    /// like [`error!`], [`warning!`], [`info!`], or [`debug!`].
+    /// like [`error!`](crate::error!),
+    /// [`warn!`](crate::warn!),
+    /// [`info!`](crate::info!),
+    /// or [`debug!`](crate::debug!).
     ///
     /// In most PAM implementations, this will go to syslog.
+    /// See [Linux-PAM's `pam_syslog`][man7] or
+    /// [OpenPAM's `openpam_log`][manbsd] for more details.
     ///
     /// # Example
     ///
@@ -82,6 +89,8 @@
     /// pam_hdl.log(Level::Warning, "this is unnecessarily verbose");
     /// # }
     /// ```
+    #[doc = _man7!(3 pam_syslog)]
+    #[doc = _manbsd!(3 openpam_log)]
     fn log(&self, level: Level, entry: &str);
 
     /// Retrieves the name of the user who is authenticating or logging in.
@@ -93,8 +102,8 @@
     ///  2. The string returned by `get_user_prompt_item`.
     ///  3. The default prompt, `login: `.
     ///
-    /// See the [`pam_get_user` manual page][man]
-    /// or [`pam_get_user` in the Module Writer's Guide][mwg].
+    /// # References
+    #[doc = _linklist!(pam_get_user: mwg, _std)]
     ///
     /// # Example
     ///
@@ -110,9 +119,8 @@
     /// # Ok(())
     /// # }
     /// ```
-    ///
-    /// [man]: https://www.man7.org/linux/man-pages/man3/pam_get_user.3.html
-    /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-by-module-item.html#mwg-pam_get_user
+    #[doc = _stdlinks!(3 pam_get_user)]
+    #[doc = _guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_get_user")]
     fn username(&mut self, prompt: Option<&str>) -> Result<String>;
 
     /// The contents of the environment to set, read-only.
@@ -151,8 +159,7 @@
         item = "PAM_SERVICE"
     );
     trait_item!(
-        /// The service name, which identifies the PAM stack which is used
-        /// to perform authentication. It's probably a bad idea to change this.
+        /// Sets the service name. It's probably a bad idea to change this.
         set = set_service,
         item = "PAM_SERVICE",
         see = Self::service
@@ -191,9 +198,9 @@
         /// If set, the identity of the remote user logging in.
         ///
         /// This is only as trustworthy as the application calling PAM.
-        /// Also see [`remote_host`](Self::remote_host).
         get = remote_user,
-        item = "PAM_RUSER"
+        item = "PAM_RUSER",
+        see = Self::remote_host
     );
     trait_item!(
         /// Sets the identity of the remote user logging in.
@@ -201,7 +208,8 @@
         /// This may be set by the application before making calls
         /// into a PAM transaction.
         set = set_remote_user,
-        item = "PAM_RUSER"
+        item = "PAM_RUSER",
+        see = Self::remote_user
     );
 
     trait_item!(
@@ -215,7 +223,8 @@
         /// If unset, "it is unclear where the authentication request
         /// is originating from."
         get = remote_host,
-        item = "PAM_RHOST"
+        item = "PAM_RHOST",
+        see = Self::remote_user
     );
     trait_item!(
         /// Sets the location where the user is coming from.
@@ -240,7 +249,7 @@
 
     trait_item!(
         /// Sets the user's "old authentication token" when changing passwords.
-        //
+        ///
         /// This is usually set automatically by PAM.
         set = set_old_authtok_item,
         item = "PAM_OLDAUTHTOK",
@@ -257,12 +266,42 @@
 /// of PAM for testing PAM applications.
 pub trait PamHandleApplication: PamShared {
     /// Starts the authentication process for the user.
+    ///
+    /// The application calls this to find out who the user is, and verify that
+    /// they are really that person. If authentication is successful,
+    /// this will return an `Ok(())` [`Result`].
+    ///
+    /// A PAM module may change the caller's [username](PamShared::username)
+    /// as part of the login process, so be sure to check it after making
+    /// any PAM application call.
+    ///
+    /// # References
+    #[doc = _linklist!(pam_authenticate: adg, _std)]
+    ///
+    #[doc = _guide!(adg: "adg-interface-by-app-expected.html#adg-pam_authenticate")]
+    #[doc = _stdlinks!(3 pam_authenticate)]
     fn authenticate(&mut self, flags: Flags) -> Result<()>;
 
-    /// Does "account management".
+    /// Verifies the validity of the user's account (and other stuff).
+    ///
+    /// After [authentication](Self::authenticate), an application should call
+    /// this to ensure that the user's account is still valid. This may check
+    /// for token expiration or that the user's account is not locked.
+    ///
+    /// # References
+    #[doc = _linklist!(pam_acct_mgmt: adg, _std)]
+    ///
+    #[doc = _guide!(adg: "adg-interface-by-app-expected.html#adg-pam_acct_mgmt")]
+    #[doc = _stdlinks!(3 pam_acct_mgmt)]
     fn account_management(&mut self, flags: Flags) -> Result<()>;
 
     /// Changes the authentication token.
+    ///
+    /// # References
+    #[doc = _linklist!(pam_chauthtok: adg, _std)]
+    ///
+    #[doc = _guide!(adg: "adg-interface-by-app-expected.html#adg-pam_chauthtok")]
+    #[doc = _stdlinks!(3 pam_chauthtok)]
     fn change_authtok(&mut self, flags: Flags) -> Result<()>;
 }
 
@@ -277,10 +316,12 @@
     /// Retrieves the authentication token from the user.
     ///
     /// This should only be used by *authentication* and *password-change*
-    /// PAM modules.
+    /// PAM modules. This is an extension provided by
+    /// both Linux-PAM and OpenPAM.
     ///
-    /// See the [`pam_get_authtok` manual page][man]
-    /// or [`pam_get_item` in the Module Writer's Guide][mwg].
+    /// # References
+    ///
+    #[doc = _linklist!(pam_get_authtok: man7, manbsd)]
     ///
     /// # Example
     ///
@@ -294,9 +335,8 @@
     /// Ok(())
     /// # }
     /// ```
-    ///
-    /// [man]: https://www.man7.org/linux/man-pages/man3/pam_get_authtok.3.html
-    /// [mwg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/mwg-expected-by-module-item.html#mwg-pam_get_item
+    #[doc = _man7!(3 pam_get_authtok)]
+    #[doc = _manbsd!(3 pam_get_authtok)]
     fn authtok(&mut self, prompt: Option<&str>) -> Result<String>;
 
     trait_item!(