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

Reply via email to