mysql5/mysql-5.7.27/sql/auth/service_security_context.cc

335 lines
9.7 KiB
C++

/* Copyright (c) 2015, 2017, 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 SQL_SECURITY_CTX_SERVICE_INCLUDED
#define SQL_SECURITY_CTX_SERVICE_INCLUDED
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#include "auth_common.h"
#include "sql_class.h"
#include <mysql/service_security_context.h>
#define MY_SVC_TRUE 1
#define MY_SVC_FALSE 0
/**
Gets the security context for the thread.
@param[in] thd The thread to get the context from
@param[out] out_ctx placeholder for the security context handle
@retval true failure
@retval false success
*/
my_svc_bool thd_get_security_context(MYSQL_THD _thd,
MYSQL_SECURITY_CONTEXT *out_ctx)
{
THD *thd= dynamic_cast<THD *>(_thd);
try
{
if (out_ctx)
*out_ctx= thd->security_context();
else
return MY_SVC_TRUE;
return MY_SVC_FALSE;
}
catch (...)
{
return MY_SVC_FALSE;
}
}
/**
Sets a new security context for the thread.
@param[in] thd The thread to set the context to
@param[in] ctx The handle of the new security context
@retval true failure
@retval false success
*/
my_svc_bool thd_set_security_context(MYSQL_THD _thd,
MYSQL_SECURITY_CONTEXT in_ctx)
{
THD *thd= dynamic_cast<THD *>(_thd);
try
{
if (in_ctx)
thd->set_security_context(in_ctx);
return MY_SVC_FALSE;
}
catch (...)
{
return MY_SVC_TRUE;
}
}
/**
Creates a new security context and initializes it with the defaults
(no access, no user etc).
@param[out] out_ctx placeholder for the newly created security context handle
@retval true failure
@retval false success
*/
my_svc_bool security_context_create(MYSQL_SECURITY_CONTEXT *out_ctx)
{
try
{
if (out_ctx)
*out_ctx= new Security_context();
return MY_SVC_FALSE;
}
catch (...)
{
return MY_SVC_TRUE;
}
}
/**
Deallocates a security context.
@param[in] ctx The handle of the security context to destroy
@retval true failure
@retval false success
*/
my_svc_bool security_context_destroy(MYSQL_SECURITY_CONTEXT ctx)
{
try
{
delete ctx;
return MY_SVC_FALSE;
}
catch (...)
{
return MY_SVC_TRUE;
}
}
/**
Duplicates a security context.
@param[in] ctx The handle of the security context to copy
@param[out] out_ctx placeholder for the handle of the copied security context
@retval true failure
@retval false success
*/
my_svc_bool security_context_copy(MYSQL_SECURITY_CONTEXT in_ctx,
MYSQL_SECURITY_CONTEXT *out_ctx)
{
try
{
if (out_ctx)
{
*out_ctx= new Security_context();
if (in_ctx)
**out_ctx= *in_ctx;
}
return MY_SVC_FALSE;
}
catch (...)
{
return MY_SVC_TRUE;
}
}
/**
Looks up in the defined user accounts an account based on
the user@host[ip] combo supplied and checks if the user
has access to the database requested.
The lookup is done in exactly the same way as at login time.
@param[in] ctx The handle of the security context to update
@param[in] user The user name to look up
@param[in] host The host name to look up
@param[in] ip The ip of the incoming connection
@param[in] db The database to check access to
@retval true failure
@retval false success
*/
my_svc_bool security_context_lookup(MYSQL_SECURITY_CONTEXT ctx,
const char *user, const char *host,
const char *ip, const char *db)
{
return acl_getroot(ctx, (char *) user, (char *) host, (char *) ip, db) ?
TRUE : FALSE;
}
/**
Reads a named security context attribute and retuns its value.
Currently defined names are:
user MYSQL_LEX_CSTRING * login user (a.k.a. the user's part of USER())
host MYSQL_LEX_CSTRING * login host (a.k.a. the host's part of USER())
ip MYSQL_LEX_CSTRING * login client ip
host_or_ip MYSQL_LEX_CSTRING * host, if present, ip if not.
priv_user MYSQL_LEX_CSTRING * authenticated user (a.k.a. the user's part of CURRENT_USER())
priv_host MYSQL_LEX_CSTRING * authenticated host (a.k.a. the host's part of CURRENT_USER())
proxy_user MYSQL_LEX_CSTRING * the proxy user used in authenticating
privilege_super my_svc_bool * 1 if the user account has supper privilege, 0 otherwise
privilege_execute my_svc_bool * 1 if the user account has execute privilege, 0 otherwise
@param[in] ctx The handle of the security context to read from
@param[in] name The option name to read
@param[out] value The value of the option. Type depens on the name.
@retval true failure
@retval false success
*/
my_svc_bool security_context_get_option(MYSQL_SECURITY_CONTEXT ctx,
const char *name, void *inout_pvalue)
{
try
{
if (inout_pvalue)
{
if (!strcmp(name, "user"))
{
*((MYSQL_LEX_CSTRING *)inout_pvalue)= ctx->user();
}
else if (!strcmp(name, "host"))
{
*((MYSQL_LEX_CSTRING *) inout_pvalue)= ctx->host();
}
else if (!strcmp(name, "ip"))
{
*((MYSQL_LEX_CSTRING *) inout_pvalue)= ctx->ip();
}
else if (!strcmp(name, "host_or_ip"))
{
*((MYSQL_LEX_CSTRING *) inout_pvalue)= ctx->host_or_ip();
}
else if (!strcmp(name, "priv_user"))
{
*((MYSQL_LEX_CSTRING *) inout_pvalue)= ctx->priv_user();
}
else if (!strcmp(name, "priv_host"))
{
*((MYSQL_LEX_CSTRING *) inout_pvalue)= ctx->priv_host();
}
else if (!strcmp(name, "proxy_user"))
{
*((MYSQL_LEX_CSTRING *) inout_pvalue)= ctx->proxy_user();
}
else if (!strcmp(name, "external_user"))
{
*((MYSQL_LEX_CSTRING *) inout_pvalue)= ctx->external_user();
}
else if (!strcmp(name, "privilege_super"))
{
bool checked= ctx->check_access(SUPER_ACL);
*((my_svc_bool *) inout_pvalue)= checked ? MY_SVC_TRUE : MY_SVC_FALSE;
}
else if (!strcmp(name, "privilege_execute"))
{
bool checked= ctx->check_access(EXECUTE_ACL);
*((my_svc_bool *) inout_pvalue)= checked ? MY_SVC_TRUE : MY_SVC_FALSE;
}
else
return MY_SVC_TRUE; /** invalid option */
}
return MY_SVC_FALSE;
}
catch (...)
{
return MY_SVC_TRUE;
}
}
/**
Sets a value for a named security context attribute
Currently defined names are:
user MYSQL_LEX_CSTRING * login user (a.k.a. the user's part of USER())
host MYSQL_LEX_CSTRING * login host (a.k.a. the host's part of USER())
ip MYSQL_LEX_CSTRING * login client ip
priv_user MYSQL_LEX_CSTRING * authenticated user (a.k.a. the user's part of CURRENT_USER())
priv_host MYSQL_LEX_CSTRING * authenticated host (a.k.a. the host's part of CURRENT_USER())
proxy_user MYSQL_LEX_CSTRING * the proxy user used in authenticating
privilege_super my_svc_bool * 1 if the user account has supper privilege, 0 otherwise
privilege_execute my_svc_bool * 1 if the user account has execute privilege, 0 otherwise
@param[in] ctx The handle of the security context to set into
@param[in] name The option name to set
@param[in] value The value of the option. Type depens on the name.
@retval true failure
@retval false success
*/
my_svc_bool security_context_set_option(MYSQL_SECURITY_CONTEXT ctx,
const char *name, void *pvalue)
{
try
{
if (!strcmp(name, "user"))
{
LEX_CSTRING *value= (LEX_CSTRING *) pvalue;
ctx->assign_user(value->str, value->length);
}
else if (!strcmp(name, "host"))
{
LEX_CSTRING *value= (LEX_CSTRING *) pvalue;
ctx->assign_host(value->str, value->length);
}
else if (!strcmp(name, "ip"))
{
LEX_CSTRING *value= (LEX_CSTRING *) pvalue;
ctx->assign_ip(value->str, value->length);
}
else if (!strcmp(name, "priv_user"))
{
LEX_CSTRING *value= (LEX_CSTRING *) pvalue;
ctx->assign_priv_user(value->str, value->length);
}
else if (!strcmp(name, "priv_host"))
{
LEX_CSTRING *value= (LEX_CSTRING *) pvalue;
ctx->assign_priv_host(value->str, value->length);
}
else if (!strcmp(name, "proxy_user"))
{
LEX_CSTRING *value= (LEX_CSTRING *) pvalue;
ctx->assign_proxy_user(value->str, value->length);
}
else if (!strcmp(name, "privilege_super"))
{
my_svc_bool value= *(my_svc_bool *) pvalue;
if (value)
ctx->set_master_access(ctx->master_access() | (SUPER_ACL));
else
ctx->set_master_access(ctx->master_access() & ~(SUPER_ACL));
}
else if (!strcmp(name, "privilege_execute"))
{
my_svc_bool value= *(my_svc_bool *) pvalue;
if (value)
ctx->set_master_access(ctx->master_access() | (EXECUTE_ACL));
else
ctx->set_master_access(ctx->master_access() & ~(EXECUTE_ACL));
}
else
return MY_SVC_TRUE; /** invalid option */
return MY_SVC_FALSE;
}
catch (...)
{
return MY_SVC_TRUE;
}
}
#endif /* !NO_EMBEDDED_ACCESS_CHECKS */
#endif /* !SQL_SECURITY_CTX_SERVICE_INCLUDED */