I am locking an account with
# doas usermod -Z foobar
after that, i want to remove the user from all groups:
# doas usermod -S '' foobar
usermod: Invalid password:
`*$2b$09$Pp.mDUEORDRbCUUy4D.Vf.EhvxVA.B1u0T7VAlsKN7sU7wqhs0l3W'
This happens in -current and is caused by usr.sbin/user/user.c as of
/* $OpenBSD: user.c,v 1.111 2016/05/03 21:05:14 mestre Exp $ */
which was done to fix another bug.
The problem with that change is this change
+ if (up != NULL) {
+ if ((*pwp->pw_passwd != '\0') && (up->u_flags &~ F_PASSWORD)) {
+ up->u_flags |= F_PASSWORD;
which sets F_PASSWORD and causes this bit to check the password
if (up->u_flags & F_PASSWORD) {
if (up->u_password != NULL) {
if (!valid_password_length(up->u_password)) {
(void) close(ptmpfd);
pw_abort();
errx(EXIT_FAILURE, "Invalid password:
`%s'",
up->u_password);
}
pwp->pw_passwd = up->u_password;
}
}
Of course this will not only affect -S, but all other changes that are done
on an account with an invalid password.
from usermod(8):
-Z Lock the account by appending a `-' to the user's shell and
prefixing the password with `*'. -Z and -U are mutually
exclusive and cannot be used with -p.
and
-S secondary-group[,group,...]
Sets the secondary groups the user will be a member of in the
/etc/group file. Setting secondary-group to an empty value
(e.g. '') removes the user from all secondary groups.
This fix uses a new flag for the check and does not verify if the password
is valid in that case.
ok?
diff --git usr.sbin/user/user.c usr.sbin/user/user.c
index 27344a7..c4c33d6 100644
--- usr.sbin/user/user.c
+++ usr.sbin/user/user.c
@@ -103,7 +103,8 @@ enum {
F_CLASS = 0x1000,
F_SETSECGROUP = 0x4000,
F_ACCTLOCK = 0x8000,
- F_ACCTUNLOCK = 0x10000
+ F_ACCTUNLOCK = 0x10000,
+ F_KEEPPASSWORD = 0x20000
};
#define CONFFILE "/etc/usermgmt.conf"
@@ -1410,7 +1411,7 @@ moduser(char *login_name, char *newlogin, user_t *up)
}
if (up != NULL) {
if ((*pwp->pw_passwd != '\0') && (up->u_flags &~ F_PASSWORD)) {
- up->u_flags |= F_PASSWORD;
+ up->u_flags |= F_KEEPPASSWORD;
memsave(&up->u_password, pwp->pw_passwd,
strlen(pwp->pw_passwd));
memset(pwp->pw_passwd, 'X', strlen(pwp->pw_passwd));
@@ -1486,6 +1487,9 @@ moduser(char *login_name, char *newlogin, user_t *up)
pwp->pw_passwd = up->u_password;
}
}
+ if (up->u_flags & F_KEEPPASSWORD) {
+ pwp->pw_passwd = up->u_password;
+ }
if (up->u_flags & F_ACCTLOCK) {
/* lock the account */
if (*shell_last_char != *acctlock_str) {