> Date: Wed, 6 Sep 2023 16:41:00 +1200
> From: Mark Davies <m...@ecs.vuw.ac.nz>
> 
> OK, so revision 1.10 of pam_ksu.c adds a call to 
> krb5_set_home_dir_access(NULL, FALSE);
> which causes the subsequent call to krb5_kuserok() to return false when 
> previously it would return true causing the whole pam_ksu to bail.
> 
> krb5_kuserok() is presuambly now returning false because if it can't 
> access the homedir it can't read /root/.k5login to see that 
> mark/r...@ecs.vuw.ac.nz is allowed.

The reason for revision 1.10 is that pam_ksu had a gaping security
hole without it, allowing the calling user to totally control the krb5
context by specifying ~/.krb5/config in the _calling user's_ home
directory and thereby spoof authentication decisions:

https://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2023-005.txt.asc

I verified that the hole was there without the change, and I verified
that the change plugged the hole.

However, I think you're right that the change causes it to take this
path in krb5_kuserok to block access to the _target user's_ home
directory too:

    profile_dir = k5login_dir;
    if (profile_dir == NULL) {
        /* Don't deadlock with gssd or anything of the sort */
        if (!_krb5_homedir_access(context))
            return KRB5_PLUGIN_NO_HANDLE;

        if (rk_getpwnam_r(luser, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) {
            krb5_set_error_message(context, errno, "User unknown 
(getpwnam_r())");
            return KRB5_PLUGIN_NO_HANDLE;
        }
        if (pwd == NULL) {
            krb5_set_error_message(context, errno, "User unknown (getpwnam())");
            return KRB5_PLUGIN_NO_HANDLE;
        }
        profile_dir = pwd->pw_dir;
    }

A possible workaround is to set:

        [libdefaults]
                k5login_directory = /root

However, that applies to _all_ kuserok checks for _all_ users, not
just the pam_ksu one ror root, so it will probably break other things.
I'm not sure there is a way in the config file to specify it just for
pam_ksu or just for root.

Perhaps it would be appropriate to add these lines in pam_ksu.c (or
possibly just the first one):

                goto out;
        }
+       krb5_set_home_dir_access(context, TRUE);
        PAM_LOG("kuserok: %s -> %s", su_principal_name, user);
        rv = krb5_kuserok(context, su_principal, user);
+       krb5_set_home_dir_access(context, FALSE);

At that point, the config file should have been parsed already, so the
calling user's ~/.krb5/config can't hurt anything.  But I haven't
audited this path.  So I don't know if it's safe.

Reply via email to