comparison src/module.rs @ 14:51b097c12d3c

make PamResultCode an enum
author Anthony Nowell <anthony@algorithmia.com>
date Sat, 23 Sep 2017 14:30:18 -0600
parents cc39d168aeb8
children
comparison
equal deleted inserted replaced
13:cc39d168aeb8 14:51b097c12d3c
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 6
7 use constants; 7 use constants::{PamResultCode, PamItemType};
8 use constants::*;
9 8
10 /// Opaque type, used as a pointer when making pam API calls. 9 /// Opaque type, used as a pointer when making pam API calls.
11 /// 10 ///
12 /// A module is invoked via an external function such as `pam_sm_authenticate`. 11 /// A module is invoked via an external function such as `pam_sm_authenticate`.
13 /// Such a call provides a pam handle pointer. The same pointer should be given 12 /// Such a call provides a pam handle pointer. The same pointer should be given
75 /// http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html 74 /// http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html
76 pub unsafe fn get_data<'a, T>(pamh: &'a PamHandleT, key: &str) -> PamResult<&'a T> { 75 pub unsafe fn get_data<'a, T>(pamh: &'a PamHandleT, key: &str) -> PamResult<&'a T> {
77 let c_key = CString::new(key).unwrap().as_ptr(); 76 let c_key = CString::new(key).unwrap().as_ptr();
78 let mut ptr: *const PamDataT = ptr::null(); 77 let mut ptr: *const PamDataT = ptr::null();
79 let res = pam_get_data(pamh, c_key, &mut ptr); 78 let res = pam_get_data(pamh, c_key, &mut ptr);
80 if constants::PAM_SUCCESS == res && !ptr.is_null() { 79 if PamResultCode::PAM_SUCCESS == res && !ptr.is_null() {
81 let typed_ptr: *const T = mem::transmute(ptr); 80 let typed_ptr: *const T = mem::transmute(ptr);
82 let data: &T = &*typed_ptr; 81 let data: &T = &*typed_ptr;
83 Ok(data) 82 Ok(data)
84 } else { 83 } else {
85 Err(res) 84 Err(res)
95 let c_key = CString::new(key).unwrap().as_ptr(); 94 let c_key = CString::new(key).unwrap().as_ptr();
96 let res = unsafe { 95 let res = unsafe {
97 let c_data: Box<PamDataT> = mem::transmute(data); 96 let c_data: Box<PamDataT> = mem::transmute(data);
98 pam_set_data(pamh, c_key, c_data, cleanup::<T>) 97 pam_set_data(pamh, c_key, c_data, cleanup::<T>)
99 }; 98 };
100 if constants::PAM_SUCCESS == res { 99 if PamResultCode::PAM_SUCCESS == res {
101 Ok(()) 100 Ok(())
102 } else { 101 } else {
103 Err(res) 102 Err(res)
104 } 103 }
105 } 104 }
123 let r = pam_get_item(pamh, T::item_type(), &mut ptr); 122 let r = pam_get_item(pamh, T::item_type(), &mut ptr);
124 let typed_ptr: *const T = mem::transmute(ptr); 123 let typed_ptr: *const T = mem::transmute(ptr);
125 let t: &T = &*typed_ptr; 124 let t: &T = &*typed_ptr;
126 (r, t) 125 (r, t)
127 }; 126 };
128 if constants::PAM_SUCCESS == res { 127 if PamResultCode::PAM_SUCCESS == res {
129 Ok(item) 128 Ok(item)
130 } else { 129 } else {
131 Err(res) 130 Err(res)
132 } 131 }
133 } 132 }
148 147
149 // unwrapping is okay here, as c_item will not be a NULL 148 // unwrapping is okay here, as c_item will not be a NULL
150 // pointer 149 // pointer
151 (c_item as *const PamItemT).as_ref().unwrap()) 150 (c_item as *const PamItemT).as_ref().unwrap())
152 }; 151 };
153 if constants::PAM_SUCCESS == res { 152 if PamResultCode::PAM_SUCCESS == res {
154 Ok(()) 153 Ok(())
155 } else { 154 } else {
156 Err(res) 155 Err(res)
157 } 156 }
158 } 157 }
168 let c_prompt = match prompt { 167 let c_prompt = match prompt {
169 Some(p) => CString::new(p).unwrap().as_ptr(), 168 Some(p) => CString::new(p).unwrap().as_ptr(),
170 None => ptr::null(), 169 None => ptr::null(),
171 }; 170 };
172 let res = unsafe { pam_get_user(pamh, &ptr, c_prompt) }; 171 let res = unsafe { pam_get_user(pamh, &ptr, c_prompt) };
173 if constants::PAM_SUCCESS == res && !ptr.is_null() { 172 if PamResultCode::PAM_SUCCESS == res && !ptr.is_null() {
174 let const_ptr = ptr as *const c_char; 173 let const_ptr = ptr as *const c_char;
175 let bytes = unsafe { CStr::from_ptr(const_ptr).to_bytes() }; 174 let bytes = unsafe { CStr::from_ptr(const_ptr).to_bytes() };
176 String::from_utf8(bytes.to_vec()).map_err(|_| PAM_CONV_ERR) 175 String::from_utf8(bytes.to_vec()).map_err(|_| PamResultCode::PAM_CONV_ERR)
177 } else { 176 } else {
178 Err(res) 177 Err(res)
179 } 178 }
180 } 179 }