Skip to content

Commit f3f45e4

Browse files
cvicentiugrooverdan
authored andcommitted
[MDEV-7978] Added show create user implementation.
1 parent a470b35 commit f3f45e4

File tree

4 files changed

+233
-93
lines changed

4 files changed

+233
-93
lines changed

mysql-test/r/show_create_user.result

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
create user foo;
2+
show create user foo;
3+
CREATE USER for foo@%
4+
CREATE USER 'foo'@'%'
5+
create user foo@test;
6+
show create user foo@test;
7+
CREATE USER for foo@test
8+
CREATE USER 'foo'@'test'
9+
create user foo2@test identified by 'password';
10+
show create user foo2@test;
11+
CREATE USER for foo2@test
12+
CREATE USER 'foo2'@'test' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19'
13+
alter user foo2@test identified with 'someplugin' as 'somepassword';
14+
show create user foo2@test;
15+
CREATE USER for foo2@test
16+
CREATE USER 'foo2'@'test' IDENTIFIED VIA someplugin USING 'somepassword'
17+
create user foo3@test require SSL;
18+
show create user foo3@test;
19+
CREATE USER for foo3@test
20+
CREATE USER 'foo3'@'test' REQUIRE SSL
21+
create user foo4@test require cipher 'text' issuer 'foo_issuer' subject 'foo_subject';
22+
show create user foo4@test;
23+
CREATE USER for foo4@test
24+
CREATE USER 'foo4'@'test' REQUIRE ISSUER 'foo_issuer' SUBJECT 'foo_subject' CIPHER 'text'
25+
create user foo5@test require SSL
26+
with MAX_QUERIES_PER_HOUR 10
27+
MAX_UPDATES_PER_HOUR 20
28+
MAX_CONNECTIONS_PER_HOUR 30
29+
MAX_USER_CONNECTIONS 40
30+
MAX_STATEMENT_TIME 0.5;
31+
show create user foo5@test;
32+
CREATE USER for foo5@test
33+
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
34+
drop user foo5@test;
35+
drop user foo4@test;
36+
drop user foo3@test;
37+
drop user foo2@test;
38+
drop user foo@test;
39+
drop user foo;

mysql-test/t/show_create_user.test

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
create user foo;
2+
show create user foo;
3+
4+
create user foo@test;
5+
show create user foo@test;
6+
7+
create user foo2@test identified by 'password';
8+
show create user foo2@test;
9+
10+
alter user foo2@test identified with 'someplugin' as 'somepassword';
11+
show create user foo2@test;
12+
13+
create user foo3@test require SSL;
14+
show create user foo3@test;
15+
16+
create user foo4@test require cipher 'text' issuer 'foo_issuer' subject 'foo_subject';
17+
show create user foo4@test;
18+
19+
create user foo5@test require SSL
20+
with MAX_QUERIES_PER_HOUR 10
21+
MAX_UPDATES_PER_HOUR 20
22+
MAX_CONNECTIONS_PER_HOUR 30
23+
MAX_USER_CONNECTIONS 40
24+
MAX_STATEMENT_TIME 0.5;
25+
show create user foo5@test;
26+
27+
drop user foo5@test;
28+
drop user foo4@test;
29+
drop user foo3@test;
30+
drop user foo2@test;
31+
drop user foo@test;
32+
drop user foo;

sql/sql_acl.cc

Lines changed: 161 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -7756,6 +7756,94 @@ static void add_user_option(String *grant, double value, const char *name)
77567756
}
77577757
}
77587758

