diff options
author | Sergei Golubchik <serg@mariadb.org> | 2019-01-12 15:56:25 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2019-02-04 15:54:10 +0100 |
commit | c94ec9fc6721f50fadb1d86d1d0bf004b39c69d2 (patch) | |
tree | e94a46af346c4386fc712319be5ba2f1014a11a1 /plugin | |
parent | 3742f6f9aadc363fb83e3775066c33ba420fe97b (diff) | |
download | mariadb-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.cc | 20 | ||||
-rw-r--r-- | plugin/auth_gssapi/server_plugin.cc | 34 | ||||
-rw-r--r-- | plugin/auth_gssapi/server_plugin.h | 2 | ||||
-rw-r--r-- | plugin/auth_gssapi/sspi_server.cc | 17 | ||||
-rw-r--r-- | plugin/auth_pam/auth_pam.c | 32 | ||||
-rw-r--r-- | plugin/auth_pam/auth_pam_v1.c | 20 |
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, ¶m.cached) < 0)) + return CR_ERROR; + } + else + param.cached= NULL; + return pam_auth_base(¶m, info); } |