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 } |