7759+
static void add_user_parameters(String *result, ACL_USER* acl_user,
7760+
bool with_grant)
7761+
{
7762+
result->append(STRING_WITH_LEN("@'"));
7763+
result->append(acl_user->host.hostname, acl_user->hostname_length,
7764+
system_charset_info);
7765+
result->append('\'');
7766+
7767+
if (acl_user->plugin.str == native_password_plugin_name.str ||
7768+
acl_user->plugin.str == old_password_plugin_name.str)
7769+
{
7770+
if (acl_user->auth_string.length)
7771+
{
7772+
DBUG_ASSERT(acl_user->salt_len);
7773+
result->append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '"));
7774+
result->append(acl_user->auth_string.str, acl_user->auth_string.length);
7775+
result->append('\'');
7776+
}
7777+
}
7778+
else
7779+
{
7780+
result->append(STRING_WITH_LEN(" IDENTIFIED VIA "));
7781+
result->append(acl_user->plugin.str, acl_user->plugin.length);
7782+
if (acl_user->auth_string.length)
7783+
{
7784+
result->append(STRING_WITH_LEN(" USING '"));
7785+
result->append(acl_user->auth_string.str, acl_user->auth_string.length);
7786+
result->append('\'');
7787+
}
7788+
}
7789+
/* "show grants" SSL related stuff */
7790+
if (acl_user->ssl_type == SSL_TYPE_ANY)
7791+
result->append(STRING_WITH_LEN(" REQUIRE SSL"));
7792+
else if (acl_user->ssl_type == SSL_TYPE_X509)
7793+
result->append(STRING_WITH_LEN(" REQUIRE X509"));
7794+
else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED)
7795+
{
7796+
int ssl_options = 0;
7797+
result->append(STRING_WITH_LEN(" REQUIRE "));
7798+
if (acl_user->x509_issuer)
7799+
{
7800+
ssl_options++;
7801+
result->append(STRING_WITH_LEN("ISSUER \'"));
7802+
result->append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
7803+
result->append('\'');
7804+
}
7805+
if (acl_user->x509_subject)
7806+
{
7807+
if (ssl_options++)
7808+
result->append(' ');
7809+
result->append(STRING_WITH_LEN("SUBJECT \'"));
7810+
result->append(acl_user->x509_subject,strlen(acl_user->x509_subject),
7811+
system_charset_info);
7812+
result->append('\'');
7813+
}
7814+
if (acl_user->ssl_cipher)
7815+
{
7816+
if (ssl_options++)
7817+
result->append(' ');
7818+
result->append(STRING_WITH_LEN("CIPHER '"));
7819+
result->append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher),
7820+
system_charset_info);
7821+
result->append('\'');
7822+
}
7823+
}
7824+
if (with_grant ||
7825+
(acl_user->user_resource.questions ||
7826+
acl_user->user_resource.updates ||
7827+
acl_user->user_resource.conn_per_hour ||
7828+
acl_user->user_resource.user_conn ||
7829+
acl_user->user_resource.max_statement_time != 0.0))
7830+
{
7831+
result->append(STRING_WITH_LEN(" WITH"));
7832+
if (with_grant)
7833+
result->append(STRING_WITH_LEN(" GRANT OPTION"));
7834+
add_user_option(result, acl_user->user_resource.questions,
7835+
"MAX_QUERIES_PER_HOUR", false);
7836+
add_user_option(result, acl_user->user_resource.updates,
7837+
"MAX_UPDATES_PER_HOUR", false);
7838+
add_user_option(result, acl_user->user_resource.conn_per_hour,
7839+
"MAX_CONNECTIONS_PER_HOUR", false);
7840+
add_user_option(result, acl_user->user_resource.user_conn,
7841+
"MAX_USER_CONNECTIONS", true);
7842+
add_user_option(result, acl_user->user_resource.max_statement_time,
7843+
"MAX_STATEMENT_TIME");
7844+
}
7845+
}
7846+
77597847
static const char *command_array[]=
77607848
{
77617849
"SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "RELOAD",
@@ -7802,6 +7890,78 @@ static bool print_grants_for_role(THD *thd, ACL_ROLE * role)
78027890
}
78037891

78047892

