Subject: bin/21901: MD5 password with useradd/usermod
To: None <gnats-bugs@gnats.netbsd.org>
From: None <takumi@stride-ltd.co.jp>
List: netbsd-bugs
Date: 06/16/2003 08:42:55
>Number:         21901
>Category:       bin
>Synopsis:       MD5 password with useradd/usermod
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 16 08:43:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     NAKAMURA Takumi
>Release:        1.6
>Organization:
STRIDE,LTD.
>Environment:
NetBSD orthoclause.bwa.local 1.6 NetBSD 1.6 (GENERIC) #0: Sun Sep  8 19:43:40 UTC 2002     autobuild@tgm.daemon.org:/autobuild/i386/OBJ/autobuild/src/sys/arch/i386/compile/GENERIC i386
>Description:
useradd/usermod (-p option) doesn't accept encrypted MD5 password.

These commands check password length. If that length isn't equal to 13
(length of encrypted DES password), they doesn't change password field.

The length of encrypted MD5 password is 34. So, these commands always
discard MD5 password from -p option.
>How-To-Repeat:
1. Set /etc/passwd.conf "localcipher = md5".
2. create user by useradd command. (not -p option)
3. set initial password with passwd command.
4. set different password with usermod command. (encrypted MD5
 password from -p option)

/etc/master.passwd is updated, but password field is left unchanged.

>Fix:
/usr/src/user.sbin/users/

*** user.c.original     Tue Jun  4 21:09:56 2002
--- user.c      Mon Jun 16 16:35:29 2003
***************
*** 166,171 ****
--- 166,172 ----
        MaxCommandLen = 2048,
        MaxEntryLen = 2048,
        PasswordLength = 13,
+       Md5PasswordLength = 34,

        LowGid = DEF_LOWUID,
        HighGid = DEF_HIGHUID
***************
*** 877,883 ****
        struct tm       tm;
        time_t          expire;
        time_t          inactive;
!       char            password[PasswordLength + 1];
        char            home[MaxFileNameLen];
        char            buf[MaxFileNameLen];
        int             sync_uid_gid;
--- 878,884 ----
        struct tm       tm;
        time_t          expire;
        time_t          inactive;
!       char            password[Md5PasswordLength + 1];
        char            home[MaxFileNameLen];
        char            buf[MaxFileNameLen];
        int             sync_uid_gid;
***************
*** 1009,1014 ****
--- 1010,1020 ----
        if (up->u_password != NULL &&
            strlen(up->u_password) == PasswordLength) {
                (void) memcpy(password, up->u_password, PasswordLength);
+       }else
+       if (up->u_password != NULL &&
+           strlen(up->u_password) == Md5PasswordLength && memcmp(up->u_password, "$1", 2) == 0) {
+               (void) memcpy(password, up->u_password, Md5PasswordLength);
+               password[Md5PasswordLength] = '\0';
        } else {
                (void) memset(password, '*', PasswordLength);
                if (up->u_password != NULL) {
***************
*** 1138,1145 ****
                        }
                }
                if (up->u_flags & F_PASSWORD) {
!                       if (up->u_password != NULL && strlen(up->u_password) == PasswordLength)
!                               pwp->pw_passwd = up->u_password;
                }
                if (up->u_flags & F_UID) {
                        /* check uid isn't already allocated */
--- 1144,1155 ----
                        }
                }
                if (up->u_flags & F_PASSWORD) {
!                       if (up->u_password != NULL) {
!                               int length = strlen(up->u_password);
!                               if (length == PasswordLength || length == Md5PasswordLength) {
!                                       pwp->pw_passwd = up->u_password;
!                               }
!                       }
                }
                if (up->u_flags & F_UID) {
                        /* check uid isn't already allocated */

>Release-Note:
>Audit-Trail:
>Unformatted: