comparison pam/src/hooks.rs @ 20:734ca62159fb

Refactor exported endpoings into pam_hooks macro
author Anthony Nowell <anthony@algorithmia.com>
date Tue, 26 Sep 2017 01:51:39 -0600
parents
children aa7e8bd083ef
comparison
equal deleted inserted replaced
19:d654aa0655e5 20:734ca62159fb
1 use module::{PamHandle};
2 use constants::{PamFlag, PamResultCode};
3 use std::ffi::CStr;
4
5 /// Provides functions that are invoked by the entrypoints generated by the `pam_hooks!` macro.
6 ///
7 /// All of hooks are ignored by PAM dispatch by default given the default return value of `PAM_IGNORE`.
8 /// Override any functions that you want to handle with your module. See `man pam(3)`.
9 pub trait PamHooks {
10 /// This function performs the task of establishing whether the user is permitted to gain access at
11 /// this time. It should be understood that the user has previously been validated by an
12 /// authentication module. This function checks for other things. Such things might be: the time of
13 /// day or the date, the terminal line, remote hostname, etc. This function may also determine
14 /// things like the expiration on passwords, and respond that the user change it before continuing.
15 fn acct_mgmt(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode {
16 PamResultCode::PAM_IGNORE
17 }
18
19 /// This function performs the task of authenticating the user.
20 fn sm_authenticate(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode {
21 PamResultCode::PAM_IGNORE
22 }
23
24 /// This function is used to (re-)set the authentication token of the user.
25 ///
26 /// The PAM library calls this function twice in succession. The first time with
27 /// PAM_PRELIM_CHECK and then, if the module does not return PAM_TRY_AGAIN, subsequently with
28 /// PAM_UPDATE_AUTHTOK. It is only on the second call that the authorization token is
29 /// (possibly) changed.
30 fn sm_chauthtok(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode {
31 PamResultCode::PAM_IGNORE
32 }
33
34 /// This function is called to terminate a session.
35 fn sm_close_session(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode {
36 PamResultCode::PAM_IGNORE
37 }
38
39 /// This function is called to commence a session.
40 fn sm_open_session(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode {
41 PamResultCode::PAM_IGNORE
42 }
43
44 /// This function performs the task of altering the credentials of the user with respect to the
45 /// corresponding authorization scheme. Generally, an authentication module may have access to more
46 /// information about a user than their authentication token. This function is used to make such
47 /// information available to the application. It should only be called after the user has been
48 /// authenticated but before a session has been established.
49 fn sm_setcred(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode {
50 PamResultCode::PAM_IGNORE
51 }
52 }
53
54 /// Macro to generate the `extern "C"` entrypoint bindings needed by PAM
55 ///
56 /// You can call `pam_hooks!(SomeType);` for any type that implements `PamHooks`
57 #[macro_export]
58 macro_rules! pam_hooks {
59 ($ident:ident) => (
60 pub use pam_hooks_scope::*;
61 mod pam_hooks_scope {
62 use $crate::module::PamHandle;
63 use $crate::constants::{PamFlag, PamResultCode};
64 use $crate::hooks::PamHooks;
65 use std::ffi::CStr;
66 use std::os::raw::{c_char, c_int};
67
68 fn extract_argv<'a>(argc: c_int, argv: *const *const c_char) -> Vec<&'a CStr> {
69 (0..argc)
70 .map(|o| unsafe {
71 CStr::from_ptr(*argv.offset(o as isize) as *const c_char)
72 })
73 .collect()
74 }
75
76 #[no_mangle]
77 pub extern "C" fn pam_sm_acct_mgmt(
78 pamh: &PamHandle,
79 flags: PamFlag,
80 argc: c_int,
81 argv: *const *const c_char,
82 ) -> PamResultCode {
83 let args = extract_argv(argc, argv);
84 super::$ident::acct_mgmt(pamh, args, flags)
85 }
86
87 #[no_mangle]
88 pub extern "C" fn pam_sm_authenticate(
89 pamh: &PamHandle,
90 flags: PamFlag,
91 argc: c_int,
92 argv: *const *const c_char,
93 ) -> PamResultCode {
94 let args = extract_argv(argc, argv);
95 super::$ident::sm_authenticate(pamh, args, flags)
96 }
97
98 #[no_mangle]
99 pub extern "C" fn pam_sm_chauthtok(
100 pamh: &PamHandle,
101 flags: PamFlag,
102 argc: c_int,
103 argv: *const *const c_char,
104 ) -> PamResultCode {
105 let args = extract_argv(argc, argv);
106 super::$ident::sm_chauthtok(pamh, args, flags)
107 }
108
109 #[no_mangle]
110 pub extern "C" fn pam_sm_close_session(
111 pamh: &PamHandle,
112 flags: PamFlag,
113 argc: c_int,
114 argv: *const *const c_char,
115 ) -> PamResultCode {
116 let args = extract_argv(argc, argv);
117 super::$ident::sm_close_session(pamh, args, flags)
118 }
119
120 #[no_mangle]
121 pub extern "C" fn pam_sm_open_session(
122 pamh: &PamHandle,
123 flags: PamFlag,
124 argc: c_int,
125 argv: *const *const c_char,
126 ) -> PamResultCode {
127 let args = extract_argv(argc, argv);
128 super::$ident::sm_open_session(pamh, args, flags)
129 }
130
131 #[no_mangle]
132 pub extern "C" fn pam_sm_setcred(
133 pamh: &PamHandle,
134 flags: PamFlag,
135 argc: c_int,
136 argv: *const *const c_char,
137 ) -> PamResultCode {
138 let args = extract_argv(argc, argv);
139 super::$ident::sm_setcred(pamh, args, flags)
140 }
141 }
142 )
143 }
144
145 #[cfg(test)]
146 pub mod test {
147 use super::PamHooks;
148
149 struct Foo;
150 impl PamHooks for Foo {}
151
152 pam_hooks!(Foo);
153 }