List:Commits« Previous MessageNext Message »
From:Ashish Agarwal Date:May 14 2012 11:19am
Subject:bzr push into mysql-trunk branch (ashish.y.agarwal:3887 to 3888)
View as plain text  
 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
 3887 Ashish Agarwal	2012-05-10
      wl2739: Auditing Password Security
              Build failure in windows.

    modified:
      plugin/password_validation/validate_password.cc
=== modified file 'include/mysql/plugin_audit.h.pp'
--- a/include/mysql/plugin_audit.h.pp	2012-05-10 14:15:01 +0000
+++ b/include/mysql/plugin_audit.h.pp	2012-05-14 11:18:13 +0000
@@ -73,21 +73,26 @@ extern struct my_plugin_log_service
 } *my_plugin_log_service;
 int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
                           const char *format, ...);
-#include <mysql/service_password_string.h>
-struct password_char_case
-{
-  int has_numbers;
-  int has_lower;
-  int has_upper;
-  int has_special_chars;
-};
-typedef struct password_char_case PASSWORD_CHAR_CASE;
-extern struct password_string_service_st {
-  void (*password_string_case_type)(PASSWORD_CHAR_CASE *, void *);
-  const char *(*password_string_casedn_type)(void *);
-} *password_string_service;
-void password_string_case(PASSWORD_CHAR_CASE *chars_case, void *password);
-const char *password_string_casedn(void *password);
+#include <mysql/service_mysql_string.h>
+typedef void *mysql_string_ptr;
+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);
+} *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);
 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-10 14:15:01 +0000
+++ b/include/mysql/plugin_auth.h.pp	2012-05-14 11:18:13 +0000
@@ -73,21 +73,26 @@ extern struct my_plugin_log_service
 } *my_plugin_log_service;
 int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
                           const char *format, ...);
-#include <mysql/service_password_string.h>
-struct password_char_case
-{
-  int has_numbers;
-  int has_lower;
-  int has_upper;
-  int has_special_chars;
-};
-typedef struct password_char_case PASSWORD_CHAR_CASE;
-extern struct password_string_service_st {
-  void (*password_string_case_type)(PASSWORD_CHAR_CASE *, void *);
-  const char *(*password_string_casedn_type)(void *);
-} *password_string_service;
-void password_string_case(PASSWORD_CHAR_CASE *chars_case, void *password);
-const char *password_string_casedn(void *password);
+#include <mysql/service_mysql_string.h>
+typedef void *mysql_string_ptr;
+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);
+} *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);
 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-10 14:15:01 +0000
+++ b/include/mysql/plugin_ftparser.h.pp	2012-05-14 11:18:13 +0000
@@ -73,21 +73,26 @@ extern struct my_plugin_log_service
 } *my_plugin_log_service;
 int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
                           const char *format, ...);
-#include <mysql/service_password_string.h>
-struct password_char_case
-{
-  int has_numbers;
-  int has_lower;
-  int has_upper;
-  int has_special_chars;
-};
-typedef struct password_char_case PASSWORD_CHAR_CASE;
-extern struct password_string_service_st {
-  void (*password_string_case_type)(PASSWORD_CHAR_CASE *, void *);
-  const char *(*password_string_casedn_type)(void *);
-} *password_string_service;
-void password_string_case(PASSWORD_CHAR_CASE *chars_case, void *password);
-const char *password_string_casedn(void *password);
+#include <mysql/service_mysql_string.h>
+typedef void *mysql_string_ptr;
+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);
+} *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);
 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-10 10:54:37 +0000
+++ b/include/mysql/plugin_validate_password.h	2012-05-14 11:18:13 +0000
@@ -15,17 +15,15 @@
 
 #ifndef MYSQL_PLUGIN_VALIDATE_PASSWORD_INCLUDED
 #define MYSQL_PLUGIN_VALIDATE_PASSWORD_INCLUDED
-/*************************************************************************
-  API for validate_password plugin. (MYSQL_VALIDATE_PASSWORD_PLUGIN)
-*/
 
-#include <mysql/plugin.h>
+/* API for validate_password plugin. (MYSQL_VALIDATE_PASSWORD_PLUGIN) */
 
