On 2016/05/05 04:16, mike-...@ya.ru wrote: > Seems it happens after this change: > http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/crypt/crypt.c.diff?r1=1.26&r2=1.27
Yes. https://mariadb.com/kb/en/mariadb/encrypt/: > Encrypts str using the Unix crypt() system call (sic: it's actually a library function not a system call). This doesn't give any guarantees about encryption type though. It just passes to the OS. > If crypt() function entirely excluded from the system, the problem would be > detected on time > and solved by linking with a third party library, as is done in other systems. No, there's no fallback. Yes we should disable this properly so that have_crypt is set correctly. But the behaviour in that case would be the same as you're seeing now. As they say: "If the have_crypt system variable is set to NO (because the crypt() system call is not available), the ENCRYPT function will always return NULL." Here's the code. sql/item_strfunc.cc: 2230 String *Item_func_encrypt::val_str(String *str) 2231 { 2232 DBUG_ASSERT(fixed == 1); 2233 String *res =args[0]->val_str(str); 2234 2235 #ifdef HAVE_CRYPT 2236 char salt[3],*salt_ptr; 2237 if ((null_value=args[0]->null_value)) 2238 return 0; 2239 if (res->length() == 0) 2240 return make_empty_result(); 2241 if (arg_count == 1) 2242 { // generate random salt 2243 time_t timestamp=current_thd->query_start(); 2244 salt[0] = bin_to_ascii( (ulong) timestamp & 0x3f); 2245 salt[1] = bin_to_ascii(( (ulong) timestamp >> 5) & 0x3f); 2246 salt[2] = 0; 2247 salt_ptr=salt; 2248 } 2249 else 2250 { // obtain salt from the first two bytes 2251 String *salt_str=args[1]->val_str(&tmp_value); 2252 if ((null_value= (args[1]->null_value || salt_str->length() < 2))) 2253 return 0; 2254 salt_ptr= salt_str->c_ptr_safe(); 2255 } 2256 mysql_mutex_lock(&LOCK_crypt); 2257 char *tmp= crypt(res->c_ptr_safe(),salt_ptr); 2258 if (!tmp) 2259 { 2260 mysql_mutex_unlock(&LOCK_crypt); 2261 null_value= 1; 2262 return 0; 2263 } 2264 str->set(tmp, (uint) strlen(tmp), &my_charset_bin); 2265 str->copy(); 2266 mysql_mutex_unlock(&LOCK_crypt); 2267 return str; 2268 #else 2269 null_value=1; 2270 return 0; 2271 #endif /* HAVE_CRYPT */ 2272 } > It comes to updating the OS and migration of existing databases. MySQL/MariaDB's password storage support are *junk*. The only native support for salted storage is this ancient crypt. No bcrypt, scrypt, argon2. Even for things like salted SHA-2 you need to construct it yourself. I'd look at ways to handle this in the application instead where you should have access to better tools. Migrate to proper password storage in the database with a fallback in the application to handle unconverted passwords. This can be done before upgrading the db server and continue to function afterwards. Best method is probably to bulk-update all the existing entries so you store "newhash(salt+crypted)" then when someone tries to log in, if "newhash(salt+password)" fails you can try "newhash(salt+crypt(password))" and update the stored entry. (http://www.lornajane.net/posts/2016/upgrade-better-passwords-php)