From: Todd C. Miller Date: Sat, 24 Sep 2011 23:41:22 +0000 (-0400) Subject: If the invoking user cannot be resolved by uid fake the struct X-Git-Tag: SUDO_1_7_8~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c948d6aa2471b994ef76adbb8c83f8a9fd926d99;p=sudo 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. --HG-- branch : 1.7 --- diff --git a/pwutil.c b/pwutil.c index 548da4d2d..985b73f92 100644 --- a/pwutil.c +++ b/pwutil.c @@ -315,12 +315,10 @@ done: return item->d.pw; } -/* - * Take a uid in string form "#123" and return a faked up passwd struct. - */ -struct passwd * -sudo_fakepwnam(user, gid) +static struct passwd * +sudo_fakepwnamid(user, uid, gid) const char *user; + uid_t uid; gid_t gid; { struct cache_item *item; @@ -338,7 +336,7 @@ sudo_fakepwnam(user, 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); @@ -373,6 +371,34 @@ sudo_fakepwnam(user, gid) return pw; } +/* + * Take a uid in string form "#123" and return a faked up passwd struct. + */ +struct passwd * +sudo_fakepwnam(user, gid) + const char *user; + gid_t gid; +{ + uid_t uid; + + uid = (uid_t) atoi(user + 1); + return sudo_fakepwnamid(user, uid, gid); +} + +/* + * Take a uid and gid and return a faked up passwd struct. + */ +struct passwd * +sudo_fakepwuid(uid, gid) + uid_t uid; + gid_t gid; +{ + char user[MAX_UID_T_LEN + 1]; + + (void) snprintf(user, sizeof(user), "#%u", (unsigned int) uid); + return sudo_fakepwnamid(user, uid, gid); +} + void sudo_setpwent() { diff --git a/sudo.c b/sudo.c index aa5ae74c6..6f7e05481 100644 --- a/sudo.c +++ b/sudo.c @@ -659,15 +659,8 @@ init_vars(envp) * Stash a local copy of the user's struct passwd. */ if ((sudo_user.pw = sudo_getpwuid(getuid())) == NULL) { - /* Need to make a fake struct passwd for logging to work. */ - struct passwd pw; - char pw_name[MAX_UID_T_LEN + 1]; - - pw.pw_uid = getuid(); - (void) snprintf(pw_name, sizeof(pw_name), "%u", - (unsigned int) pw.pw_uid); - pw.pw_name = pw_name; - sudo_user.pw = &pw; + uid_t uid = getuid(); + gid_t gid = getgid(); /* * If we are in -k/-K mode, just spew to stderr. It is not unusual for @@ -675,8 +668,11 @@ init_vars(envp) * 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 uid: %s", pw_name); - log_error(0, "unknown uid: %s", pw_name); + errorx(1, "unknown uid: %u", (unsigned int) uid); + + /* Need to make a fake struct passwd for the call to log_error(). */ + sudo_user.pw = sudo_fakepwuid(uid, gid); + log_error(0, "unknown uid: %u", (unsigned int) uid); } #ifdef HAVE_MBR_CHECK_MEMBERSHIP mbr_uid_to_uuid(user_uid, user_uuid); diff --git a/sudo.h b/sudo.h index 8fe4a6bed..acd23633b 100644 --- a/sudo.h +++ b/sudo.h @@ -295,6 +295,7 @@ struct group *sudo_fakegrnam __P((const char *)); struct group *sudo_getgrgid __P((gid_t)); struct group *sudo_getgrnam __P((const char *)); struct passwd *sudo_fakepwnam __P((const char *, gid_t)); +struct passwd *sudo_fakepwuid __P((uid_t uid, gid_t gid)); struct passwd *sudo_getpwnam __P((const char *)); struct passwd *sudo_getpwuid __P((uid_t)); void sudo_endgrent __P((void));