tree-wide: dlopen libpam in pam plugins
Same reasoning as for cryptsetup tokens. It means we can include the pam plugins in the main systemd package without the package manager introducing a dependency on libpam. It also makes things more consistent and makes writing the upcoming linking test script a lot simpler. At the same time, we get rid of the libpam_misc dependency as the one symbol we were using from it is trivial to reimplement ourselves.
This commit is contained in:
+2
-21
@@ -1133,12 +1133,7 @@ if not libpam.found()
|
||||
# Debian older than bookworm and Ubuntu older than 22.10 do not provide the .pc file.
|
||||
libpam = cc.find_library('pam', required : feature)
|
||||
endif
|
||||
libpam_misc = dependency('pam_misc',
|
||||
required : feature.disabled() ? feature : false)
|
||||
if not libpam_misc.found()
|
||||
libpam_misc = cc.find_library('pam_misc', required : feature)
|
||||
endif
|
||||
conf.set10('HAVE_PAM', libpam.found() and libpam_misc.found())
|
||||
conf.set10('HAVE_PAM', libpam.found())
|
||||
libpam_cflags = libpam.partial_dependency(includes: true, compile_args: true)
|
||||
|
||||
libmicrohttpd = dependency('libmicrohttpd',
|
||||
@@ -1949,21 +1944,7 @@ pam_template = {
|
||||
libshared_static,
|
||||
],
|
||||
'dependencies' : [
|
||||
# Note: our PAM modules also call dlopen_libpam() and use
|
||||
# symbols acquired through that, hence the explicit dep here is
|
||||
# strictly speaking unnecessary. We put it in place anyway,
|
||||
# since for the PAM modules we cannot avoid libpam anyway,
|
||||
# after all they are loaded *by* libpam, and hence there's no
|
||||
# loss in having explicit deps here, but there's a win: it
|
||||
# makes the deps more visible.
|
||||
#
|
||||
# (In case you wonder why we do dlopen_libpam() from the PAM
|
||||
# modules in the first place: that's mostly so that all our PAM
|
||||
# code (regardless if our PAM modules or our PAM consuming
|
||||
# programs) can use the same helpers, which hence go via
|
||||
# dlopen_libpam().
|
||||
libpam_misc,
|
||||
libpam,
|
||||
libpam_cflags,
|
||||
threads,
|
||||
],
|
||||
'install' : true,
|
||||
|
||||
@@ -116,8 +116,7 @@ modules += [
|
||||
'sources' : pam_systemd_home_sources,
|
||||
'dependencies' : [
|
||||
libintl,
|
||||
libpam_misc,
|
||||
libpam,
|
||||
libpam_cflags,
|
||||
threads,
|
||||
],
|
||||
'version-script' : meson.current_source_dir() / 'pam_systemd_home.sym',
|
||||
|
||||
+38
-35
@@ -1,7 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <libintl.h>
|
||||
#include <security/pam_misc.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
@@ -45,7 +44,7 @@ static int parse_argv(
|
||||
|
||||
k = parse_boolean(v);
|
||||
if (k < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse suspend= argument, ignoring: %s", v);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse suspend= argument, ignoring: %s", v);
|
||||
else if (flags)
|
||||
SET_FLAG(*flags, ACQUIRE_PLEASE_SUSPEND, k);
|
||||
|
||||
@@ -57,12 +56,12 @@ static int parse_argv(
|
||||
int k;
|
||||
k = parse_boolean(v);
|
||||
if (k < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", v);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", v);
|
||||
else if (debug)
|
||||
*debug = k;
|
||||
|
||||
} else
|
||||
pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -76,7 +75,7 @@ static int parse_env(pam_handle_t *pamh, AcquireHomeFlags *flags) {
|
||||
* easy to declare the features of a display manager in code rather than configuration, and this is
|
||||
* really a feature of code */
|
||||
|
||||
v = pam_getenv(pamh, "SYSTEMD_HOME_SUSPEND");
|
||||
v = sym_pam_getenv(pamh, "SYSTEMD_HOME_SUSPEND");
|
||||
if (!v) {
|
||||
/* Also check the process env block, so that people can control this via an env var from the
|
||||
* outside of our process. */
|
||||
@@ -87,7 +86,7 @@ static int parse_env(pam_handle_t *pamh, AcquireHomeFlags *flags) {
|
||||
|
||||
r = parse_boolean(v);
|
||||
if (r < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse $SYSTEMD_HOME_SUSPEND argument, ignoring: %s", v);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse $SYSTEMD_HOME_SUSPEND argument, ignoring: %s", v);
|
||||
else if (flags)
|
||||
SET_FLAG(*flags, ACQUIRE_PLEASE_SUSPEND, r);
|
||||
|
||||
@@ -106,7 +105,7 @@ static int acquire_user_record(
|
||||
assert(pamh);
|
||||
|
||||
if (!username) {
|
||||
r = pam_get_user(pamh, &username, NULL);
|
||||
r = sym_pam_get_user(pamh, &username, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
|
||||
if (isempty(username))
|
||||
@@ -149,7 +148,7 @@ static int acquire_user_record(
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
/* Let's use the cache, so that we can share it between the session and the authentication hooks */
|
||||
r = pam_get_data(pamh, homed_field, (const void**) &json);
|
||||
r = sym_pam_get_data(pamh, homed_field, (const void**) &json);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM user record data: @PAMERR@");
|
||||
if (r == PAM_SUCCESS && json) {
|
||||
@@ -211,13 +210,13 @@ static int acquire_user_record(
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR,
|
||||
"Acquired user record does not match user name.");
|
||||
|
||||
/* Update the 'username' pointer to point to our own record now. The pam_set_item() call below is
|
||||
/* Update the 'username' pointer to point to our own record now. The sym_pam_set_item() call below is
|
||||
* going to invalidate the old version after all */
|
||||
username = ur->user_name;
|
||||
|
||||
/* We passed all checks. Let's now make sure the rest of the PAM stack continues with the primary,
|
||||
* normalized name of the user record (i.e. not an alias or so). */
|
||||
r = pam_set_item(pamh, PAM_USER, ur->user_name);
|
||||
r = sym_pam_set_item(pamh, PAM_USER, ur->user_name);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to update username PAM item to '%s': @PAMERR@", ur->user_name);
|
||||
@@ -230,7 +229,7 @@ static int acquire_user_record(
|
||||
if (!json_copy)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_set_data(pamh, homed_field, json_copy, pam_cleanup_free);
|
||||
r = sym_pam_set_data(pamh, homed_field, json_copy, pam_cleanup_free);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM user record data '%s': @PAMERR@", homed_field);
|
||||
@@ -246,7 +245,7 @@ static int acquire_user_record(
|
||||
if (!generic_field)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_set_data(pamh, generic_field, json_copy, pam_cleanup_free);
|
||||
r = sym_pam_set_data(pamh, generic_field, json_copy, pam_cleanup_free);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM user record data '%s': @PAMERR@", generic_field);
|
||||
@@ -256,7 +255,7 @@ static int acquire_user_record(
|
||||
|
||||
/* Let's store the area we parsed out of the name in an env var, so that pam_systemd later can honour it. */
|
||||
if (area) {
|
||||
r = pam_misc_setenv(pamh, "XDG_AREA", area, /* readonly= */ 0);
|
||||
r = pam_putenv_assign(pamh, "XDG_AREA", area);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set environment variable $XDG_AREA to '%s': @PAMERR@", area);
|
||||
@@ -269,7 +268,7 @@ static int acquire_user_record(
|
||||
|
||||
user_unknown:
|
||||
/* Cache this, so that we don't check again */
|
||||
r = pam_set_data(pamh, homed_field, POINTER_MAX, NULL);
|
||||
r = sym_pam_set_data(pamh, homed_field, POINTER_MAX, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM user record data '%s' to invalid, ignoring: @PAMERR@",
|
||||
@@ -289,7 +288,7 @@ static int release_user_record(pam_handle_t *pamh, const char *username) {
|
||||
if (!homed_field)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_set_data(pamh, homed_field, NULL, NULL);
|
||||
r = sym_pam_set_data(pamh, homed_field, NULL, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to release PAM user record data '%s': @PAMERR@", homed_field);
|
||||
@@ -298,7 +297,7 @@ static int release_user_record(pam_handle_t *pamh, const char *username) {
|
||||
if (!generic_field)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
k = pam_set_data(pamh, generic_field, NULL, NULL);
|
||||
k = sym_pam_set_data(pamh, generic_field, NULL, NULL);
|
||||
if (k != PAM_SUCCESS)
|
||||
pam_syslog_pam_error(pamh, LOG_ERR, k,
|
||||
"Failed to release PAM user record data '%s': @PAMERR@", generic_field);
|
||||
@@ -569,7 +568,7 @@ static int acquire_home(
|
||||
* prompt the user for the missing unlock credentials, and then chainload the real shell.
|
||||
*/
|
||||
|
||||
r = pam_get_user(pamh, &username, NULL);
|
||||
r = sym_pam_get_user(pamh, &username, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
|
||||
if (isempty(username))
|
||||
@@ -580,7 +579,7 @@ static int acquire_home(
|
||||
if (!fd_field)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_get_data(pamh, fd_field, &home_fd_ptr);
|
||||
r = sym_pam_get_data(pamh, fd_field, &home_fd_ptr);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to retrieve PAM home reference fd: @PAMERR@");
|
||||
@@ -618,7 +617,7 @@ static int acquire_home(
|
||||
/* If there's already a cached password, use it. But if not let's authenticate
|
||||
* without anything, maybe some other authentication mechanism systemd-homed
|
||||
* implements (such as PKCS#11) allows us to authenticate without anything else. */
|
||||
r = pam_get_item(pamh, PAM_AUTHTOK, (const void**) &cached_password);
|
||||
r = sym_pam_get_item(pamh, PAM_AUTHTOK, (const void**) &cached_password);
|
||||
if (!IN_SET(r, PAM_BAD_ITEM, PAM_SUCCESS))
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to get cached password: @PAMERR@");
|
||||
@@ -681,7 +680,7 @@ static int acquire_home(
|
||||
(void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Home of user %s is currently locked, please unlock locally first."), ur->user_name);
|
||||
|
||||
if (FLAGS_SET(flags, ACQUIRE_MUST_AUTHENTICATE))
|
||||
pam_syslog(pamh, LOG_ERR, "Failed to prompt for password/prompt.");
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Failed to prompt for password/prompt.");
|
||||
else
|
||||
pam_debug_syslog(pamh, debug, "Failed to prompt for password/prompt.");
|
||||
|
||||
@@ -720,12 +719,12 @@ static int acquire_home(
|
||||
|
||||
/* Later PAM modules may need the auth token, but only during pam_authenticate. */
|
||||
if (FLAGS_SET(flags, ACQUIRE_MUST_AUTHENTICATE) && !strv_isempty(secret->password)) {
|
||||
r = pam_set_item(pamh, PAM_AUTHTOK, *secret->password);
|
||||
r = sym_pam_set_item(pamh, PAM_AUTHTOK, *secret->password);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to set PAM auth token: @PAMERR@");
|
||||
}
|
||||
|
||||
r = pam_set_data(pamh, fd_field, FD_TO_PTR(acquired_fd), cleanup_home_fd);
|
||||
r = sym_pam_set_data(pamh, fd_field, FD_TO_PTR(acquired_fd), cleanup_home_fd);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to set PAM bus data: @PAMERR@");
|
||||
TAKE_FD(acquired_fd);
|
||||
@@ -744,13 +743,13 @@ static int acquire_home(
|
||||
* manager for us (since it would see an inaccessible home directory). Hence set an environment
|
||||
* variable that pam_systemd looks for). */
|
||||
if (unrestricted) {
|
||||
r = pam_putenv(pamh, "XDG_SESSION_INCOMPLETE=1");
|
||||
r = sym_pam_putenv(pamh, "XDG_SESSION_INCOMPLETE=1");
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_WARNING, r, "Failed to set XDG_SESSION_INCOMPLETE= environment variable: @PAMERR@");
|
||||
|
||||
pam_syslog(pamh, LOG_NOTICE, "Home for user %s acquired in incomplete mode, requires later activation.", ur->user_name);
|
||||
sym_pam_syslog(pamh, LOG_NOTICE, "Home for user %s acquired in incomplete mode, requires later activation.", ur->user_name);
|
||||
} else
|
||||
pam_syslog(pamh, LOG_NOTICE, "Home for user %s successfully acquired.", ur->user_name);
|
||||
sym_pam_syslog(pamh, LOG_NOTICE, "Home for user %s successfully acquired.", ur->user_name);
|
||||
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
@@ -767,13 +766,13 @@ static int release_home_fd(pam_handle_t *pamh, const char *username) {
|
||||
if (!fd_field)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_get_data(pamh, fd_field, &home_fd_ptr);
|
||||
r = sym_pam_get_data(pamh, fd_field, &home_fd_ptr);
|
||||
if (r == PAM_NO_MODULE_DATA || (r == PAM_SUCCESS && PTR_TO_FD(home_fd_ptr) < 0))
|
||||
return PAM_NO_MODULE_DATA;
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to retrieve PAM home reference fd: @PAMERR@");
|
||||
|
||||
r = pam_set_data(pamh, fd_field, NULL, NULL);
|
||||
r = sym_pam_set_data(pamh, fd_field, NULL, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to release PAM home reference fd: @PAMERR@");
|
||||
|
||||
@@ -887,12 +886,12 @@ _public_ PAM_EXTERN int pam_sm_open_session(
|
||||
if (r != PAM_SUCCESS)
|
||||
return r;
|
||||
|
||||
r = pam_putenv(pamh, "SYSTEMD_HOME=1");
|
||||
r = sym_pam_putenv(pamh, "SYSTEMD_HOME=1");
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM environment variable $SYSTEMD_HOME: @PAMERR@");
|
||||
|
||||
r = pam_putenv(pamh, FLAGS_SET(flags, ACQUIRE_PLEASE_SUSPEND) ? "SYSTEMD_HOME_SUSPEND=1" : "SYSTEMD_HOME_SUSPEND=0");
|
||||
r = sym_pam_putenv(pamh, FLAGS_SET(flags, ACQUIRE_PLEASE_SUSPEND) ? "SYSTEMD_HOME_SUSPEND=1" : "SYSTEMD_HOME_SUSPEND=0");
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM environment variable $SYSTEMD_HOME_SUSPEND: @PAMERR@");
|
||||
@@ -911,6 +910,10 @@ _public_ PAM_EXTERN int pam_sm_close_session(
|
||||
bool debug = false;
|
||||
int r;
|
||||
|
||||
r = dlopen_libpam(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return PAM_SERVICE_ERR;
|
||||
|
||||
pam_log_setup();
|
||||
|
||||
if (parse_argv(pamh,
|
||||
@@ -921,7 +924,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
|
||||
|
||||
pam_debug_syslog(pamh, debug, "pam-systemd-homed: closing session...");
|
||||
|
||||
r = pam_get_user(pamh, &username, NULL);
|
||||
r = sym_pam_get_user(pamh, &username, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
|
||||
if (isempty(username))
|
||||
@@ -954,7 +957,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SESSION_ERR,
|
||||
"Failed to release user home: %s", bus_error_message(&error, r));
|
||||
|
||||
pam_syslog(pamh, LOG_NOTICE, "Not deactivating home directory of %s, as it is still used.", username);
|
||||
sym_pam_syslog(pamh, LOG_NOTICE, "Not deactivating home directory of %s, as it is still used.", username);
|
||||
}
|
||||
|
||||
return PAM_SUCCESS;
|
||||
@@ -1005,7 +1008,7 @@ _public_ PAM_EXTERN int pam_sm_acct_mgmt(
|
||||
switch (r) {
|
||||
|
||||
case -ESTALE:
|
||||
pam_syslog(pamh, LOG_WARNING, "User record for '%s' is newer than current system time, assuming incorrect system clock, allowing access.", ur->user_name);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "User record for '%s' is newer than current system time, assuming incorrect system clock, allowing access.", ur->user_name);
|
||||
break;
|
||||
|
||||
case -ENOLCK:
|
||||
@@ -1062,7 +1065,7 @@ _public_ PAM_EXTERN int pam_sm_acct_mgmt(
|
||||
|
||||
case -ESTALE:
|
||||
/* If the system clock is wrong, let's log but continue */
|
||||
pam_syslog(pamh, LOG_WARNING, "Couldn't check if password change is required, last change is in the future, system clock likely wrong.");
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Couldn't check if password change is required, last change is in the future, system clock likely wrong.");
|
||||
break;
|
||||
|
||||
case -EROFS:
|
||||
@@ -1121,7 +1124,7 @@ _public_ PAM_EXTERN int pam_sm_chauthtok(
|
||||
/* No, it's not cached, then let's ask for the password and its verification, and cache
|
||||
* it. */
|
||||
|
||||
r = pam_get_authtok_noverify(pamh, &new_password, "New password: ");
|
||||
r = sym_pam_get_authtok_noverify(pamh, &new_password, "New password: ");
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get new password: @PAMERR@");
|
||||
|
||||
@@ -1130,7 +1133,7 @@ _public_ PAM_EXTERN int pam_sm_chauthtok(
|
||||
return PAM_AUTHTOK_ERR;
|
||||
}
|
||||
|
||||
r = pam_get_authtok_verify(pamh, &new_password, "new password: "); /* Lower case, since PAM prefixes 'Repeat' */
|
||||
r = sym_pam_get_authtok_verify(pamh, &new_password, "new password: "); /* Lower case, since PAM prefixes 'Repeat' */
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get password again: @PAMERR@");
|
||||
|
||||
|
||||
+51
-49
@@ -3,7 +3,6 @@
|
||||
#include <endian.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <security/pam_misc.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysmacros.h>
|
||||
@@ -88,7 +87,7 @@ static int parse_caps(
|
||||
|
||||
c = capability_from_name(s);
|
||||
if (c < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Unknown capability, ignoring: %s", s);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Unknown capability, ignoring: %s", s);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -146,7 +145,7 @@ static int parse_argv(
|
||||
} else if ((p = startswith(argv[i], "area="))) {
|
||||
|
||||
if (!isempty(p) && !filename_is_valid(p))
|
||||
pam_syslog(pamh, LOG_WARNING, "Area name specified among PAM module parameters is not valid, ignoring: %s", p);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Area name specified among PAM module parameters is not valid, ignoring: %s", p);
|
||||
else if (area)
|
||||
*area = p;
|
||||
|
||||
@@ -157,22 +156,22 @@ static int parse_argv(
|
||||
} else if ((p = startswith(argv[i], "debug="))) {
|
||||
r = parse_boolean(p);
|
||||
if (r < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", p);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", p);
|
||||
else if (debug)
|
||||
*debug = r;
|
||||
|
||||
} else if ((p = startswith(argv[i], "default-capability-bounding-set="))) {
|
||||
r = parse_caps(pamh, p, default_capability_bounding_set);
|
||||
if (r < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse default-capability-bounding-set= argument, ignoring: %s", p);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse default-capability-bounding-set= argument, ignoring: %s", p);
|
||||
|
||||
} else if ((p = startswith(argv[i], "default-capability-ambient-set="))) {
|
||||
r = parse_caps(pamh, p, default_capability_ambient_set);
|
||||
if (r < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse default-capability-ambient-set= argument, ignoring: %s", p);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse default-capability-ambient-set= argument, ignoring: %s", p);
|
||||
|
||||
} else
|
||||
pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -184,7 +183,7 @@ static int acquire_user_record(pam_handle_t *pamh, UserRecord **ret_record) {
|
||||
assert(pamh);
|
||||
|
||||
const char *username = NULL;
|
||||
r = pam_get_user(pamh, &username, NULL);
|
||||
r = sym_pam_get_user(pamh, &username, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
|
||||
if (isempty(username))
|
||||
@@ -198,7 +197,7 @@ static int acquire_user_record(pam_handle_t *pamh, UserRecord **ret_record) {
|
||||
|
||||
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
|
||||
const char *json = NULL;
|
||||
r = pam_get_data(pamh, field, (const void**) &json);
|
||||
r = sym_pam_get_data(pamh, field, (const void**) &json);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM user record data: @PAMERR@");
|
||||
if (r == PAM_SUCCESS && json) {
|
||||
@@ -240,7 +239,7 @@ static int acquire_user_record(pam_handle_t *pamh, UserRecord **ret_record) {
|
||||
return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to format user JSON: %m");
|
||||
|
||||
/* And cache it for everyone else */
|
||||
r = pam_set_data(pamh, field, formatted, pam_cleanup_free);
|
||||
r = sym_pam_set_data(pamh, field, formatted, pam_cleanup_free);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM user record data '%s': @PAMERR@", field);
|
||||
@@ -382,7 +381,7 @@ static int append_session_memory_max(pam_handle_t *pamh, sd_bus_message *m, cons
|
||||
uint64_t val;
|
||||
r = parse_size(limit, 1024, &val);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.memory_max, ignoring: %s", limit);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.memory_max, ignoring: %s", limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -402,7 +401,7 @@ static int append_session_runtime_max_sec(pam_handle_t *pamh, sd_bus_message *m,
|
||||
usec_t val;
|
||||
r = parse_sec(limit, &val);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.runtime_max_sec: %s, ignoring.", limit);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.runtime_max_sec: %s, ignoring.", limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -422,7 +421,7 @@ static int append_session_tasks_max(pam_handle_t *pamh, sd_bus_message *m, const
|
||||
uint64_t val;
|
||||
r = safe_atou64(limit, &val);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.tasks_max, ignoring: %s", limit);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.tasks_max, ignoring: %s", limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -441,7 +440,7 @@ static int append_session_cpu_weight(pam_handle_t *pamh, sd_bus_message *m, cons
|
||||
uint64_t val;
|
||||
r = cg_cpu_weight_parse(limit, &val);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.cpu_weight, ignoring: %s", limit);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.cpu_weight, ignoring: %s", limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -460,7 +459,7 @@ static int append_session_io_weight(pam_handle_t *pamh, sd_bus_message *m, const
|
||||
uint64_t val;
|
||||
r = cg_weight_parse(limit, &val);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.io_weight, ignoring: %s", limit);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.io_weight, ignoring: %s", limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -479,7 +478,7 @@ static const char* getenv_harder(pam_handle_t *pamh, const char *key, const char
|
||||
* PAM services don't have to be reworked to set systemd-specific properties, but these properties
|
||||
* can still be set from the unit file Environment= block. */
|
||||
|
||||
v = pam_getenv(pamh, key);
|
||||
v = sym_pam_getenv(pamh, key);
|
||||
if (!isempty(v))
|
||||
return v;
|
||||
|
||||
@@ -507,9 +506,9 @@ static bool getenv_harder_bool(pam_handle_t *pamh, const char *key, bool fallbac
|
||||
|
||||
r = parse_boolean(v);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING,
|
||||
"Failed to parse environment variable value '%s' of '%s', falling back to using '%s'.",
|
||||
v, key, true_false(fallback));
|
||||
sym_pam_syslog(pamh, LOG_WARNING,
|
||||
"Failed to parse environment variable value '%s' of '%s', falling back to using '%s'.",
|
||||
v, key, true_false(fallback));
|
||||
return fallback;
|
||||
}
|
||||
|
||||
@@ -529,9 +528,9 @@ static uint32_t getenv_harder_uint32(pam_handle_t *pamh, const char *key, uint32
|
||||
uint32_t u;
|
||||
r = safe_atou32(v, &u);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING,
|
||||
"Failed to parse environment variable value '%s' of '%s' as unsigned integer, falling back to using %" PRIu32 ".",
|
||||
v, key, fallback);
|
||||
sym_pam_syslog(pamh, LOG_WARNING,
|
||||
"Failed to parse environment variable value '%s' of '%s' as unsigned integer, falling back to using %" PRIu32 ".",
|
||||
v, key, fallback);
|
||||
return fallback;
|
||||
}
|
||||
|
||||
@@ -548,14 +547,14 @@ static int update_environment(pam_handle_t *pamh, const char *key, const char *v
|
||||
* about errors. */
|
||||
|
||||
if (isempty(value)) {
|
||||
/* Unset the variable if set. Note that pam_putenv() would log nastily behind our back if we
|
||||
/* Unset the variable if set. Note that sym_pam_putenv() would log nastily behind our back if we
|
||||
* call it without the variable actually being set. Hence we check explicitly if it's set
|
||||
* before. */
|
||||
|
||||
if (!pam_getenv(pamh, key))
|
||||
if (!sym_pam_getenv(pamh, key))
|
||||
return PAM_SUCCESS;
|
||||
|
||||
r = pam_putenv(pamh, key);
|
||||
r = sym_pam_putenv(pamh, key);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_BAD_ITEM))
|
||||
return pam_syslog_pam_error(pamh, LOG_WARNING, r,
|
||||
"Failed to unset %s environment variable: @PAMERR@", key);
|
||||
@@ -563,7 +562,7 @@ static int update_environment(pam_handle_t *pamh, const char *key, const char *v
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
r = pam_misc_setenv(pamh, key, value, /* readonly= */ false);
|
||||
r = pam_putenv_assign(pamh, key, value);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set environment variable %s: @PAMERR@", key);
|
||||
@@ -588,7 +587,7 @@ static int propagate_credential_to_environment(pam_handle_t *pamh, bool debug, c
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
r = pam_misc_setenv(pamh, varname, value, 0);
|
||||
r = pam_putenv_assign(pamh, varname, value);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set environment variable %s: @PAMERR@", varname);
|
||||
@@ -610,7 +609,7 @@ static bool validate_runtime_directory(pam_handle_t *pamh, const char *path, uid
|
||||
* otherwise we might end up setting $XDG_RUNTIME_DIR to some directory owned by the wrong user. */
|
||||
|
||||
if (!path_is_absolute(path)) {
|
||||
pam_syslog(pamh, LOG_ERR, "Provided runtime directory '%s' is not absolute.", path);
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Provided runtime directory '%s' is not absolute.", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -620,19 +619,19 @@ static bool validate_runtime_directory(pam_handle_t *pamh, const char *path, uid
|
||||
}
|
||||
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
pam_syslog(pamh, LOG_ERR, "Runtime directory '%s' is not actually a directory.", path);
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Runtime directory '%s' is not actually a directory.", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (st.st_uid != uid) {
|
||||
pam_syslog(pamh, LOG_ERR, "Runtime directory '%s' is not owned by UID " UID_FMT ", as it should.", path, uid);
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Runtime directory '%s' is not owned by UID " UID_FMT ", as it should.", path, uid);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
pam_syslog(pamh, LOG_WARNING, "Not setting $XDG_RUNTIME_DIR, as the directory is not in order.");
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Not setting $XDG_RUNTIME_DIR, as the directory is not in order.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -642,7 +641,7 @@ static int pam_putenv_and_log(pam_handle_t *pamh, const char *e, bool debug) {
|
||||
assert(pamh);
|
||||
assert(e);
|
||||
|
||||
r = pam_putenv(pamh, e);
|
||||
r = sym_pam_putenv(pamh, e);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM environment variable %s: @PAMERR@", e);
|
||||
@@ -992,7 +991,7 @@ static void session_context_mangle(
|
||||
c->area = ur->default_area;
|
||||
|
||||
if (!isempty(c->area) && !filename_is_valid(c->area)) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Specified area '%s' is not a valid filename, ignoring area request.", c->area);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Specified area '%s' is not a valid filename, ignoring area request.", c->area);
|
||||
c->area = NULL;
|
||||
}
|
||||
|
||||
@@ -1048,7 +1047,7 @@ static void session_context_mangle(
|
||||
if (streq(c->class, "user"))
|
||||
c->class = "user-incomplete";
|
||||
else
|
||||
pam_syslog(pamh, LOG_WARNING, "PAM session of class '%s' is incomplete, which is not supported, ignoring.", c->class);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "PAM session of class '%s' is incomplete, which is not supported, ignoring.", c->class);
|
||||
}
|
||||
|
||||
c->remote = !isempty(c->remote_host) && !is_localhost(c->remote_host);
|
||||
@@ -1253,8 +1252,7 @@ static int register_session(
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"Failed to create session: %s", bus_error_message(&error, r));
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Failed to create session: %s", bus_error_message(&error, r));
|
||||
return PAM_SESSION_ERR;
|
||||
}
|
||||
|
||||
@@ -1282,7 +1280,7 @@ static int register_session(
|
||||
if (fd < 0)
|
||||
return pam_syslog_errno(pamh, LOG_ERR, errno, "Failed to dup session fd: %m");
|
||||
|
||||
r = pam_set_data(pamh, "systemd.session-fd", FD_TO_PTR(fd), NULL);
|
||||
r = sym_pam_set_data(pamh, "systemd.session-fd", FD_TO_PTR(fd), NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to install session fd: @PAMERR@");
|
||||
TAKE_FD(fd);
|
||||
@@ -1580,7 +1578,7 @@ static int setup_environment(
|
||||
pam_syslog_errno(pamh, LOG_WARNING, r, "Path '%s' of requested user area '%s' is not accessible, reverting to regular home directory: %m", j, area);
|
||||
|
||||
/* Also tell the user directly at login, but a bit more vague */
|
||||
pam_info(pamh, "Path '%s' of requested user area '%s' is not accessible, reverting to regular home directory.", j, area);
|
||||
sym_pam_info(pamh, "Path '%s' of requested user area '%s' is not accessible, reverting to regular home directory.", j, area);
|
||||
area = NULL;
|
||||
} else {
|
||||
/* Validate that the target is definitely owned by user */
|
||||
@@ -1589,10 +1587,10 @@ static int setup_environment(
|
||||
return pam_syslog_errno(pamh, LOG_ERR, errno, "Unable to fstat() target area directory '%s': %m", ha);
|
||||
|
||||
if (st.st_uid != ur->uid) {
|
||||
pam_syslog(pamh, LOG_ERR, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
|
||||
|
||||
/* Also tell the user directly at login. */
|
||||
pam_info(pamh, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
|
||||
sym_pam_info(pamh, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
|
||||
area = NULL;
|
||||
} else {
|
||||
/* All good, now make a copy of the area string, since we quite likely are
|
||||
@@ -1631,13 +1629,13 @@ static int open_osc_context(pam_handle_t *pamh, const char *session_type, UserRe
|
||||
if (!streq_ptr(session_type, "tty"))
|
||||
return PAM_SUCCESS;
|
||||
|
||||
const char *e = pam_getenv(pamh, "TERM");
|
||||
const char *e = sym_pam_getenv(pamh, "TERM");
|
||||
if (!e)
|
||||
e = getenv("TERM");
|
||||
if (streq_ptr(e, "dumb"))
|
||||
return PAM_SUCCESS;
|
||||
|
||||
/* NB: we output directly to stdout, instead of going via pam_info() or so, because that's too
|
||||
/* NB: we output directly to stdout, instead of going via sym_pam_info() or so, because that's too
|
||||
* high-level for us, as it suffixes the output with a newline, expecting a full blown text message
|
||||
* as prompt string, not just an ANSI sequence. Note that PAM's conv_misc() actually goes to stdout
|
||||
* anyway, hence let's do so here too, but only after careful validation. */
|
||||
@@ -1657,7 +1655,7 @@ static int open_osc_context(pam_handle_t *pamh, const char *session_type, UserRe
|
||||
sd_id128_t osc_id;
|
||||
r = osc_context_open_session(
|
||||
ur->user_name,
|
||||
pam_getenv(pamh, "XDG_SESSION_ID"),
|
||||
sym_pam_getenv(pamh, "XDG_SESSION_ID"),
|
||||
&osc,
|
||||
&osc_id);
|
||||
if (r < 0)
|
||||
@@ -1672,7 +1670,7 @@ static int open_osc_context(pam_handle_t *pamh, const char *session_type, UserRe
|
||||
if (!osc_id_copy)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_set_data(pamh, "systemd.osc-context-id", osc_id_copy, pam_cleanup_free);
|
||||
r = sym_pam_set_data(pamh, "systemd.osc-context-id", osc_id_copy, pam_cleanup_free);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM OSC sequence ID data: @PAMERR@");
|
||||
@@ -1680,7 +1678,7 @@ static int open_osc_context(pam_handle_t *pamh, const char *session_type, UserRe
|
||||
TAKE_PTR(osc_id_copy);
|
||||
|
||||
if (tty_opath_fd >= 0) {
|
||||
r = pam_set_data(pamh, "systemd.osc-context-fd", FD_TO_PTR(tty_opath_fd), pam_cleanup_close);
|
||||
r = sym_pam_set_data(pamh, "systemd.osc-context-fd", FD_TO_PTR(tty_opath_fd), pam_cleanup_close);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM OSC sequence fd data: @PAMERR@");
|
||||
@@ -1698,7 +1696,7 @@ static int close_osc_context(pam_handle_t *pamh, bool debug) {
|
||||
|
||||
const void *p;
|
||||
int tty_opath_fd = -EBADF;
|
||||
r = pam_get_data(pamh, "systemd.osc-context-fd", &p);
|
||||
r = sym_pam_get_data(pamh, "systemd.osc-context-fd", &p);
|
||||
if (r == PAM_SUCCESS)
|
||||
tty_opath_fd = PTR_TO_FD(p);
|
||||
else if (r != PAM_NO_MODULE_DATA)
|
||||
@@ -1707,7 +1705,7 @@ static int close_osc_context(pam_handle_t *pamh, bool debug) {
|
||||
return PAM_SUCCESS;
|
||||
|
||||
const sd_id128_t *osc_id = NULL;
|
||||
r = pam_get_data(pamh, "systemd.osc-context-id", (const void**) &osc_id);
|
||||
r = sym_pam_get_data(pamh, "systemd.osc-context-id", (const void**) &osc_id);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM OSC context id data: @PAMERR@");
|
||||
if (!osc_id)
|
||||
@@ -1721,7 +1719,7 @@ static int close_osc_context(pam_handle_t *pamh, bool debug) {
|
||||
}
|
||||
|
||||
/* /bin/login calls us with fds 0, 1, 2 closed, which is just weird. Let's step outside of that
|
||||
* range, just in case pam_syslog() or so logs to stderr */
|
||||
* range, just in case sym_pam_syslog() or so logs to stderr */
|
||||
fd = fd_move_above_stdio(fd);
|
||||
|
||||
/* Safety check, let's verify this is a valid TTY we just opened */
|
||||
@@ -1849,6 +1847,10 @@ _public_ PAM_EXTERN int pam_sm_close_session(
|
||||
|
||||
assert(pamh);
|
||||
|
||||
r = dlopen_libpam(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return PAM_SERVICE_ERR;
|
||||
|
||||
pam_log_setup();
|
||||
|
||||
if (parse_argv(pamh,
|
||||
@@ -1866,7 +1868,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
|
||||
|
||||
(void) close_osc_context(pamh, debug);
|
||||
|
||||
id = pam_getenv(pamh, "XDG_SESSION_ID");
|
||||
id = sym_pam_getenv(pamh, "XDG_SESSION_ID");
|
||||
if (id) {
|
||||
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
|
||||
bool done = false;
|
||||
|
||||
@@ -41,7 +41,7 @@ _public_ PAM_EXTERN int pam_sm_authenticate(
|
||||
else if (streq(argv[i], "debug"))
|
||||
debug = true;
|
||||
else
|
||||
pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
}
|
||||
|
||||
pam_debug_syslog(pamh, debug, "pam-systemd-loadkey: initializing...");
|
||||
@@ -81,7 +81,7 @@ _public_ PAM_EXTERN int pam_sm_authenticate(
|
||||
} else if (passwords_len > 1)
|
||||
pam_debug_syslog(pamh, debug, "Multiple passwords found in the key. Using the last one.");
|
||||
|
||||
r = pam_set_item(pamh, PAM_AUTHTOK, passwords[passwords_len - 1]);
|
||||
r = sym_pam_set_item(pamh, PAM_AUTHTOK, passwords[passwords_len - 1]);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to set PAM auth token: @PAMERR@");
|
||||
|
||||
|
||||
@@ -25,10 +25,15 @@ static void *libpam_dl = NULL;
|
||||
DLSYM_PROTOTYPE(pam_acct_mgmt) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_close_session) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_end) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_get_authtok_noverify) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_get_authtok_verify) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_get_data) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_get_item) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_get_user) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_getenv) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_getenvlist) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_open_session) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_prompt) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_putenv) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_set_data) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_set_item) = NULL;
|
||||
@@ -361,6 +366,19 @@ int pam_prompt_graceful(pam_handle_t *pamh, int style, char **ret_response, cons
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
int pam_putenv_assign(pam_handle_t *pamh, const char *name, const char *value) {
|
||||
_cleanup_(erase_and_freep) char *s = NULL;
|
||||
|
||||
assert(pamh);
|
||||
assert(name);
|
||||
assert(value);
|
||||
|
||||
if (asprintf(&s, "%s=%s", name, value) < 0)
|
||||
return PAM_BUF_ERR;
|
||||
|
||||
return sym_pam_putenv(pamh, s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int dlopen_libpam(int log_level) {
|
||||
@@ -378,10 +396,15 @@ int dlopen_libpam(int log_level) {
|
||||
DLSYM_ARG(pam_acct_mgmt),
|
||||
DLSYM_ARG(pam_close_session),
|
||||
DLSYM_ARG(pam_end),
|
||||
DLSYM_ARG(pam_get_authtok_noverify),
|
||||
DLSYM_ARG(pam_get_authtok_verify),
|
||||
DLSYM_ARG(pam_get_data),
|
||||
DLSYM_ARG(pam_get_item),
|
||||
DLSYM_ARG(pam_get_user),
|
||||
DLSYM_ARG(pam_getenv),
|
||||
DLSYM_ARG(pam_getenvlist),
|
||||
DLSYM_ARG(pam_open_session),
|
||||
DLSYM_ARG(pam_prompt),
|
||||
DLSYM_ARG(pam_putenv),
|
||||
DLSYM_ARG(pam_set_data),
|
||||
DLSYM_ARG(pam_set_item),
|
||||
|
||||
+15
-1
@@ -6,7 +6,7 @@
|
||||
#if HAVE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_ext.h>
|
||||
#include <security/pam_modules.h> /* IWYU pragma: export */
|
||||
#include <security/pam_modules.h> /* IWYU pragma: export */
|
||||
#include <syslog.h>
|
||||
|
||||
#include "dlfcn-util.h"
|
||||
@@ -14,10 +14,15 @@
|
||||
extern DLSYM_PROTOTYPE(pam_acct_mgmt);
|
||||
extern DLSYM_PROTOTYPE(pam_close_session);
|
||||
extern DLSYM_PROTOTYPE(pam_end);
|
||||
extern DLSYM_PROTOTYPE(pam_get_authtok_noverify);
|
||||
extern DLSYM_PROTOTYPE(pam_get_authtok_verify);
|
||||
extern DLSYM_PROTOTYPE(pam_get_data);
|
||||
extern DLSYM_PROTOTYPE(pam_get_item);
|
||||
extern DLSYM_PROTOTYPE(pam_get_user);
|
||||
extern DLSYM_PROTOTYPE(pam_getenv);
|
||||
extern DLSYM_PROTOTYPE(pam_getenvlist);
|
||||
extern DLSYM_PROTOTYPE(pam_open_session);
|
||||
extern DLSYM_PROTOTYPE(pam_prompt);
|
||||
extern DLSYM_PROTOTYPE(pam_putenv);
|
||||
extern DLSYM_PROTOTYPE(pam_set_data);
|
||||
extern DLSYM_PROTOTYPE(pam_set_item);
|
||||
@@ -27,6 +32,11 @@ extern DLSYM_PROTOTYPE(pam_strerror);
|
||||
extern DLSYM_PROTOTYPE(pam_syslog);
|
||||
extern DLSYM_PROTOTYPE(pam_vsyslog);
|
||||
|
||||
/* sym_pam_prompt() replacement for the pam_info() macro from <security/pam_ext.h>, which expands to a direct
|
||||
* pam_prompt() call. */
|
||||
#define sym_pam_info(pamh, fmt, ...) \
|
||||
sym_pam_prompt((pamh), PAM_TEXT_INFO, NULL, (fmt), ## __VA_ARGS__)
|
||||
|
||||
void pam_log_setup(void);
|
||||
|
||||
int errno_to_pam_error(int error) _const_;
|
||||
@@ -90,6 +100,10 @@ int pam_get_data_many_internal(pam_handle_t *pamh, ...) _sentinel_;
|
||||
|
||||
int pam_prompt_graceful(pam_handle_t *pamh, int style, char **ret_response, const char *fmt, ...) _printf_(4,5);
|
||||
|
||||
/* Equivalent of pam_misc_setenv(pamh, name, value, 0), without the libpam_misc dep — builds "name=value"
|
||||
* and hands it to sym_pam_putenv(), then erases the buffer before freeing in case it carried a secret. */
|
||||
int pam_putenv_assign(pam_handle_t *pamh, const char *name, const char *value);
|
||||
|
||||
#endif
|
||||
|
||||
int dlopen_libpam(int log_level);
|
||||
|
||||
Reference in New Issue
Block a user