7893+
bool mysql_show_create_user(THD *thd, LEX_USER *lex_user)
7894+
{
7895+
const char *username = safe_str(lex_user->user.str);
7896+
const char *hostname = safe_str(lex_user->host.str);
7897+
char buff[1024]; //Show create user should not take more than 1024 bytes.
7898+
Protocol *protocol= thd->protocol;
7899+
bool error= false;
7900+
ACL_USER *acl_user;
7901+
DBUG_ENTER("mysql_show_create_user");
7902+
7903+
// Check if the command specifies a username or not.
7904+
if (lex_user->user.str == current_user.str)
7905+
{
7906+
username= thd->security_ctx->priv_user;
7907+
hostname= thd->security_ctx->priv_host;
7908+
}
7909+
7910+
String field_name(buff, sizeof(buff), system_charset_info);
7911+
List<Item> field_list;
7912+
strxmov(buff, "CREATE USER for ", username, "@", hostname, NullS);
7913+
Item_string *field = new (thd->mem_root) Item_string_ascii(thd, "", 0);
7914+
if (!field)
7915+
{
7916+
my_error(ER_OUTOFMEMORY, MYF(0));
7917+
DBUG_RETURN(true);
7918+
}
7919+
7920+
field->name= buff;
7921+
field->max_length= sizeof(buff);
7922+
field_list.push_back(field, thd->mem_root);
7923+
if (protocol->send_result_set_metadata(&field_list,
7924+
Protocol::SEND_NUM_ROWS |
7925+
Protocol::SEND_EOF))
7926+
DBUG_RETURN(true);
7927+
7928+
String result(buff, sizeof(buff), system_charset_info);
7929+
result.length(0);
7930+
mysql_rwlock_rdlock(&LOCK_grant);
7931+
mysql_mutex_lock(&acl_cache->lock);
7932+
7933+
acl_user= find_user_exact(hostname, username);
7934+
7935+
// User not found in the internal data structures.
7936+
if (!acl_user)
7937+
{
7938+
my_error(ER_PASSWORD_NO_MATCH, MYF(0));
7939+
error= true;
7940+
goto end;
7941+
}
7942+
7943+
result.append("CREATE USER '");
7944+
result.append(username);
7945+
result.append('\'');
7946+
7947+
add_user_parameters(&result, acl_user, false);
7948+
7949+
protocol->prepare_for_resend();
7950+
protocol->store(result.ptr(), result.length(), result.charset());
7951+
if (protocol->write())
7952+
{
7953+
error= true;
7954+
}
7955+
my_eof(thd);
7956+
7957+
end:
7958+
mysql_rwlock_unlock(&LOCK_grant);
7959+
mysql_mutex_unlock(&acl_cache->lock);
7960+
7961+
DBUG_RETURN(error);
7962+
}
7963+
7964+
78057965
static int show_grants_callback(ACL_USER_BASE *role, void *data)
78067966
{
78077967
THD *thd= (THD *)data;
@@ -7811,11 +7971,6 @@ static int show_grants_callback(ACL_USER_BASE *role, void *data)
78117971
return 0;
78127972
}
78137973

