summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <cvicentiu@gmail.com>2013-10-17 15:11:13 -0700
committerSergei Golubchik <sergii@pisem.net>2013-10-17 15:11:13 -0700
commit7ec24435b324c27412a94cbd71b707c9fd06b8ed (patch)
tree297877af8d356478acdedd739af31151a5ec6dfa /sql
parent6680bb14a40c917e24e09a67894d9c7fd5065be0 (diff)
downloadmariadb-git-7ec24435b324c27412a94cbd71b707c9fd06b8ed.tar.gz
Added acl_setrole function. The function enables/disables role privileges to
the current user via the current security_context
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_acl.cc61
-rw-r--r--sql/sql_acl.h1
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h2
4 files changed, 65 insertions, 1 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index a5544ae7244..b7e9f3f97fb 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1672,6 +1672,67 @@ bool acl_getroot(Security_context *sctx, char *user, char *host,
DBUG_RETURN(res);
}
+bool acl_setrole(THD *thd, char *rolename)
+{
+ bool is_granted;
+ int result= 0;
+
+ /* clear role privileges */
+ mysql_mutex_lock(&acl_cache->lock);
+
+ ACL_USER *role= find_acl_role(rolename);
+ ACL_USER *acl_user;
+
+ if (!strcasecmp(rolename, "NONE")) {
+ /* have to clear the privileges */
+ /* get the current user */
+ acl_user= find_acl_user(thd->security_ctx->host, thd->security_ctx->user,
+ FALSE);
+ if (acl_user == NULL)
+ result= -1;
+ else
+ thd->security_ctx->master_access= acl_user->access;
+
+ goto end;
+ }
+
+ if (role == NULL) {
+ result= -1;
+ goto end;
+ }
+
+ for (uint i=0 ; i < role->role_grants.elements ; i++)
+ {
+ acl_user= *(dynamic_element(&role->role_grants, i, ACL_USER**));
+ if ((!acl_user->user.str && !thd->security_ctx->user[0]) ||
+ (acl_user->user.str && !strcmp(thd->security_ctx->user,
+ acl_user->user.str)))
+ {
+ if (compare_hostname(&acl_user->host, thd->security_ctx->host,
+ thd->security_ctx->host))
+ {
+ is_granted= TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!is_granted)
+ {
+ result= 1;
+ goto end;
+ }
+
+ /* merge the privileges */
+ thd->security_ctx->master_access= acl_user->access | role->access;
+ /* mark the current role */
+ strcpy(thd->security_ctx->priv_role, rolename);
+
+end:
+ mysql_mutex_unlock(&acl_cache->lock);
+ return result;
+}
+
static uchar* check_get_key(ACL_USER *buff, size_t *length,
my_bool not_used __attribute__((unused)))
{
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index b45b70ad069..abc5e8ac25c 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -382,4 +382,5 @@ get_cached_table_access(GRANT_INTERNAL_INFO *grant_internal_info,
bool acl_check_proxy_grant_access (THD *thd, const char *host, const char *user,
bool with_grant);
+bool acl_setrole(THD *thd, char *rolename);
#endif /* SQL_ACL_INCLUDED */
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 461d4d02e2f..cec46a0a3a7 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -3647,7 +3647,7 @@ void Security_context::init()
{
host= user= ip= external_user= 0;
host_or_ip= "connecting host";
- priv_user[0]= priv_host[0]= proxy_user[0]= '\0';
+ priv_user[0]= priv_host[0]= proxy_user[0]= priv_role[0]= '\0';
master_access= 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
db_access= NO_ACCESS;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 053ac98c453..64de6a63ded 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1041,6 +1041,8 @@ public:
char proxy_user[USERNAME_LENGTH + MAX_HOSTNAME + 5];
/* The host privilege we are using */
char priv_host[MAX_HOSTNAME];
+ /* The role privilege we are using */
+ char priv_role[USERNAME_LENGTH];
/* The external user (if available) */
char *external_user;
/* points to host if host is available, otherwise points to ip */