summaryrefslogtreecommitdiff
path: root/plugin
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2019-01-12 15:56:25 +0100
committerSergei Golubchik <serg@mariadb.org>2019-02-04 15:54:10 +0100
commitc94ec9fc6721f50fadb1d86d1d0bf004b39c69d2 (patch)
treee94a46af346c4386fc712319be5ba2f1014a11a1 /plugin
parent3742f6f9aadc363fb83e3775066c33ba420fe97b (diff)
downloadmariadb-git-c94ec9fc6721f50fadb1d86d1d0bf004b39c69d2.tar.gz
MDEV-17950 SHOW GRANTS FOR does not work for a user identified with non-existing plugin
Revert the side effect of 7c40996cc866. Do not convert password hash to its binary representation when a user entry is loaded. Do it lazily on the first authenticatation attempt. As a collateral - force all authentication plugins to follow the protocol and read_packet at least once before accessing info->username (username is not available before first client handshake packet is read). Fix PAM and GSSAPI plugins to behave.
Diffstat (limited to 'plugin')
-rw-r--r--plugin/auth_gssapi/gssapi_server.cc20
-rw-r--r--plugin/auth_gssapi/server_plugin.cc34
-rw-r--r--plugin/auth_gssapi/server_plugin.h2
-rw-r--r--plugin/auth_gssapi/sspi_server.cc17
-rw-r--r--plugin/auth_pam/auth_pam.c32
-rw-r--r--plugin/auth_pam/auth_pam_v1.c20
6 files changed, 79 insertions, 46 deletions
diff --git a/plugin/auth_gssapi/gssapi_server.cc b/plugin/auth_gssapi/gssapi_server.cc
index a498aba982d..8aa13aac6c9 100644
--- a/plugin/auth_gssapi/gssapi_server.cc
+++ b/plugin/auth_gssapi/gssapi_server.cc
@@ -145,7 +145,7 @@ int plugin_deinit()
}
-int auth_server(MYSQL_PLUGIN_VIO *vio,const char *user, size_t userlen, int use_full_name)
+int auth_server(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *auth_info)
{
int rc= CR_ERROR; /* return code */
@@ -157,6 +157,9 @@ int auth_server(MYSQL_PLUGIN_VIO *vio,const char *user, size_t userlen, int use_
gss_name_t client_name;
gss_buffer_desc client_name_buf, input, output;
char *client_name_str;
+ const char *user= 0;
+ size_t userlen;
+ int use_full_name;
/* server acquires credential */
major= gss_acquire_cred(&minor, service_name, GSS_C_INDEFINITE,
@@ -180,6 +183,21 @@ int auth_server(MYSQL_PLUGIN_VIO *vio,const char *user, size_t userlen, int use_
log_error(0, 0, "fail to read token from client");
goto cleanup;
}
+ if (!user)
+ {
+ if (auth_info->auth_string_length > 0)
+ {
+ use_full_name= 1;
+ user= auth_info->auth_string;
+ userlen= auth_info->auth_string_length;
+ }
+ else
+ {
+ use_full_name= 0;
+ user= auth_info->user_name;
+ userlen= auth_info->user_name_length;
+ }
+ }
input.length= len;
major= gss_accept_sec_context(&minor, &ctxt, cred, &input,
diff --git a/plugin/auth_gssapi/server_plugin.cc b/plugin/auth_gssapi/server_plugin.cc
index 5db86cffbe4..550ae775e0f 100644
--- a/plugin/auth_gssapi/server_plugin.cc
+++ b/plugin/auth_gssapi/server_plugin.cc
@@ -64,41 +64,11 @@ unsigned long srv_mech;
*/
static int gssapi_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *auth_info)
{
- int use_full_name;
- const char *user;
- int user_len;
-
- /* No user name yet ? Read the client handshake packet with the user name. */
- if (auth_info->user_name == 0)
- {
- unsigned char *pkt;
- if (vio->read_packet(vio, &pkt) < 0)
- return CR_ERROR;
- }
-
/* Send first packet with target name and mech name */
if (vio->write_packet(vio, (unsigned char *)first_packet, first_packet_len))
- {
return CR_ERROR;
- }
-
- /* Figure out whether to use full name (as given in IDENTIFIED AS clause)
- * or just short username auth_string
- */
- if (auth_info->auth_string_length > 0)
- {
- use_full_name= 1;
- user= auth_info->auth_string;
- user_len= auth_info->auth_string_length;
- }
- else
- {
- use_full_name= 0;
- user= auth_info->user_name;
- user_len= auth_info->user_name_length;
- }
-
- return auth_server(vio, user, user_len, use_full_name);
+
+ return auth_server(vio, auth_info);
}
static int initialize_plugin(void *unused)
diff --git a/plugin/auth_gssapi/server_plugin.h b/plugin/auth_gssapi/server_plugin.h
index 6284a319d03..84552d3a263 100644
--- a/plugin/auth_gssapi/server_plugin.h
+++ b/plugin/auth_gssapi/server_plugin.h
@@ -48,4 +48,4 @@ extern char *srv_keytab_path;
int plugin_init();
int plugin_deinit();
-int auth_server(MYSQL_PLUGIN_VIO *vio, const char *username, size_t username_len, int use_full_name);
+int auth_server(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *auth_info);
diff --git a/plugin/auth_gssapi/sspi_server.cc b/plugin/auth_gssapi/sspi_server.cc
index af78829df6e..44aa5051472 100644
--- a/plugin/auth_gssapi/sspi_server.cc
+++ b/plugin/auth_gssapi/sspi_server.cc
@@ -140,7 +140,7 @@ static int get_client_name_from_context(CtxtHandle *ctxt,
}
-int auth_server(MYSQL_PLUGIN_VIO *vio, const char *user, size_t user_len, int compare_full_name)
+int auth_server(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *auth_info)
{
int ret;
SECURITY_STATUS sspi_ret;
@@ -155,6 +155,8 @@ int auth_server(MYSQL_PLUGIN_VIO *vio, const char *user, size_t user_len, int co
SecBuffer outbuf;
void* out= NULL;
char client_name[MYSQL_USERNAME_LENGTH + 1];
+ const char *user= 0;
+ int compare_full_name;
ret= CR_ERROR;
SecInvalidateHandle(&cred);
@@ -207,6 +209,19 @@ int auth_server(MYSQL_PLUGIN_VIO *vio, const char *user, size_t user_len, int co
log_error(SEC_E_OK, "communication error(read)");
goto cleanup;
}
+ if (!user)
+ {
+ if (auth_info->auth_string_length > 0)
+ {
+ compare_full_name= 1;
+ user= auth_info->auth_string;
+ }
+ else
+ {
+ compare_full_name= 0;
+ user= auth_info->user_name;
+ }
+ }
inbuf.cbBuffer= len;
outbuf.cbBuffer= SSPI_MAX_TOKEN_SIZE;
sspi_ret= AcceptSecurityContext(
diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c
index 1ffc3285a3d..56154fb1656 100644
--- a/plugin/auth_pam/auth_pam.c
+++ b/plugin/auth_pam/auth_pam.c
@@ -36,8 +36,8 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
{
int p_to_c[2], c_to_p[2]; /* Parent-to-child and child-to-parent pipes. */
pid_t proc_id;
- int result= CR_ERROR;
- unsigned char field;
+ int result= CR_ERROR, pkt_len;
+ unsigned char field, *pkt;
PAM_DEBUG((stderr, "PAM: opening pipes.\n"));
if (pipe(p_to_c) < 0 || pipe(c_to_p) < 0)
@@ -96,6 +96,14 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
close(c_to_p[1]) < 0)
goto error_ret;
+ /* no user name yet ? read the client handshake packet with the user name */
+ if (info->user_name == 0)
+ {
+ if ((pkt_len= vio->read_packet(vio, &pkt) < 0))
+ return CR_ERROR;
+ }
+ else
+ pkt= NULL;
PAM_DEBUG((stderr, "PAM: parent sends user data [%s], [%s].\n",
info->user_name, info->auth_string));
@@ -140,23 +148,27 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
{
unsigned char buf[10240];
int buf_len;
- unsigned char *pkt;
PAM_DEBUG((stderr, "PAM: getting CONV string.\n"));
if ((buf_len= read_string(c_to_p[0], (char *) buf, sizeof(buf))) < 0)
goto error_ret;
- PAM_DEBUG((stderr, "PAM: sending CONV string.\n"));
- if (vio->write_packet(vio, buf, buf_len))
- goto error_ret;
+ if (!pkt || (buf[0] >> 1) != 2)
+ {
+ PAM_DEBUG((stderr, "PAM: sending CONV string.\n"));
+ if (vio->write_packet(vio, buf, buf_len))
+ goto error_ret;
- PAM_DEBUG((stderr, "PAM: reading CONV answer.\n"));
- if ((buf_len= vio->read_packet(vio, &pkt)) < 0)
- goto error_ret;
+ PAM_DEBUG((stderr, "PAM: reading CONV answer.\n"));
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ goto error_ret;
+ }
PAM_DEBUG((stderr, "PAM: answering CONV.\n"));
- if (write_string(p_to_c[1], pkt, buf_len))
+ if (write_string(p_to_c[1], pkt, pkt_len))
goto error_ret;
+
+ pkt= NULL;
}
break;
diff --git a/plugin/auth_pam/auth_pam_v1.c b/plugin/auth_pam/auth_pam_v1.c
index 95110a5e310..6e0b2ea9991 100644
--- a/plugin/auth_pam/auth_pam_v1.c
+++ b/plugin/auth_pam/auth_pam_v1.c
@@ -17,13 +17,21 @@
#include <mysql/plugin_auth.h>
struct param {
- unsigned char buf[10240], *ptr;
+ unsigned char buf[10240], *ptr, *cached;
+ int cached_len;
MYSQL_PLUGIN_VIO *vio;
};
static int roundtrip(struct param *param, const unsigned char *buf,
int buf_len, unsigned char **pkt)
{
+ if (param->cached && (buf[0] >> 1) == 2)
+ {
+ *pkt= param->cached;
+ param->cached= NULL;
+ return param->cached_len;
+ }
+ param->cached= NULL;
if (param->vio->write_packet(param->vio, buf, buf_len))
return -1;
return param->vio->read_packet(param->vio, pkt);
@@ -35,6 +43,16 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
{
struct param param;
param.vio = vio;
+
+ /* no user name yet ? read the client handshake packet with the user name */
+ if (info->user_name == 0)
+ {
+ if ((param.cached_len= vio->read_packet(vio, &param.cached) < 0))
+ return CR_ERROR;
+ }
+ else
+ param.cached= NULL;
+
return pam_auth_base(&param, info);
}