1 /* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #define MYSQL_SERVER  "We need security context"
24 
25 #include <sql_class.h>                      /* THD, Security context */
26 #include <sql_acl.h>                        /* SUPER_ACL */
27 #include <mysql/service_security_context.h> /* Security context service */
28 
29 #include "security_context_wrapper.h"
30 
31 namespace connection_control
32 {
33   /**
34     Security_context_wrapper constructor.
35 
36     @param [in] thd    Handle to THD
37 
38     Get security context from thd.
39   */
Security_context_wrapper(MYSQL_THD thd)40   Security_context_wrapper::Security_context_wrapper(MYSQL_THD thd)
41   {
42     m_valid= thd_get_security_context(thd, &m_sctx) ? false : true;
43   }
44 
45 
46   /**
47     Get value for given property from security context
48 
49     @param [in] property    Property to be checked
50     @param [out] value      Value of the property
51 
52     @returns status of property check
53       @retval true Error fetching property value
54       @retval false value contains valid value for given property
55   */
56 
57   bool
get_property(const char * property,LEX_CSTRING * value)58     Security_context_wrapper::get_property(const char *property, LEX_CSTRING *value)
59   {
60     value->length=0;
61     value->str= 0;
62 
63     if (!m_valid)
64       return true;
65     else
66       return security_context_get_option(m_sctx, property, value);
67   }
68 
69 
70   /**  Get proxy user information from security context */
71 
72   const char *
get_proxy_user()73     Security_context_wrapper::get_proxy_user()
74   {
75     MYSQL_LEX_CSTRING proxy_user;
76     if (get_property("proxy_user", &proxy_user))
77       return 0;
78     return proxy_user.str;
79   }
80 
81 
82   /** Get priv user information from security context */
83 
84   const char *
get_priv_user()85     Security_context_wrapper::get_priv_user()
86   {
87     MYSQL_LEX_CSTRING priv_user;
88     if (get_property("priv_user", &priv_user))
89       return 0;
90     return priv_user.str;
91   }
92 
93 
94   /** Get priv host information from security context */
95 
96   const char *
get_priv_host()97     Security_context_wrapper::get_priv_host()
98   {
99     MYSQL_LEX_CSTRING priv_host;
100     if (get_property("priv_host", &priv_host))
101       return 0;
102     return priv_host.str;
103   }
104 
105 
106   /** Get connected user information from security context */
107 
108   const char *
get_user()109     Security_context_wrapper::get_user()
110   {
111     MYSQL_LEX_CSTRING user;
112     if (get_property("user", &user))
113       return 0;
114     return user.str;
115   }
116 
117 
118   /** Get connected host information from security context */
119 
120   const char *
get_host()121     Security_context_wrapper::get_host()
122   {
123     /*
124       We can't use thd->security_ctx->priv_host_name()
125       because it returns "%" if hostname is empty.
126       However, thd->security_ctx->proxy_user won't have
127       "%" if hostname was empty.
128 
129       To be consistent, we will always use
130       'user'@'host'/''@'host'/''@'' type of representation.
131     */
132     MYSQL_LEX_CSTRING host;
133     if (get_property("host", &host))
134       return 0;
135     return host.str;
136   }
137 
138 
139   /** Get connected ip information from security context */
140 
141   const char *
get_ip()142     Security_context_wrapper::get_ip()
143   {
144     MYSQL_LEX_CSTRING ip;
145     if (get_property("ip", &ip))
146       return 0;
147     return ip.str;
148   }
149 
150 
151   /** Check if valid security context exists for give THD or not */
152 
153   bool
security_context_exists()154     Security_context_wrapper::security_context_exists()
155   {
156     return m_valid;
157   }
158 
159 
160   /** Check whether user has requried privilege or not */
161 
162   bool
is_super_user()163     Security_context_wrapper::is_super_user()
164   {
165     if (!m_valid)
166       return false;
167 
168     bool has_super= false;
169     if (security_context_get_option(m_sctx, "privilege_super", &has_super))
170       return false;
171 
172     return has_super;
173   }
174 }
175