7814-
bool mysql_show_create_user(THD *thd, LEX_USER *lex_user)
7815-
{
7816-
return FALSE;
7817-
}
7818-
78197974
void mysql_show_grants_get_fields(THD *thd, List<Item> *fields,
78207975
const char *name)
78217976
{
@@ -8090,93 +8245,7 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry,
80908245
global.append('\'');
80918246

80928247
if (!handle_as_role)
8093-
{
8094-
ACL_USER *acl_user= (ACL_USER *)acl_entry;
8095-
8096-
global.append (STRING_WITH_LEN("@'"));
8097-
global.append(acl_user->host.hostname, acl_user->hostname_length,
8098-
system_charset_info);
8099-
global.append ('\'');
8100-
8101-
if (acl_user->plugin.str == native_password_plugin_name.str ||
8102-
acl_user->plugin.str == old_password_plugin_name.str)
8103-
{
8104-
if (acl_user->auth_string.length)
8105-
{
8106-
DBUG_ASSERT(acl_user->salt_len);
8107-
global.append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '"));
8108-
global.append(acl_user->auth_string.str, acl_user->auth_string.length);
8109-
global.append('\'');
8110-
}
8111-
}
8112-
else
8113-
{
8114-
global.append(STRING_WITH_LEN(" IDENTIFIED VIA "));
8115-
global.append(acl_user->plugin.str, acl_user->plugin.length);
8116-
if (acl_user->auth_string.length)
8117-
{
8118-
global.append(STRING_WITH_LEN(" USING '"));
8119-
global.append(acl_user->auth_string.str, acl_user->auth_string.length);
8120-
global.append('\'');
8121-
}
8122-
}
8123-
/* "show grants" SSL related stuff */
8124-
if (acl_user->ssl_type == SSL_TYPE_ANY)
8125-
global.append(STRING_WITH_LEN(" REQUIRE SSL"));
8126-
else if (acl_user->ssl_type == SSL_TYPE_X509)
8127-
global.append(STRING_WITH_LEN(" REQUIRE X509"));
8128-
else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED)
8129-
{
8130-
int ssl_options = 0;
8131-
global.append(STRING_WITH_LEN(" REQUIRE "));
8132-
if (acl_user->x509_issuer)
8133-
{
8134-
ssl_options++;
8135-
global.append(STRING_WITH_LEN("ISSUER \'"));
8136-
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
8137-
global.append('\'');
8138-
}
8139-
if (acl_user->x509_subject)
8140-
{
8141-
if (ssl_options++)
8142-
global.append(' ');
8143-
global.append(STRING_WITH_LEN("SUBJECT \'"));
8144-
global.append(acl_user->x509_subject,strlen(acl_user->x509_subject),
8145-
system_charset_info);
8146-
global.append('\'');
8147-
}
8148-
if (acl_user->ssl_cipher)
8149-
{
8150-
if (ssl_options++)
8151-
global.append(' ');
8152-
global.append(STRING_WITH_LEN("CIPHER '"));
8153-
global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher),
8154-
system_charset_info);
8155-
global.append('\'');
8156-
}
8157-
}
8158-
if ((want_access & GRANT_ACL) ||
8159-
(acl_user->user_resource.questions ||
8160-
acl_user->user_resource.updates ||
8161-
acl_user->user_resource.conn_per_hour ||
8162-
acl_user->user_resource.user_conn ||
8163-
acl_user->user_resource.max_statement_time != 0.0))
8164-
{
8165-
global.append(STRING_WITH_LEN(" WITH"));
8166-
if (want_access & GRANT_ACL)
8167-
global.append(STRING_WITH_LEN(" GRANT OPTION"));
8168-
add_user_option(&global, acl_user->user_resource.questions,
8169-
"MAX_QUERIES_PER_HOUR", false);
8170-
add_user_option(&global, acl_user->user_resource.updates,
8171-
"MAX_UPDATES_PER_HOUR", false);
8172-
add_user_option(&global, acl_user->user_resource.conn_per_hour,
8173-
"MAX_CONNECTIONS_PER_HOUR", false);
8174-
add_user_option(&global, acl_user->user_resource.user_conn,
8175-
"MAX_USER_CONNECTIONS", true);
8176-
add_user_option(&global, acl_user->user_resource.max_statement_time,
8177-
"MAX_STATEMENT_TIME");
8178-
}
8179-
}
8248+
add_user_parameters(&global, (ACL_USER *)acl_entry, (want_access & GRANT_ACL));
81808249

81818250
protocol->prepare_for_resend();
81828251
protocol->store(global.ptr(),global.length(),global.charset());

sql/sql_yacc.yy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12498,7 +12498,7 @@ show_param:
1249812498
Lex->sql_command= SQLCOM_SHOW_CREATE_USER;
1249912499
if (!(Lex->grant_user= (LEX_USER*)thd->alloc(sizeof(LEX_USER))))
1250012500
MYSQL_YYABORT;
12501-
Lex->grant_user->user= current_user_and_current_role;
12501+
Lex->grant_user->user= current_user;
1250212502
}
1250312503
| CREATE USER user
1250412504
{

0 commit comments

Comments
 (0)