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 Agarwal | 16 May |