use pam::{PamConversation, PamHandle, PamFlag, PamReturnCode};
pub fn login(service: &str, user: &str, password: &str) -> bool {
use std::ptr;
let creds: [&str; 2] = [user, password];
let conv = PamConversation {
conv: Some(::ffi::converse),
data_ptr: creds.as_ptr() as *mut ::libc::c_void,
};
let mut handle: *mut PamHandle = ptr::null_mut();
let success = PamReturnCode::SUCCESS;
let mut res = ::pam::start(service, None, &conv, &mut handle);
if res != success {
return false;
}
let handle: &mut PamHandle = unsafe {&mut *handle };
res = ::pam::authenticate(handle, PamFlag::NONE);
if res != success {
return pam_fail(handle);
}
res = ::pam::acct_mgmt(handle, PamFlag::NONE);
if res != success {
return pam_fail(handle);
}
res = ::pam::setcred(handle, PamFlag::ESTABLISH_CRED);
if res != success {
return pam_fail(handle);
}
res = ::pam::open_session(handle, PamFlag::NONE);
if res != success {
return pam_fail(handle);
}
true
}
fn pam_fail(handle: &mut PamHandle) -> bool {
::pam::setcred(handle, PamFlag::DELETE_CRED);
::pam::end(handle, PamReturnCode::SUCCESS);
false
}