List:Commits« Previous MessageNext Message »
From:Ashish Agarwal Date:May 18 2012 6:33am
Subject:bzr push into mysql-trunk branch (ashish.y.agarwal:3888 to 3889)
View as plain text  
 3889 Ashish Agarwal	2012-05-18
      WL2739: Auditing Password Security
              Implementing review comment

    added:
      sql/string_service.cc
      sql/string_service.h
    modified:
      include/mysql/plugin_audit.h.pp
      include/mysql/plugin_auth.h.pp
      include/mysql/plugin_ftparser.h.pp
      include/mysql/plugin_validate_password.h
      include/mysql/service_mysql_string.h
      mysql-test/include/have_validate_password_plugin.inc
      mysql-test/include/plugin.defs
      mysql-test/r/validate_password_plugin.result
      mysql-test/t/validate_password_plugin-master.opt
      mysql-test/t/validate_password_plugin.test
      plugin/password_validation/validate_password.cc
      sql/CMakeLists.txt
      sql/item_strfunc.cc
      sql/share/errmsg-utf8.txt
      sql/sql_acl.cc
      sql/sql_acl.h
      sql/sql_plugin_services.h
      sql/sql_yacc.yy
 3888 Ashish Agarwal	2012-05-14
      WL2739: Auditing Password Security
              Implementing review comments.

    removed:
      include/mysql/service_password_string.h
      libservices/password_string_service.c
    added:
      include/mysql/service_mysql_string.h
      libservices/mysql_string_service.c
    modified:
      include/mysql/plugin_audit.h.pp
      include/mysql/plugin_auth.h.pp
      include/mysql/plugin_ftparser.h.pp
      include/mysql/plugin_validate_password.h
      include/mysql/services.h
      include/service_versions.h
      libservices/CMakeLists.txt
      mysql-test/include/have_validate_password_plugin.inc
      mysql-test/include/plugin.defs
      mysql-test/r/validate_password_plugin.result
      mysql-test/t/validate_password_plugin-master.opt
      mysql-test/t/validate_password_plugin.test
      plugin/password_validation/CMakeLists.txt
      plugin/password_validation/validate_password.cc
      sql/item_func.cc
      sql/item_strfunc.cc
      sql/share/errmsg-utf8.txt
      sql/sql_acl.cc
      sql/sql_plugin.h
      sql/sql_plugin_services.h
=== modified file 'include/mysql/plugin_audit.h.pp'
--- a/include/mysql/plugin_audit.h.pp	2012-05-14 11:18:13 +0000
+++ b/include/mysql/plugin_audit.h.pp	2012-05-18 06:31:26 +0000
@@ -74,25 +74,34 @@ extern struct my_plugin_log_service
 int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
                           const char *format, ...);
 #include <mysql/service_mysql_string.h>
-typedef void *mysql_string_ptr;
+typedef void *mysql_string_iterator_handle;
+typedef void *mysql_string_handle;
 extern struct mysql_string_service_st {
-  const char *(*mysql_string_character_beg_type)(mysql_string_ptr);
-  const char *(*mysql_string_character_end_type)(mysql_string_ptr);
-  const char *(*mysql_string_character_casedn_type)(mysql_string_ptr);
-  int (*mysql_string_character_ctype_type)
-      (mysql_string_ptr, int *, const char*);
-  int (*mysql_string_character_isupper_type)(int);
-  int (*mysql_string_character_islower_type)(int);
-  int (*mysql_string_character_isdigit_type)(int);
+  int (*mysql_string_convert_to_char_ptr_type)
+       (mysql_string_handle, const char *, char *, int *);
+  mysql_string_iterator_handle (*mysql_string_get_iterator_type)
+                                (mysql_string_handle);
+  int (*mysql_string_iterator_next_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_isupper_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_islower_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_isdigit_type)(mysql_string_iterator_handle);
+  mysql_string_handle (*mysql_string_to_lowercase_type)(mysql_string_handle);
+  void (*mysql_string_free_type)(mysql_string_handle);
+  void (*mysql_string_iterator_free_type)(mysql_string_iterator_handle);
 } *mysql_string_service;
