A note first off, particularly as this is cryptography-related: I have no idea 
what I'm doing. Do not trust my code on my say so, which I'm not giving anyway. 
That said, it works (TM).

There is apparently a new blowfish format supported by bcrypt, denoted by the 
prefix $2b where the previous version used $2a. user(8) checks the length of 
the crypted password supplied to the -p option but does not understand the new 
($2b) format:

# usermod -p "$( echo secret | encrypt )" root                
usermod: Invalid password: 
`$2b$08$NTiZ2vg8UZqhbloFaJLqMOh9mvOVA8eh4upVCJGvVPGALINZje1I2'

The included patch assumes that the opaque crypted string for form b follows 
the same rules as form a, which held true in my solitary test.
--- user.c	2014-07-20 04:38:40.000000000 +0300
+++ user.c.new	2015-02-24 17:33:06.049031636 +0200
@@ -876,12 +876,14 @@
 	int		length;		/* length of password */
 } passwd_type_t;
 
-#define BLF "$2a"
+#define BLFa "$2a"
+#define BLFb "$2b"
 #define MD5 "$1"
 #define DES ""
 
 static passwd_type_t	passwd_types[] = {
-	{ BLF,	3,	54	},	/* Blowfish */
+	{ BLFa,	3,	54	},	/* Blowfish (type a) */
+	{ BLFb,	3,	54	},	/* Blowfish (type b) */
 	{ MD5,	2,	34	},	/* MD5 */
 	{ DES,	0,	DES_Len	},	/* standard DES */
 	{ NULL,	-1,	-1	}	/* none - terminate search */
@@ -897,7 +899,7 @@
 		if (strncmp(newpasswd, pwtp->type, pwtp->desc_length) == 0) {
 			char *p;
 
-			if (strcmp(pwtp->type, BLF) != 0) {
+			if (strcmp(pwtp->type, BLFa) != 0 && strcmp(pwtp->type, BLFb) != 0) {
 				return strlen(newpasswd) == pwtp->length;
 			}
 			/* Skip first three `$'. */

Reply via email to