comparison src/macros.rs @ 56:daa2cde64601

Big big refactor. Probably should have been multiple changes. - Makes FFI safer by explicitly specifying c_int in calls. - Uses ToPrimitive/FromPrimitive to make this easier. - Pulls PamFlag variables into a bitflags! struct. - Pulls PamMessageStyle variables into an enum. - Renames ResultCode to ErrorCode. - Switches from PAM_SUCCESS to using a Result<(), ErrorCode>. - Uses thiserror to make ErrorCode into an Error. - Gets rid of pam_try! because now we have Results. - Expands some names (e.g. Conv to Conversation). - Adds more doc comments. - Returns passwords as a SecureString, to avoid unnecessarily keeping it around in memory.
author Paul Fisher <paul@pfish.zone>
date Sun, 04 May 2025 02:56:55 -0400
parents a921b72743e4
children 3f4a77aa88be
comparison
equal deleted inserted replaced
55:676675c3d434 56:daa2cde64601
5 /// ## Examples: 5 /// ## Examples:
6 /// 6 ///
7 /// Here is full example of a PAM module that would authenticate and authorize everybody: 7 /// Here is full example of a PAM module that would authenticate and authorize everybody:
8 /// 8 ///
9 /// ``` 9 /// ```
10 /// #[macro_use] extern crate pam; 10 /// #[macro_use] extern crate nonstick;
11 /// 11 ///
12 /// use pam::module::{PamHooks, PamHandle}; 12 /// use nonstick::module::{PamHooks, PamHandle};
13 /// use pam::constants::{PamResultCode, PamFlag}; 13 /// use nonstick::constants::{PamResult, Flags};
14 /// use std::ffi::CStr; 14 /// use std::ffi::CStr;
15 /// 15 ///
16 /// # fn main() {} 16 /// # fn main() {}
17 /// struct MyPamModule; 17 /// struct MyPamModule;
18 /// pam_hooks!(MyPamModule); 18 /// pam_hooks!(MyPamModule);
19 /// 19 ///
20 /// impl PamHooks for MyPamModule { 20 /// impl PamHooks for MyPamModule {
21 /// fn sm_authenticate(pamh: &mut PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { 21 /// fn acct_mgmt(pamh: &mut PamHandle, args: Vec<&CStr>, flags: Flags) -> PamResult<()> {
22 /// println!("Everybody is authenticated!"); 22 /// println!("Everybody is authorized!");
23 /// PamResultCode::PAM_SUCCESS 23 /// Ok(())
24 /// } 24 /// }
25 /// 25 ///
26 /// fn acct_mgmt(pamh: &mut PamHandle, args: Vec<&CStr>, flags: PamFlag) -> PamResultCode { 26 /// fn sm_authenticate(pamh: &mut PamHandle, args: Vec<&CStr>, flags: Flags) -> PamResult<()> {
27 /// println!("Everybody is authorized!"); 27 /// println!("Everybody is authenticated!");
28 /// PamResultCode::PAM_SUCCESS 28 /// Ok(())
29 /// } 29 /// }
30 /// } 30 /// }
31 /// ``` 31 /// ```
32 #[macro_export] 32 #[macro_export]
33 macro_rules! pam_hooks { 33 macro_rules! pam_hooks {
34 ($ident:ident) => { 34 ($ident:ident) => {
35 pub use self::pam_hooks_scope::*; 35 pub use self::pam_hooks_scope::*;
36 mod pam_hooks_scope { 36 mod pam_hooks_scope {
37 use std::ffi::CStr; 37 use std::ffi::CStr;
38 use std::os::raw::{c_char, c_int}; 38 use std::os::raw::{c_char, c_int};
39 use $crate::constants::{PamFlag, PamResultCode}; 39 use $crate::constants::{Flags, ErrorCode};
40 use $crate::module::{PamHandle, PamHooks}; 40 use $crate::module::{PamHandle, PamHooks};
41 41
42 fn extract_argv<'a>(argc: c_int, argv: *const *const c_char) -> Vec<&'a CStr> { 42 fn extract_argv<'a>(argc: c_int, argv: *const *const c_char) -> Vec<&'a CStr> {
43 (0..argc) 43 (0..argc)
44 .map(|o| unsafe { CStr::from_ptr(*argv.offset(o as isize) as *const c_char) }) 44 .map(|o| unsafe { CStr::from_ptr(*argv.offset(o as isize) as *const c_char) })
46 } 46 }
47 47
48 #[no_mangle] 48 #[no_mangle]
49 pub extern "C" fn pam_sm_acct_mgmt( 49 pub extern "C" fn pam_sm_acct_mgmt(
50 pamh: &mut PamHandle, 50 pamh: &mut PamHandle,
51 flags: PamFlag, 51 flags: Flags,
52 argc: c_int, 52 argc: c_int,
53 argv: *const *const c_char, 53 argv: *const *const c_char,
54 ) -> PamResultCode { 54 ) -> c_int {
55 let args = extract_argv(argc, argv); 55 let args = extract_argv(argc, argv);
56 super::$ident::acct_mgmt(pamh, args, flags) 56 ErrorCode::result_to_c(super::$ident::acct_mgmt(pamh, args, flags))
57 } 57 }
58 58
59 #[no_mangle] 59 #[no_mangle]
60 pub extern "C" fn pam_sm_authenticate( 60 pub extern "C" fn pam_sm_authenticate(
61 pamh: &mut PamHandle, 61 pamh: &mut PamHandle,
62 flags: PamFlag, 62 flags: Flags,
63 argc: c_int, 63 argc: c_int,
64 argv: *const *const c_char, 64 argv: *const *const c_char,
65 ) -> PamResultCode { 65 ) -> c_int {
66 let args = extract_argv(argc, argv); 66 let args = extract_argv(argc, argv);
67 super::$ident::sm_authenticate(pamh, args, flags) 67 ErrorCode::result_to_c(super::$ident::sm_authenticate(pamh, args, flags))
68 } 68 }
69 69
70 #[no_mangle] 70 #[no_mangle]
71 pub extern "C" fn pam_sm_chauthtok( 71 pub extern "C" fn pam_sm_chauthtok(
72 pamh: &mut PamHandle, 72 pamh: &mut PamHandle,
73 flags: PamFlag, 73 flags: Flags,
74 argc: c_int, 74 argc: c_int,
75 argv: *const *const c_char, 75 argv: *const *const c_char,
76 ) -> PamResultCode { 76 ) -> c_int {
77 let args = extract_argv(argc, argv); 77 let args = extract_argv(argc, argv);
78 super::$ident::sm_chauthtok(pamh, args, flags) 78 ErrorCode::result_to_c(super::$ident::sm_chauthtok(pamh, args, flags))
79 } 79 }
80 80
81 #[no_mangle] 81 #[no_mangle]
82 pub extern "C" fn pam_sm_close_session( 82 pub extern "C" fn pam_sm_close_session(
83 pamh: &mut PamHandle, 83 pamh: &mut PamHandle,
84 flags: PamFlag, 84 flags: Flags,
85 argc: c_int, 85 argc: c_int,
86 argv: *const *const c_char, 86 argv: *const *const c_char,
87 ) -> PamResultCode { 87 ) -> c_int {
88 let args = extract_argv(argc, argv); 88 let args = extract_argv(argc, argv);
89 super::$ident::sm_close_session(pamh, args, flags) 89 ErrorCode::result_to_c(super::$ident::sm_close_session(pamh, args, flags))
90 } 90 }
91 91
92 #[no_mangle] 92 #[no_mangle]
93 pub extern "C" fn pam_sm_open_session( 93 pub extern "C" fn pam_sm_open_session(
94 pamh: &mut PamHandle, 94 pamh: &mut PamHandle,
95 flags: PamFlag, 95 flags: Flags,
96 argc: c_int, 96 argc: c_int,
97 argv: *const *const c_char, 97 argv: *const *const c_char,
98 ) -> PamResultCode { 98 ) -> c_int {
99 let args = extract_argv(argc, argv); 99 let args = extract_argv(argc, argv);
100 super::$ident::sm_open_session(pamh, args, flags) 100 ErrorCode::result_to_c(super::$ident::sm_open_session(pamh, args, flags))
101 } 101 }
102 102
103 #[no_mangle] 103 #[no_mangle]
104 pub extern "C" fn pam_sm_setcred( 104 pub extern "C" fn pam_sm_setcred(
105 pamh: &mut PamHandle, 105 pamh: &mut PamHandle,
106 flags: PamFlag, 106 flags: Flags,
107 argc: c_int, 107 argc: c_int,
108 argv: *const *const c_char, 108 argv: *const *const c_char,
109 ) -> PamResultCode { 109 ) -> c_int {
110 let args = extract_argv(argc, argv); 110 let args = extract_argv(argc, argv);
111 super::$ident::sm_setcred(pamh, args, flags) 111 ErrorCode::result_to_c(super::$ident::sm_setcred(pamh, args, flags))
112 } 112 }
113 }
114 };
115 }
116
117 #[macro_export]
118 macro_rules! pam_try {
119 ($r:expr) => {
120 match $r {
121 Ok(t) => t,
122 Err(e) => return e,
123 }
124 };
125 ($r:expr, $e:expr) => {
126 match $r {
127 Ok(t) => t,
128 Err(_) => return $e,
129 } 113 }
130 }; 114 };
131 } 115 }
132 116
133 #[cfg(test)] 117 #[cfg(test)]