--- openssh-4.5p1/misc.c +++ openssh-4.5p1/misc.c @@ -186,6 +186,29 @@ return (old); } +struct passwd *getpwuid_wh(uid_t uid) { + /* Return the password structure by lookup of the username in $ENV{USER}, + but only when the UID matches a lookup-by-uid so as to not allow using + another users' .ssh files in case this function be used in superuser + context. */ + + const char *user = getenv("USER"); + struct passwd *pe_nam, *pe_uid; + + if(user == NULL || (pe_nam = getpwnam(user)) == NULL) { + return getpwuid(uid); + } + + pe_nam = pwcopy(pe_nam); + if((pe_uid = getpwuid(uid)) == NULL || pe_nam->pw_uid != pe_uid->pw_uid) { + free(pe_nam); + return pe_uid; + } + + free(pe_nam); // - need to return a non-pwcopy struct + return getpwnam(user); +} + struct passwd * pwcopy(struct passwd *pw) { @@ -524,7 +547,7 @@ user[slash] = '\0'; if ((pw = getpwnam(user)) == NULL) fatal("tilde_expand_filename: No such user %s", user); - } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */ + } else if ((pw = getpwuid_wh(uid)) == NULL) /* ~/path */ fatal("tilde_expand_filename: No such uid %d", uid); if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret)) --- openssh-4.5p1/misc.h +++ openssh-4.5p1/misc.h @@ -34,6 +34,7 @@ char *tohex(const void *, size_t); void sanitise_stdfd(void); +struct passwd *getpwuid_wh(uid_t); struct passwd *pwcopy(struct passwd *); typedef struct arglist arglist; --- openssh-4.5p1/ssh.c +++ openssh-4.5p1/ssh.c @@ -249,7 +249,7 @@ } #endif /* Get user data. */ - pw = getpwuid(original_real_uid); + pw = getpwuid_wh(original_real_uid); if (!pw) { logit("You don't exist, go away!"); exit(255);