+#include <mysql/plugin.h>
 #define MYSQL_VALIDATE_PASSWORD_INTERFACE_VERSION 0x0100
 
 typedef void* string_handle;
 
-/*************************************************************************
+/*  
   The descriptor structure for the plugin, that is referred from
   st_mysql_plugin.
 */
@@ -33,13 +31,13 @@ typedef void* string_handle;
 struct st_mysql_validate_password
 {
   int interface_version;
-  /**
+  /*  
     This function retuns TRUE for passwords which satisfy the password
     policy (as choosen by plugin variable) and FALSE for all other
     password
   */
   int (*validate_password)(string_handle password, size_t password_length);
-  /**
+  /*  
     This function returns the password strength (0-100) depending
     upon the policies
   */

=== added file 'include/mysql/service_mysql_string.h'
--- a/include/mysql/service_mysql_string.h	1970-01-01 00:00:00 +0000
+++ b/include/mysql/service_mysql_string.h	2012-05-14 11:18:13 +0000
@@ -0,0 +1,105 @@
+/* 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 service provides functions to parse mysql String */
+
+#ifndef MYSQL_SERVICE_MYSQL_STRING_INCLUDED
+#define MYSQL_SERVICE_MYSQL_STRING_INCLUDED
+
+#ifndef MYSQL_ABI_CHECK
+#include <stdlib.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *mysql_string_ptr;
+
+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);
+} *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)
+#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 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
+*/
+int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
+                                 const char *current_ptr);
+
+/*  
+  This service function return 1 if character is a uppercase
+  character else return 0 for client character set.
+*/
+int mysql_string_character_isupper(int char_type);
+/*  
+  This service function return 1 if character is a lowercase
+  character else return 0 for client character set.
+*/
+int mysql_string_character_islower(int char_type);
+/*  
+  This service function return 1 if character is a digit
+  else return 0 for client character sets.
+*/
+int mysql_string_character_isdigit(int char_type);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif

=== removed file 'include/mysql/service_password_string.h'
--- a/include/mysql/service_password_string.h	2012-05-10 14:15:01 +0000
+++ b/include/mysql/service_password_string.h	1970-01-01 00:00:00 +0000
@@ -1,76 +0,0 @@
-/* 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 */
-
-/**
-  @file
-  This service provides functions to parse password String
-*/
-
-#ifndef MYSQL_SERVICE_PASSWORD_STRING_INCLUDED
-#define MYSQL_SERVICE_PASSWORD_STRING_INCLUDED
-
-#ifndef MYSQL_ABI_CHECK
-#include <stdlib.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct password_char_case
-{
-  int has_numbers;
-  int has_lower;
-  int has_upper;
-  int has_special_chars;
-};
-
-typedef struct password_char_case PASSWORD_CHAR_CASE;
-
-extern struct password_string_service_st {
-  void (*password_string_case_type)(PASSWORD_CHAR_CASE *, void *);
-  const char *(*password_string_casedn_type)(void *);
-} *password_string_service;
-
-#ifdef MYSQL_DYNAMIC_PLUGIN
-
-#define password_string_case(chars_case, password) \
-        password_string_service->password_string_case_type \
-        (chars_case, password)
-#define password_string_casedn(password) \
-        password_string_service->password_string_casedn_type(password)
-#else
-
-/**
-   It takes password string and calculate the number of uppercase,
-   lowercase, digits and special character. stores the value in
-   PASSWORD_CHAR_CASE. Support mysql character sets.
-*/ 
-void password_string_case(PASSWORD_CHAR_CASE *chars_case, void *password);
-
-/**
-   It converts the uppercase into lowercase based on the
-   character set
-*/
-const char *password_string_casedn(void *password);
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-

=== modified file 'include/mysql/services.h'
--- a/include/mysql/services.h	2012-05-10 10:54:37 +0000
+++ b/include/mysql/services.h	2012-05-14 11:18:13 +0000
@@ -23,7 +23,7 @@ extern "C" {
 #include <mysql/service_thd_wait.h>
 #include <mysql/service_thread_scheduler.h>
 #include <mysql/service_my_plugin_log.h>
-#include <mysql/service_password_string.h>
+#include <mysql/service_mysql_string.h>
 
 #ifdef __cplusplus
 }

