summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2016-01-21 13:20:40 +0200
committerDaniel Black <daniel@mariadb.org>2020-09-20 16:10:01 +1000
commitf3f45e46b614bddcef0a37f4352c5909ca565d1d (patch)
tree1946ed2c20eac1d8866321fd6170e294587322b8
parenta470b3570a7ce2534c9021f3b84d7457a3ba08e1 (diff)
downloadmariadb-git-f3f45e46b614bddcef0a37f4352c5909ca565d1d.tar.gz
[MDEV-7978] Added show create user implementation.
-rw-r--r--mysql-test/r/show_create_user.result39
-rw-r--r--mysql-test/t/show_create_user.test32
-rw-r--r--sql/sql_acl.cc253
-rw-r--r--sql/sql_yacc.yy2
4 files changed, 233 insertions, 93 deletions
diff --git a/mysql-test/r/show_create_user.result b/mysql-test/r/show_create_user.result
new file mode 100644
index 00000000000..63013eca074
--- /dev/null
+++ b/mysql-test/r/show_create_user.result
@@ -0,0 +1,39 @@
+create user foo;
+show create user foo;
+CREATE USER for foo@%
+CREATE USER 'foo'@'%'
+create user foo@test;
+show create user foo@test;
+CREATE USER for foo@test
+CREATE USER 'foo'@'test'
+create user foo2@test identified by 'password';
+show create user foo2@test;
+CREATE USER for foo2@test
+CREATE USER 'foo2'@'test' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19'
+alter user foo2@test identified with 'someplugin' as 'somepassword';
+show create user foo2@test;
+CREATE USER for foo2@test
+CREATE USER 'foo2'@'test' IDENTIFIED VIA someplugin USING 'somepassword'
+create user foo3@test require SSL;
+show create user foo3@test;
+CREATE USER for foo3@test
+CREATE USER 'foo3'@'test' REQUIRE SSL
+create user foo4@test require cipher 'text' issuer 'foo_issuer' subject 'foo_subject';
+show create user foo4@test;
+CREATE USER for foo4@test
+CREATE USER 'foo4'@'test' REQUIRE ISSUER 'foo_issuer' SUBJECT 'foo_subject' CIPHER 'text'
+create user foo5@test require SSL
+with MAX_QUERIES_PER_HOUR 10
+MAX_UPDATES_PER_HOUR 20
+MAX_CONNECTIONS_PER_HOUR 30
+MAX_USER_CONNECTIONS 40
+MAX_STATEMENT_TIME 0.5;
+show create user foo5@test;
+CREATE USER for foo5@test
+CREATE USER 'foo5'@'test' REQUIRE SSL WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30 MAX_USER_CONNECTIONS 40 MAX_STATEMENT_TIME 0.500000
+drop user foo5@test;
+drop user foo4@test;
+drop user foo3@test;
+drop user foo2@test;
+drop user foo@test;
+drop user foo;
diff --git a/mysql-test/t/show_create_user.test b/mysql-test/t/show_create_user.test
new file mode 100644
index 00000000000..124856ad564
--- /dev/null
+++ b/mysql-test/t/show_create_user.test
@@ -0,0 +1,32 @@
+create user foo;
+show create user foo;
+
+create user foo@test;
+show create user foo@test;
+
+create user foo2@test identified by 'password';
+show create user foo2@test;
+
+alter user foo2@test identified with 'someplugin' as 'somepassword';
+show create user foo2@test;
+
+create user foo3@test require SSL;
+show create user foo3@test;
+
+create user foo4@test require cipher 'text' issuer 'foo_issuer' subject 'foo_subject';
+show create user foo4@test;
+
+create user foo5@test require SSL
+ with MAX_QUERIES_PER_HOUR 10
+ MAX_UPDATES_PER_HOUR 20
+ MAX_CONNECTIONS_PER_HOUR 30
+ MAX_USER_CONNECTIONS 40
+ MAX_STATEMENT_TIME 0.5;
+show create user foo5@test;
+
+drop user foo5@test;
+drop user foo4@test;
+drop user foo3@test;
+drop user foo2@test;
+drop user foo@test;
+drop user foo;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 74ceb611a8f..11272f586c9 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -7756,6 +7756,94 @@ static void add_user_option(String *grant, double value, const char *name)
}
}
+static void add_user_parameters(String *result, ACL_USER* acl_user,
+ bool with_grant)
+{
+ result->append(STRING_WITH_LEN("@'"));
+ result->append(acl_user->host.hostname, acl_user->hostname_length,
+ system_charset_info);
+ result->append('\'');
+
+ if (acl_user->plugin.str == native_password_plugin_name.str ||
+ acl_user->plugin.str == old_password_plugin_name.str)
+ {
+ if (acl_user->auth_string.length)
+ {
+ DBUG_ASSERT(acl_user->salt_len);
+ result->append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '"));
+ result->append(acl_user->auth_string.str, acl_user->auth_string.length);
+ result->append('\'');
+ }
+ }
+ else
+ {
+ result->append(STRING_WITH_LEN(" IDENTIFIED VIA "));
+ result->append(acl_user->plugin.str, acl_user->plugin.length);
+ if (acl_user->auth_string.length)
+ {
+ result->append(STRING_WITH_LEN(" USING '"));
+ result->append(acl_user->auth_string.str, acl_user->auth_string.length);
+ result->append('\'');
+ }
+ }
+ /* "show grants" SSL related stuff */
+ if (acl_user->ssl_type == SSL_TYPE_ANY)
+ result->append(STRING_WITH_LEN(" REQUIRE SSL"));
+ else if (acl_user->ssl_type == SSL_TYPE_X509)
+ result->append(STRING_WITH_LEN(" REQUIRE X509"));
+ else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED)
+ {
+ int ssl_options = 0;
+ result->append(STRING_WITH_LEN(" REQUIRE "));
+ if (acl_user->x509_issuer)
+ {
+ ssl_options++;
+ result->append(STRING_WITH_LEN("ISSUER \'"));
+ result->append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
+ result->append('\'');
+ }
+ if (acl_user->x509_subject)
+ {
+ if (ssl_options++)
+ result->append(' ');
+ result->append(STRING_WITH_LEN("SUBJECT \'"));
+ result->append(acl_user->x509_subject,strlen(acl_user->x509_subject),
+ system_charset_info);
+ result->append('\'');
+ }
+ if (acl_user->ssl_cipher)
+ {
+ if (ssl_options++)
+ result->append(' ');
+ result->append(STRING_WITH_LEN("CIPHER '"));
+ result->append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher),
+ system_charset_info);
+ result->append('\'');
+ }
+ }
+ if (with_grant ||
+ (acl_user->user_resource.questions ||
+ acl_user->user_resource.updates ||
+ acl_user->user_resource.conn_per_hour ||
+ acl_user->user_resource.user_conn ||
+ acl_user->user_resource.max_statement_time != 0.0))
+ {
+ result->append(STRING_WITH_LEN(" WITH"));
+ if (with_grant)
+ result->append(STRING_WITH_LEN(" GRANT OPTION"));
+ add_user_option(result, acl_user->user_resource.questions,
+ "MAX_QUERIES_PER_HOUR", false);
+ add_user_option(result, acl_user->user_resource.updates,
+ "MAX_UPDATES_PER_HOUR", false);
+ add_user_option(result, acl_user->user_resource.conn_per_hour,
+ "MAX_CONNECTIONS_PER_HOUR", false);
+ add_user_option(result, acl_user->user_resource.user_conn,
+ "MAX_USER_CONNECTIONS", true);
+ add_user_option(result, acl_user->user_resource.max_statement_time,
+ "MAX_STATEMENT_TIME");
+ }
+}
+
static const char *command_array[]=
{
"SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "RELOAD",
@@ -7802,6 +7890,78 @@ static bool print_grants_for_role(THD *thd, ACL_ROLE * role)
}
+bool mysql_show_create_user(THD *thd, LEX_USER *lex_user)
+{
+ const char *username = safe_str(lex_user->user.str);
+ const char *hostname = safe_str(lex_user->host.str);
+ char buff[1024]; //Show create user should not take more than 1024 bytes.
+ Protocol *protocol= thd->protocol;
+ bool error= false;
+ ACL_USER *acl_user;
+ DBUG_ENTER("mysql_show_create_user");
+
+ // Check if the command specifies a username or not.
+ if (lex_user->user.str == current_user.str)
+ {
+ username= thd->security_ctx->priv_user;
+ hostname= thd->security_ctx->priv_host;
+ }
+
+ String field_name(buff, sizeof(buff), system_charset_info);
+ List<Item> field_list;
+ strxmov(buff, "CREATE USER for ", username, "@", hostname, NullS);
+ Item_string *field = new (thd->mem_root) Item_string_ascii(thd, "", 0);
+ if (!field)
+ {
+ my_error(ER_OUTOFMEMORY, MYF(0));
+ DBUG_RETURN(true);
+ }
+
+ field->name= buff;
+ field->max_length= sizeof(buff);
+ field_list.push_back(field, thd->mem_root);
+ if (protocol->send_result_set_metadata(&field_list,
+ Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
+ DBUG_RETURN(true);
+
+ String result(buff, sizeof(buff), system_charset_info);
+ result.length(0);
+ mysql_rwlock_rdlock(&LOCK_grant);
+ mysql_mutex_lock(&acl_cache->lock);
+
+ acl_user= find_user_exact(hostname, username);
+
+ // User not found in the internal data structures.
+ if (!acl_user)
+ {
+ my_error(ER_PASSWORD_NO_MATCH, MYF(0));
+ error= true;
+ goto end;
+ }
+
+ result.append("CREATE USER '");
+ result.append(username);
+ result.append('\'');
+
+ add_user_parameters(&result, acl_user, false);
+
+ protocol->prepare_for_resend();
+ protocol->store(result.ptr(), result.length(), result.charset());
+ if (protocol->write())
+ {
+ error= true;
+ }
+ my_eof(thd);
+
+end:
+ mysql_rwlock_unlock(&LOCK_grant);
+ mysql_mutex_unlock(&acl_cache->lock);
+
+ DBUG_RETURN(error);
+}
+
+
static int show_grants_callback(ACL_USER_BASE *role, void *data)
{
THD *thd= (THD *)data;
@@ -7811,11 +7971,6 @@ static int show_grants_callback(ACL_USER_BASE *role, void *data)
return 0;
}
-bool mysql_show_create_user(THD *thd, LEX_USER *lex_user)
-{
- return FALSE;
-}
-
void mysql_show_grants_get_fields(THD *thd, List<Item> *fields,
const char *name)
{
@@ -8090,93 +8245,7 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry,
global.append('\'');
if (!handle_as_role)
- {
- ACL_USER *acl_user= (ACL_USER *)acl_entry;
-
- global.append (STRING_WITH_LEN("@'"));
- global.append(acl_user->host.hostname, acl_user->hostname_length,
- system_charset_info);
- global.append ('\'');
-
- if (acl_user->plugin.str == native_password_plugin_name.str ||
- acl_user->plugin.str == old_password_plugin_name.str)
- {
- if (acl_user->auth_string.length)
- {
- DBUG_ASSERT(acl_user->salt_len);
- global.append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '"));
- global.append(acl_user->auth_string.str, acl_user->auth_string.length);
- global.append('\'');
- }
- }
- else
- {
- global.append(STRING_WITH_LEN(" IDENTIFIED VIA "));
- global.append(acl_user->plugin.str, acl_user->plugin.length);
- if (acl_user->auth_string.length)
- {
- global.append(STRING_WITH_LEN(" USING '"));
- global.append(acl_user->auth_string.str, acl_user->auth_string.length);
- global.append('\'');
- }
- }
- /* "show grants" SSL related stuff */
- if (acl_user->ssl_type == SSL_TYPE_ANY)
- global.append(STRING_WITH_LEN(" REQUIRE SSL"));
- else if (acl_user->ssl_type == SSL_TYPE_X509)
- global.append(STRING_WITH_LEN(" REQUIRE X509"));
- else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED)
- {
- int ssl_options = 0;
- global.append(STRING_WITH_LEN(" REQUIRE "));
- if (acl_user->x509_issuer)
- {
- ssl_options++;
- global.append(STRING_WITH_LEN("ISSUER \'"));
- global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
- global.append('\'');
- }
- if (acl_user->x509_subject)
- {
- if (ssl_options++)
- global.append(' ');
- global.append(STRING_WITH_LEN("SUBJECT \'"));
- global.append(acl_user->x509_subject,strlen(acl_user->x509_subject),
- system_charset_info);
- global.append('\'');
- }
- if (acl_user->ssl_cipher)
- {
- if (ssl_options++)
- global.append(' ');
- global.append(STRING_WITH_LEN("CIPHER '"));
- global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher),
- system_charset_info);
- global.append('\'');
- }
- }
- if ((want_access & GRANT_ACL) ||
- (acl_user->user_resource.questions ||
- acl_user->user_resource.updates ||
- acl_user->user_resource.conn_per_hour ||
- acl_user->user_resource.user_conn ||
- acl_user->user_resource.max_statement_time != 0.0))
- {
- global.append(STRING_WITH_LEN(" WITH"));
- if (want_access & GRANT_ACL)
- global.append(STRING_WITH_LEN(" GRANT OPTION"));
- add_user_option(&global, acl_user->user_resource.questions,
- "MAX_QUERIES_PER_HOUR", false);
- add_user_option(&global, acl_user->user_resource.updates,
- "MAX_UPDATES_PER_HOUR", false);
- add_user_option(&global, acl_user->user_resource.conn_per_hour,
- "MAX_CONNECTIONS_PER_HOUR", false);
- add_user_option(&global, acl_user->user_resource.user_conn,
- "MAX_USER_CONNECTIONS", true);
- add_user_option(&global, acl_user->user_resource.max_statement_time,
- "MAX_STATEMENT_TIME");
- }
- }
+ add_user_parameters(&global, (ACL_USER *)acl_entry, (want_access & GRANT_ACL));
protocol->prepare_for_resend();
protocol->store(global.ptr(),global.length(),global.charset());
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d7e4fb34005..14616d33fbe 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -12498,7 +12498,7 @@ show_param:
Lex->sql_command= SQLCOM_SHOW_CREATE_USER;
if (!(Lex->grant_user= (LEX_USER*)thd->alloc(sizeof(LEX_USER))))
MYSQL_YYABORT;
- Lex->grant_user->user= current_user_and_current_role;
+ Lex->grant_user->user= current_user;
}
| CREATE USER user
{