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 28 #include "security_context_wrapper.h" 29 30 namespace connection_control 31 { 32 /** 33 Security_context_wrapper constructor. 34 35 @param [in] thd Handle to THD 36 37 Get security context from thd. 38 */ Security_context_wrapper(MYSQL_THD thd)39 Security_context_wrapper::Security_context_wrapper(MYSQL_THD thd) 40 { 41 m_valid= thd->security_ctx ? true : false; 42 m_thd= thd; 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 || !property) 64 return true; 65 else 66 { 67 if (!strcmp(property, "priv_user")) 68 { 69 compile_time_assert (sizeof(m_thd->security_ctx->priv_user) / sizeof(void*) > 1); 70 value->str= m_thd->security_ctx->priv_user; 71 value->length= strlen(value->str); 72 } 73 else if (!strcmp(property, "priv_host")) 74 { 75 compile_time_assert (sizeof(m_thd->security_ctx->priv_host) / sizeof(void*) > 1); 76 value->str= m_thd->security_ctx->priv_host; 77 value->length= strlen(value->str); 78 } 79 else if (!strcmp(property, "user")) 80 { 81 if (m_thd->security_ctx->user) 82 { 83 value->str= m_thd->security_ctx->user; 84 value->length= strlen(value->str); 85 } 86 } 87 else if (!strcmp(property, "proxy_user")) 88 { 89 compile_time_assert (sizeof(m_thd->security_ctx->proxy_user) / sizeof(void*) > 1); 90 value->str= m_thd->security_ctx->proxy_user; 91 value->length= strlen(value->str); 92 } 93 else if (!strcmp(property, "host")) 94 { 95 if (m_thd->security_ctx->get_host()->length()) 96 { 97 value->str= m_thd->security_ctx->get_host()->c_ptr(); 98 value->length= strlen(value->str); 99 } 100 } 101 else if (!strcmp(property, "ip")) 102 { 103 if (m_thd->security_ctx->get_ip()->length()) 104 { 105 value->str= m_thd->security_ctx->get_ip()->c_ptr(); 106 value->length= strlen(value->str); 107 } 108 } 109 else 110 { 111 return true; 112 } 113 } 114 return false; 115 } 116 117 118 /** Get proxy user information from security context */ 119 120 const char * get_proxy_user()121 Security_context_wrapper::get_proxy_user() 122 { 123 LEX_CSTRING proxy_user; 124 if (get_property("proxy_user", &proxy_user)) 125 return 0; 126 return proxy_user.str; 127 } 128 129 130 /** Get priv user information from security context */ 131 132 const char * get_priv_user()133 Security_context_wrapper::get_priv_user() 134 { 135 LEX_CSTRING priv_user; 136 if (get_property("priv_user", &priv_user)) 137 return 0; 138 return priv_user.str; 139 } 140 141 142 /** Get priv host information from security context */ 143 144 const char * get_priv_host()145 Security_context_wrapper::get_priv_host() 146 { 147 LEX_CSTRING priv_host; 148 if (get_property("priv_host", &priv_host)) 149 return 0; 150 return priv_host.str; 151 } 152 153 154 /** Get connected user information from security context */ 155 156 const char * get_user()157 Security_context_wrapper::get_user() 158 { 159 LEX_CSTRING user; 160 if (get_property("user", &user)) 161 return 0; 162 return user.str; 163 } 164 165 166 /** Get connected host information from security context */ 167 168 const char * get_host()169 Security_context_wrapper::get_host() 170 { 171 /* 172 We can't use thd->security_ctx->priv_host_name() 173 because it returns "%" if hostname is empty. 174 However, thd->security_ctx->proxy_user won't have 175 "%" if hostname was empty. 176 177 To be consistent, we will always use 178 'user'@'host'/''@'host'/''@'' type of representation. 179 */ 180 LEX_CSTRING host; 181 if (get_property("host", &host)) 182 return 0; 183 return host.str; 184 } 185 186 187 /** Get connected ip information from security context */ 188 189 const char * get_ip()190 Security_context_wrapper::get_ip() 191 { 192 LEX_CSTRING ip; 193 if (get_property("ip", &ip)) 194 return 0; 195 return ip.str; 196 } 197 198 199 /** Check if valid security context exists for give THD or not */ 200 201 bool security_context_exists()202 Security_context_wrapper::security_context_exists() 203 { 204 return m_valid; 205 } 206 207 208 /** Check whether user has requried privilege or not */ 209 210 bool is_super_user()211 Security_context_wrapper::is_super_user() 212 { 213 if (!m_valid) 214 return false; 215 216 bool has_super= ((m_thd->security_ctx->master_access & SUPER_ACL) == SUPER_ACL); 217 218 return has_super; 219 } 220 } 221