=== modified file 'include/service_versions.h'
--- a/include/service_versions.h	2012-05-10 10:54:37 +0000
+++ b/include/service_versions.h	2012-05-14 11:18:13 +0000
@@ -24,4 +24,4 @@
 #define VERSION_thd_wait        0x0100
 #define VERSION_my_thread_scheduler 0x0100
 #define VERSION_my_plugin_log 0x0100
-#define VERSION_password_string  0x0100
+#define VERSION_mysql_string  0x0100

=== modified file 'libservices/CMakeLists.txt'
--- a/libservices/CMakeLists.txt	2012-05-10 10:54:37 +0000
+++ b/libservices/CMakeLists.txt	2012-05-14 11:18:13 +0000
@@ -21,7 +21,7 @@ SET(MYSQLSERVICES_SOURCES
   thd_wait_service.c
   my_plugin_log_service.c
   my_thread_scheduler_service.c
-  password_string_service.c)
+  mysql_string_service.c)
 
 ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
 INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)

=== added file 'libservices/mysql_string_service.c'
--- a/libservices/mysql_string_service.c	1970-01-01 00:00:00 +0000
+++ b/libservices/mysql_string_service.c	2012-05-14 11:18:13 +0000
@@ -0,0 +1,18 @@
+/*  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 */
+
+#include <service_versions.h>
+SERVICE_VERSION *mysql_string_service= (void*)VERSION_mysql_string;

=== removed file 'libservices/password_string_service.c'
--- a/libservices/password_string_service.c	2012-05-10 10:54:37 +0000
+++ b/libservices/password_string_service.c	1970-01-01 00:00:00 +0000
@@ -1,18 +0,0 @@
-/*  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 */
-
-#include <service_versions.h>
-SERVICE_VERSION *password_string_service= (void*)VERSION_password_string;

=== modified file 'mysql-test/include/have_validate_password_plugin.inc'
--- a/mysql-test/include/have_validate_password_plugin.inc	2012-04-16 12:25:21 +0000
+++ b/mysql-test/include/have_validate_password_plugin.inc	2012-05-14 11:18:13 +0000
@@ -1,20 +1,5 @@
-#
-# 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)
-}
+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;

=== modified file 'mysql-test/include/plugin.defs'
--- a/mysql-test/include/plugin.defs	2012-04-16 12:25:21 +0000
+++ b/mysql-test/include/plugin.defs	2012-05-14 11:18:13 +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  plugin/password_validation VALIDATE_PASSWORD validate_password

=== modified file 'mysql-test/r/validate_password_plugin.result'
--- a/mysql-test/r/validate_password_plugin.result	2012-05-10 14:15:01 +0000
+++ b/mysql-test/r/validate_password_plugin.result	2012-05-14 11:18:13 +0000
@@ -1,36 +1,35 @@
-CREATE USER 'base_user'@'localhost' IDENTIFIED BY '';
-GRANT ALL ON mysql.* TO 'user'@'localhost' IDENTIFIED BY 'password';
-INSTALL PLUGIN validate_password SONAME 'validate_password.so';
+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)
 # default case: password length should be minimum 8
-SET @@global.validate_password_policy_number= 1;
 CREATE USER 'user'@'localhost' IDENTIFIED BY '';
-ERROR HY000: not a valid password ''
+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: not a valid password 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements 'password'
 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)
 # default case : atleast 1 mixed_case, 1 digit, 1 special_char
 SET @@global.validate_password_policy_number= 2;
 CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
-ERROR HY000: not a valid password 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements 'password'
 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: not a valid password 'password1A#'
+ERROR HY000: Your password does not satisfy the current policy requirements 'password1A#'
 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: not a valid password 'password1A#'
+ERROR HY000: Your password does not satisfy the current policy requirements 'password1A#'
 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: not a valid password 'password1A#'
+ERROR HY000: Your password does not satisfy the current policy requirements 'password1A#'
 GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#$';
 SET @@global.validate_password_special_char_count= 1;
 # password policy strong
@@ -38,13 +37,13 @@ SET @@global.validate_password_special_c
 SET@@global.validate_password_dictionary_file='MYSQL_ERRMSG_BASEDIR/dictionary.txt';
 SET @@global.validate_password_policy_number= 3;
 CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
-ERROR HY000: not a valid password 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements 'password'
 SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
