mirror of
https://github.com/hyprwm/hyprlock.git
synced 2026-03-24 23:10:34 +01:00
pam: get username once (#974)
* pam: fix username race by using getpwuid_r instead of getpwuid
getpwuid() returns a pointer into a static buffer shared across all
threads. Any getpw*/getpwent call from another thread — including
those made internally by PAM modules during authentication — will
overwrite it before pam_start() reads pw_name, causing hyprlock to
authenticate as a random system user (root, bin, systemd-network)
or fail with 'user unknown'.
Replace with getpwuid_r(), which writes into a caller-supplied buffer,
and copy pw_name into a std::string before calling pam_start().
* pam: get username once
Instead of retrieving the username via getpwuid_r as in a69f526c95,
get the username once when initializing CPam and save it in a string.
This should be sufficent for making sure there are no problems with the
static buffer returned by getpwuid and is simpler.
* misc: clang-format
---------
Co-authored-by: mcgi5sr2 <mcgi5sr2@gmail.com>
This commit is contained in:
parent
d7079a1248
commit
768ade88a8
5 changed files with 35 additions and 16 deletions
|
|
@ -1,11 +1,11 @@
|
|||
#include "Pam.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../core/hyprlock.hpp"
|
||||
#include "../helpers/Log.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <security/pam_appl.h>
|
||||
#if __has_include(<security/pam_misc.h>)
|
||||
#include <security/pam_misc.h>
|
||||
|
|
@ -69,6 +69,8 @@ CPam::CPam() {
|
|||
m_sPamModule = "su";
|
||||
}
|
||||
|
||||
m_username = getUsernameForCurrentUid();
|
||||
|
||||
m_sConversationState.waitForInput = [this]() { this->waitForInput(); };
|
||||
}
|
||||
|
||||
|
|
@ -106,12 +108,15 @@ void CPam::init() {
|
|||
}
|
||||
|
||||
bool CPam::auth() {
|
||||
const pam_conv localConv = {.conv = conv, .appdata_ptr = (void*)&m_sConversationState};
|
||||
pam_handle_t* handle = nullptr;
|
||||
auto uidPassword = getpwuid(getuid());
|
||||
RASSERT(uidPassword && uidPassword->pw_name, "Failed to get username (getpwuid)");
|
||||
const pam_conv localConv = {.conv = conv, .appdata_ptr = (void*)&m_sConversationState};
|
||||
pam_handle_t* handle = nullptr;
|
||||
|
||||
int ret = pam_start(m_sPamModule.c_str(), uidPassword->pw_name, &localConv, &handle);
|
||||
if (m_username.empty()) {
|
||||
m_sConversationState.failText = "Username not set";
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret = pam_start(m_sPamModule.c_str(), m_username.c_str(), &localConv, &handle);
|
||||
|
||||
if (ret != PAM_SUCCESS) {
|
||||
m_sConversationState.failText = "pam_start failed";
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ class CPam : public IAuthImplementation {
|
|||
|
||||
bool m_bBlockInput = true;
|
||||
|
||||
std::string m_sPamModule;
|
||||
std::string m_sPamModule = "";
|
||||
std::string m_username = "";
|
||||
|
||||
bool auth();
|
||||
void resetConversation();
|
||||
|
|
|
|||
|
|
@ -369,11 +369,10 @@ std::vector<CConfigManager::SWidgetConfig> CConfigManager::getWidgetConfigs() {
|
|||
|
||||
#define SHADOWABLE(name) \
|
||||
{"shadow_size", m_config.getSpecialConfigValue(name, "shadow_size", k.c_str())}, {"shadow_passes", m_config.getSpecialConfigValue(name, "shadow_passes", k.c_str())}, \
|
||||
{"shadow_color", m_config.getSpecialConfigValue(name, "shadow_color", k.c_str())}, { \
|
||||
"shadow_boost", m_config.getSpecialConfigValue(name, "shadow_boost", k.c_str()) \
|
||||
}
|
||||
{"shadow_color", m_config.getSpecialConfigValue(name, "shadow_color", k.c_str())}, {"shadow_boost", m_config.getSpecialConfigValue(name, "shadow_boost", k.c_str())}
|
||||
|
||||
#define CLICKABLE(name) {"onclick", m_config.getSpecialConfigValue(name, "onclick", k.c_str())}
|
||||
#define CLICKABLE(name) \
|
||||
{ "onclick", m_config.getSpecialConfigValue(name, "onclick", k.c_str()) }
|
||||
|
||||
//
|
||||
auto keys = m_config.listKeysForSpecialCategory("background");
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
#include <filesystem>
|
||||
#include "MiscFunctions.hpp"
|
||||
#include "Log.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <fcntl.h>
|
||||
#include "MiscFunctions.hpp"
|
||||
#include "Log.hpp"
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <filesystem>
|
||||
#include <hyprutils/os/Process.hpp>
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace Hyprutils::String;
|
||||
|
|
@ -158,3 +160,14 @@ void spawnAsync(const std::string& cmd) {
|
|||
if (!proc.runAsync())
|
||||
Debug::log(ERR, "Failed to start \"{}\"", cmd);
|
||||
}
|
||||
|
||||
std::string getUsernameForCurrentUid() {
|
||||
const uid_t UID = getuid();
|
||||
auto uidPassword = getpwuid(UID);
|
||||
if (!uidPassword || !uidPassword->pw_name) {
|
||||
Debug::log(ERR, "Failed to get username for uid {} (getpwuid)", UID);
|
||||
return "";
|
||||
}
|
||||
|
||||
return std::string{uidPassword->pw_name};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,3 +9,4 @@ int64_t configStringToInt(const std::string& VALUE);
|
|||
int createPoolFile(size_t size, std::string& name);
|
||||
std::string spawnSync(const std::string& cmd);
|
||||
void spawnAsync(const std::string& cmd);
|
||||
std::string getUsernameForCurrentUid();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue