#include #include #include #include #include #include #include #include #include #include #define DLL_PUBLIC __attribute__((visibility("default"))) using namespace std; DLL_PUBLIC int pam_sm_setcred([[maybe_unused]] pam_handle_t * pamh, [[maybe_unused]] int flags, [[maybe_unused]] int argc, [[maybe_unused]] const char ** argv) { return PAM_SUCCESS; } DLL_PUBLIC int pam_sm_acct_mgmt([[maybe_unused]] pam_handle_t * pamh, [[maybe_unused]] int flags, [[maybe_unused]] int argc, [[maybe_unused]] const char ** argv) { return PAM_SUCCESS; } DLL_PUBLIC int pam_sm_authenticate(pam_handle_t * pamh, [[maybe_unused]] int flags, [[maybe_unused]] int argc, [[maybe_unused]] const char ** argv) { using namespace rublon; auto rublonConfig = ConfigurationFactory{}.systemConfig(); std::byte sharedMemory[32 * 1024] = {}; std::pmr::monotonic_buffer_resource mr{sharedMemory, std::size(sharedMemory)}; std::pmr::unsynchronized_pool_resource rublonPoolResource{&mr}; std::pmr::set_default_resource(&rublonPoolResource); CoreHandler CH{rublonConfig.value()}; LinuxPam pam{pamh}; auto selectMethod = [&](const MethodSelect & selector) { return selector.create(pam); }; auto confirmMethod = [&](const PostMethod & confirm) { return confirm.fire(CH); }; auto verifi = [&](const MethodProxy & method) { return method.fire(CH, pam); }; auto authStatus = Init{rublonConfig.value()} .fire(CH, pam) // .and_then(selectMethod) .and_then(confirmMethod) .and_then(verifi); if(authStatus.has_value()) { rublon::log(rublon::LogLevel::Info, "Auth OK"); return PAM_SUCCESS; } else { const auto & error = authStatus.error(); rublon::log( LogLevel::Error, "auth failed due to %d class and %d category", error.errorClass(), static_cast< int >(error.category())); } rublon::log(LogLevel::Warning, "User login failed"); return PAM_PERM_DENIED; }