-ERROR HY000: not a valid password 'password1a#'
+ERROR HY000: Your password does not satisfy the current policy requirements 'password1a#'
 UPDATE mysql.user SET PASSWORD= PASSWORD('pass12345A#') WHERE user='base_user';
-ERROR HY000: not a valid password 'pass12345a#'
+ERROR HY000: Your password does not satisfy the current policy requirements 'pass12345a#'
 UPDATE mysql.user SET PASSWORD= PASSWORD('pass0000A#') WHERE user='base_user';
-ERROR HY000: not a valid password 'pass0000a#'
+ERROR HY000: Your password does not satisfy the current policy requirements 'pass0000a#'
 GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'PA00wrd!#';
 # test for password_validate_strength function
 SELECT VALIDATE_PASSWORD_STRENGTH('password', 0);
@@ -72,7 +71,7 @@ VALIDATE_PASSWORD_STRENGTH('PA12wrd!#')
 SELECT VALIDATE_PASSWORD_STRENGTH('PA00wrd!#');
 VALIDATE_PASSWORD_STRENGTH('PA00wrd!#')
 100
-SET @@global.validate_password_dictionary_file='NULL';
+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#');
@@ -91,13 +90,12 @@ SET @@global.validate_password_special_c
 ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
 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
-UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='user';
-ERROR HY000: not a valid password 'password'
-UPDATE mysql.user SET PASSWORD= PASSWORD('PA00wrd!#') WHERE user='user';
-CREATE USER 'user1'@'localhost' IDENTIFIED BY 'password';
-ERROR HY000: not a valid password 'password'
-CREATE USER 'user1'@'localhost' IDENTIFIED BY 'PA00wrd!#';
-DROP USER 'user1'@'localhost';
+CREATE USER 'user2'@'localhost' IDENTIFIED BY 'password';
+ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+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'
+UPDATE mysql.user SET PASSWORD= PASSWORD('PA00wrd!#') WHERE user='user2';
+DROP USER 'user2'@'localhost';
 DROP USER 'base_user'@'localhost';
-DROP USER 'user'@'localhost';
-UNINSTALL PLUGIN validate_password;
+DROP USER 'user1'@'localhost';

=== modified file 'mysql-test/t/validate_password_plugin-master.opt'
--- a/mysql-test/t/validate_password_plugin-master.opt	2012-04-16 12:25:21 +0000
+++ b/mysql-test/t/validate_password_plugin-master.opt	2012-05-14 11:18:13 +0000
@@ -1 +1,2 @@
 $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-10 14:15:01 +0000
+++ b/mysql-test/t/validate_password_plugin.test	2012-05-14 11:18:13 +0000
@@ -3,12 +3,9 @@
 
 let $MYSQL_ERRMSG_BASEDIR=`select @@lc_messages_dir`;
 
-# Plugin not installed no password required
-CREATE USER 'base_user'@'localhost' IDENTIFIED BY '';
-GRANT ALL ON mysql.* TO 'user'@'localhost' IDENTIFIED BY 'password';
-
---replace_regex /\.dll/.so/
-eval INSTALL PLUGIN validate_password SONAME '$VALIDATE_PASSWORD';
+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';
 
 # test for all the three password policy
 # policy: low= 1, medium= 2, strong= 3
@@ -16,7 +13,6 @@ eval INSTALL PLUGIN validate_password SO
 --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= 1;
 --error ER_NOT_VALID_PASSWORD
 CREATE USER 'user'@'localhost' IDENTIFIED BY '';
 SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password');