-const char *mysql_string_character_beg(mysql_string_ptr string_ptr);
-const char *mysql_string_character_end(mysql_string_ptr string_ptr);
-const char *mysql_string_character_casedn(mysql_string_ptr string_ptr);
-int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
-                                 const char * current_ptr);
-int mysql_string_character_isupper(int char_type);
-int mysql_string_character_islower(int char_type);
-int mysql_string_character_isdigit(int char_type);
+int mysql_string_convert_to_char_ptr(mysql_string_handle string_handle,
+                                     const char *charset_name, char *buffer,
+                                     int *error);
+mysql_string_iterator_handle mysql_string_get_iterator(mysql_string_handle
+                                                       string_handle);
+int mysql_string_iterator_next(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isupper(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_islower(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isdigit(mysql_string_iterator_handle iterator_handle);
+mysql_string_handle mysql_string_to_lowercase(mysql_string_handle
+                                              string_handle);
+void mysql_string_free(mysql_string_handle);
+void mysql_string_iterator_free(mysql_string_iterator_handle);
 struct st_mysql_xid {
   long formatID;
   long gtrid_length;

=== modified file 'include/mysql/plugin_auth.h.pp'
--- a/include/mysql/plugin_auth.h.pp	2012-05-14 11:18:13 +0000
+++ b/include/mysql/plugin_auth.h.pp	2012-05-18 06:31:26 +0000
@@ -74,25 +74,34 @@ extern struct my_plugin_log_service
 int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
                           const char *format, ...);
 #include <mysql/service_mysql_string.h>
-typedef void *mysql_string_ptr;
+typedef void *mysql_string_iterator_handle;
+typedef void *mysql_string_handle;
 extern struct mysql_string_service_st {
-  const char *(*mysql_string_character_beg_type)(mysql_string_ptr);
-  const char *(*mysql_string_character_end_type)(mysql_string_ptr);
-  const char *(*mysql_string_character_casedn_type)(mysql_string_ptr);
-  int (*mysql_string_character_ctype_type)
-      (mysql_string_ptr, int *, const char*);
-  int (*mysql_string_character_isupper_type)(int);
-  int (*mysql_string_character_islower_type)(int);
-  int (*mysql_string_character_isdigit_type)(int);
+  int (*mysql_string_convert_to_char_ptr_type)
+       (mysql_string_handle, const char *, char *, int *);
+  mysql_string_iterator_handle (*mysql_string_get_iterator_type)
+                                (mysql_string_handle);
+  int (*mysql_string_iterator_next_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_isupper_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_islower_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_isdigit_type)(mysql_string_iterator_handle);
+  mysql_string_handle (*mysql_string_to_lowercase_type)(mysql_string_handle);
+  void (*mysql_string_free_type)(mysql_string_handle);
+  void (*mysql_string_iterator_free_type)(mysql_string_iterator_handle);
 } *mysql_string_service;
-const char *mysql_string_character_beg(mysql_string_ptr string_ptr);
-const char *mysql_string_character_end(mysql_string_ptr string_ptr);
-const char *mysql_string_character_casedn(mysql_string_ptr string_ptr);
-int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
-                                 const char * current_ptr);
-int mysql_string_character_isupper(int char_type);
-int mysql_string_character_islower(int char_type);
-int mysql_string_character_isdigit(int char_type);
+int mysql_string_convert_to_char_ptr(mysql_string_handle string_handle,
+                                     const char *charset_name, char *buffer,
+                                     int *error);
+mysql_string_iterator_handle mysql_string_get_iterator(mysql_string_handle
+                                                       string_handle);
+int mysql_string_iterator_next(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isupper(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_islower(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isdigit(mysql_string_iterator_handle iterator_handle);
+mysql_string_handle mysql_string_to_lowercase(mysql_string_handle
+                                              string_handle);
+void mysql_string_free(mysql_string_handle);
+void mysql_string_iterator_free(mysql_string_iterator_handle);
 struct st_mysql_xid {
   long formatID;
   long gtrid_length;

=== modified file 'include/mysql/plugin_ftparser.h.pp'
--- a/include/mysql/plugin_ftparser.h.pp	2012-05-14 11:18:13 +0000
+++ b/include/mysql/plugin_ftparser.h.pp	2012-05-18 06:31:26 +0000
@@ -74,25 +74,34 @@ extern struct my_plugin_log_service
 int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
                           const char *format, ...);
 #include <mysql/service_mysql_string.h>
-typedef void *mysql_string_ptr;
+typedef void *mysql_string_iterator_handle;
+typedef void *mysql_string_handle;
 extern struct mysql_string_service_st {
-  const char *(*mysql_string_character_beg_type)(mysql_string_ptr);
-  const char *(*mysql_string_character_end_type)(mysql_string_ptr);
-  const char *(*mysql_string_character_casedn_type)(mysql_string_ptr);
-  int (*mysql_string_character_ctype_type)
-      (mysql_string_ptr, int *, const char*);
-  int (*mysql_string_character_isupper_type)(int);
-  int (*mysql_string_character_islower_type)(int);
-  int (*mysql_string_character_isdigit_type)(int);
+  int (*mysql_string_convert_to_char_ptr_type)
+       (mysql_string_handle, const char *, char *, int *);
+  mysql_string_iterator_handle (*mysql_string_get_iterator_type)
+                                (mysql_string_handle);
+  int (*mysql_string_iterator_next_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_isupper_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_islower_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_isdigit_type)(mysql_string_iterator_handle);
+  mysql_string_handle (*mysql_string_to_lowercase_type)(mysql_string_handle);
+  void (*mysql_string_free_type)(mysql_string_handle);
+  void (*mysql_string_iterator_free_type)(mysql_string_iterator_handle);
 } *mysql_string_service;
-const char *mysql_string_character_beg(mysql_string_ptr string_ptr);
-const char *mysql_string_character_end(mysql_string_ptr string_ptr);
-const char *mysql_string_character_casedn(mysql_string_ptr string_ptr);
-int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
-                                 const char * current_ptr);
-int mysql_string_character_isupper(int char_type);
-int mysql_string_character_islower(int char_type);
-int mysql_string_character_isdigit(int char_type);
+int mysql_string_convert_to_char_ptr(mysql_string_handle string_handle,
+                                     const char *charset_name, char *buffer,
+                                     int *error);
+mysql_string_iterator_handle mysql_string_get_iterator(mysql_string_handle
+                                                       string_handle);
+int mysql_string_iterator_next(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isupper(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_islower(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isdigit(mysql_string_iterator_handle iterator_handle);
+mysql_string_handle mysql_string_to_lowercase(mysql_string_handle
+                                              string_handle);
+void mysql_string_free(mysql_string_handle);
+void mysql_string_iterator_free(mysql_string_iterator_handle);
 struct st_mysql_xid {
   long formatID;
   long gtrid_length;

=== modified file 'include/mysql/plugin_validate_password.h'
--- a/include/mysql/plugin_validate_password.h	2012-05-14 11:18:13 +0000
+++ b/include/mysql/plugin_validate_password.h	2012-05-18 06:31:26 +0000
@@ -21,7 +21,7 @@
 #include <mysql/plugin.h>
 #define MYSQL_VALIDATE_PASSWORD_INTERFACE_VERSION 0x0100
 
-typedef void* string_handle;
+typedef void *mysql_string_handle;
 
 /*  
   The descriptor structure for the plugin, that is referred from
@@ -36,11 +36,11 @@ struct st_mysql_validate_password
     policy (as choosen by plugin variable) and FALSE for all other
     password
   */
-  int (*validate_password)(string_handle password, size_t password_length);
+  int (*validate_password)(mysql_string_handle password);
   /*  
     This function returns the password strength (0-100) depending
     upon the policies
   */
-  int (*get_password_strength)(string_handle password, size_t password_length);
+  int (*get_password_strength)(mysql_string_handle password);
 };
 #endif

=== modified file 'include/mysql/service_mysql_string.h'
--- a/include/mysql/service_mysql_string.h	2012-05-14 11:18:13 +0000
+++ b/include/mysql/service_mysql_string.h	2012-05-18 06:31:26 +0000
@@ -26,76 +26,103 @@
 extern "C" {
 #endif
 
-typedef void *mysql_string_ptr;
+typedef void *mysql_string_iterator_handle;
+typedef void *mysql_string_handle;
 
 extern struct mysql_string_service_st {
-  const char *(*mysql_string_character_beg_type)(mysql_string_ptr);
-  const char *(*mysql_string_character_end_type)(mysql_string_ptr);
-  const char *(*mysql_string_character_casedn_type)(mysql_string_ptr);
-  int (*mysql_string_character_ctype_type)
-      (mysql_string_ptr, int *, const char*);
-  int (*mysql_string_character_isupper_type)(int);
-  int (*mysql_string_character_islower_type)(int);
-  int (*mysql_string_character_isdigit_type)(int);
+  int (*mysql_string_convert_to_char_ptr_type)
+       (mysql_string_handle, const char *, char *, int *);
+  mysql_string_iterator_handle (*mysql_string_get_iterator_type)
+                                (mysql_string_handle);
+  int (*mysql_string_iterator_next_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_isupper_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_islower_type)(mysql_string_iterator_handle);
+  int (*mysql_string_iterator_isdigit_type)(mysql_string_iterator_handle);
+  mysql_string_handle (*mysql_string_to_lowercase_type)(mysql_string_handle);
+  void (*mysql_string_free_type)(mysql_string_handle);
+  void (*mysql_string_iterator_free_type)(mysql_string_iterator_handle);
 } *mysql_string_service;
 
 #ifdef MYSQL_DYNAMIC_PLUGIN
 
-#define mysql_string_character_beg(string_ptr) \
-        mysql_string_service->mysql_string_character_beg_type(string_ptr)
-
-#define mysql_string_character_end(string_ptr) \
-        mysql_string_service->mysql_string_character_end_type(string_ptr)
-
-#define mysql_string_character_casedn(string_ptr) \
-        mysql_string_service->mysql_string_character_casedn_type(string_ptr)
-
-#define mysql_string_character_ctype(string_ptr, char_type, current_ptr) \
-        mysql_string_service->mysql_string_character_ctype_type \
-                              (string_ptr, char_type, current_ptr)
-
-#define mysql_string_character_isupper(char_type) \
-        mysql_string_service->mysql_string_character_isupper_type(char_type)
-
-#define mysql_string_character_islower(char_type) \
-        mysql_string_service->mysql_string_character_islower_type(char_type)
-
-#define mysql_string_character_isdigit(char_type) \
-        mysql_string_service->mysql_string_character_isdigit_type(char_type)
+#define mysql_string_convert_to_char_ptr(string_handle, charset_name, \
+                                         buffer, error) \
+        mysql_string_service->mysql_string_convert_to_char_ptr_type \
+                              (string_handle, charset_name, buffer, error)
+
+#define mysql_string_get_iterator(string_handle) \
+        mysql_string_service->mysql_string_get_iterator_type(string_handle)
+
+#define mysql_string_iterator_next(iterator_handle) \
+        mysql_string_service->mysql_string_iterator_next_type(iterator_handle)
+
+#define mysql_string_iterator_isupper(iterator_handle) \
+        mysql_string_service->mysql_string_iterator_isupper_type \
+                                     (iterator_handle)
+
+#define mysql_string_iterator_islower(iterator_handle) \
+        mysql_string_service->mysql_string_iterator_islower_type \
+                                     (iterator_handle)
+
+#define mysql_string_iterator_isdigit(iterator_handle) \
+        mysql_string_service->mysql_string_iterator_isdigit_type \
+                                     (iterator_handle)
+
+#define mysql_string_to_lowercase(string_handle) \
+        mysql_string_service->mysql_string_to_lowercase_type(string_handle)
+
+#define mysql_string_free(mysql_string_handle) \
+        mysql_string_service->mysql_string_free_type(mysql_string_handle)
+
+#define mysql_string_iterator_free(mysql_string_iterator_handle) \
+        mysql_string_service->mysql_string_iterator_free_type \
+                                  (mysql_string_iterator_handle)
 #else
 
-/* This service function returns the beginning of the mysql String */
-const char *mysql_string_character_beg(mysql_string_ptr string_ptr);
-
-/* This service function returns the end of the mysql String */
-const char *mysql_string_character_end(mysql_string_ptr string_ptr);
-
-/* This service function converts mysql String into lowercase */
-const char *mysql_string_character_casedn(mysql_string_ptr string_ptr);
-
+/* This service function convert string into given character set */
+int mysql_string_convert_to_char_ptr(mysql_string_handle string_handle,
+                                     const char *charset_name, char *buffer,
+                                     int *error);
+
+/* This service function returns the beginning of the iterator handle */
+mysql_string_iterator_handle mysql_string_get_iterator(mysql_string_handle
+                                                       string_handle);
 /*  
-  This service function takes mysql string, current string position
-  calculate the ctype of the character based on client character set
-  store it in char_type and return the character length
+  This service function gets the next iterator handle
+  returns 0 if reached the end else return 1
 */
-int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
-                                 const char *current_ptr);
+int mysql_string_iterator_next(mysql_string_iterator_handle iterator_handle);
 
 /*  
-  This service function return 1 if character is a uppercase
-  character else return 0 for client character set.
+  This service function return 1 if current iterator handle points to a
+  uppercase character else return 0 for client character set.
 */
-int mysql_string_character_isupper(int char_type);
+int mysql_string_iterator_isupper(mysql_string_iterator_handle iterator_handle);
+
 /*  
-  This service function return 1 if character is a lowercase
-  character else return 0 for client character set.
+  This service function return 1 if current iterator handle points to a
+  lowercase character else return 0 for client character set.
 */
-int mysql_string_character_islower(int char_type);
+int mysql_string_iterator_islower(mysql_string_iterator_handle iterator_handle);
+
 /*  
-  This service function return 1 if character is a digit
+  This service function return 1 if current iterator handle points to a digit
   else return 0 for client character sets.
 */
-int mysql_string_character_isdigit(int char_type);
+int mysql_string_iterator_isdigit(mysql_string_iterator_handle iterator_handle);
+
+/* convert string_handle into lowercase */
+mysql_string_handle mysql_string_to_lowercase(mysql_string_handle
+                                              string_handle);
+
+/* It deallocates the string created on server side during plugin operations */
+void mysql_string_free(mysql_string_handle);
+
+/*  
+  It deallocates the string iterator created on server side
+  during plugin operations
+*/
+void mysql_string_iterator_free(mysql_string_iterator_handle);
 
 #endif
 #ifdef __cplusplus

=== modified file 'mysql-test/include/have_validate_password_plugin.inc'
--- a/mysql-test/include/have_validate_password_plugin.inc	2012-05-14 11:18:13 +0000
+++ b/mysql-test/include/have_validate_password_plugin.inc	2012-05-18 06:31:26 +0000
@@ -1,5 +1,20 @@
-disable_query_log;
---require r/true.require
-select (PLUGIN_LIBRARY LIKE 'validate_password%') as `TRUE` FROM INFORMATION_SCHEMA.PLUGINS
-  WHERE PLUGIN_NAME='validate_password';
-enable_query_log;
+#
+# Check if server has support for loading plugins
+#
+if (`SELECT @@have_dynamic_loading != 'YES'`) {
+  --skip validate password requires dynamic loading
+}
+
+#
+# Check if the variable VALIDATE_PASSWORD is set
+#
+if (!$VALIDATE_PASSWORD) {
+  --skip validate password requires the environment variable \$VALIDATE_PASSWORD to be set (normally done by mtr)
+}
+
+#
+# Check if --plugin-dir was setup for validate password
+#
+if (`SELECT CONCAT('--plugin-dir=', REPLACE(@@plugin_dir, '\\\\', '/')) != '$VALIDATE_PASSWORD_OPT/'`) {
+  --skip validate password requires that --plugin-dir is set to the validate password dir (either the .opt file does not contain \$VALIDATE_PASSWORD_OPT or another plugin is in use)
+}

=== modified file 'mysql-test/include/plugin.defs'
--- a/mysql-test/include/plugin.defs	2012-05-14 11:18:13 +0000
+++ b/mysql-test/include/plugin.defs	2012-05-18 06:31:26 +0000
@@ -44,4 +44,4 @@ adt_null           plugin/audit_null  AU
 libdaemon_example  plugin/daemon_example DAEMONEXAMPLE
 libmemcached       plugin/innodb_memcached/daemon_memcached DAEMON_MEMCACHED daemon_memcached
 innodb_engine      plugin/innodb_memcached/innodb_memcache INNODB_ENGINE
-validate_password  plugin/password_validation VALIDATE_PASSWORD validate_password
+validate_password  plugin/password_validation VALIDATE_PASSWORD

=== modified file 'mysql-test/r/validate_password_plugin.result'
--- a/mysql-test/r/validate_password_plugin.result	2012-05-14 11:18:13 +0000
+++ b/mysql-test/r/validate_password_plugin.result	2012-05-18 06:31:26 +0000
@@ -1,49 +1,57 @@
-SET @@global.validate_password_policy_number= 1;
-CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'password';
-GRANT ALL ON mysql.* TO 'user1'@'localhost' IDENTIFIED BY 'password';
-# password policy low (which only check for password length)
+CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'pass';
+GRANT ALL ON mysql.* TO 'user1'@'localhost' IDENTIFIED BY 'pass';
+INSTALL PLUGIN validate_password SONAME 'validate_password.so';
+# password policy LOW (which only check for password length)
 # default case: password length should be minimum 8
+SET @@global.validate_password_policy_number=LOW;
 CREATE USER 'user'@'localhost' IDENTIFIED BY '';
-ERROR HY000: Your password does not satisfy the current policy requirements ''
+ERROR HY000: Your password does not satisfy the current policy requirements 
 SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password');
 SET @@global.validate_password_length= 12;
 UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='base_user';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1234';
 SET @@global.validate_password_length= 8;
-# password policy medium (check for mixed_case, digits, special_chars)
+# password policy MEDIUM (check for mixed_case, digits, special_chars)
 # default case : atleast 1 mixed_case, 1 digit, 1 special_char
-SET @@global.validate_password_policy_number= 2;
+SET @@global.validate_password_policy_number=MEDIUM;
 CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
 SET @@global.validate_password_number_count= 2;
 UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password1A#'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 UPDATE mysql.user SET PASSWORD= PASSWORD('password12A#') WHERE user='base_user';
 SET @@global.validate_password_number_count= 1;
 SET @@global.validate_password_mixed_case_count= 2;
 UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password1A#'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 UPDATE mysql.user SET PASSWORD= PASSWORD('password1AB#') WHERE user='base_user';
 SET @@global.validate_password_mixed_case_count= 1;
 SET @@global.validate_password_special_char_count= 2;
 GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password1A#'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#$';
 SET @@global.validate_password_special_char_count= 1;
+# No dictionary file present, no dictionary check
+SET @@global.validate_password_policy_number=STRONG;
+SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
+UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user';
+UNINSTALL PLUGIN validate_password;
+# restarting the server with dictionary file.
+# Restart server.
+INSTALL PLUGIN validate_password SONAME 'validate_password.so';
 # password policy strong
 # default_file : dictionary.txt
-SET@@global.validate_password_dictionary_file='MYSQL_ERRMSG_BASEDIR/dictionary.txt';
-SET @@global.validate_password_policy_number= 3;
+SET @@global.validate_password_policy_number=STRONG;
 CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
-ERROR HY000: Your password does not satisfy the current policy requirements 'password1a#'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 UPDATE mysql.user SET PASSWORD= PASSWORD('pass12345A#') WHERE user='base_user';
-ERROR HY000: Your password does not satisfy the current policy requirements 'pass12345a#'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 UPDATE mysql.user SET PASSWORD= PASSWORD('pass0000A#') WHERE user='base_user';
-ERROR HY000: Your password does not satisfy the current policy requirements 'pass0000a#'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'PA00wrd!#';
 # test for password_validate_strength function
 SELECT VALIDATE_PASSWORD_STRENGTH('password', 0);
@@ -71,18 +79,12 @@ VALIDATE_PASSWORD_STRENGTH('PA12wrd!#')
 SELECT VALIDATE_PASSWORD_STRENGTH('PA00wrd!#');
 VALIDATE_PASSWORD_STRENGTH('PA00wrd!#')
 100
-SET @@global.validate_password_dictionary_file=NULL;
-# same password was not accepted as it was present in the dictionary file
-SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
-SELECT VALIDATE_PASSWORD_STRENGTH('password1A#');
-VALIDATE_PASSWORD_STRENGTH('password1A#')
-100
 SET NAMES 'ujis';
 SELECT VALIDATE_PASSWORD_STRENGTH('PA12wrd!#');
 VALIDATE_PASSWORD_STRENGTH('PA12wrd!#')
-100
-SET @@global.validate_password_policy_number= 2;
-SET @@global.validate_password_policy_number= 1;
+75
+SET @@global.validate_password_policy_number=MEDIUM;
+SET @@global.validate_password_policy_number=LOW;
 ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
 SET @@global.validate_password_length= 4;
 ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
@@ -91,11 +93,12 @@ ERROR 42000: Access denied; you need (at
 SET @@global.validate_password_mixed_case_count= 0;
 ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
 CREATE USER 'user2'@'localhost' IDENTIFIED BY 'password';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 CREATE USER 'user2'@'localhost' IDENTIFIED BY 'PA00wrd!#';
 UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='user2';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements 
 UPDATE mysql.user SET PASSWORD= PASSWORD('PA00wrd!#') WHERE user='user2';
 DROP USER 'user2'@'localhost';
 DROP USER 'base_user'@'localhost';
 DROP USER 'user1'@'localhost';
+UNINSTALL PLUGIN validate_password;

=== modified file 'mysql-test/t/validate_password_plugin-master.opt'
--- a/mysql-test/t/validate_password_plugin-master.opt	2012-05-14 11:18:13 +0000
+++ b/mysql-test/t/validate_password_plugin-master.opt	2012-05-18 06:31:26 +0000
@@ -1,2 +1 @@
 $VALIDATE_PASSWORD_OPT
-$VALIDATE_PASSWORD_LOAD

=== modified file 'mysql-test/t/validate_password_plugin.test'
--- a/mysql-test/t/validate_password_plugin.test	2012-05-14 11:18:13 +0000
+++ b/mysql-test/t/validate_password_plugin.test	2012-05-18 06:31:26 +0000
@@ -3,16 +3,21 @@
 
 let $MYSQL_ERRMSG_BASEDIR=`select @@lc_messages_dir`;
 
-SET @@global.validate_password_policy_number= 1;
-CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'password';
-GRANT ALL ON mysql.* TO 'user1'@'localhost' IDENTIFIED BY 'password';
+# plugin is not installed so even 'pass' (very weak)
+# is accepted as a password
+CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'pass';
+GRANT ALL ON mysql.* TO 'user1'@'localhost' IDENTIFIED BY 'pass';
+
+--replace_regex /\.dll/.so/
+eval INSTALL PLUGIN validate_password SONAME '$VALIDATE_PASSWORD';
 
 # test for all the three password policy
-# policy: low= 1, medium= 2, strong= 3
+# policy: LOW, MEDIUM, STRONG 
 
---echo # password policy low (which only check for password length)
+--echo # password policy LOW (which only check for password length)
 --echo # default case: password length should be minimum 8
 
+SET @@global.validate_password_policy_number=LOW;
 --error ER_NOT_VALID_PASSWORD
 CREATE USER 'user'@'localhost' IDENTIFIED BY '';
 SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password');
@@ -22,10 +27,10 @@ UPDATE mysql.user SET PASSWORD= PASSWORD
 GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1234';
 SET @@global.validate_password_length= 8;
 
---echo # password policy medium (check for mixed_case, digits, special_chars)
+--echo # password policy MEDIUM (check for mixed_case, digits, special_chars)
 --echo # default case : atleast 1 mixed_case, 1 digit, 1 special_char
 
-SET @@global.validate_password_policy_number= 2;
+SET @@global.validate_password_policy_number=MEDIUM;
 --error ER_NOT_VALID_PASSWORD
 CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
 SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
@@ -45,14 +50,47 @@ GRANT USAGE ON *.* TO 'base_user'@'local
 GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#$';
 SET @@global.validate_password_special_char_count= 1;
 
+--echo # No dictionary file present, no dictionary check
+SET @@global.validate_password_policy_number=STRONG;
+SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
+UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user';
+
+UNINSTALL PLUGIN validate_password;
+
+--echo # restarting the server with dictionary file.
+
+# Write file to make mysql-test-run.pl wait for the server to stop
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+# Request shutdown
+-- send_shutdown
+
+# Call script that will poll the server waiting for it to disapear
+-- source include/wait_until_disconnected.inc
+
+--echo # Restart server.
+
+--exec echo "restart:--loose-validate_password_dictionary_file=$MYSQL_ERRMSG_BASEDIR/dictionary.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+# Turn on reconnect
+--enable_reconnect
+
+# Call script that will poll the server waiting for it to be back online again
+--source include/wait_until_connected_again.inc
+
+# Turn off reconnect again
+--disable_reconnect
+
+--replace_regex /\.dll/.so/
+eval INSTALL PLUGIN validate_password SONAME '$VALIDATE_PASSWORD';
+
 --echo # password policy strong
 --echo # default_file : dictionary.txt
+
 # file should contain 1 word per line
 # error if substring of password is a dictionary word
 
---replace_result $MYSQL_ERRMSG_BASEDIR MYSQL_ERRMSG_BASEDIR
-eval SET@@global.validate_password_dictionary_file='$MYSQL_ERRMSG_BASEDIR/dictionary.txt';
-SET @@global.validate_password_policy_number= 3;
+SET @@global.validate_password_policy_number=STRONG;
 --error ER_NOT_VALID_PASSWORD
 CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
 --error ER_NOT_VALID_PASSWORD
@@ -77,26 +115,19 @@ SELECT VALIDATE_PASSWORD_STRENGTH('passw
 SELECT VALIDATE_PASSWORD_STRENGTH('PA12wrd!#');
 SELECT VALIDATE_PASSWORD_STRENGTH('PA00wrd!#');
 
-SET @@global.validate_password_dictionary_file=NULL;
---echo # same password was not accepted as it was present in the dictionary file
-
-SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
-SELECT VALIDATE_PASSWORD_STRENGTH('password1A#');
-
 # Test for multibyte character set that have greater size when converted
 # from uppercase to lowercase.
-
 SET NAMES 'ujis';
 SELECT VALIDATE_PASSWORD_STRENGTH('PA12wrd!#');
 
 # default policy is set, all other plugin variables set to default
 # Test to ensure that only the privileged user can access the plugin variables
-SET @@global.validate_password_policy_number= 2;
+SET @@global.validate_password_policy_number=MEDIUM;
 
 # New connection
-connect (plug_con,localhost,user1,password);
+connect (plug_con,localhost,user1,pass);
 --error ER_SPECIFIC_ACCESS_DENIED_ERROR
-SET @@global.validate_password_policy_number= 1;
+SET @@global.validate_password_policy_number=LOW;
 --error ER_SPECIFIC_ACCESS_DENIED_ERROR
 SET @@global.validate_password_length= 4;
 --error ER_SPECIFIC_ACCESS_DENIED_ERROR
@@ -106,7 +137,6 @@ SET @@global.validate_password_mixed_cas
 # user has the update/create privilege but needs to satisfy password policy
 # to update/create new account 
 --error ER_NOT_VALID_PASSWORD
---error ER_NOT_VALID_PASSWORD
 CREATE USER 'user2'@'localhost' IDENTIFIED BY 'password';
 CREATE USER 'user2'@'localhost' IDENTIFIED BY 'PA00wrd!#';
 --error ER_NOT_VALID_PASSWORD
@@ -117,3 +147,4 @@ connection default;
 
 DROP USER 'base_user'@'localhost';
 DROP USER 'user1'@'localhost';
+UNINSTALL PLUGIN validate_password;

=== modified file 'plugin/password_validation/validate_password.cc'
--- a/plugin/password_validation/validate_password.cc	2012-05-14 11:18:13 +0000
+++ b/plugin/password_validation/validate_password.cc	2012-05-18 06:31:26 +0000
@@ -18,7 +18,7 @@
 #include <set>
 #include <iostream>
 #include <fstream>
-#include <pthread.h>
+#include <my_sys.h>
 
 /*  
   __attribute__(A) needs to be defined for Windows else complier
@@ -32,26 +32,36 @@
 #define MAX_DICTIONARY_FILE_LENGTH    1024 * 1024
 #define PASSWORD_SCORE                25
 #define MIN_DICTIONARY_WORD_LENGTH    4
+#define MAX_PASSWORD_LENGTH           100
 
 /*  
   These are the 3 password policies that this plugin allow to set
   and configure as per the requirements.
 */
-enum password_policy_name_enum { PASSWORD_POLICY_LOW= 1,
-                                 PASSWORD_POLICY_MEDIUM,
-                                 PASSWORD_POLICY_STRONG
+
+enum password_policy_enum { PASSWORD_POLICY_LOW,
+                            PASSWORD_POLICY_MEDIUM,
+                            PASSWORD_POLICY_STRONG
+};
+
+static const char* policy_names[] = { "LOW", "MEDIUM", "STRONG", NullS };
+
+static TYPELIB password_policy_typelib_t = {
+        array_elements(policy_names) - 1,
+        "password_policy_typelib_t",
+        policy_names,
+        NULL
 };
 
-pthread_mutex_t dictionary_mutex;
 typedef std::string string_type;
 typedef std::set<string_type> set_type;
-set_type dictionary_words;
+static set_type dictionary_words;
 
 static int validate_password_length;
 static int validate_password_number_count;
 static int validate_password_mixed_case_count;
 static int validate_password_special_char_count;
-static int validate_password_policy_number;
+static ulong validate_password_policy_number;
 static char *validate_password_dictionary_file;
 
 /* To read dictionary file into std::set */
@@ -71,13 +81,11 @@ static void read_dictionary_file()
     dictionary_stream.close();
     return;
   }
-  pthread_mutex_lock(&dictionary_mutex);
   while (dictionary_stream.good())
   {
     std::getline(dictionary_stream, words);
     dictionary_words.insert(words);
   }
-  pthread_mutex_unlock(&dictionary_mutex);
   dictionary_stream.close();
 }
 
@@ -85,23 +93,30 @@ static void read_dictionary_file()
 static void free_dictionary_file()
 {
   if (!dictionary_words.empty())
-  {
-    pthread_mutex_lock(&dictionary_mutex);
     dictionary_words.clear();
-    pthread_mutex_unlock(&dictionary_mutex);
-  }
 }
 
 /*  
   Checks weather password or substring of password
   is present in dictionary file stored as std::set
 */
-static int validate_dictionary_check(string_handle password, size_t length)
+static int validate_dictionary_check(mysql_string_handle password)
 {
-  size_t substr_pos= 0;
-  size_t substr_length= length;
-  string_type password_str= (const char *)mysql_string_character_casedn
-                                          (password);
+  int length;
+  int error= 0;
+  char *buffer;
+  mysql_string_handle lower_string_handle;
+  lower_string_handle= mysql_string_to_lowercase(password);
+  if (!(buffer= (char*) malloc(MAX_PASSWORD_LENGTH)))
+    return (0);
+
+  if ((length= mysql_string_convert_to_char_ptr(lower_string_handle, "utf8",
+                                         buffer, &error)) > 0 && error == 0)
+     buffer[length]= '\0';
+
+  int substr_pos= 0;
+  int substr_length= length;
+  string_type password_str= (const char *)buffer;
   string_type password_substr;
   set_type::iterator itr;
   /*  
@@ -110,7 +125,6 @@ static int validate_dictionary_check(str
   */
   if (!dictionary_words.empty())
   {
-    pthread_mutex_lock(&dictionary_mutex);
     while (substr_length >= MIN_DICTIONARY_WORD_LENGTH)
     {
       substr_pos= 0;
@@ -120,54 +134,56 @@ static int validate_dictionary_check(str
         itr= dictionary_words.find(password_substr);
         if (itr != dictionary_words.end())
         {
-          pthread_mutex_unlock(&dictionary_mutex);
+          free(buffer);
           return (0);
         }
         substr_pos++;
       }
       substr_length--;
     }
-    pthread_mutex_unlock(&dictionary_mutex);
   }
+  free(buffer);
   return (1);
 }
 
-static int validate_password_policy(string_handle password, size_t length,
-                                    int policy)
+static int validate_password_policy(mysql_string_handle password, int policy)
 {
-  int has_numbers= 0;
+  int has_digit= 0;
   int has_lower= 0;
   int has_upper= 0;
   int has_special_chars= 0;
-  int char_type, char_len;
-  const char *current_ptr, *end_ptr;
+  int n_chars= 0;
+  mysql_string_iterator_handle iter;
 
-  if ((int)length >= validate_password_length)
+  iter = mysql_string_get_iterator(password);
+  while(mysql_string_iterator_next(iter))
   {
-    if (policy == PASSWORD_POLICY_LOW)
-      return (1);
-    current_ptr= mysql_string_character_beg(password);
-    end_ptr= mysql_string_character_end(password);
-    while (current_ptr < end_ptr)
+    n_chars++;
+    if (policy > PASSWORD_POLICY_LOW)
     {
-      char_len= mysql_string_character_ctype(password, &char_type, current_ptr);
-      if (mysql_string_character_islower(char_type))
+      if (mysql_string_iterator_islower(iter))
         has_lower++;
-      else if (mysql_string_character_isupper(char_type))
+      else if (mysql_string_iterator_isupper(iter))
         has_upper++;
-      else if (mysql_string_character_isdigit(char_type))
-        has_numbers++;
+      else if (mysql_string_iterator_isdigit(iter))
+        has_digit++;
       else
         has_special_chars++;
-      current_ptr+= (char_len > 0 ? char_len : (char_len < 0 ? -char_len : 1));
     }
+  }
+
+  mysql_string_iterator_free(iter);
+  if (n_chars >= validate_password_length)
+  {
+    if (policy == PASSWORD_POLICY_LOW)
+      return (1);
     if (has_upper >= validate_password_mixed_case_count &&
         has_lower >= validate_password_mixed_case_count &&
         has_special_chars >= validate_password_special_char_count &&
-        has_numbers >= validate_password_number_count)
+        has_digit >= validate_password_number_count)
     {
-      if (policy == PASSWORD_POLICY_MEDIUM ||
-          validate_dictionary_check(password, length))
+      if (policy == PASSWORD_POLICY_MEDIUM || validate_dictionary_check
+                                              (password))
         return (1);
     }
   }
@@ -175,31 +191,38 @@ static int validate_password_policy(stri
 }
 
 /* Actual plugin function which acts as a wrapper */
-static int validate_password(string_handle password, size_t length)
+static int validate_password(mysql_string_handle password)
 {
-  return validate_password_policy
-         (password, length, validate_password_policy_number);
+  return validate_password_policy(password, validate_password_policy_number);
 }
 
 /* Password strength between (0-100) */
-static int get_password_strength(string_handle password, size_t length)
+static int get_password_strength(mysql_string_handle password)
 {
   int policy= 0;
-  
-  if (length < MIN_DICTIONARY_WORD_LENGTH)
-    return policy;
+  int n_chars= 0;
+  mysql_string_iterator_handle iter;
 
-  if (validate_password_policy(password, length, PASSWORD_POLICY_LOW))
+  iter = mysql_string_get_iterator(password);
+  while(mysql_string_iterator_next(iter))
+    n_chars++;
+  
+  mysql_string_iterator_free(iter);
+  if (n_chars < MIN_DICTIONARY_WORD_LENGTH)
+    return (policy);
+  if (n_chars < validate_password_length)
+    return (PASSWORD_SCORE);
+  else
   {
     policy= PASSWORD_POLICY_LOW;
-    if (validate_password_policy(password, length, PASSWORD_POLICY_MEDIUM))
+    if (validate_password_policy(password, PASSWORD_POLICY_MEDIUM))
     {
       policy= PASSWORD_POLICY_MEDIUM;
-      if (validate_dictionary_check(password, length))
+      if (validate_dictionary_check(password))
         policy= PASSWORD_POLICY_STRONG;
     }
   }
-  return (policy * PASSWORD_SCORE + PASSWORD_SCORE);
+  return ((policy+1) * PASSWORD_SCORE + PASSWORD_SCORE);
 }
 
 /* Plugin type-specific descriptor */
@@ -232,20 +255,6 @@ static int validate_password_deinit(void
   return (0);
 }
 
-/*  
-  When dictionary file is changed it reloads the new file in
-  std::set
-*/  
-static void validate_password_dictionary_file_update(THD *thd, struct
-                                                     st_mysql_sys_var *var,
-                                                     void *dest,
-                                                     const void *save)
-{
-  *(char **) dest= *(char **) save;
-  free_dictionary_file();
-  read_dictionary_file();
-}
-
 /* Plugin system variables */
 
 static MYSQL_SYSVAR_INT(length, validate_password_length,
@@ -268,16 +277,16 @@ static MYSQL_SYSVAR_INT(special_char_cou
   "password validate special to ensure minimum special character in password",
   NULL, NULL, 1, 0, 0, 0);
 
-static MYSQL_SYSVAR_INT(policy_number, validate_password_policy_number,
+static MYSQL_SYSVAR_ENUM(policy_number, validate_password_policy_number,
   PLUGIN_VAR_RQCMDARG,
   "password_validate_policy choosen policy to validate password"
-  "possible values are LOW=1, MEDIUM=2 (default), HIGH=3",
-  NULL, NULL, 2, 1, 3, 0 );
+  "possible values are LOW MEDIUM (default), STRONG",
+  NULL, NULL, PASSWORD_POLICY_MEDIUM, &password_policy_typelib_t);
 
 static MYSQL_SYSVAR_STR(dictionary_file, validate_password_dictionary_file,
-  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
+  PLUGIN_VAR_READONLY,
   "password_validate_dictionary file to be loaded and check for password",
-  NULL, validate_password_dictionary_file_update, NULL);
+  NULL, NULL, NULL);
 
 static struct st_mysql_sys_var* validate_password_system_variables[]= {
   MYSQL_SYSVAR(length),

=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt	2012-04-02 14:31:07 +0000
+++ b/sql/CMakeLists.txt	2012-05-18 06:31:26 +0000
@@ -113,6 +113,7 @@ SET(SQL_SHARED_SOURCES
   sp_pcontext.cc 
   sp_rcontext.cc
   spatial.cc
+  string_service.cc
   sql_acl.cc
   sql_admin.cc
   sql_alloc_error_handler.cc

=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc	2012-05-14 11:18:13 +0000
+++ b/sql/item_strfunc.cc	2012-05-18 06:31:26 +0000
@@ -1938,7 +1938,12 @@ char *Item_func_password::alloc(THD *thd
 {
   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);
     my_make_scrambled_password(buff, password, pass_len);
+  }
   return buff;
 }
 
@@ -1963,7 +1968,12 @@ char *Item_func_old_password::alloc(THD
 {
   char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
   if (buff)
+  {
+    String *password_str= new (thd->mem_root)String(password, thd->variables.
+                                                    character_set_client);
+    check_password_policy(password_str);
     my_make_scrambled_password_323(buff, password, pass_len);
+  }
   return buff;
 }
 

=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2012-05-14 11:18:13 +0000
+++ b/sql/share/errmsg-utf8.txt	2012-05-18 06:31:26 +0000
@@ -6754,7 +6754,7 @@ ER_MTS_RESET_WORKERS
   eng "Cannot clean up worker info tables. Additional error messages can be found in the MySQL error log."
 
 ER_NOT_VALID_PASSWORD
-  eng "Your password does not satisfy the current policy requirements '%s'"
+  eng "Your password does not satisfy the current policy requirements "
 #
 #  End of 5.6 error messages.
 #

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2012-05-14 11:18:13 +0000
+++ b/sql/sql_acl.cc	2012-05-18 06:31:26 +0000
@@ -176,7 +176,7 @@ const TABLE_FIELD_DEF
 static LEX_STRING native_password_plugin_name= {
   C_STRING_WITH_LEN("mysql_native_password")
 };
-  
+
 static LEX_STRING old_password_plugin_name= {
   C_STRING_WITH_LEN("mysql_old_password")
 };
@@ -9926,7 +9926,7 @@ int check_password_strength(String *pass
     st_mysql_validate_password *password_strength=
                       (st_mysql_validate_password *) plugin_decl(plugin)->info;
 
-    res= password_strength->get_password_strength(password, password->length());
+    res= password_strength->get_password_strength(password);
     plugin_unlock(0, plugin);
   }
   return(res);
@@ -9942,103 +9942,9 @@ void check_password_policy(String *passw
     st_mysql_validate_password *password_validate=
                       (st_mysql_validate_password *) plugin_decl(plugin)->info;
 
-    if (!password_validate->validate_password(password, password->length()))
-      my_error(ER_NOT_VALID_PASSWORD, MYF(0), password->ptr());
-    plugin_unlock(0, plugin);
-  }
-}
+    if (!password_validate->validate_password(password))
+      my_error(ER_NOT_VALID_PASSWORD, MYF(0));
 
-/*  
-  This is plugin service function which returns the beginning of the
-  mysql String.
-*/
-extern "C"
-const char *mysql_string_character_beg(mysql_string_ptr string_ptr)
-{
-  String *str= (String *) string_ptr;
-  return str->ptr();
-}
-
-/* This is plugin service function which end of the mysql String */
-extern "C"
-const char *mysql_string_character_end(mysql_string_ptr string_ptr)
-{
-  String *str= (String *) string_ptr;
-  return (str->ptr() + str->length());
-}
-
-/*  
-  This is plugin service function which tells weather the character
-  is a uppercase character or not, for client character set
-*/
-extern "C"
-int mysql_string_character_isupper(int char_type)
-{
-  return (char_type & _MY_U);
-}
-
-/*  
-  This is plugin service function which tells weather the character
-  is a lowercase character or not, for client character set
-*/
-extern "C"
-int mysql_string_character_islower(int char_type)
-{
-  return (char_type & _MY_L);
-}
-
-/*  
-  This is plugin service function which tells weather the character
-  is a digit or not, for client character set
-*/
-extern "C"
-int mysql_string_character_isdigit(int char_type)
-{
-  return (char_type & _MY_NMR);
-}
-
-/*  
-  This is plugin service function which evaluate the ctype and
-  returns the character length, for client character set.
-*/
-extern "C"
-int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
-                                 const char *current_ptr)
-{
-  String *str= (String *) string_ptr;
-  const CHARSET_INFO *cs= str->charset();
-  char *end= (char*) str->ptr() + str->length();
-  return (cs->cset->ctype(cs, char_type, (uchar*) current_ptr,
-                          (uchar*) end));
-}
-
-/*  
-  This function provide plugin service to convert a String into
-  lower case. Conversion depends on the client character set info
-*/
-extern "C"
-const char *mysql_string_character_casedn(mysql_string_ptr string_ptr)
-{
-  String *str= (String *) string_ptr;
-  String temp_str;
-  const CHARSET_INFO *cs= str->charset();
- 
-  if (cs->casedn_multiply == 1)
-  {
-    uint len;
-    len= cs->cset->casedn(cs, (char*) str->ptr(), str->length(),
-                          (char*) str->ptr(), str->length());
-    str->length(len);
-  }
-  else
-  {
-    uint len= str->length() * cs->casedn_multiply;
-    temp_str.alloc(len);
-    temp_str.set_charset(cs);
-    len= cs->cset->casedn(cs, (char*) str->ptr(), str->length(),
-                          (char*) temp_str.ptr(), len);
-    temp_str.length(len);
-    str= &temp_str;
+    plugin_unlock(0, plugin);
   }
-  return (str->ptr());
 }

=== modified file 'sql/sql_acl.h'
--- a/sql/sql_acl.h	2012-04-30 06:36:01 +0000
+++ b/sql/sql_acl.h	2012-05-18 06:31:26 +0000
@@ -253,7 +253,6 @@ int fill_schema_column_privileges(THD *t
 int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
 int check_password_strength(String *password);
 void check_password_policy(String *password);
-
 #ifdef NO_EMBEDDED_ACCESS_CHECKS
 #define check_grant(A,B,C,D,E,F) 0
 #define check_grant_db(A,B) 0

=== modified file 'sql/sql_plugin_services.h'
--- a/sql/sql_plugin_services.h	2012-05-14 11:18:13 +0000
+++ b/sql/sql_plugin_services.h	2012-05-18 06:31:26 +0000
@@ -51,13 +51,15 @@ static struct my_plugin_log_service my_p
 };
 
 static struct mysql_string_service_st mysql_string_handler= {
-  mysql_string_character_beg,
-  mysql_string_character_end,
-  mysql_string_character_casedn,
-  mysql_string_character_ctype,
-  mysql_string_character_isupper,
-  mysql_string_character_islower,
-  mysql_string_character_isdigit,
+  mysql_string_convert_to_char_ptr,
+  mysql_string_get_iterator,
+  mysql_string_iterator_next,
+  mysql_string_iterator_isupper,
+  mysql_string_iterator_islower,
+  mysql_string_iterator_isdigit,
+  mysql_string_to_lowercase,
+  mysql_string_free,
+  mysql_string_iterator_free,
 };
 
 static struct st_service_ref list_of_services[]=

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2012-04-30 06:36:01 +0000
+++ b/sql/sql_yacc.yy	2012-05-18 06:31:26 +0000
@@ -14199,9 +14199,6 @@ text_or_password:
           TEXT_STRING { $$=$1.str;}
         | PASSWORD '(' TEXT_STRING ')'
           {
-            String *password = new (YYTHD->mem_root) String((const char*)$3.str,
-                                    YYTHD->variables.character_set_client);
-            check_password_policy(password);
             $$= $3.length ? YYTHD->variables.old_passwords ?
               Item_func_old_password::alloc(YYTHD, $3.str, $3.length) :
               Item_func_password::alloc(YYTHD, $3.str, $3.length) :

=== added file 'sql/string_service.cc'
--- a/sql/string_service.cc	1970-01-01 00:00:00 +0000
+++ b/sql/string_service.cc	2012-05-18 06:31:26 +0000
@@ -0,0 +1,156 @@
+/* Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
+
+
+/*  
+  This file provide mysql_string service to plugins.
+  operations on mysql_string can be performed by plugins via these service
+  functions.
+*/
+
+#include <string_service.h>
+#include <my_sys.h>
+
+/*  
+  This service function converts the mysql_string to the character set
+  specified by charset_name parameter.
+*/
+extern "C"
+int mysql_string_convert_to_char_ptr(mysql_string_handle string_handle,
+                                     const char *charset_name, char *buffer,
+                                     int *error)
+{
+  String *str= (String *) string_handle;
+  int len= (int)my_convert(buffer, 100, &my_charset_utf8_general_ci, str->ptr(),
+                           str->length(), str->charset(), (uint*) error);
+  return (len);
+}
+
+/*  
+  This service function deallocates the mysql_string_handle allocated on
+  server and used in plugins.
+*/
+extern "C"
+void mysql_string_free(mysql_string_handle string_handle)
+{
+  my_free(string_handle);
+}
+
+/*  
+  This service function deallocates the mysql_string_iterator_handle
+  allocated on server and used in plugins.
+*/
+extern "C"
+void mysql_string_iterator_free(mysql_string_iterator_handle iterator_handle)
+{
+  my_free(iterator_handle);
+}
+
+/* This service function allocate mysql_string_iterator_handle and return it */
+extern "C"
+mysql_string_iterator_handle mysql_string_get_iterator(mysql_string_handle
+                                                       string_handle)
+{
+  String *str= (String *) string_handle;
+  string_iterator *iterator= (string_iterator *)(my_malloc(sizeof
+                                                 (string_iterator *), MYF(0)));
+  iterator->iterator_str= str;
+  iterator->iterator_ptr= str->ptr();
+  iterator->ctype= 0;
+  return (iterator);
+}
+
+/* Provide service which returns the next mysql_string_iterator_handle */
+extern "C"
+int mysql_string_iterator_next(mysql_string_iterator_handle iterator_handle)
+{
+  int char_len, char_type;
+  string_iterator *iterator= (string_iterator *) iterator_handle;
+  String *str= iterator->iterator_str;
+  const CHARSET_INFO *cs= str->charset();
+  char *end= (char*) str->ptr() + str->length();
+  if (iterator->iterator_ptr == (const char*) end)
+    return (0);
+  char_len= (cs->cset->ctype(cs, &char_type, (uchar*) iterator->iterator_ptr,
+                             (uchar*) end));
+  iterator->ctype= char_type;
+  iterator->iterator_ptr+= (char_len > 0 ? char_len : (char_len < 0
+                                                       ? -char_len : 1));
+  return (1);
+}
+
+/*  
+  Provide service which calculate weather the current iterator_ptr points to
+  upper case character or not
+*/
+extern "C"
+int mysql_string_iterator_isupper(mysql_string_iterator_handle iterator_handle)
+{
+  string_iterator *iterator= (string_iterator *) iterator_handle;
+  return (iterator->ctype & _MY_U);
+}
+
+/*  
+  Provide service which calculate weather the current iterator_ptr points to
+  lower case character or not
+*/
+extern "C"
+int mysql_string_iterator_islower(mysql_string_iterator_handle iterator_handle)
+{
+  string_iterator *iterator= (string_iterator *) iterator_handle;
+  return (iterator->ctype & _MY_L);
+}
+
+/*  
+  Provide service which calculate weather the current iterator_ptr points to
+  digit or not
+*/
+extern "C"
+int mysql_string_iterator_isdigit(mysql_string_iterator_handle iterator_handle)
+{
+  string_iterator *iterator= (string_iterator *) iterator_handle;
+  return (iterator->ctype & _MY_NMR);
+}
+
+/*  
+  This function provide plugin service to convert a String pointed by handle to
+  lower case. Conversion depends on the client character set info
+*/
+extern "C"
+mysql_string_handle mysql_string_to_lowercase(mysql_string_handle string_handle)
+{
+  String *str= (String *) string_handle;
+  String temp_str;
+  const CHARSET_INFO *cs= str->charset();
+
+  if (cs->casedn_multiply == 1)
+  {
+    uint len;
+    len= cs->cset->casedn(cs, (char*) str->ptr(), str->length(),
+                          (char*) str->ptr(), str->length());
+    str->length(len);
+  }
+  else
+  {
+    uint len= str->length() * cs->casedn_multiply;
+    temp_str.alloc(len);
+    temp_str.set_charset(cs);
+    len= cs->cset->casedn(cs, (char*) str->ptr(), str->length(),
+                          (char*) temp_str.ptr(), len);
+    temp_str.length(len);
+    str= &temp_str;
+  }
+  return (str);
+}

=== added file 'sql/string_service.h'
--- a/sql/string_service.h	1970-01-01 00:00:00 +0000
+++ b/sql/string_service.h	2012-05-18 06:31:26 +0000
@@ -0,0 +1,29 @@
+/* Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
+
+#ifndef STRING_SERVICE_INCLUDED
+#define STRING_SERVICE_INCLUDED
+
+#include <sql_string.h>
+
+/* mysql_string_itrerator structure to provide service to plugins */
+struct string_iterator
+{
+  String *iterator_str;
+  const char *iterator_ptr;
+  int ctype;
+};
+
+#endif /* STRING_SERVICE_INCLUDED */

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (ashish.y.agarwal:3888 to 3889) Ashish Agarwal18 May