summaryrefslogtreecommitdiffstats
path: root/usr.sbin/user
diff options
context:
space:
mode:
authormestre <mestre@openbsd.org>2016-05-03 21:05:14 +0000
committermestre <mestre@openbsd.org>2016-05-03 21:05:14 +0000
commit716c272b16e98a852f63d814e666ff1349874d08 (patch)
tree0c6de3cfdfb869b5a642b785fa1d906c874c1138 /usr.sbin/user
parentFix some Perl statements perlcritic was bitching about: Variable (diff)
downloadwireguard-openbsd-716c272b16e98a852f63d814e666ff1349874d08.tar.xz
wireguard-openbsd-716c272b16e98a852f63d814e666ff1349874d08.zip
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"
Diffstat (limited to 'usr.sbin/user')
-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");