]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
login-utils/su-common: Check that the user didn't change during PAM transaction
authorMarco Trevisan (Treviño) <mail@3v1n0.net>
Fri, 20 Sep 2024 15:23:16 +0000 (17:23 +0200)
committerMarco Trevisan (Treviño) <mail@3v1n0.net>
Fri, 20 Sep 2024 15:23:16 +0000 (17:23 +0200)
PAM modules can change the user during their execution, in such case su
would still use the user that has been provided giving potentially
access to another user with the credentials of another one.

So prevent this to happen, by ensuring that the final PAM user is
matching the one required

login-utils/su-common.c

index 12c9336339cd9331c19a6b0d5717c494fc869bd8..844d1d43170dbf7a407eb83c009b294fd268b4d0 100644 (file)
@@ -382,6 +382,7 @@ static void supam_export_environment(struct su_context *su)
 static void supam_authenticate(struct su_context *su)
 {
        const char *srvname = NULL;
+       const char *pam_user = NULL;
        int rc;
 
        srvname = su->runuser ?
@@ -422,6 +423,16 @@ static void supam_authenticate(struct su_context *su)
        rc = pam_acct_mgmt(su->pamh, 0);
        if (rc == PAM_NEW_AUTHTOK_REQD)
                rc = pam_chauthtok(su->pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+
+       rc = pam_get_item(su->pamh, PAM_USER, (const void **) &pam_user);
+       if (is_pam_failure(rc))
+               goto done;
+
+       if (pam_user == NULL || strcmp(pam_user, su->pwd->pw_name) != 0) {
+               rc = PAM_USER_UNKNOWN;
+               goto done;
+       }
+
  done:
        log_syslog(su, !is_pam_failure(rc));