aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-07-27 11:22:34 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-07-27 11:22:34 +0000
commit1d10aaf11617558592b0215fe85bc42fa444e384 (patch)
tree033e1b9896e651a3ab1d94b255a534ff39a91845
parent3734b946bfef55c8f63d367422da5c7aa7b972db (diff)
downloadbusybox-w32-1d10aaf11617558592b0215fe85bc42fa444e384.tar.gz
busybox-w32-1d10aaf11617558592b0215fe85bc42fa444e384.tar.bz2
busybox-w32-1d10aaf11617558592b0215fe85bc42fa444e384.zip
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.
-rw-r--r--include/libbb.h8
-rw-r--r--loginutils/passwd.c20
2 files changed, 19 insertions, 9 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 82cee380b..b438ec25f 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -482,10 +482,10 @@ int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok);
482/* chown-like handling of "user[:[group]" */ 482/* chown-like handling of "user[:[group]" */
483void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group); 483void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group);
484/* bb_getpwuid, bb_getgrgid: 484/* bb_getpwuid, bb_getgrgid:
485bb_getXXXid(buf, bufsz, id) - copy user/group name or id 485 * bb_getXXXid(buf, bufsz, id) - copy user/group name or id
486 as a string to buf, return user/group name or NULL 486 * as a string to buf, return user/group name or NULL
487bb_getXXXid(NULL, 0, id) - return user/group name or NULL 487 * bb_getXXXid(NULL, 0, id) - return user/group name or NULL
488bb_getXXXid(NULL, -1, id) - return user/group name or exit 488 * bb_getXXXid(NULL, -1, id) - return user/group name or exit
489*/ 489*/
490char *bb_getpwuid(char *name, int bufsize, long uid); 490char *bb_getpwuid(char *name, int bufsize, long uid);
491char *bb_getgrgid(char *group, int bufsize, long gid); 491char *bb_getgrgid(char *group, int bufsize, long gid);
diff --git a/loginutils/passwd.c b/loginutils/passwd.c
index a293ee926..4f7094aec 100644
--- a/loginutils/passwd.c
+++ b/loginutils/passwd.c
@@ -127,15 +127,16 @@ int passwd_main(int argc, char **argv)
127 bb_error_msg_and_die("%s can't change password for %s", myname, name); 127 bb_error_msg_and_die("%s can't change password for %s", myname, name);
128 } 128 }
129 129
130 filename = bb_path_passwd_file;
131#if ENABLE_FEATURE_SHADOWPASSWDS 130#if ENABLE_FEATURE_SHADOWPASSWDS
132 if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result)) { 131 /* getspnam_r() can lie! Even if user isn't in shadow, it can
132 * return success (pwd field was seen set to "!" in this case) */
133 if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result)
134 || LONE_CHAR(spw.sp_pwdp, '!')) {
133 /* LOGMODE_BOTH */ 135 /* LOGMODE_BOTH */
134 bb_error_msg("no record of %s in %s, using %s", 136 bb_error_msg("no record of %s in %s, using %s",
135 name, bb_path_shadow_file, 137 name, bb_path_shadow_file,
136 bb_path_passwd_file); 138 bb_path_passwd_file);
137 } else { 139 } else {
138 filename = bb_path_shadow_file;
139 pw->pw_passwd = spw.sp_pwdp; 140 pw->pw_passwd = spw.sp_pwdp;
140 } 141 }
141#endif 142#endif
@@ -175,8 +176,17 @@ int passwd_main(int argc, char **argv)
175 signal(SIGQUIT, SIG_IGN); 176 signal(SIGQUIT, SIG_IGN);
176 umask(077); 177 umask(077);
177 xsetuid(0); 178 xsetuid(0);
178 rc = update_passwd(filename, name, newp); 179
179 logmode = LOGMODE_BOTH; 180#if ENABLE_FEATURE_SHADOWPASSWDS
181 filename = bb_path_shadow_file;
182 rc = update_passwd(bb_path_shadow_file, name, newp);
183 if (rc == 0) /* no lines updated, no errors detected */
184#endif
185 {
186 filename = bb_path_passwd_file;
187 rc = update_passwd(bb_path_passwd_file, name, newp);
188 }
189 /* LOGMODE_BOTH */
180 if (rc < 0) 190 if (rc < 0)
181 bb_error_msg_and_die("cannot update password file %s", 191 bb_error_msg_and_die("cannot update password file %s",
182 filename); 192 filename);