aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2024-01-04 18:23:57 +0100
committerDmitry V. Levin <ldv@strace.io>2024-01-15 20:01:23 +0000
commitb23d337b86488d23b2f77fc71a5de30348af671d (patch)
treebfb4962eb53e21b4da5fcf24c0fb30ed30eacd80 /modules
parentb430e2d1c93414cb14e9a3557ac895e864138497 (diff)
downloadpam-b23d337b86488d23b2f77fc71a5de30348af671d.tar.gz
pam-b23d337b86488d23b2f77fc71a5de30348af671d.tar.bz2
pam-b23d337b86488d23b2f77fc71a5de30348af671d.zip
pam_unix: reject unix_update(8) running on different unprivileged user
In case unix_update(8) is installed as a setuid binary, which Fedora and Debian does not do, prevent unprivileged users to probe (and eventually change) passwords of other users (including root).
Diffstat (limited to 'modules')
-rw-r--r--modules/pam_unix/unix_update.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/modules/pam_unix/unix_update.c b/modules/pam_unix/unix_update.c
index 4adaa5af..95e99494 100644
--- a/modules/pam_unix/unix_update.c
+++ b/modules/pam_unix/unix_update.c
@@ -42,6 +42,7 @@ static int
set_password(const char *forwho, const char *shadow, const char *remember)
{
struct passwd *pwd = NULL;
+ uid_t ruid;
int retval;
char pass[PAM_MAX_RESP_SIZE + 1];
char towhat[PAM_MAX_RESP_SIZE + 1];
@@ -80,9 +81,18 @@ set_password(const char *forwho, const char *shadow, const char *remember)
}
/* If real caller uid is not root we must verify that
- received old pass agrees with the current one.
- We always allow change from null pass. */
- if (getuid()) {
+ * the target user is the caller and the
+ * received old pass agrees with the current one.
+ * We always allow change from null pass. */
+ ruid = getuid();
+ if (ruid != 0) {
+ if (pwd->pw_uid != ruid) {
+ helper_log_err(LOG_NOTICE, "user mismatch detected: source=%d target=%d",
+ ruid, pwd->pw_uid);
+ retval = PAM_AUTHTOK_ERR;
+ goto done;
+ }
+
retval = helper_verify_password(forwho, pass, 1);
#ifdef HAVE_LIBAUDIT
audit_log(AUDIT_USER_AUTH, getuidname(getuid()), retval);