pam_systemd_home: always close already opened bus connection in open_session()

Fixes #31375.
This commit is contained in:
Yu Watanabe
2024-02-21 13:22:54 +09:00
parent 0324e3d045
commit a6a6197e9d
3 changed files with 33 additions and 0 deletions
+6
View File
@@ -826,6 +826,12 @@ _public_ PAM_EXTERN int pam_sm_open_session(
if (r != PAM_SUCCESS)
return r;
/* Explicitly get saved PamBusData here. Otherwise, this function may succeed without setting 'd'
* even if there is an opened sd-bus connection, and it will be leaked. See issue #31375. */
r = pam_get_bus_data(handle, "pam-systemd-home", &d);
if (r != PAM_SUCCESS)
return r;
r = acquire_home(handle, flags, debug, &d);
if (r == PAM_USER_UNKNOWN) /* Not managed by us? Don't complain. */
return PAM_SUCCESS;
+26
View File
@@ -209,6 +209,32 @@ int pam_release_bus_connection(pam_handle_t *handle, const char *module_name) {
return PAM_SUCCESS;
}
int pam_get_bus_data(
pam_handle_t *handle,
const char *module_name,
PamBusData **ret) {
PamBusData *d = NULL;
_cleanup_free_ char *cache_id = NULL;
int r;
assert(handle);
assert(module_name);
assert(ret);
cache_id = pam_make_bus_cache_id(module_name);
if (!cache_id)
return pam_log_oom(handle);
/* We cache the bus connection so that we can share it between the session and the authentication hooks */
r = pam_get_data(handle, cache_id, (const void**) &d);
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get bus connection: @PAMERR@");
*ret = d;
return PAM_SUCCESS;
}
void pam_cleanup_free(pam_handle_t *handle, void *data, int error_status) {
/* A generic destructor for pam_set_data() that just frees the specified data */
free(data);
+1
View File
@@ -37,6 +37,7 @@ void pam_bus_data_disconnectp(PamBusData **d);
* helps avoid a clash in the internal data structures of sd-bus. It will be used as key for cache items. */
int pam_acquire_bus_connection(pam_handle_t *handle, const char *module_name, sd_bus **ret_bus, PamBusData **ret_bus_data);
int pam_release_bus_connection(pam_handle_t *handle, const char *module_name);
int pam_get_bus_data(pam_handle_t *handle, const char *module_name, PamBusData **ret);
void pam_cleanup_free(pam_handle_t *handle, void *data, int error_status);