summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r--sql/item_strfunc.cc125
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)