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) {