From 05bfd66693b22fabaccfb75ec67b1d7f521b6a83 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sun, 25 Sep 2011 06:35:40 -0400 Subject: [PATCH] If the invoking user cannot be resolved by uid fake the struct passwd and store it in the cache so we can delref it on exit. --- plugins/sudoers/pwutil.c | 18 +++++++++++++++--- plugins/sudoers/sudoers.c | 17 ++++++----------- plugins/sudoers/sudoers.h | 1 + 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/plugins/sudoers/pwutil.c b/plugins/sudoers/pwutil.c index fc45787e7..7d719e10a 100644 --- a/plugins/sudoers/pwutil.c +++ b/plugins/sudoers/pwutil.c @@ -312,10 +312,10 @@ done: } /* - * Take a uid in string form "#123" and return a faked up passwd struct. + * Take a user, uid and gid and return a faked up passwd struct. */ struct passwd * -sudo_fakepwnam(const char *user, gid_t gid) +sudo_fakepwnamid(const char *user, uid_t uid, gid_t gid) { struct cache_item *item; struct passwd *pw; @@ -332,7 +332,7 @@ sudo_fakepwnam(const char *user, gid_t gid) item = emalloc(len); zero_bytes(item, sizeof(*item) + sizeof(*pw)); pw = (struct passwd *) ((char *)item + sizeof(*item)); - pw->pw_uid = (uid_t) atoi(user + 1); + pw->pw_uid = uid; pw->pw_gid = gid; pw->pw_name = (char *)pw + sizeof(struct passwd); memcpy(pw->pw_name, user, namelen + 1); @@ -367,6 +367,18 @@ sudo_fakepwnam(const char *user, gid_t gid) return pw; } +/* + * Take a uid in string form "#123" and return a faked up passwd struct. + */ +struct passwd * +sudo_fakepwnam(const char *user, gid_t gid) +{ + uid_t uid; + + uid = (uid_t) atoi(user + 1); + return sudo_fakepwnamid(user, uid, gid); +} + void sudo_setpwent(void) { diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 36a19f4f5..9f27fe812 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -792,23 +792,18 @@ init_vars(char * const envp[]) * if necessary. It is assumed that euid is 0 at this point so we * can read the shadow passwd file if necessary. */ - if ((sudo_user.pw = sudo_getpwnam(user_name)) == NULL) { - static struct passwd pw; - - /* Create a fake struct passwd for log_error(). */ - memset(&pw, 0, sizeof(pw)); - pw.pw_uid = getuid(); - pw.pw_name = user_name; - sudo_user.pw = &pw; - + if ((sudo_user.pw = sudo_getpwuid(user_uid)) == NULL) { /* * It is not unusual for users to place "sudo -k" in a .logout * file which can cause sudo to be run during reboot after the * YP/NIS/NIS+/LDAP/etc daemon has died. */ if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) - errorx(1, _("unknown user: %s"), user_name); - log_error(0, _("unknown user: %s"), user_name); + errorx(1, _("unknown uid: %u"), (unsigned int) user_uid); + + /* Need to make a fake struct passwd for the call to log_error(). */ + sudo_user.pw = sudo_fakepwnamid(user_name, user_uid, user_gid); + log_error(0, _("unknown uid: %u"), (unsigned int) user_uid); /* NOTREACHED */ } diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index 6e21d9684..c88e90b13 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -268,6 +268,7 @@ void sudo_endspent(void); struct group_list *get_group_list(struct passwd *pw); void set_group_list(const char *, GETGROUPS_T *gids, int ngids); struct passwd *sudo_getpwnam(const char *); +struct passwd *sudo_fakepwnamid(const char *user, uid_t uid, gid_t gid); struct passwd *sudo_fakepwnam(const char *, gid_t); struct passwd *sudo_getpwuid(uid_t); struct group *sudo_getgrnam(const char *);