3889 Ashish Agarwal 2012-05-18
WL2739: Auditing Password Security
Implementing review comment
added:
sql/string_service.cc
sql/string_service.h
modified:
include/mysql/plugin_audit.h.pp
include/mysql/plugin_auth.h.pp
include/mysql/plugin_ftparser.h.pp
include/mysql/plugin_validate_password.h
include/mysql/service_mysql_string.h
mysql-test/include/have_validate_password_plugin.inc
mysql-test/include/plugin.defs
mysql-test/r/validate_password_plugin.result
mysql-test/t/validate_password_plugin-master.opt
mysql-test/t/validate_password_plugin.test
plugin/password_validation/validate_password.cc
sql/CMakeLists.txt
sql/item_strfunc.cc
sql/share/errmsg-utf8.txt
sql/sql_acl.cc
sql/sql_acl.h
sql/sql_plugin_services.h
sql/sql_yacc.yy
3888 Ashish Agarwal 2012-05-14
WL2739: Auditing Password Security
Implementing review comments.
removed:
include/mysql/service_password_string.h
libservices/password_string_service.c
added:
include/mysql/service_mysql_string.h
libservices/mysql_string_service.c
modified:
include/mysql/plugin_audit.h.pp
include/mysql/plugin_auth.h.pp
include/mysql/plugin_ftparser.h.pp
include/mysql/plugin_validate_password.h
include/mysql/services.h
include/service_versions.h
libservices/CMakeLists.txt
mysql-test/include/have_validate_password_plugin.inc
mysql-test/include/plugin.defs
mysql-test/r/validate_password_plugin.result
mysql-test/t/validate_password_plugin-master.opt
mysql-test/t/validate_password_plugin.test
plugin/password_validation/CMakeLists.txt
plugin/password_validation/validate_password.cc
sql/item_func.cc
sql/item_strfunc.cc
sql/share/errmsg-utf8.txt
sql/sql_acl.cc
sql/sql_plugin.h
sql/sql_plugin_services.h
=== modified file 'include/mysql/plugin_audit.h.pp'
--- a/include/mysql/plugin_audit.h.pp 2012-05-14 11:18:13 +0000
+++ b/include/mysql/plugin_audit.h.pp 2012-05-18 06:31:26 +0000
@@ -74,25 +74,34 @@ extern struct my_plugin_log_service
int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
const char *format, ...);
#include <mysql/service_mysql_string.h>
-typedef void *mysql_string_ptr;
+typedef void *mysql_string_iterator_handle;
+typedef void *mysql_string_handle;
extern struct mysql_string_service_st {
- const char *(*mysql_string_character_beg_type)(mysql_string_ptr);
- const char *(*mysql_string_character_end_type)(mysql_string_ptr);
- const char *(*mysql_string_character_casedn_type)(mysql_string_ptr);
- int (*mysql_string_character_ctype_type)
- (mysql_string_ptr, int *, const char*);
- int (*mysql_string_character_isupper_type)(int);
- int (*mysql_string_character_islower_type)(int);
- int (*mysql_string_character_isdigit_type)(int);
+ int (*mysql_string_convert_to_char_ptr_type)
+ (mysql_string_handle, const char *, char *, int *);
+ mysql_string_iterator_handle (*mysql_string_get_iterator_type)
+ (mysql_string_handle);
+ int (*mysql_string_iterator_next_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_isupper_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_islower_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_isdigit_type)(mysql_string_iterator_handle);
+ mysql_string_handle (*mysql_string_to_lowercase_type)(mysql_string_handle);
+ void (*mysql_string_free_type)(mysql_string_handle);
+ void (*mysql_string_iterator_free_type)(mysql_string_iterator_handle);
} *mysql_string_service;
-const char *mysql_string_character_beg(mysql_string_ptr string_ptr);
-const char *mysql_string_character_end(mysql_string_ptr string_ptr);
-const char *mysql_string_character_casedn(mysql_string_ptr string_ptr);
-int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
- const char * current_ptr);
-int mysql_string_character_isupper(int char_type);
-int mysql_string_character_islower(int char_type);
-int mysql_string_character_isdigit(int char_type);
+int mysql_string_convert_to_char_ptr(mysql_string_handle string_handle,
+ const char *charset_name, char *buffer,
+ int *error);
+mysql_string_iterator_handle mysql_string_get_iterator(mysql_string_handle
+ string_handle);
+int mysql_string_iterator_next(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isupper(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_islower(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isdigit(mysql_string_iterator_handle iterator_handle);
+mysql_string_handle mysql_string_to_lowercase(mysql_string_handle
+ string_handle);
+void mysql_string_free(mysql_string_handle);
+void mysql_string_iterator_free(mysql_string_iterator_handle);
struct st_mysql_xid {
long formatID;
long gtrid_length;
=== modified file 'include/mysql/plugin_auth.h.pp'
--- a/include/mysql/plugin_auth.h.pp 2012-05-14 11:18:13 +0000
+++ b/include/mysql/plugin_auth.h.pp 2012-05-18 06:31:26 +0000
@@ -74,25 +74,34 @@ extern struct my_plugin_log_service
int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
const char *format, ...);
#include <mysql/service_mysql_string.h>
-typedef void *mysql_string_ptr;
+typedef void *mysql_string_iterator_handle;
+typedef void *mysql_string_handle;
extern struct mysql_string_service_st {
- const char *(*mysql_string_character_beg_type)(mysql_string_ptr);
- const char *(*mysql_string_character_end_type)(mysql_string_ptr);
- const char *(*mysql_string_character_casedn_type)(mysql_string_ptr);
- int (*mysql_string_character_ctype_type)
- (mysql_string_ptr, int *, const char*);
- int (*mysql_string_character_isupper_type)(int);
- int (*mysql_string_character_islower_type)(int);
- int (*mysql_string_character_isdigit_type)(int);
+ int (*mysql_string_convert_to_char_ptr_type)
+ (mysql_string_handle, const char *, char *, int *);
+ mysql_string_iterator_handle (*mysql_string_get_iterator_type)
+ (mysql_string_handle);
+ int (*mysql_string_iterator_next_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_isupper_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_islower_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_isdigit_type)(mysql_string_iterator_handle);
+ mysql_string_handle (*mysql_string_to_lowercase_type)(mysql_string_handle);
+ void (*mysql_string_free_type)(mysql_string_handle);
+ void (*mysql_string_iterator_free_type)(mysql_string_iterator_handle);
} *mysql_string_service;
-const char *mysql_string_character_beg(mysql_string_ptr string_ptr);
-const char *mysql_string_character_end(mysql_string_ptr string_ptr);
-const char *mysql_string_character_casedn(mysql_string_ptr string_ptr);
-int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
- const char * current_ptr);
-int mysql_string_character_isupper(int char_type);
-int mysql_string_character_islower(int char_type);
-int mysql_string_character_isdigit(int char_type);
+int mysql_string_convert_to_char_ptr(mysql_string_handle string_handle,
+ const char *charset_name, char *buffer,
+ int *error);
+mysql_string_iterator_handle mysql_string_get_iterator(mysql_string_handle
+ string_handle);
+int mysql_string_iterator_next(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isupper(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_islower(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isdigit(mysql_string_iterator_handle iterator_handle);
+mysql_string_handle mysql_string_to_lowercase(mysql_string_handle
+ string_handle);
+void mysql_string_free(mysql_string_handle);
+void mysql_string_iterator_free(mysql_string_iterator_handle);
struct st_mysql_xid {
long formatID;
long gtrid_length;
=== modified file 'include/mysql/plugin_ftparser.h.pp'
--- a/include/mysql/plugin_ftparser.h.pp 2012-05-14 11:18:13 +0000
+++ b/include/mysql/plugin_ftparser.h.pp 2012-05-18 06:31:26 +0000
@@ -74,25 +74,34 @@ extern struct my_plugin_log_service
int my_plugin_log_message(MYSQL_PLUGIN *plugin, enum plugin_log_level level,
const char *format, ...);
#include <mysql/service_mysql_string.h>
-typedef void *mysql_string_ptr;
+typedef void *mysql_string_iterator_handle;
+typedef void *mysql_string_handle;
extern struct mysql_string_service_st {
- const char *(*mysql_string_character_beg_type)(mysql_string_ptr);
- const char *(*mysql_string_character_end_type)(mysql_string_ptr);
- const char *(*mysql_string_character_casedn_type)(mysql_string_ptr);
- int (*mysql_string_character_ctype_type)
- (mysql_string_ptr, int *, const char*);
- int (*mysql_string_character_isupper_type)(int);
- int (*mysql_string_character_islower_type)(int);
- int (*mysql_string_character_isdigit_type)(int);
+ int (*mysql_string_convert_to_char_ptr_type)
+ (mysql_string_handle, const char *, char *, int *);
+ mysql_string_iterator_handle (*mysql_string_get_iterator_type)
+ (mysql_string_handle);
+ int (*mysql_string_iterator_next_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_isupper_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_islower_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_isdigit_type)(mysql_string_iterator_handle);
+ mysql_string_handle (*mysql_string_to_lowercase_type)(mysql_string_handle);
+ void (*mysql_string_free_type)(mysql_string_handle);
+ void (*mysql_string_iterator_free_type)(mysql_string_iterator_handle);
} *mysql_string_service;
-const char *mysql_string_character_beg(mysql_string_ptr string_ptr);
-const char *mysql_string_character_end(mysql_string_ptr string_ptr);
-const char *mysql_string_character_casedn(mysql_string_ptr string_ptr);
-int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
- const char * current_ptr);
-int mysql_string_character_isupper(int char_type);
-int mysql_string_character_islower(int char_type);
-int mysql_string_character_isdigit(int char_type);
+int mysql_string_convert_to_char_ptr(mysql_string_handle string_handle,
+ const char *charset_name, char *buffer,
+ int *error);
+mysql_string_iterator_handle mysql_string_get_iterator(mysql_string_handle
+ string_handle);
+int mysql_string_iterator_next(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isupper(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_islower(mysql_string_iterator_handle iterator_handle);
+int mysql_string_iterator_isdigit(mysql_string_iterator_handle iterator_handle);
+mysql_string_handle mysql_string_to_lowercase(mysql_string_handle
+ string_handle);
+void mysql_string_free(mysql_string_handle);
+void mysql_string_iterator_free(mysql_string_iterator_handle);
struct st_mysql_xid {
long formatID;
long gtrid_length;
=== modified file 'include/mysql/plugin_validate_password.h'
--- a/include/mysql/plugin_validate_password.h 2012-05-14 11:18:13 +0000
+++ b/include/mysql/plugin_validate_password.h 2012-05-18 06:31:26 +0000
@@ -21,7 +21,7 @@
#include <mysql/plugin.h>
#define MYSQL_VALIDATE_PASSWORD_INTERFACE_VERSION 0x0100
-typedef void* string_handle;
+typedef void *mysql_string_handle;
/*
The descriptor structure for the plugin, that is referred from
@@ -36,11 +36,11 @@ struct st_mysql_validate_password
policy (as choosen by plugin variable) and FALSE for all other
password
*/
- int (*validate_password)(string_handle password, size_t password_length);
+ int (*validate_password)(mysql_string_handle password);
/*
This function returns the password strength (0-100) depending
upon the policies
*/
- int (*get_password_strength)(string_handle password, size_t password_length);
+ int (*get_password_strength)(mysql_string_handle password);
};
#endif
=== modified file 'include/mysql/service_mysql_string.h'
--- a/include/mysql/service_mysql_string.h 2012-05-14 11:18:13 +0000
+++ b/include/mysql/service_mysql_string.h 2012-05-18 06:31:26 +0000
@@ -26,76 +26,103 @@
extern "C" {
#endif
-typedef void *mysql_string_ptr;
+typedef void *mysql_string_iterator_handle;
+typedef void *mysql_string_handle;
extern struct mysql_string_service_st {
- const char *(*mysql_string_character_beg_type)(mysql_string_ptr);
- const char *(*mysql_string_character_end_type)(mysql_string_ptr);
- const char *(*mysql_string_character_casedn_type)(mysql_string_ptr);
- int (*mysql_string_character_ctype_type)
- (mysql_string_ptr, int *, const char*);
- int (*mysql_string_character_isupper_type)(int);
- int (*mysql_string_character_islower_type)(int);
- int (*mysql_string_character_isdigit_type)(int);
+ int (*mysql_string_convert_to_char_ptr_type)
+ (mysql_string_handle, const char *, char *, int *);
+ mysql_string_iterator_handle (*mysql_string_get_iterator_type)
+ (mysql_string_handle);
+ int (*mysql_string_iterator_next_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_isupper_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_islower_type)(mysql_string_iterator_handle);
+ int (*mysql_string_iterator_isdigit_type)(mysql_string_iterator_handle);
+ mysql_string_handle (*mysql_string_to_lowercase_type)(mysql_string_handle);
+ void (*mysql_string_free_type)(mysql_string_handle);
+ void (*mysql_string_iterator_free_type)(mysql_string_iterator_handle);
} *mysql_string_service;
#ifdef MYSQL_DYNAMIC_PLUGIN
-#define mysql_string_character_beg(string_ptr) \
- mysql_string_service->mysql_string_character_beg_type(string_ptr)
-
-#define mysql_string_character_end(string_ptr) \
- mysql_string_service->mysql_string_character_end_type(string_ptr)
-
-#define mysql_string_character_casedn(string_ptr) \
- mysql_string_service->mysql_string_character_casedn_type(string_ptr)
-
-#define mysql_string_character_ctype(string_ptr, char_type, current_ptr) \
- mysql_string_service->mysql_string_character_ctype_type \
- (string_ptr, char_type, current_ptr)
-
-#define mysql_string_character_isupper(char_type) \
- mysql_string_service->mysql_string_character_isupper_type(char_type)
-
-#define mysql_string_character_islower(char_type) \
- mysql_string_service->mysql_string_character_islower_type(char_type)
-
-#define mysql_string_character_isdigit(char_type) \
- mysql_string_service->mysql_string_character_isdigit_type(char_type)
+#define mysql_string_convert_to_char_ptr(string_handle, charset_name, \
+ buffer, error) \
+ mysql_string_service->mysql_string_convert_to_char_ptr_type \
+ (string_handle, charset_name, buffer, error)
+
+#define mysql_string_get_iterator(string_handle) \
+ mysql_string_service->mysql_string_get_iterator_type(string_handle)
+
+#define mysql_string_iterator_next(iterator_handle) \
+ mysql_string_service->mysql_string_iterator_next_type(iterator_handle)
+
+#define mysql_string_iterator_isupper(iterator_handle) \
+ mysql_string_service->mysql_string_iterator_isupper_type \
+ (iterator_handle)
+
+#define mysql_string_iterator_islower(iterator_handle) \
+ mysql_string_service->mysql_string_iterator_islower_type \
+ (iterator_handle)
+
+#define mysql_string_iterator_isdigit(iterator_handle) \
+ mysql_string_service->mysql_string_iterator_isdigit_type \
+ (iterator_handle)
+
+#define mysql_string_to_lowercase(string_handle) \
+ mysql_string_service->mysql_string_to_lowercase_type(string_handle)
+
+#define mysql_string_free(mysql_string_handle) \
+ mysql_string_service->mysql_string_free_type(mysql_string_handle)
+
+#define mysql_string_iterator_free(mysql_string_iterator_handle) \
+ mysql_string_service->mysql_string_iterator_free_type \
+ (mysql_string_iterator_handle)
#else
-/* This service function returns the beginning of the mysql String */
-const char *mysql_string_character_beg(mysql_string_ptr string_ptr);
-
-/* This service function returns the end of the mysql String */
-const char *mysql_string_character_end(mysql_string_ptr string_ptr);
-
-/* This service function converts mysql String into lowercase */
-const char *mysql_string_character_casedn(mysql_string_ptr string_ptr);
-
+/* This service function convert string into given character set */
+int mysql_string_convert_to_char_ptr(mysql_string_handle string_handle,
+ const char *charset_name, char *buffer,
+ int *error);
+
+/* This service function returns the beginning of the iterator handle */
+mysql_string_iterator_handle mysql_string_get_iterator(mysql_string_handle
+ string_handle);
/*
- This service function takes mysql string, current string position
- calculate the ctype of the character based on client character set
- store it in char_type and return the character length
+ This service function gets the next iterator handle
+ returns 0 if reached the end else return 1
*/
-int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
- const char *current_ptr);
+int mysql_string_iterator_next(mysql_string_iterator_handle iterator_handle);
/*
- This service function return 1 if character is a uppercase
- character else return 0 for client character set.
+ This service function return 1 if current iterator handle points to a
+ uppercase character else return 0 for client character set.
*/
-int mysql_string_character_isupper(int char_type);
+int mysql_string_iterator_isupper(mysql_string_iterator_handle iterator_handle);
+
/*
- This service function return 1 if character is a lowercase
- character else return 0 for client character set.
+ This service function return 1 if current iterator handle points to a
+ lowercase character else return 0 for client character set.
*/
-int mysql_string_character_islower(int char_type);
+int mysql_string_iterator_islower(mysql_string_iterator_handle iterator_handle);
+
/*
- This service function return 1 if character is a digit
+ This service function return 1 if current iterator handle points to a digit
else return 0 for client character sets.
*/
-int mysql_string_character_isdigit(int char_type);
+int mysql_string_iterator_isdigit(mysql_string_iterator_handle iterator_handle);
+
+/* convert string_handle into lowercase */
+mysql_string_handle mysql_string_to_lowercase(mysql_string_handle
+ string_handle);
+
+/* It deallocates the string created on server side during plugin operations */
+void mysql_string_free(mysql_string_handle);
+
+/*
+ It deallocates the string iterator created on server side
+ during plugin operations
+*/
+void mysql_string_iterator_free(mysql_string_iterator_handle);
#endif
#ifdef __cplusplus
=== modified file 'mysql-test/include/have_validate_password_plugin.inc'
--- a/mysql-test/include/have_validate_password_plugin.inc 2012-05-14 11:18:13 +0000
+++ b/mysql-test/include/have_validate_password_plugin.inc 2012-05-18 06:31:26 +0000
@@ -1,5 +1,20 @@
-disable_query_log;
---require r/true.require
-select (PLUGIN_LIBRARY LIKE 'validate_password%') as `TRUE` FROM INFORMATION_SCHEMA.PLUGINS
- WHERE PLUGIN_NAME='validate_password';
-enable_query_log;
+#
+# Check if server has support for loading plugins
+#
+if (`SELECT @@have_dynamic_loading != 'YES'`) {
+ --skip validate password requires dynamic loading
+}
+
+#
+# Check if the variable VALIDATE_PASSWORD is set
+#
+if (!$VALIDATE_PASSWORD) {
+ --skip validate password requires the environment variable \$VALIDATE_PASSWORD to be set (normally done by mtr)
+}
+
+#
+# Check if --plugin-dir was setup for validate password
+#
+if (`SELECT CONCAT('--plugin-dir=', REPLACE(@@plugin_dir, '\\\\', '/')) != '$VALIDATE_PASSWORD_OPT/'`) {
+ --skip validate password requires that --plugin-dir is set to the validate password dir (either the .opt file does not contain \$VALIDATE_PASSWORD_OPT or another plugin is in use)
+}
=== modified file 'mysql-test/include/plugin.defs'
--- a/mysql-test/include/plugin.defs 2012-05-14 11:18:13 +0000
+++ b/mysql-test/include/plugin.defs 2012-05-18 06:31:26 +0000
@@ -44,4 +44,4 @@ adt_null plugin/audit_null AU
libdaemon_example plugin/daemon_example DAEMONEXAMPLE
libmemcached plugin/innodb_memcached/daemon_memcached DAEMON_MEMCACHED daemon_memcached
innodb_engine plugin/innodb_memcached/innodb_memcache INNODB_ENGINE
-validate_password plugin/password_validation VALIDATE_PASSWORD validate_password
+validate_password plugin/password_validation VALIDATE_PASSWORD
=== modified file 'mysql-test/r/validate_password_plugin.result'
--- a/mysql-test/r/validate_password_plugin.result 2012-05-14 11:18:13 +0000
+++ b/mysql-test/r/validate_password_plugin.result 2012-05-18 06:31:26 +0000
@@ -1,49 +1,57 @@
-SET @@global.validate_password_policy_number= 1;
-CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'password';
-GRANT ALL ON mysql.* TO 'user1'@'localhost' IDENTIFIED BY 'password';
-# password policy low (which only check for password length)
+CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'pass';
+GRANT ALL ON mysql.* TO 'user1'@'localhost' IDENTIFIED BY 'pass';
+INSTALL PLUGIN validate_password SONAME 'validate_password.so';
+# password policy LOW (which only check for password length)
# default case: password length should be minimum 8
+SET @@global.validate_password_policy_number=LOW;
CREATE USER 'user'@'localhost' IDENTIFIED BY '';
-ERROR HY000: Your password does not satisfy the current policy requirements ''
+ERROR HY000: Your password does not satisfy the current policy requirements
SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password');
SET @@global.validate_password_length= 12;
UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='base_user';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements
GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1234';
SET @@global.validate_password_length= 8;
-# password policy medium (check for mixed_case, digits, special_chars)
+# password policy MEDIUM (check for mixed_case, digits, special_chars)
# default case : atleast 1 mixed_case, 1 digit, 1 special_char
-SET @@global.validate_password_policy_number= 2;
+SET @@global.validate_password_policy_number=MEDIUM;
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements
SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
SET @@global.validate_password_number_count= 2;
UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password1A#'
+ERROR HY000: Your password does not satisfy the current policy requirements
UPDATE mysql.user SET PASSWORD= PASSWORD('password12A#') WHERE user='base_user';
SET @@global.validate_password_number_count= 1;
SET @@global.validate_password_mixed_case_count= 2;
UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password1A#'
+ERROR HY000: Your password does not satisfy the current policy requirements
UPDATE mysql.user SET PASSWORD= PASSWORD('password1AB#') WHERE user='base_user';
SET @@global.validate_password_mixed_case_count= 1;
SET @@global.validate_password_special_char_count= 2;
GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password1A#'
+ERROR HY000: Your password does not satisfy the current policy requirements
GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#$';
SET @@global.validate_password_special_char_count= 1;
+# No dictionary file present, no dictionary check
+SET @@global.validate_password_policy_number=STRONG;
+SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
+UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user';
+UNINSTALL PLUGIN validate_password;
+# restarting the server with dictionary file.
+# Restart server.
+INSTALL PLUGIN validate_password SONAME 'validate_password.so';
# password policy strong
# default_file : dictionary.txt
-SET@@global.validate_password_dictionary_file='MYSQL_ERRMSG_BASEDIR/dictionary.txt';
-SET @@global.validate_password_policy_number= 3;
+SET @@global.validate_password_policy_number=STRONG;
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements
SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
-ERROR HY000: Your password does not satisfy the current policy requirements 'password1a#'
+ERROR HY000: Your password does not satisfy the current policy requirements
UPDATE mysql.user SET PASSWORD= PASSWORD('pass12345A#') WHERE user='base_user';
-ERROR HY000: Your password does not satisfy the current policy requirements 'pass12345a#'
+ERROR HY000: Your password does not satisfy the current policy requirements
UPDATE mysql.user SET PASSWORD= PASSWORD('pass0000A#') WHERE user='base_user';
-ERROR HY000: Your password does not satisfy the current policy requirements 'pass0000a#'
+ERROR HY000: Your password does not satisfy the current policy requirements
GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'PA00wrd!#';
# test for password_validate_strength function
SELECT VALIDATE_PASSWORD_STRENGTH('password', 0);
@@ -71,18 +79,12 @@ VALIDATE_PASSWORD_STRENGTH('PA12wrd!#')
SELECT VALIDATE_PASSWORD_STRENGTH('PA00wrd!#');
VALIDATE_PASSWORD_STRENGTH('PA00wrd!#')
100
-SET @@global.validate_password_dictionary_file=NULL;
-# same password was not accepted as it was present in the dictionary file
-SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
-SELECT VALIDATE_PASSWORD_STRENGTH('password1A#');
-VALIDATE_PASSWORD_STRENGTH('password1A#')
-100
SET NAMES 'ujis';
SELECT VALIDATE_PASSWORD_STRENGTH('PA12wrd!#');
VALIDATE_PASSWORD_STRENGTH('PA12wrd!#')
-100
-SET @@global.validate_password_policy_number= 2;
-SET @@global.validate_password_policy_number= 1;
+75
+SET @@global.validate_password_policy_number=MEDIUM;
+SET @@global.validate_password_policy_number=LOW;
ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
SET @@global.validate_password_length= 4;
ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
@@ -91,11 +93,12 @@ ERROR 42000: Access denied; you need (at
SET @@global.validate_password_mixed_case_count= 0;
ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
CREATE USER 'user2'@'localhost' IDENTIFIED BY 'password';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements
CREATE USER 'user2'@'localhost' IDENTIFIED BY 'PA00wrd!#';
UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='user2';
-ERROR HY000: Your password does not satisfy the current policy requirements 'password'
+ERROR HY000: Your password does not satisfy the current policy requirements
UPDATE mysql.user SET PASSWORD= PASSWORD('PA00wrd!#') WHERE user='user2';
DROP USER 'user2'@'localhost';
DROP USER 'base_user'@'localhost';
DROP USER 'user1'@'localhost';
+UNINSTALL PLUGIN validate_password;
=== modified file 'mysql-test/t/validate_password_plugin-master.opt'
--- a/mysql-test/t/validate_password_plugin-master.opt 2012-05-14 11:18:13 +0000
+++ b/mysql-test/t/validate_password_plugin-master.opt 2012-05-18 06:31:26 +0000
@@ -1,2 +1 @@
$VALIDATE_PASSWORD_OPT
-$VALIDATE_PASSWORD_LOAD
=== modified file 'mysql-test/t/validate_password_plugin.test'
--- a/mysql-test/t/validate_password_plugin.test 2012-05-14 11:18:13 +0000
+++ b/mysql-test/t/validate_password_plugin.test 2012-05-18 06:31:26 +0000
@@ -3,16 +3,21 @@
let $MYSQL_ERRMSG_BASEDIR=`select @@lc_messages_dir`;
-SET @@global.validate_password_policy_number= 1;
-CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'password';
-GRANT ALL ON mysql.* TO 'user1'@'localhost' IDENTIFIED BY 'password';
+# plugin is not installed so even 'pass' (very weak)
+# is accepted as a password
+CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'pass';
+GRANT ALL ON mysql.* TO 'user1'@'localhost' IDENTIFIED BY 'pass';
+
+--replace_regex /\.dll/.so/
+eval INSTALL PLUGIN validate_password SONAME '$VALIDATE_PASSWORD';
# test for all the three password policy
-# policy: low= 1, medium= 2, strong= 3
+# policy: LOW, MEDIUM, STRONG
---echo # password policy low (which only check for password length)
+--echo # password policy LOW (which only check for password length)
--echo # default case: password length should be minimum 8
+SET @@global.validate_password_policy_number=LOW;
--error ER_NOT_VALID_PASSWORD
CREATE USER 'user'@'localhost' IDENTIFIED BY '';
SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password');
@@ -22,10 +27,10 @@ UPDATE mysql.user SET PASSWORD= PASSWORD
GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1234';
SET @@global.validate_password_length= 8;
---echo # password policy medium (check for mixed_case, digits, special_chars)
+--echo # password policy MEDIUM (check for mixed_case, digits, special_chars)
--echo # default case : atleast 1 mixed_case, 1 digit, 1 special_char
-SET @@global.validate_password_policy_number= 2;
+SET @@global.validate_password_policy_number=MEDIUM;
--error ER_NOT_VALID_PASSWORD
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
@@ -45,14 +50,47 @@ GRANT USAGE ON *.* TO 'base_user'@'local
GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#$';
SET @@global.validate_password_special_char_count= 1;
+--echo # No dictionary file present, no dictionary check
+SET @@global.validate_password_policy_number=STRONG;
+SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
+UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user';
+
+UNINSTALL PLUGIN validate_password;
+
+--echo # restarting the server with dictionary file.
+
+# Write file to make mysql-test-run.pl wait for the server to stop
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+# Request shutdown
+-- send_shutdown
+
+# Call script that will poll the server waiting for it to disapear
+-- source include/wait_until_disconnected.inc
+
+--echo # Restart server.
+
+--exec echo "restart:--loose-validate_password_dictionary_file=$MYSQL_ERRMSG_BASEDIR/dictionary.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+# Turn on reconnect
+--enable_reconnect
+
+# Call script that will poll the server waiting for it to be back online again
+--source include/wait_until_connected_again.inc
+
+# Turn off reconnect again
+--disable_reconnect
+
+--replace_regex /\.dll/.so/
+eval INSTALL PLUGIN validate_password SONAME '$VALIDATE_PASSWORD';
+
--echo # password policy strong
--echo # default_file : dictionary.txt
+
# file should contain 1 word per line
# error if substring of password is a dictionary word
---replace_result $MYSQL_ERRMSG_BASEDIR MYSQL_ERRMSG_BASEDIR
-eval SET@@global.validate_password_dictionary_file='$MYSQL_ERRMSG_BASEDIR/dictionary.txt';
-SET @@global.validate_password_policy_number= 3;
+SET @@global.validate_password_policy_number=STRONG;
--error ER_NOT_VALID_PASSWORD
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
--error ER_NOT_VALID_PASSWORD
@@ -77,26 +115,19 @@ SELECT VALIDATE_PASSWORD_STRENGTH('passw
SELECT VALIDATE_PASSWORD_STRENGTH('PA12wrd!#');
SELECT VALIDATE_PASSWORD_STRENGTH('PA00wrd!#');
-SET @@global.validate_password_dictionary_file=NULL;
---echo # same password was not accepted as it was present in the dictionary file
-
-SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#');
-SELECT VALIDATE_PASSWORD_STRENGTH('password1A#');
-
# Test for multibyte character set that have greater size when converted
# from uppercase to lowercase.
-
SET NAMES 'ujis';
SELECT VALIDATE_PASSWORD_STRENGTH('PA12wrd!#');
# default policy is set, all other plugin variables set to default
# Test to ensure that only the privileged user can access the plugin variables
-SET @@global.validate_password_policy_number= 2;
+SET @@global.validate_password_policy_number=MEDIUM;
# New connection
-connect (plug_con,localhost,user1,password);
+connect (plug_con,localhost,user1,pass);
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
-SET @@global.validate_password_policy_number= 1;
+SET @@global.validate_password_policy_number=LOW;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
SET @@global.validate_password_length= 4;
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
@@ -106,7 +137,6 @@ SET @@global.validate_password_mixed_cas
# user has the update/create privilege but needs to satisfy password policy
# to update/create new account
--error ER_NOT_VALID_PASSWORD
---error ER_NOT_VALID_PASSWORD
CREATE USER 'user2'@'localhost' IDENTIFIED BY 'password';
CREATE USER 'user2'@'localhost' IDENTIFIED BY 'PA00wrd!#';
--error ER_NOT_VALID_PASSWORD
@@ -117,3 +147,4 @@ connection default;
DROP USER 'base_user'@'localhost';
DROP USER 'user1'@'localhost';
+UNINSTALL PLUGIN validate_password;
=== modified file 'plugin/password_validation/validate_password.cc'
--- a/plugin/password_validation/validate_password.cc 2012-05-14 11:18:13 +0000
+++ b/plugin/password_validation/validate_password.cc 2012-05-18 06:31:26 +0000
@@ -18,7 +18,7 @@
#include <set>
#include <iostream>
#include <fstream>
-#include <pthread.h>
+#include <my_sys.h>
/*
__attribute__(A) needs to be defined for Windows else complier
@@ -32,26 +32,36 @@
#define MAX_DICTIONARY_FILE_LENGTH 1024 * 1024
#define PASSWORD_SCORE 25
#define MIN_DICTIONARY_WORD_LENGTH 4
+#define MAX_PASSWORD_LENGTH 100
/*
These are the 3 password policies that this plugin allow to set
and configure as per the requirements.
*/
-enum password_policy_name_enum { PASSWORD_POLICY_LOW= 1,
- PASSWORD_POLICY_MEDIUM,
- PASSWORD_POLICY_STRONG
+
+enum password_policy_enum { PASSWORD_POLICY_LOW,
+ PASSWORD_POLICY_MEDIUM,
+ PASSWORD_POLICY_STRONG
+};
+
+static const char* policy_names[] = { "LOW", "MEDIUM", "STRONG", NullS };
+
+static TYPELIB password_policy_typelib_t = {
+ array_elements(policy_names) - 1,
+ "password_policy_typelib_t",
+ policy_names,
+ NULL
};
-pthread_mutex_t dictionary_mutex;
typedef std::string string_type;
typedef std::set<string_type> set_type;
-set_type dictionary_words;
+static set_type dictionary_words;
static int validate_password_length;
static int validate_password_number_count;
static int validate_password_mixed_case_count;
static int validate_password_special_char_count;
-static int validate_password_policy_number;
+static ulong validate_password_policy_number;
static char *validate_password_dictionary_file;
/* To read dictionary file into std::set */
@@ -71,13 +81,11 @@ static void read_dictionary_file()
dictionary_stream.close();
return;
}
- pthread_mutex_lock(&dictionary_mutex);
while (dictionary_stream.good())
{
std::getline(dictionary_stream, words);
dictionary_words.insert(words);
}
- pthread_mutex_unlock(&dictionary_mutex);
dictionary_stream.close();
}
@@ -85,23 +93,30 @@ static void read_dictionary_file()
static void free_dictionary_file()
{
if (!dictionary_words.empty())
- {
- pthread_mutex_lock(&dictionary_mutex);
dictionary_words.clear();
- pthread_mutex_unlock(&dictionary_mutex);
- }
}
/*
Checks weather password or substring of password
is present in dictionary file stored as std::set
*/
-static int validate_dictionary_check(string_handle password, size_t length)
+static int validate_dictionary_check(mysql_string_handle password)
{
- size_t substr_pos= 0;
- size_t substr_length= length;
- string_type password_str= (const char *)mysql_string_character_casedn
- (password);
+ int length;
+ int error= 0;
+ char *buffer;
+ mysql_string_handle lower_string_handle;
+ lower_string_handle= mysql_string_to_lowercase(password);
+ if (!(buffer= (char*) malloc(MAX_PASSWORD_LENGTH)))
+ return (0);
+
+ if ((length= mysql_string_convert_to_char_ptr(lower_string_handle, "utf8",
+ buffer, &error)) > 0 && error == 0)
+ buffer[length]= '\0';
+
+ int substr_pos= 0;
+ int substr_length= length;
+ string_type password_str= (const char *)buffer;
string_type password_substr;
set_type::iterator itr;
/*
@@ -110,7 +125,6 @@ static int validate_dictionary_check(str
*/
if (!dictionary_words.empty())
{
- pthread_mutex_lock(&dictionary_mutex);
while (substr_length >= MIN_DICTIONARY_WORD_LENGTH)
{
substr_pos= 0;
@@ -120,54 +134,56 @@ static int validate_dictionary_check(str
itr= dictionary_words.find(password_substr);
if (itr != dictionary_words.end())
{
- pthread_mutex_unlock(&dictionary_mutex);
+ free(buffer);
return (0);
}
substr_pos++;
}
substr_length--;
}
- pthread_mutex_unlock(&dictionary_mutex);
}
+ free(buffer);
return (1);
}
-static int validate_password_policy(string_handle password, size_t length,
- int policy)
+static int validate_password_policy(mysql_string_handle password, int policy)
{
- int has_numbers= 0;
+ int has_digit= 0;
int has_lower= 0;
int has_upper= 0;
int has_special_chars= 0;
- int char_type, char_len;
- const char *current_ptr, *end_ptr;
+ int n_chars= 0;
+ mysql_string_iterator_handle iter;
- if ((int)length >= validate_password_length)
+ iter = mysql_string_get_iterator(password);
+ while(mysql_string_iterator_next(iter))
{
- if (policy == PASSWORD_POLICY_LOW)
- return (1);
- current_ptr= mysql_string_character_beg(password);
- end_ptr= mysql_string_character_end(password);
- while (current_ptr < end_ptr)
+ n_chars++;
+ if (policy > PASSWORD_POLICY_LOW)
{
- char_len= mysql_string_character_ctype(password, &char_type, current_ptr);
- if (mysql_string_character_islower(char_type))
+ if (mysql_string_iterator_islower(iter))
has_lower++;
- else if (mysql_string_character_isupper(char_type))
+ else if (mysql_string_iterator_isupper(iter))
has_upper++;
- else if (mysql_string_character_isdigit(char_type))
- has_numbers++;
+ else if (mysql_string_iterator_isdigit(iter))
+ has_digit++;
else
has_special_chars++;
- current_ptr+= (char_len > 0 ? char_len : (char_len < 0 ? -char_len : 1));
}
+ }
+
+ mysql_string_iterator_free(iter);
+ if (n_chars >= validate_password_length)
+ {
+ if (policy == PASSWORD_POLICY_LOW)
+ return (1);
if (has_upper >= validate_password_mixed_case_count &&
has_lower >= validate_password_mixed_case_count &&
has_special_chars >= validate_password_special_char_count &&
- has_numbers >= validate_password_number_count)
+ has_digit >= validate_password_number_count)
{
- if (policy == PASSWORD_POLICY_MEDIUM ||
- validate_dictionary_check(password, length))
+ if (policy == PASSWORD_POLICY_MEDIUM || validate_dictionary_check
+ (password))
return (1);
}
}
@@ -175,31 +191,38 @@ static int validate_password_policy(stri
}
/* Actual plugin function which acts as a wrapper */
-static int validate_password(string_handle password, size_t length)
+static int validate_password(mysql_string_handle password)
{
- return validate_password_policy
- (password, length, validate_password_policy_number);
+ return validate_password_policy(password, validate_password_policy_number);
}
/* Password strength between (0-100) */
-static int get_password_strength(string_handle password, size_t length)
+static int get_password_strength(mysql_string_handle password)
{
int policy= 0;
-
- if (length < MIN_DICTIONARY_WORD_LENGTH)
- return policy;
+ int n_chars= 0;
+ mysql_string_iterator_handle iter;
- if (validate_password_policy(password, length, PASSWORD_POLICY_LOW))
+ iter = mysql_string_get_iterator(password);
+ while(mysql_string_iterator_next(iter))
+ n_chars++;
+
+ mysql_string_iterator_free(iter);
+ if (n_chars < MIN_DICTIONARY_WORD_LENGTH)
+ return (policy);
+ if (n_chars < validate_password_length)
+ return (PASSWORD_SCORE);
+ else
{
policy= PASSWORD_POLICY_LOW;
- if (validate_password_policy(password, length, PASSWORD_POLICY_MEDIUM))
+ if (validate_password_policy(password, PASSWORD_POLICY_MEDIUM))
{
policy= PASSWORD_POLICY_MEDIUM;
- if (validate_dictionary_check(password, length))
+ if (validate_dictionary_check(password))
policy= PASSWORD_POLICY_STRONG;
}
}
- return (policy * PASSWORD_SCORE + PASSWORD_SCORE);
+ return ((policy+1) * PASSWORD_SCORE + PASSWORD_SCORE);
}
/* Plugin type-specific descriptor */
@@ -232,20 +255,6 @@ static int validate_password_deinit(void
return (0);
}
-/*
- When dictionary file is changed it reloads the new file in
- std::set
-*/
-static void validate_password_dictionary_file_update(THD *thd, struct
- st_mysql_sys_var *var,
- void *dest,
- const void *save)
-{
- *(char **) dest= *(char **) save;
- free_dictionary_file();
- read_dictionary_file();
-}
-
/* Plugin system variables */
static MYSQL_SYSVAR_INT(length, validate_password_length,
@@ -268,16 +277,16 @@ static MYSQL_SYSVAR_INT(special_char_cou
"password validate special to ensure minimum special character in password",
NULL, NULL, 1, 0, 0, 0);
-static MYSQL_SYSVAR_INT(policy_number, validate_password_policy_number,
+static MYSQL_SYSVAR_ENUM(policy_number, validate_password_policy_number,
PLUGIN_VAR_RQCMDARG,
"password_validate_policy choosen policy to validate password"
- "possible values are LOW=1, MEDIUM=2 (default), HIGH=3",
- NULL, NULL, 2, 1, 3, 0 );
+ "possible values are LOW MEDIUM (default), STRONG",
+ NULL, NULL, PASSWORD_POLICY_MEDIUM, &password_policy_typelib_t);
static MYSQL_SYSVAR_STR(dictionary_file, validate_password_dictionary_file,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
+ PLUGIN_VAR_READONLY,
"password_validate_dictionary file to be loaded and check for password",
- NULL, validate_password_dictionary_file_update, NULL);
+ NULL, NULL, NULL);
static struct st_mysql_sys_var* validate_password_system_variables[]= {
MYSQL_SYSVAR(length),
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2012-04-02 14:31:07 +0000
+++ b/sql/CMakeLists.txt 2012-05-18 06:31:26 +0000
@@ -113,6 +113,7 @@ SET(SQL_SHARED_SOURCES
sp_pcontext.cc
sp_rcontext.cc
spatial.cc
+ string_service.cc
sql_acl.cc
sql_admin.cc
sql_alloc_error_handler.cc
=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc 2012-05-14 11:18:13 +0000
+++ b/sql/item_strfunc.cc 2012-05-18 06:31:26 +0000
@@ -1938,7 +1938,12 @@ char *Item_func_password::alloc(THD *thd
{
char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
if (buff)
+ {
+ String *password_str= new (thd->mem_root)String(password, thd->variables.
+ character_set_client);
+ check_password_policy(password_str);
my_make_scrambled_password(buff, password, pass_len);
+ }
return buff;
}
@@ -1963,7 +1968,12 @@ char *Item_func_old_password::alloc(THD
{
char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
if (buff)
+ {
+ String *password_str= new (thd->mem_root)String(password, thd->variables.
+ character_set_client);
+ check_password_policy(password_str);
my_make_scrambled_password_323(buff, password, pass_len);
+ }
return buff;
}
=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt 2012-05-14 11:18:13 +0000
+++ b/sql/share/errmsg-utf8.txt 2012-05-18 06:31:26 +0000
@@ -6754,7 +6754,7 @@ ER_MTS_RESET_WORKERS
eng "Cannot clean up worker info tables. Additional error messages can be found in the MySQL error log."
ER_NOT_VALID_PASSWORD
- eng "Your password does not satisfy the current policy requirements '%s'"
+ eng "Your password does not satisfy the current policy requirements "
#
# End of 5.6 error messages.
#
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2012-05-14 11:18:13 +0000
+++ b/sql/sql_acl.cc 2012-05-18 06:31:26 +0000
@@ -176,7 +176,7 @@ const TABLE_FIELD_DEF
static LEX_STRING native_password_plugin_name= {
C_STRING_WITH_LEN("mysql_native_password")
};
-
+
static LEX_STRING old_password_plugin_name= {
C_STRING_WITH_LEN("mysql_old_password")
};
@@ -9926,7 +9926,7 @@ int check_password_strength(String *pass
st_mysql_validate_password *password_strength=
(st_mysql_validate_password *) plugin_decl(plugin)->info;
- res= password_strength->get_password_strength(password, password->length());
+ res= password_strength->get_password_strength(password);
plugin_unlock(0, plugin);
}
return(res);
@@ -9942,103 +9942,9 @@ void check_password_policy(String *passw
st_mysql_validate_password *password_validate=
(st_mysql_validate_password *) plugin_decl(plugin)->info;
- if (!password_validate->validate_password(password, password->length()))
- my_error(ER_NOT_VALID_PASSWORD, MYF(0), password->ptr());
- plugin_unlock(0, plugin);
- }
-}
+ if (!password_validate->validate_password(password))
+ my_error(ER_NOT_VALID_PASSWORD, MYF(0));
-/*
- This is plugin service function which returns the beginning of the
- mysql String.
-*/
-extern "C"
-const char *mysql_string_character_beg(mysql_string_ptr string_ptr)
-{
- String *str= (String *) string_ptr;
- return str->ptr();
-}
-
-/* This is plugin service function which end of the mysql String */
-extern "C"
-const char *mysql_string_character_end(mysql_string_ptr string_ptr)
-{
- String *str= (String *) string_ptr;
- return (str->ptr() + str->length());
-}
-
-/*
- This is plugin service function which tells weather the character
- is a uppercase character or not, for client character set
-*/
-extern "C"
-int mysql_string_character_isupper(int char_type)
-{
- return (char_type & _MY_U);
-}
-
-/*
- This is plugin service function which tells weather the character
- is a lowercase character or not, for client character set
-*/
-extern "C"
-int mysql_string_character_islower(int char_type)
-{
- return (char_type & _MY_L);
-}
-
-/*
- This is plugin service function which tells weather the character
- is a digit or not, for client character set
-*/
-extern "C"
-int mysql_string_character_isdigit(int char_type)
-{
- return (char_type & _MY_NMR);
-}
-
-/*
- This is plugin service function which evaluate the ctype and
- returns the character length, for client character set.
-*/
-extern "C"
-int mysql_string_character_ctype(mysql_string_ptr string_ptr, int *char_type,
- const char *current_ptr)
-{
- String *str= (String *) string_ptr;
- const CHARSET_INFO *cs= str->charset();
- char *end= (char*) str->ptr() + str->length();
- return (cs->cset->ctype(cs, char_type, (uchar*) current_ptr,
- (uchar*) end));
-}
-
-/*
- This function provide plugin service to convert a String into
- lower case. Conversion depends on the client character set info
-*/
-extern "C"
-const char *mysql_string_character_casedn(mysql_string_ptr string_ptr)
-{
- String *str= (String *) string_ptr;
- String temp_str;
- const CHARSET_INFO *cs= str->charset();
-
- if (cs->casedn_multiply == 1)
- {
- uint len;
- len= cs->cset->casedn(cs, (char*) str->ptr(), str->length(),
- (char*) str->ptr(), str->length());
- str->length(len);
- }
- else
- {
- uint len= str->length() * cs->casedn_multiply;
- temp_str.alloc(len);
- temp_str.set_charset(cs);
- len= cs->cset->casedn(cs, (char*) str->ptr(), str->length(),
- (char*) temp_str.ptr(), len);
- temp_str.length(len);
- str= &temp_str;
+ plugin_unlock(0, plugin);
}
- return (str->ptr());
}
=== modified file 'sql/sql_acl.h'
--- a/sql/sql_acl.h 2012-04-30 06:36:01 +0000
+++ b/sql/sql_acl.h 2012-05-18 06:31:26 +0000
@@ -253,7 +253,6 @@ int fill_schema_column_privileges(THD *t
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
int check_password_strength(String *password);
void check_password_policy(String *password);
-
#ifdef NO_EMBEDDED_ACCESS_CHECKS
#define check_grant(A,B,C,D,E,F) 0
#define check_grant_db(A,B) 0
=== modified file 'sql/sql_plugin_services.h'
--- a/sql/sql_plugin_services.h 2012-05-14 11:18:13 +0000
+++ b/sql/sql_plugin_services.h 2012-05-18 06:31:26 +0000
@@ -51,13 +51,15 @@ static struct my_plugin_log_service my_p
};
static struct mysql_string_service_st mysql_string_handler= {
- mysql_string_character_beg,
- mysql_string_character_end,
- mysql_string_character_casedn,
- mysql_string_character_ctype,
- mysql_string_character_isupper,
- mysql_string_character_islower,
- mysql_string_character_isdigit,
+ mysql_string_convert_to_char_ptr,
+ mysql_string_get_iterator,
+ mysql_string_iterator_next,
+ mysql_string_iterator_isupper,
+ mysql_string_iterator_islower,
+ mysql_string_iterator_isdigit,
+ mysql_string_to_lowercase,
+ mysql_string_free,
+ mysql_string_iterator_free,
};
static struct st_service_ref list_of_services[]=
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2012-04-30 06:36:01 +0000
+++ b/sql/sql_yacc.yy 2012-05-18 06:31:26 +0000
@@ -14199,9 +14199,6 @@ text_or_password:
TEXT_STRING { $$=$1.str;}
| PASSWORD '(' TEXT_STRING ')'
{
- String *password = new (YYTHD->mem_root) String((const char*)$3.str,
- YYTHD->variables.character_set_client);
- check_password_policy(password);
$$= $3.length ? YYTHD->variables.old_passwords ?
Item_func_old_password::alloc(YYTHD, $3.str, $3.length) :
Item_func_password::alloc(YYTHD, $3.str, $3.length) :
=== added file 'sql/string_service.cc'
--- a/sql/string_service.cc 1970-01-01 00:00:00 +0000
+++ b/sql/string_service.cc 2012-05-18 06:31:26 +0000
@@ -0,0 +1,156 @@
+/* Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+
+/*
+ This file provide mysql_string service to plugins.
+ operations on mysql_string can be performed by plugins via these service
+ functions.
+*/
+
+#include <string_service.h>
+#include <my_sys.h>
+
+/*
+ This service function converts the mysql_string to the character set
+ specified by charset_name parameter.
+*/
+extern "C"
+int mysql_string_convert_to_char_ptr(mysql_string_handle string_handle,
+ const char *charset_name, char *buffer,
+ int *error)
+{
+ String *str= (String *) string_handle;
+ int len= (int)my_convert(buffer, 100, &my_charset_utf8_general_ci, str->ptr(),
+ str->length(), str->charset(), (uint*) error);
+ return (len);
+}
+
+/*
+ This service function deallocates the mysql_string_handle allocated on
+ server and used in plugins.
+*/
+extern "C"
+void mysql_string_free(mysql_string_handle string_handle)
+{
+ my_free(string_handle);
+}
+
+/*
+ This service function deallocates the mysql_string_iterator_handle
+ allocated on server and used in plugins.
+*/
+extern "C"
+void mysql_string_iterator_free(mysql_string_iterator_handle iterator_handle)
+{
+ my_free(iterator_handle);
+}
+
+/* This service function allocate mysql_string_iterator_handle and return it */
+extern "C"
+mysql_string_iterator_handle mysql_string_get_iterator(mysql_string_handle
+ string_handle)
+{
+ String *str= (String *) string_handle;
+ string_iterator *iterator= (string_iterator *)(my_malloc(sizeof
+ (string_iterator *), MYF(0)));
+ iterator->iterator_str= str;
+ iterator->iterator_ptr= str->ptr();
+ iterator->ctype= 0;
+ return (iterator);
+}
+
+/* Provide service which returns the next mysql_string_iterator_handle */
+extern "C"
+int mysql_string_iterator_next(mysql_string_iterator_handle iterator_handle)
+{
+ int char_len, char_type;
+ string_iterator *iterator= (string_iterator *) iterator_handle;
+ String *str= iterator->iterator_str;
+ const CHARSET_INFO *cs= str->charset();
+ char *end= (char*) str->ptr() + str->length();
+ if (iterator->iterator_ptr == (const char*) end)
+ return (0);
+ char_len= (cs->cset->ctype(cs, &char_type, (uchar*) iterator->iterator_ptr,
+ (uchar*) end));
+ iterator->ctype= char_type;
+ iterator->iterator_ptr+= (char_len > 0 ? char_len : (char_len < 0
+ ? -char_len : 1));
+ return (1);
+}
+
+/*
+ Provide service which calculate weather the current iterator_ptr points to
+ upper case character or not
+*/
+extern "C"
+int mysql_string_iterator_isupper(mysql_string_iterator_handle iterator_handle)
+{
+ string_iterator *iterator= (string_iterator *) iterator_handle;
+ return (iterator->ctype & _MY_U);
+}
+
+/*
+ Provide service which calculate weather the current iterator_ptr points to
+ lower case character or not
+*/
+extern "C"
+int mysql_string_iterator_islower(mysql_string_iterator_handle iterator_handle)
+{
+ string_iterator *iterator= (string_iterator *) iterator_handle;
+ return (iterator->ctype & _MY_L);
+}
+
+/*
+ Provide service which calculate weather the current iterator_ptr points to
+ digit or not
+*/
+extern "C"
+int mysql_string_iterator_isdigit(mysql_string_iterator_handle iterator_handle)
+{
+ string_iterator *iterator= (string_iterator *) iterator_handle;
+ return (iterator->ctype & _MY_NMR);
+}
+
+/*
+ This function provide plugin service to convert a String pointed by handle to
+ lower case. Conversion depends on the client character set info
+*/
+extern "C"
+mysql_string_handle mysql_string_to_lowercase(mysql_string_handle string_handle)
+{
+ String *str= (String *) string_handle;
+ String temp_str;
+ const CHARSET_INFO *cs= str->charset();
+
+ if (cs->casedn_multiply == 1)
+ {
+ uint len;
+ len= cs->cset->casedn(cs, (char*) str->ptr(), str->length(),
+ (char*) str->ptr(), str->length());
+ str->length(len);
+ }
+ else
+ {
+ uint len= str->length() * cs->casedn_multiply;
+ temp_str.alloc(len);
+ temp_str.set_charset(cs);
+ len= cs->cset->casedn(cs, (char*) str->ptr(), str->length(),
+ (char*) temp_str.ptr(), len);
+ temp_str.length(len);
+ str= &temp_str;
+ }
+ return (str);
+}
=== added file 'sql/string_service.h'
--- a/sql/string_service.h 1970-01-01 00:00:00 +0000
+++ b/sql/string_service.h 2012-05-18 06:31:26 +0000
@@ -0,0 +1,29 @@
+/* Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef STRING_SERVICE_INCLUDED
+#define STRING_SERVICE_INCLUDED
+
+#include <sql_string.h>
+
+/* mysql_string_itrerator structure to provide service to plugins */
+struct string_iterator
+{
+ String *iterator_str;
+ const char *iterator_ptr;
+ int ctype;
+};
+
+#endif /* STRING_SERVICE_INCLUDED */
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-trunk branch (ashish.y.agarwal:3888 to 3889) | Ashish Agarwal | 18 May |