diff --git a/pam-module/src/pam_module.cpp b/pam-module/src/pam_module.cpp index 00ff1bb..75e5622 100644 --- a/pam-module/src/pam_module.cpp +++ b/pam-module/src/pam_module.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include "rust_backend_ffi.h" #include "auth_client.h" @@ -19,10 +20,20 @@ int pam_sm_authenticate(pam_handle_t* pamh, int flags, int argc, const char** ar const char* user = nullptr; - pam_get_user(pamh, &user, NULL); - const void* pw_ptr = nullptr; - int item_result = pam_get_item(pamh, PAM_AUTHTOK, &pw_ptr); - const char* password = (item_result == PAM_SUCCESS && pw_ptr) ? static_cast(pw_ptr) : nullptr; + int rc = pam_get_user(pamh, &user, nullptr); + if (rc != PAM_SUCCESS || user == nullptr) { + RUST_CERR() << "Failed to get username: " << pam_strerror(pamh, rc) << std::flush; + return PAM_AUTH_ERR; + } + + const char* password = nullptr; + rc = pam_get_authtok(pamh, PAM_AUTHTOK, &password, nullptr); + if (rc != PAM_SUCCESS || password == nullptr) { + RUST_CERR() << "Failed to get password: " << pam_strerror(pamh, rc) << std::flush; + return PAM_AUTH_ERR; + } + RUST_CDEBUG() << "Extracted credentials: user='" << (user ? user : "(null)") << "' password='" << (password ? "(redacted)" : "(null)") << "'" << std::flush; + int result = auth_client_authenticate(user, password); return result; } catch (...) { diff --git a/rust-backend/src/lib.rs b/rust-backend/src/lib.rs index b2be75e..8885791 100644 --- a/rust-backend/src/lib.rs +++ b/rust-backend/src/lib.rs @@ -9,6 +9,20 @@ use std::os::raw::c_char; use std::panic::{catch_unwind, AssertUnwindSafe}; use std::env; +// Formatting macros for crate-local logging. +// Define these in the crate root so any module can invoke them as `crate::log!(...)`. +macro_rules! pam_log_with_level { + ($level:expr, $($arg:tt)+) => { + crate::logging::log_event_with_level($level, &format!($($arg)+)); + }; +} + +macro_rules! pam_log { + ($($arg:tt)+) => { + crate::logging::log_event_with_level(crate::logging::LogLevel::Info, &format!($($arg)+)); + }; +} + mod auth; mod logging; mod error; @@ -42,7 +56,7 @@ pub extern "C" fn rust_log_event(event: *const c_char) { CStr::from_ptr(event).to_str().unwrap_or("") }; // Legacy wrapper: default to INFO - logging::log_event_with_level(logging::LogLevel::Info, msg); + pam_log_with_level!(logging::LogLevel::Info, "{}", msg); })); } @@ -56,25 +70,29 @@ pub extern "C" fn rust_log_event_with_level(event: *const c_char, level: i32) { CStr::from_ptr(event).to_str().unwrap_or("") }; let lvl = logging::LogLevel::from(level); - logging::log_event_with_level(lvl, msg); + pam_log_with_level!(lvl, "{}", msg); })); } #[no_mangle] pub extern "C" fn rust_auth_user(user: *const c_char, password: *const c_char) -> i32 { catch_unwind(AssertUnwindSafe(|| { + let u = unsafe { if user.is_null() { + pam_log_with_level!(logging::LogLevel::Error, "Null pointer for username"); // Log error return error::ERR_INVALID_INPUT; } CStr::from_ptr(user).to_str().unwrap_or("") }; let p = unsafe { if password.is_null() { + pam_log_with_level!(logging::LogLevel::Error, "Null pointer for password"); // Log error return error::ERR_INVALID_INPUT; } CStr::from_ptr(password).to_str().unwrap_or("") }; + match auth::authenticate(u, p) { Ok(_) => error::SUCCESS, Err(_) => error::ERR_AUTH_FAILED,