diff options
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r-- | sql/item_strfunc.cc | 125 |
1 files changed, 115 insertions, 10 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9b88e45be0e..a8287d5fe43 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1808,28 +1808,133 @@ void Item_func_trim::print(String *str, enum_query_type query_type) /* Item_func_password */ +/** + Helper function for calculating a new password. Used in + Item_func_password::fix_length_and_dec() for const parameters and in + Item_func_password::val_str_ascii() for non-const parameters. + @param str The plain text password which should be digested + @param buffer a pointer to the buffer where the digest will be stored. + + @note The buffer must be of at least CRYPT_MAX_PASSWORD_SIZE size. + + @return Size of the password. +*/ + +static int calculate_password(String *str, char *buffer) +{ + DBUG_ASSERT(str); + if (str->length() == 0) // PASSWORD('') returns '' + return 0; + + int buffer_len= 0; + THD *thd= current_thd; + int old_passwords= 0; + if (thd) + old_passwords= thd->variables.old_passwords; + +#if defined(HAVE_OPENSSL) + if (old_passwords == 2) + { + my_make_scrambled_password(buffer, str->ptr(), + str->length()); + buffer_len= (int) strlen(buffer) + 1; + } + else +#endif + if (old_passwords == 0) + { + my_make_scrambled_password_sha1(buffer, str->ptr(), + str->length()); + buffer_len= SCRAMBLED_PASSWORD_CHAR_LENGTH; + } + else + if (old_passwords == 1) + { + my_make_scrambled_password_323(buffer, str->ptr(), + str->length()); + buffer_len= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; + } + return buffer_len; +} + +/* Item_func_password */ +void Item_func_password::fix_length_and_dec() +{ + maybe_null= false; // PASSWORD() never returns NULL + + if (args[0]->const_item()) + { + String str; + String *res= args[0]->val_str(&str); + if (!args[0]->null_value) + { + m_hashed_password_buffer_len= + calculate_password(res, m_hashed_password_buffer); + fix_length_and_charset(m_hashed_password_buffer_len, default_charset()); + m_recalculate_password= false; + return; + } + } + + m_recalculate_password= true; + fix_length_and_charset(CRYPT_MAX_PASSWORD_SIZE, default_charset()); +} + String *Item_func_password::val_str_ascii(String *str) { DBUG_ASSERT(fixed == 1); - String *res= args[0]->val_str(str); - if ((null_value=args[0]->null_value)) - return 0; - if (res->length() == 0) + + String *res= args[0]->val_str(str); + + if (args[0]->null_value) + res= make_empty_result(); + + /* we treat NULLs as equal to empty string when calling the plugin */ + check_password_policy(res); + + null_value= 0; + if (args[0]->null_value) // PASSWORD(NULL) returns '' + return res; + + if (m_recalculate_password) + m_hashed_password_buffer_len= calculate_password(res, + m_hashed_password_buffer); + + if (m_hashed_password_buffer_len == 0) return make_empty_result(); - my_make_scrambled_password(tmp_value, res->ptr(), res->length()); - str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, &my_charset_latin1); + + str->set(m_hashed_password_buffer, m_hashed_password_buffer_len, + default_charset()); + return str; } -char *Item_func_password::alloc(THD *thd, const char *password, - size_t pass_len) +char *Item_func_password:: + create_password_hash_buffer(THD *thd, const char *password, size_t pass_len) { - char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1); - if (buff) + String *password_str= new (thd->mem_root)String(password, thd->variables. + character_set_client); + check_password_policy(password_str); + + char *buff= NULL; + if (thd->variables.old_passwords == 0) + { + /* Allocate memory for the password scramble and one extra byte for \0 */ + buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH + 1); + my_make_scrambled_password_sha1(buff, password, pass_len); + } +#if defined(HAVE_OPENSSL) + else + { + /* Allocate memory for the password scramble and one extra byte for \0 */ + buff= (char *) thd->alloc(CRYPT_MAX_PASSWORD_SIZE + 1); my_make_scrambled_password(buff, password, pass_len); + } +#endif return buff; } + /* Item_func_old_password */ String *Item_func_old_password::val_str_ascii(String *str) |