Mercurial > crates > nonstick
comparison src/module.rs @ 8:a83c56216e21
Ran everything through rustfmt.
author | Marc Brinkmann <git@marcbrinkmann.de> |
---|---|
date | Sun, 26 Feb 2017 11:29:31 +0100 |
parents | 9380392b9a60 |
children | 74b53b921b23 |
comparison
equal
deleted
inserted
replaced
7:9380392b9a60 | 8:a83c56216e21 |
---|---|
1 //! Functions for use in pam modules. | 1 //! Functions for use in pam modules. |
2 | 2 |
3 use libc::{c_char}; | 3 use libc::c_char; |
4 use std::{mem, ptr}; | 4 use std::{mem, ptr}; |
5 use std::ffi::{CStr, CString}; | 5 use std::ffi::{CStr, CString}; |
6 use std::marker::{PhantomData}; | 6 use std::marker::PhantomData; |
7 | 7 |
8 use constants; | 8 use constants; |
9 use constants::*; | 9 use constants::*; |
10 | 10 |
11 /// Opaque type, used as a pointer when making pam API calls. | 11 /// Opaque type, used as a pointer when making pam API calls. |
21 | 21 |
22 #[allow(missing_copy_implementations)] | 22 #[allow(missing_copy_implementations)] |
23 pub enum PamDataT {} | 23 pub enum PamDataT {} |
24 | 24 |
25 #[link(name = "pam")] | 25 #[link(name = "pam")] |
26 extern { | 26 extern "C" { |
27 fn pam_get_data(pamh: *const PamHandleT, | 27 fn pam_get_data(pamh: *const PamHandleT, |
28 module_data_name: *const c_char, | 28 module_data_name: *const c_char, |
29 data: &mut *const PamDataT, | 29 data: &mut *const PamDataT) |
30 ) -> PamResultCode; | 30 -> PamResultCode; |
31 | 31 |
32 fn pam_set_data(pamh: *const PamHandleT, | 32 fn pam_set_data(pamh: *const PamHandleT, |
33 module_data_name: *const c_char, | 33 module_data_name: *const c_char, |
34 data: Box<PamDataT>, | 34 data: Box<PamDataT>, |
35 cleanup: extern fn (pamh: *const PamHandleT, | 35 cleanup: extern "C" fn(pamh: *const PamHandleT, |
36 data: Box<PamDataT>, | 36 data: Box<PamDataT>, |
37 error_status: PamResultCode | 37 error_status: PamResultCode)) |
38 ), | 38 -> PamResultCode; |
39 ) -> PamResultCode; | |
40 | 39 |
41 fn pam_get_item(pamh: *const PamHandleT, | 40 fn pam_get_item(pamh: *const PamHandleT, |
42 item_type: PamItemType, | 41 item_type: PamItemType, |
43 item: &mut *const PamItemT, | 42 item: &mut *const PamItemT) |
44 ) -> PamResultCode; | 43 -> PamResultCode; |
45 | 44 |
46 fn pam_set_item(pamh: *mut PamHandleT, | 45 fn pam_set_item(pamh: *mut PamHandleT, |
47 item_type: PamItemType, | 46 item_type: PamItemType, |
48 item: &PamItemT, | 47 item: &PamItemT) |
49 ) -> PamResultCode; | 48 -> PamResultCode; |
50 | 49 |
51 fn pam_get_user(pamh: *const PamHandleT, | 50 fn pam_get_user(pamh: *const PamHandleT, |
52 user: & *mut c_char, | 51 user: &*mut c_char, |
53 prompt: *const c_char, | 52 prompt: *const c_char) |
54 ) -> PamResultCode; | 53 -> PamResultCode; |
55 } | 54 } |
56 | 55 |
57 pub type PamResult<T> = Result<T, PamResultCode>; | 56 pub type PamResult<T> = Result<T, PamResultCode>; |
58 | 57 |
59 /// Type-level mapping for safely retrieving values with `get_item`. | 58 /// Type-level mapping for safely retrieving values with `get_item`. |
81 let res = pam_get_data(pamh, c_key, &mut ptr); | 80 let res = pam_get_data(pamh, c_key, &mut ptr); |
82 if constants::PAM_SUCCESS == res && !ptr.is_null() { | 81 if constants::PAM_SUCCESS == res && !ptr.is_null() { |
83 let typed_ptr: *const T = mem::transmute(ptr); | 82 let typed_ptr: *const T = mem::transmute(ptr); |
84 let data: &T = &*typed_ptr; | 83 let data: &T = &*typed_ptr; |
85 Ok(data) | 84 Ok(data) |
86 } | 85 } else { |
87 else { | |
88 Err(res) | 86 Err(res) |
89 } | 87 } |
90 } | 88 } |
91 | 89 |
92 /// Stores a value that can be retrieved later with `get_data`. The value lives | 90 /// Stores a value that can be retrieved later with `get_data`. The value lives |
98 let c_key = CString::new(key).unwrap().as_ptr(); | 96 let c_key = CString::new(key).unwrap().as_ptr(); |
99 let res = unsafe { | 97 let res = unsafe { |
100 let c_data: Box<PamDataT> = mem::transmute(data); | 98 let c_data: Box<PamDataT> = mem::transmute(data); |
101 pam_set_data(pamh, c_key, c_data, cleanup::<T>) | 99 pam_set_data(pamh, c_key, c_data, cleanup::<T>) |
102 }; | 100 }; |
103 if constants::PAM_SUCCESS == res { Ok(()) } else { Err(res) } | 101 if constants::PAM_SUCCESS == res { |
102 Ok(()) | |
103 } else { | |
104 Err(res) | |
105 } | |
104 } | 106 } |
105 | 107 |
106 #[no_mangle] | 108 #[no_mangle] |
107 pub extern fn cleanup<T>(_: *const PamHandleT, c_data: Box<PamDataT>, _: PamResultCode) { | 109 pub extern "C" fn cleanup<T>(_: *const PamHandleT, c_data: Box<PamDataT>, _: PamResultCode) { |
108 unsafe { | 110 unsafe { |
109 let data: Box<T> = mem::transmute(c_data); | 111 let data: Box<T> = mem::transmute(c_data); |
110 mem::drop(data); | 112 mem::drop(data); |
111 } | 113 } |
112 } | 114 } |
122 let r = pam_get_item(pamh, PamItem::item_type(PhantomData::<T>), &mut ptr); | 124 let r = pam_get_item(pamh, PamItem::item_type(PhantomData::<T>), &mut ptr); |
123 let typed_ptr: *const T = mem::transmute(ptr); | 125 let typed_ptr: *const T = mem::transmute(ptr); |
124 let t: &T = &*typed_ptr; | 126 let t: &T = &*typed_ptr; |
125 (r, t) | 127 (r, t) |
126 }; | 128 }; |
127 if constants::PAM_SUCCESS == res { Ok(item) } else { Err(res) } | 129 if constants::PAM_SUCCESS == res { |
130 Ok(item) | |
131 } else { | |
132 Err(res) | |
133 } | |
128 } | 134 } |
129 | 135 |
130 /// Retrieves the name of the user who is authenticating or logging in. | 136 /// Retrieves the name of the user who is authenticating or logging in. |
131 /// | 137 /// |
132 /// This is really a specialization of `get_item`. | 138 /// This is really a specialization of `get_item`. |
135 /// http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html | 141 /// http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html |
136 pub fn get_user<'a>(pamh: &'a PamHandleT, prompt: Option<&str>) -> PamResult<String> { | 142 pub fn get_user<'a>(pamh: &'a PamHandleT, prompt: Option<&str>) -> PamResult<String> { |
137 let ptr: *mut c_char = ptr::null_mut(); | 143 let ptr: *mut c_char = ptr::null_mut(); |
138 let c_prompt = match prompt { | 144 let c_prompt = match prompt { |
139 Some(p) => CString::new(p).unwrap().as_ptr(), | 145 Some(p) => CString::new(p).unwrap().as_ptr(), |
140 None => ptr::null(), | 146 None => ptr::null(), |
141 }; | 147 }; |
142 let res = unsafe { pam_get_user(pamh, &ptr, c_prompt) }; | 148 let res = unsafe { pam_get_user(pamh, &ptr, c_prompt) }; |
143 if constants::PAM_SUCCESS == res && !ptr.is_null() { | 149 if constants::PAM_SUCCESS == res && !ptr.is_null() { |
144 let const_ptr = ptr as *const c_char; | 150 let const_ptr = ptr as *const c_char; |
145 let bytes = unsafe { CStr::from_ptr(const_ptr).to_bytes() }; | 151 let bytes = unsafe { CStr::from_ptr(const_ptr).to_bytes() }; |
146 String::from_utf8(bytes.to_vec()) | 152 String::from_utf8(bytes.to_vec()).map_err(|_| PAM_CONV_ERR) |
147 .map_err(|_| PAM_CONV_ERR) | 153 } else { |
148 } | |
149 else { | |
150 Err(res) | 154 Err(res) |
151 } | 155 } |
152 } | 156 } |