@@ -81,7 +77,7 @@ SELECT VALIDATE_PASSWORD_STRENGTH('passw
 SELECT VALIDATE_PASSWORD_STRENGTH('PA12wrd!#');
 SELECT VALIDATE_PASSWORD_STRENGTH('PA00wrd!#');
 
-SET @@global.validate_password_dictionary_file='NULL';
+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#');
@@ -98,7 +94,7 @@ SELECT VALIDATE_PASSWORD_STRENGTH('PA12w
 SET @@global.validate_password_policy_number= 2;
 
 # New connection
-connect (plug_con,localhost,user,password);
+connect (plug_con,localhost,user1,password);
 --error ER_SPECIFIC_ACCESS_DENIED_ERROR
 SET @@global.validate_password_policy_number= 1;
 --error ER_SPECIFIC_ACCESS_DENIED_ERROR
@@ -110,14 +106,14 @@ 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
-UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='user';
-UPDATE mysql.user SET PASSWORD= PASSWORD('PA00wrd!#') WHERE user='user';
 --error ER_NOT_VALID_PASSWORD
-CREATE USER 'user1'@'localhost' IDENTIFIED BY 'password';
-CREATE USER 'user1'@'localhost' IDENTIFIED BY 'PA00wrd!#';
-DROP USER 'user1'@'localhost';
+CREATE USER 'user2'@'localhost' IDENTIFIED BY 'password';
+CREATE USER 'user2'@'localhost' IDENTIFIED BY 'PA00wrd!#';
+--error ER_NOT_VALID_PASSWORD
+UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='user2';
+UPDATE mysql.user SET PASSWORD= PASSWORD('PA00wrd!#') WHERE user='user2';
+DROP USER 'user2'@'localhost';
 connection default;
 
 DROP USER 'base_user'@'localhost';
-DROP USER 'user'@'localhost';
-UNINSTALL PLUGIN validate_password;
+DROP USER 'user1'@'localhost';

=== modified file 'plugin/password_validation/CMakeLists.txt'
--- a/plugin/password_validation/CMakeLists.txt	2012-05-10 10:54:37 +0000
+++ b/plugin/password_validation/CMakeLists.txt	2012-05-14 11:18:13 +0000
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# 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

=== modified file 'plugin/password_validation/validate_password.cc'
--- a/plugin/password_validation/validate_password.cc	2012-05-10 15:53:17 +0000
+++ b/plugin/password_validation/validate_password.cc	2012-05-14 11:18:13 +0000
@@ -18,7 +18,13 @@
 #include <set>
 #include <iostream>
 #include <fstream>
+#include <pthread.h>
 
+/*  
+  __attribute__(A) needs to be defined for Windows else complier
+  do not recognise it. Argument in plugin_init and plugin_deinit
+  Used in other plugins as well.
+*/
 #if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__)  || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
 #define __attribute__(A)
 #endif
@@ -27,14 +33,20 @@
 #define PASSWORD_SCORE                25
 #define MIN_DICTIONARY_WORD_LENGTH    4
 
-enum PASSWORD_POLICY { PASSWORD_STRENGTH_REJECTED, PASSWORD_STRENGTH_LOW,
-                       PASSWORD_STRENGTH_MEDIUM, PASSWORD_STRENGTH_STRONG };
+/*  
+  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
+};
 
+pthread_mutex_t dictionary_mutex;
 typedef std::string string_type;
 typedef std::set<string_type> set_type;
 set_type dictionary_words;
 
-static char *dictionary_file= NULL;
 static int validate_password_length;
 static int validate_password_number_count;
 static int validate_password_mixed_case_count;
@@ -47,7 +59,7 @@ static void read_dictionary_file()
 {
   string_type words;
   long file_length;
-  std::ifstream dictionary_stream(dictionary_file);
+  std::ifstream dictionary_stream(validate_password_dictionary_file);
 
   if (!dictionary_stream)
     return;
@@ -59,11 +71,13 @@ 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();
 }
 
@@ -71,31 +85,32 @@ static void read_dictionary_file()
 static void free_dictionary_file()
 {
   if (!dictionary_words.empty())
-   dictionary_words.clear();
+  {
+    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
+/*  
+  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)
 {
   size_t substr_pos= 0;
   size_t substr_length= length;
-  string_type password_str= password_string_casedn(password);
+  string_type password_str= (const char *)mysql_string_character_casedn
+                                          (password);
   string_type password_substr;
   set_type::iterator itr;
-
-  /* New dictionary file */
-  if (dictionary_file != validate_password_dictionary_file)
-  {
-    dictionary_file= validate_password_dictionary_file;
-    free_dictionary_file();
-    read_dictionary_file();
-  }
-  /* std::set as container stores the dictionary words,
-     binary comparison between dictionary words and password */
+  /*  
+    std::set as container stores the dictionary words,
+    binary comparison between dictionary words and password
+  */
   if (!dictionary_words.empty())
   {
+    pthread_mutex_lock(&dictionary_mutex);
     while (substr_length >= MIN_DICTIONARY_WORD_LENGTH)
     {
       substr_pos= 0;
@@ -104,36 +119,54 @@ static int validate_dictionary_check(str
         password_substr= password_str.substr(substr_pos, substr_length);
         itr= dictionary_words.find(password_substr);
         if (itr != dictionary_words.end())
+        {
+          pthread_mutex_unlock(&dictionary_mutex);
           return (0);
+        }
         substr_pos++;
       }
       substr_length--;
     }
+    pthread_mutex_unlock(&dictionary_mutex);
   }
   return (1);
 }
 
 static int validate_password_policy(string_handle password, size_t length,
-                                     int policy)
+                                    int policy)
 {
-  PASSWORD_CHAR_CASE chars_case;
-  chars_case.has_numbers= 0;
-  chars_case.has_lower= 0;
-  chars_case.has_upper= 0;
-  chars_case.has_special_chars= 0;
+  int has_numbers= 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;
 
   if ((int)length >= validate_password_length)
   {
-    if (policy == PASSWORD_STRENGTH_LOW)
+    if (policy == PASSWORD_POLICY_LOW)
       return (1);
-    password_string_case(&chars_case, password);
-
-    if (chars_case.has_upper >= validate_password_mixed_case_count &&
-        chars_case.has_lower >= validate_password_mixed_case_count &&
-        chars_case.has_special_chars >= validate_password_special_char_count &&
-        chars_case.has_numbers >= validate_password_number_count)
+    current_ptr= mysql_string_character_beg(password);
+    end_ptr= mysql_string_character_end(password);
+    while (current_ptr < end_ptr)
     {
-      if (policy == PASSWORD_STRENGTH_MEDIUM ||
+      char_len= mysql_string_character_ctype(password, &char_type, current_ptr);
+      if (mysql_string_character_islower(char_type))
+        has_lower++;
+      else if (mysql_string_character_isupper(char_type))
+        has_upper++;
+      else if (mysql_string_character_isdigit(char_type))
+        has_numbers++;
+      else
+        has_special_chars++;
+      current_ptr+= (char_len > 0 ? char_len : (char_len < 0 ? -char_len : 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)
+    {
+      if (policy == PASSWORD_POLICY_MEDIUM ||
           validate_dictionary_check(password, length))
         return (1);
     }
@@ -151,28 +184,25 @@ static int validate_password(string_hand
 /* Password strength between (0-100) */
 static int get_password_strength(string_handle password, size_t length)
 {
-  int policy=0;
+  int policy= 0;
   
   if (length < MIN_DICTIONARY_WORD_LENGTH)
     return policy;
 
-  if (validate_password_policy(password, length, PASSWORD_STRENGTH_LOW))
+  if (validate_password_policy(password, length, PASSWORD_POLICY_LOW))
   {
-    policy= PASSWORD_STRENGTH_LOW;
-    if (validate_password_policy(password, length, PASSWORD_STRENGTH_MEDIUM))
+    policy= PASSWORD_POLICY_LOW;
+    if (validate_password_policy(password, length, PASSWORD_POLICY_MEDIUM))
     {
-      policy= PASSWORD_STRENGTH_MEDIUM;
+      policy= PASSWORD_POLICY_MEDIUM;
       if (validate_dictionary_check(password, length))
-        policy= PASSWORD_STRENGTH_STRONG;
+        policy= PASSWORD_POLICY_STRONG;
     }
   }
   return (policy * PASSWORD_SCORE + PASSWORD_SCORE);
 }
 
-/*
-  Plugin type-specific descriptor
-*/
-
+/* Plugin type-specific descriptor */
 static struct st_mysql_validate_password validate_password_descriptor=
 {
   MYSQL_VALIDATE_PASSWORD_INTERFACE_VERSION,
@@ -180,19 +210,20 @@ static struct st_mysql_validate_password
   get_password_strength                      /* validate strength function */
 };
 
-/**
-    Initialize the password plugin at server start or plugin installation
-    Does nothing, return 0
+/*  
+  Initialize the password plugin at server start or plugin installation,
+  read dictionary file into std::set.
 */
 
 static int validate_password_init(void *arg __attribute__((unused)))
 {
+  read_dictionary_file();
   return (0);
 }
 
-/**
-   Terminate the password plugin at server shutdown or plugin deinstallation.
-   It empty the std::set and returns 0
+/*  
+  Terminate the password plugin at server shutdown or plugin deinstallation.
+  It empty the std::set and returns 0
 */
 
 static int validate_password_deinit(void *arg __attribute__((unused)))
@@ -201,9 +232,21 @@ static int validate_password_deinit(void
   return (0);
 }
 
-/*
-  Plugin system variables.
-*/
+/*  
+  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,
   PLUGIN_VAR_RQCMDARG,
@@ -221,19 +264,20 @@ static MYSQL_SYSVAR_INT(mixed_case_count
   NULL, NULL, 1, 0, 0, 0);
 
 static MYSQL_SYSVAR_INT(special_char_count,
-                      validate_password_special_char_count, PLUGIN_VAR_RQCMDARG,
+  validate_password_special_char_count, PLUGIN_VAR_RQCMDARG,
   "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,
   PLUGIN_VAR_RQCMDARG,
-  "password_validate_policy choosen policy to validate password",
-  NULL, NULL, 2, 1, 3, 0);
+  "password_validate_policy choosen policy to validate password"
+  "possible values are LOW=1, MEDIUM=2 (default), HIGH=3",
+  NULL, NULL, 2, 1, 3, 0 );
 
 static MYSQL_SYSVAR_STR(dictionary_file, validate_password_dictionary_file,
   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
   "password_validate_dictionary file to be loaded and check for password",
-  NULL, NULL, NULL);
+  NULL, validate_password_dictionary_file_update, NULL);
 
 static struct st_mysql_sys_var* validate_password_system_variables[]= {
   MYSQL_SYSVAR(length),

=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc	2012-05-10 10:54:37 +0000
+++ b/sql/item_func.cc	2012-05-14 11:18:13 +0000
@@ -3229,7 +3229,6 @@ void Item_func_locate::print(String *str
 
 longlong Item_func_validate_password_strength::val_int()
 {
-  DBUG_ASSERT(fixed == 1);
   String *field;
   if (!(field= args[0]->val_str(&value)))
     return 0;

=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc	2012-04-30 06:36:01 +0000
+++ b/sql/item_strfunc.cc	2012-05-14 11:18:13 +0000
@@ -1950,6 +1950,7 @@ String *Item_func_old_password::val_str_
   String *res= args[0]->val_str(str);
   if ((null_value=args[0]->null_value))
     return 0;
+  check_password_policy(res);
   if (res->length() == 0)
     return make_empty_result();
   my_make_scrambled_password_323(tmp_value, res->ptr(), res->length());

=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2012-04-16 12:25:21 +0000
+++ b/sql/share/errmsg-utf8.txt	2012-05-14 11:18:13 +0000
@@ -6745,8 +6745,6 @@ ER_UNKNOWN_ALTER_ALGORITHM
   eng "Unknown ALGORITHM '%s'"
 ER_UNKNOWN_ALTER_LOCK
   eng "Unknown LOCK type '%s'"
-ER_NOT_VALID_PASSWORD
-  eng "not a valid password '%s'"
 
 ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS
   eng "CHANGE MASTER cannot be executed when the slave was stopped with an error or killed in MTS mode. Consider using RESET SLAVE or START SLAVE UNTIL."
@@ -6754,6 +6752,9 @@ ER_MTS_RECOVERY_FAILURE
   eng "Cannot recover after SLAVE errored out in parallel execution mode. Additional error messages can be found in the MySQL error log."
 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'"
 #
 #  End of 5.6 error messages.
 #

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2012-05-10 10:54:37 +0000
+++ b/sql/sql_acl.cc	2012-05-14 11:18:13 +0000
@@ -9910,13 +9910,12 @@ mysql_declare_plugin(mysql_password)
 }
 mysql_declare_plugin_end;
 
-/*********************************************************************
+/*  
  PASSWORD_VALIDATION_CODE, invoking appropriate plugin to validate
  the password strength.
-**********************************************************************/
+*/
 
 /* for validate_password_strength SQL function */
-
 int check_password_strength(String *password)
 {
   int res= 0;
@@ -9934,7 +9933,6 @@ int check_password_strength(String *pass
 }
 
 /* called when new user is created or exsisting password is changed */
-
 void check_password_policy(String *password)
 {
   plugin_ref plugin= my_plugin_lock_by_name(0, &validate_password_plugin_name,
@@ -9950,60 +9948,97 @@ void check_password_policy(String *passw
   }
 }
 
-/* This function provide plugin service for calculating number of 
-   upper_case, lower_case, digits. Calculation depends on the
-   client character set.
-*/ 
-extern "C"
-void password_string_case(PASSWORD_CHAR_CASE *chars_case, void *password)
-{
-  String *password_str= (String *) password;
-  const CHARSET_INFO *cs= password_str->charset();
-  char *beg= (char*) password_str->ptr();
-  char *end= (char*) password_str->ptr() + password_str->length();
-  while (beg < end)
-  {
-    int ctype, char_len;
-    char_len= cs->cset->ctype(cs, &ctype, (uchar*) beg, (uchar*) end);
-    if (ctype & _MY_NMR)
-      chars_case->has_numbers++;
-    else if (ctype & _MY_L)
-      chars_case->has_lower++;
-    else if (ctype & _MY_U)
-      chars_case->has_upper++;
-    else
-      chars_case->has_special_chars++;
-    beg+= (char_len > 0 ? char_len : (char_len < 0 ? -char_len : 1));
-  }
+/*  
+  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 clinet character set info
+/*  
+  This function provide plugin service to convert a String into
+  lower case. Conversion depends on the client character set info
 */
 extern "C"
-const char *password_string_casedn(void *password)
+const char *mysql_string_character_casedn(mysql_string_ptr string_ptr)
 {
-  String *password_str= (String *) password;
-  const CHARSET_INFO *cs= password_str->charset();
-  String tmp_password_str;
+  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*) password_str->ptr(),
-                          password_str->length(), (char*) password_str->ptr(),
-                          password_str->length());
-    password_str->length(len);
+    len= cs->cset->casedn(cs, (char*) str->ptr(), str->length(),
+                          (char*) str->ptr(), str->length());
+    str->length(len);
   }
   else
   {
-    uint len= password_str->length() * cs->casedn_multiply;
-    tmp_password_str.alloc(len);
-    tmp_password_str.set_charset(cs);
-    len= cs->cset->casedn(cs, (char*) password_str->ptr(),
-                          password_str->length(),
-                          (char*) tmp_password_str.ptr(), len);
-    tmp_password_str.length(len);
-    password_str= &tmp_password_str;
+    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 password_str->ptr();
+  return (str->ptr());
 }

=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h	2012-05-10 10:54:37 +0000
+++ b/sql/sql_plugin.h	2012-05-14 11:18:13 +0000
@@ -138,6 +138,7 @@ extern I_List<i_string> *opt_plugin_load
 extern char *opt_plugin_dir_ptr;
 extern char opt_plugin_dir[FN_REFLEN];
 extern const LEX_STRING plugin_type_names[];
+
 extern int plugin_init(int *argc, char **argv, int init_flags);
 extern void plugin_shutdown(void);
 void add_plugin_options(std::vector<my_option> *options, MEM_ROOT *mem_root);

=== modified file 'sql/sql_plugin_services.h'
--- a/sql/sql_plugin_services.h	2012-05-10 10:54:37 +0000
+++ b/sql/sql_plugin_services.h	2012-05-14 11:18:13 +0000
@@ -50,12 +50,16 @@ static struct my_plugin_log_service my_p
   my_plugin_log_message
 };
 
-static struct password_string_service_st password_string_handler= {
-  password_string_case,
-  password_string_casedn,
+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,
 };
 
-
 static struct st_service_ref list_of_services[]=
 {
   { "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
@@ -64,7 +68,7 @@ static struct st_service_ref list_of_ser
   { "my_thread_scheduler_service",
     VERSION_my_thread_scheduler, &my_thread_scheduler_handler },
   { "my_plugin_log_service", VERSION_my_plugin_log, &my_plugin_log_handler },
-  { "password_string_service",
-    VERSION_password_string, &password_string_handler },
+  { "mysql_string_service",
+    VERSION_mysql_string, &mysql_string_handler },
 };
 

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