summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRicardo Mestre <mestre@cvs.openbsd.org>2016-05-03 21:05:15 +0000
committerRicardo Mestre <mestre@cvs.openbsd.org>2016-05-03 21:05:15 +0000
commit574e25e5346a072323ee6caae33aa7e17663a910 (patch)
tree0bfdd3a8b6d58dc827ddf947f9393cb4338f809e
parent038c1503d1e9350cd20c8a09443719bfcda1f66d (diff)
Fix regression on usermod/userdel by calling getpwnam_shadow(3) and saving
passwd hash early, instead of getpwnam(3), then close fds by calling endpwent(3) and finally only call pledge(2) after it, otherwise on any modification to the user it would destroy the passwd hash and therefore forbidding him/her to login again to the machine. Reported and tested by Edgar Pettijohn <edgar ! pettijohn-web at com> According to deraadt@ "that looks better then"
-rw-r--r--usr.sbin/user/user.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/usr.sbin/user/user.c b/usr.sbin/user/user.c
index 95deb93f9b5..27344a768b8 100644
--- a/usr.sbin/user/user.c
+++ b/usr.sbin/user/user.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: user.c,v 1.110 2016/05/02 15:25:03 millert Exp $ */
+/* $OpenBSD: user.c,v 1.111 2016/05/03 21:05:14 mestre Exp $ */
/* $NetBSD: user.c,v 1.69 2003/04/14 17:40:07 agc Exp $ */
/*
@@ -1377,7 +1377,7 @@ is_local(char *name, const char *file)
static int
moduser(char *login_name, char *newlogin, user_t *up)
{
- struct passwd *pwp;
+ struct passwd *pwp = NULL;
struct group *grp;
const char *homedir;
char buf[LINE_MAX];
@@ -1405,9 +1405,23 @@ moduser(char *login_name, char *newlogin, user_t *up)
if (!valid_login(newlogin)) {
errx(EXIT_FAILURE, "`%s' is not a valid login name", login_name);
}
- if ((pwp = getpwnam(login_name)) == NULL) {
+ if ((pwp = getpwnam_shadow(login_name)) == NULL) {
errx(EXIT_FAILURE, "No such user `%s'", login_name);
}
+ if (up != NULL) {
+ if ((*pwp->pw_passwd != '\0') && (up->u_flags &~ F_PASSWORD)) {
+ up->u_flags |= F_PASSWORD;
+ memsave(&up->u_password, pwp->pw_passwd,
+ strlen(pwp->pw_passwd));
+ memset(pwp->pw_passwd, 'X', strlen(pwp->pw_passwd));
+ }
+ }
+ endpwent();
+
+ if (pledge("stdio rpath wpath cpath fattr flock proc exec getpw id",
+ NULL) == -1)
+ err(1, "pledge");
+
if (!is_local(login_name, _PATH_MASTERPASSWD)) {
errx(EXIT_FAILURE, "User `%s' must be a local user", login_name);
}
@@ -1987,10 +2001,6 @@ usermod(int argc, char **argv)
}
}
- if (pledge("stdio rpath wpath cpath fattr flock proc exec getpw id",
- NULL) == -1)
- err(1, "pledge");
-
if ((u.u_flags & F_MKDIR) && !(u.u_flags & F_HOMEDIR) &&
!(u.u_flags & F_USERNAME)) {
warnx("option 'm' useless without 'd' or 'l' -- ignored");