passwd: fix bug: we are trying to update shadow even if user's record is in passwd!

getspnam is guilty, it lies that user record exists in shadow.
This commit is contained in:
Denis Vlasenko 2007-07-27 11:22:34 +00:00
parent 3734b946bf
commit 1d10aaf116
2 changed files with 19 additions and 9 deletions

View File

@ -482,10 +482,10 @@ int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok);
/* chown-like handling of "user[:[group]" */ /* chown-like handling of "user[:[group]" */
void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group); void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group);
/* bb_getpwuid, bb_getgrgid: /* bb_getpwuid, bb_getgrgid:
bb_getXXXid(buf, bufsz, id) - copy user/group name or id * bb_getXXXid(buf, bufsz, id) - copy user/group name or id
as a string to buf, return user/group name or NULL * as a string to buf, return user/group name or NULL
bb_getXXXid(NULL, 0, id) - return user/group name or NULL * bb_getXXXid(NULL, 0, id) - return user/group name or NULL
bb_getXXXid(NULL, -1, id) - return user/group name or exit * bb_getXXXid(NULL, -1, id) - return user/group name or exit
*/ */
char *bb_getpwuid(char *name, int bufsize, long uid); char *bb_getpwuid(char *name, int bufsize, long uid);
char *bb_getgrgid(char *group, int bufsize, long gid); char *bb_getgrgid(char *group, int bufsize, long gid);

View File

@ -127,15 +127,16 @@ int passwd_main(int argc, char **argv)
bb_error_msg_and_die("%s can't change password for %s", myname, name); bb_error_msg_and_die("%s can't change password for %s", myname, name);
} }
filename = bb_path_passwd_file;
#if ENABLE_FEATURE_SHADOWPASSWDS #if ENABLE_FEATURE_SHADOWPASSWDS
if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result)) { /* getspnam_r() can lie! Even if user isn't in shadow, it can
* return success (pwd field was seen set to "!" in this case) */
if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result)
|| LONE_CHAR(spw.sp_pwdp, '!')) {
/* LOGMODE_BOTH */ /* LOGMODE_BOTH */
bb_error_msg("no record of %s in %s, using %s", bb_error_msg("no record of %s in %s, using %s",
name, bb_path_shadow_file, name, bb_path_shadow_file,
bb_path_passwd_file); bb_path_passwd_file);
} else { } else {
filename = bb_path_shadow_file;
pw->pw_passwd = spw.sp_pwdp; pw->pw_passwd = spw.sp_pwdp;
} }
#endif #endif
@ -175,8 +176,17 @@ int passwd_main(int argc, char **argv)
signal(SIGQUIT, SIG_IGN); signal(SIGQUIT, SIG_IGN);
umask(077); umask(077);
xsetuid(0); xsetuid(0);
rc = update_passwd(filename, name, newp);
logmode = LOGMODE_BOTH; #if ENABLE_FEATURE_SHADOWPASSWDS
filename = bb_path_shadow_file;
rc = update_passwd(bb_path_shadow_file, name, newp);
if (rc == 0) /* no lines updated, no errors detected */
#endif
{
filename = bb_path_passwd_file;
rc = update_passwd(bb_path_passwd_file, name, newp);
}
/* LOGMODE_BOTH */
if (rc < 0) if (rc < 0)
bb_error_msg_and_die("cannot update password file %s", bb_error_msg_and_die("cannot update password file %s",
filename); filename);