Mercurial > crates > nonstick
comparison src/constants.rs @ 84:a638a45e5f1f
do some real irritating i32/u32 juggling to make bindgen happy
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Tue, 10 Jun 2025 02:35:11 -0400 |
| parents | 5aa1a010f1e8 |
| children | 5e14bb093851 |
comparison
equal
deleted
inserted
replaced
| 83:9fc778c03bff | 84:a638a45e5f1f |
|---|---|
| 3 #[cfg(feature = "link")] | 3 #[cfg(feature = "link")] |
| 4 use crate::libpam::pam_ffi; | 4 use crate::libpam::pam_ffi; |
| 5 use bitflags::bitflags; | 5 use bitflags::bitflags; |
| 6 use libc::c_int; | 6 use libc::c_int; |
| 7 use num_enum::{IntoPrimitive, TryFromPrimitive}; | 7 use num_enum::{IntoPrimitive, TryFromPrimitive}; |
| 8 use std::ffi::c_uint; | |
| 8 use std::result::Result as StdResult; | 9 use std::result::Result as StdResult; |
| 9 | 10 |
| 10 /// Arbitrary values for PAM constants when not linking against system PAM. | 11 /// Arbitrary values for PAM constants when not linking against system PAM. |
| 11 /// | 12 /// |
| 12 /// **The values of these constants are deliberately selected _not_ to match | 13 /// **The values of these constants are deliberately selected _not_ to match |
| 16 mod ffi { | 17 mod ffi { |
| 17 macro_rules! define { | 18 macro_rules! define { |
| 18 ($(#[$attr:meta])* $($name:ident = $value:expr),+) => { | 19 ($(#[$attr:meta])* $($name:ident = $value:expr),+) => { |
| 19 define!( | 20 define!( |
| 20 @meta { $(#[$attr])* } | 21 @meta { $(#[$attr])* } |
| 21 $(pub const $name: i32 = $value;)+ | 22 $(pub const $name: u32 = $value;)+ |
| 22 ); | 23 ); |
| 23 }; | 24 }; |
| 24 (@meta $m:tt $($i:item)+) => { define!(@expand $($m $i)+); }; | 25 (@meta $m:tt $($i:item)+) => { define!(@expand $($m $i)+); }; |
| 25 (@expand $({ $(#[$m:meta])* } $i:item)+) => {$($(#[$m])* $i)+}; | 26 (@expand $({ $(#[$m:meta])* } $i:item)+) => {$($(#[$m])* $i)+}; |
| 26 } | 27 } |
| 27 const fn bit(n: i8) -> i32 { | 28 const fn bit(n: u8) -> u32 { |
| 28 1 << n | 29 1 << n |
| 29 } | 30 } |
| 30 define!( | 31 define!( |
| 31 PAM_SILENT = bit(13), | 32 PAM_SILENT = bit(13), |
| 32 PAM_DISALLOW_NULL_AUTHTOK = bit(14), | 33 PAM_DISALLOW_NULL_AUTHTOK = bit(14), |
| 79 /// | 80 /// |
| 80 /// See `/usr/include/security/_pam_types.h` and | 81 /// See `/usr/include/security/_pam_types.h` and |
| 81 /// See `/usr/include/security/pam_modules.h` for more details. | 82 /// See `/usr/include/security/pam_modules.h` for more details. |
| 82 #[derive(Debug, PartialEq)] | 83 #[derive(Debug, PartialEq)] |
| 83 #[repr(transparent)] | 84 #[repr(transparent)] |
| 84 pub struct Flags: c_int { | 85 pub struct Flags: c_uint { |
| 85 /// The module should not generate any messages. | 86 /// The module should not generate any messages. |
| 86 const SILENT = pam_ffi::PAM_SILENT; | 87 const SILENT = pam_ffi::PAM_SILENT; |
| 87 | 88 |
| 88 /// The module should return [ErrorCode::AuthError] | 89 /// The module should return [ErrorCode::AuthError] |
| 89 /// if the user has an empty authentication token | 90 /// if the user has an empty authentication token |
| 136 /// For more detailed information, see | 137 /// For more detailed information, see |
| 137 /// `/usr/include/security/_pam_types.h`. | 138 /// `/usr/include/security/_pam_types.h`. |
| 138 #[allow(non_camel_case_types, dead_code)] | 139 #[allow(non_camel_case_types, dead_code)] |
| 139 #[derive(Copy, Clone, Debug, PartialEq, thiserror::Error, TryFromPrimitive, IntoPrimitive)] | 140 #[derive(Copy, Clone, Debug, PartialEq, thiserror::Error, TryFromPrimitive, IntoPrimitive)] |
| 140 #[non_exhaustive] // C might give us anything! | 141 #[non_exhaustive] // C might give us anything! |
| 141 #[repr(i32)] | 142 #[repr(u32)] |
| 142 pub enum ErrorCode { | 143 pub enum ErrorCode { |
| 143 #[error("dlopen() failure when dynamically loading a service module")] | 144 #[error("dlopen() failure when dynamically loading a service module")] |
| 144 OpenError = pam_ffi::PAM_OPEN_ERR, | 145 OpenError = pam_ffi::PAM_OPEN_ERR, |
| 145 #[error("symbol not found")] | 146 #[error("symbol not found")] |
| 146 SymbolError = pam_ffi::PAM_SYMBOL_ERR, | 147 SymbolError = pam_ffi::PAM_SYMBOL_ERR, |
| 210 impl ErrorCode { | 211 impl ErrorCode { |
| 211 /// Converts this [Result] into a C-compatible result code. | 212 /// Converts this [Result] into a C-compatible result code. |
| 212 pub fn result_to_c<T>(value: Result<T>) -> c_int { | 213 pub fn result_to_c<T>(value: Result<T>) -> c_int { |
| 213 match value { | 214 match value { |
| 214 Ok(_) => 0, // PAM_SUCCESS | 215 Ok(_) => 0, // PAM_SUCCESS |
| 215 Err(otherwise) => otherwise.into(), | 216 Err(otherwise) => u32::from(otherwise) as i32, |
| 216 } | 217 } |
| 217 } | 218 } |
| 218 | 219 |
| 219 /// Converts a C result code into a [Result], with success as Ok. | 220 /// Converts a C result code into a [Result], with success as Ok. |
| 220 /// Invalid values are returned as a [Self::SystemError]. | 221 /// Invalid values are returned as a [Self::SystemError]. |
| 221 pub fn result_from(value: c_int) -> Result<()> { | 222 pub fn result_from(value: c_int) -> Result<()> { |
| 222 match value { | 223 match value { |
| 223 0 => Ok(()), | 224 0 => Ok(()), |
| 224 value => Err(value.try_into().unwrap_or(Self::SystemError)), | 225 value => Err((value as u32).try_into().unwrap_or(Self::SystemError)), |
| 225 } | 226 } |
| 226 } | 227 } |
| 227 } | 228 } |
| 228 | 229 |
| 229 /// Returned when text that should not have any `\0` bytes in it does. | 230 /// Returned when text that should not have any `\0` bytes in it does. |
| 235 | 236 |
| 236 #[test] | 237 #[test] |
| 237 fn test_enums() { | 238 fn test_enums() { |
| 238 assert_eq!(Ok(()), ErrorCode::result_from(0)); | 239 assert_eq!(Ok(()), ErrorCode::result_from(0)); |
| 239 assert_eq!( | 240 assert_eq!( |
| 240 pam_ffi::PAM_BAD_ITEM, | 241 pam_ffi::PAM_BAD_ITEM as i32, |
| 241 ErrorCode::result_to_c::<()>(Err(ErrorCode::BadItem)) | 242 ErrorCode::result_to_c::<()>(Err(ErrorCode::BadItem)) |
| 242 ); | 243 ); |
| 243 assert_eq!( | 244 assert_eq!( |
| 244 Err(ErrorCode::Abort), | 245 Err(ErrorCode::Abort), |
| 245 ErrorCode::result_from(pam_ffi::PAM_ABORT) | 246 ErrorCode::result_from(pam_ffi::PAM_ABORT as i32) |
| 246 ); | 247 ); |
| 247 assert_eq!(Err(ErrorCode::SystemError), ErrorCode::result_from(423)); | 248 assert_eq!(Err(ErrorCode::SystemError), ErrorCode::result_from(423)); |
| 248 } | 249 } |
| 249 } | 250 } |
