1 #ifndef SQL_USER_CACHE_INCLUDED
2 #define SQL_USER_CACHE_INCLUDED
3
4 /* Copyright (c) 2000, 2021, Oracle and/or its affiliates.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2.0,
8 as published by the Free Software Foundation.
9
10 This program is also distributed with certain software (including
11 but not limited to OpenSSL) that is licensed under separate terms,
12 as designated in a particular file or component or in included license
13 documentation. The authors of MySQL hereby grant you an additional
14 permission to link the program and your derivative works with the
15 separately licensed software that they have included with MySQL.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License, version 2.0, for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software Foundation,
24 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
25
26 #include "my_global.h" // NO_EMBEDDED_ACCESS_CHECKS
27 #include "my_sys.h" // wild_many, wild_one, wild_prefix
28 #include <string.h> // strchr
29 #include "mysql_com.h" // SCRAMBLE_LENGTH
30 #include "violite.h" // SSL_type
31 #include "hash_filo.h" // HASH, hash_filo
32 #include "records.h" // READ_RECORD
33 #include "partitioned_rwlock.h" // Partitioned_rwlock
34
35 #include "prealloced_array.h"
36 #include "log_event.h"
37
38 /* Forward Declarations */
39 class String;
40
41 /* Classes */
42
43 class ACL_HOST_AND_IP
44 {
45 char *hostname;
46 size_t hostname_length;
47 long ip, ip_mask; // Used with masked ip:s
48
49 const char *calc_ip(const char *ip_arg, long *val, char end);
50
51 public:
get_host()52 const char *get_host() const { return hostname ? hostname : ""; }
get_host_len()53 size_t get_host_len() const { return hostname_length; }
54
has_wildcard()55 bool has_wildcard()
56 {
57 return (strchr(hostname,wild_many) ||
58 strchr(hostname,wild_one) || ip_mask );
59 }
60
check_allow_all_hosts()61 bool check_allow_all_hosts()
62 {
63 return (!hostname ||
64 (hostname[0] == wild_many && !hostname[1]));
65 }
66
67 void update_hostname(const char *host_arg);
68 bool compare_hostname(const char *host_arg, const char *ip_arg);
is_null()69 bool is_null() const { return hostname == NULL; }
70 };
71
72 class ACL_ACCESS {
73 public:
74 ACL_HOST_AND_IP host;
75 ulong sort;
76 ulong access;
77 };
78
79 /* ACL_HOST is used if no host is specified */
80
81 class ACL_HOST :public ACL_ACCESS
82 {
83 public:
84 char *db;
85 };
86
87 class ACL_USER :public ACL_ACCESS
88 {
89 public:
90 USER_RESOURCES user_resource;
91 char *user;
92 /**
93 The salt variable is used as the password hash for
94 native_password_authetication.
95 */
96 uint8 salt[SCRAMBLE_LENGTH + 1]; // scrambled password in binary form
97 /**
98 In the old protocol the salt_len indicated what type of autnetication
99 protocol was used: 0 - no password, 4 - 3.20, 8 - 4.0, 20 - 4.1.1
100 */
101 uint8 salt_len;
102 enum SSL_type ssl_type;
103 const char *ssl_cipher, *x509_issuer, *x509_subject;
104 LEX_CSTRING plugin;
105 LEX_STRING auth_string;
106 bool password_expired;
107 bool can_authenticate;
108 MYSQL_TIME password_last_changed;
109 uint password_lifetime;
110 bool use_default_password_lifetime;
111 /**
112 Specifies whether the user account is locked or unlocked.
113 */
114 bool account_locked;
115
116 ACL_USER *copy(MEM_ROOT *root);
117 };
118
119 class ACL_DB :public ACL_ACCESS
120 {
121 public:
122 char *user,*db;
123 };
124
125 class ACL_PROXY_USER :public ACL_ACCESS
126 {
127 const char *user;
128 ACL_HOST_AND_IP proxied_host;
129 const char *proxied_user;
130 bool with_grant;
131
132 typedef enum {
133 MYSQL_PROXIES_PRIV_HOST,
134 MYSQL_PROXIES_PRIV_USER,
135 MYSQL_PROXIES_PRIV_PROXIED_HOST,
136 MYSQL_PROXIES_PRIV_PROXIED_USER,
137 MYSQL_PROXIES_PRIV_WITH_GRANT,
138 MYSQL_PROXIES_PRIV_GRANTOR,
139 MYSQL_PROXIES_PRIV_TIMESTAMP } old_acl_proxy_users;
140 public:
ACL_PROXY_USER()141 ACL_PROXY_USER () {};
142
143 void init(const char *host_arg, const char *user_arg,
144 const char *proxied_host_arg, const char *proxied_user_arg,
145 bool with_grant_arg);
146
147 void init(MEM_ROOT *mem, const char *host_arg, const char *user_arg,
148 const char *proxied_host_arg, const char *proxied_user_arg,
149 bool with_grant_arg);
150
151 void init(TABLE *table, MEM_ROOT *mem);
152
get_with_grant()153 bool get_with_grant() { return with_grant; }
get_user()154 const char *get_user() { return user; }
get_proxied_user()155 const char *get_proxied_user() { return proxied_user; }
get_proxied_host()156 const char *get_proxied_host() { return proxied_host.get_host(); }
set_user(MEM_ROOT * mem,const char * user_arg)157 void set_user(MEM_ROOT *mem, const char *user_arg)
158 {
159 user= user_arg && *user_arg ? strdup_root(mem, user_arg) : NULL;
160 }
161
162 void check_validity(bool check_no_resolve);
163
164 bool matches(const char *host_arg, const char *user_arg, const char *ip_arg,
165 const char *proxied_user_arg, bool any_proxy_user);
166
auth_element_equals(const char * a,const char * b)167 inline static bool auth_element_equals(const char *a, const char *b)
168 {
169 return (a == b || (a != NULL && b != NULL && !strcmp(a,b)));
170 }
171
172
173 bool pk_equals(ACL_PROXY_USER *grant);
174
granted_on(const char * host_arg,const char * user_arg)175 bool granted_on(const char *host_arg, const char *user_arg)
176 {
177 return (((!user && (!user_arg || !user_arg[0])) ||
178 (user && user_arg && !strcmp(user, user_arg))) &&
179 ((host.is_null() && (!host_arg || !host_arg[0])) ||
180 (!host.is_null() && host_arg && !strcmp(host.get_host(), host_arg))));
181 }
182
183
184 void print_grant(THD *thd, String *str);
185
set_data(ACL_PROXY_USER * grant)186 void set_data(ACL_PROXY_USER *grant)
187 {
188 with_grant= grant->with_grant;
189 }
190
191 static int store_pk(TABLE *table,
192 const LEX_CSTRING &host,
193 const LEX_CSTRING &user,
194 const LEX_CSTRING &proxied_host,
195 const LEX_CSTRING &proxied_user);
196
197 static int store_with_grant(TABLE * table,
198 bool with_grant);
199
200 static int store_data_record(TABLE *table,
201 const LEX_CSTRING &host,
202 const LEX_CSTRING &user,
203 const LEX_CSTRING &proxied_host,
204 const LEX_CSTRING &proxied_user,
205 bool with_grant,
206 const char *grantor);
207
get_user_length()208 size_t get_user_length() const { return user ? strlen(user) : 0; }
209
get_proxied_user_length()210 size_t get_proxied_user_length() const {
211 return proxied_user ? strlen(proxied_user) : 0;
212 }
213 };
214
215 #ifndef NO_EMBEDDED_ACCESS_CHECKS
216
217 class acl_entry :public hash_filo_element
218 {
219 public:
220 ulong access;
221 uint16 length;
222 char key[1]; // Key will be stored here
223 };
224
225
226 class GRANT_COLUMN :public Sql_alloc
227 {
228 public:
229 char *column;
230 ulong rights;
231 size_t key_length;
232 GRANT_COLUMN(String &c, ulong y);
233 };
234
235
236 class GRANT_NAME :public Sql_alloc
237 {
238 public:
239 ACL_HOST_AND_IP host;
240 char *db, *user, *tname, *hash_key;
241 ulong privs;
242 ulong sort;
243 size_t key_length;
244 GRANT_NAME(const char *h, const char *d,const char *u,
245 const char *t, ulong p, bool is_routine);
246 GRANT_NAME (TABLE *form, bool is_routine);
~GRANT_NAME()247 virtual ~GRANT_NAME() {};
ok()248 virtual bool ok() { return privs != 0; }
249 void set_user_details(const char *h, const char *d,
250 const char *u, const char *t,
251 bool is_routine);
252 };
253
254
255 class GRANT_TABLE :public GRANT_NAME
256 {
257 public:
258 ulong cols;
259 HASH hash_columns;
260
261 GRANT_TABLE(const char *h, const char *d,const char *u,
262 const char *t, ulong p, ulong c);
263 explicit GRANT_TABLE(TABLE *form);
264 bool init(TABLE *col_privs);
265 ~GRANT_TABLE();
ok()266 bool ok() { return privs != 0 || cols != 0; }
267 };
268
269
270 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
271
272
273 /* Data Structures */
274
275 #ifndef NO_EMBEDDED_ACCESS_CHECKS
276 extern MEM_ROOT global_acl_memory;
277 extern MEM_ROOT memex;
278 extern bool initialized;
279 const size_t ACL_PREALLOC_SIZE = 10U;
280 extern Prealloced_array<ACL_USER, ACL_PREALLOC_SIZE> *acl_users;
281 extern Prealloced_array<ACL_PROXY_USER, ACL_PREALLOC_SIZE> *acl_proxy_users;
282 extern Prealloced_array<ACL_DB, ACL_PREALLOC_SIZE> *acl_dbs;
283 extern Prealloced_array<ACL_HOST_AND_IP, ACL_PREALLOC_SIZE> *acl_wild_hosts;
284 extern HASH column_priv_hash, proc_priv_hash, func_priv_hash;
285 extern hash_filo *acl_cache;
286 extern HASH acl_check_hosts;
287 extern bool allow_all_hosts;
288 extern uint grant_version; /* Version of priv tables */
289 extern Partitioned_rwlock LOCK_grant;
290
291 GRANT_NAME *name_hash_search(HASH *name_hash,
292 const char *host,const char* ip,
293 const char *db,
294 const char *user, const char *tname,
295 bool exact, bool name_tolower);
296
routine_hash_search(const char * host,const char * ip,const char * db,const char * user,const char * tname,bool proc,bool exact)297 inline GRANT_NAME * routine_hash_search(const char *host, const char *ip,
298 const char *db, const char *user,
299 const char *tname, bool proc,
300 bool exact)
301 {
302 return (GRANT_TABLE*)
303 name_hash_search(proc ? &proc_priv_hash : &func_priv_hash,
304 host, ip, db, user, tname, exact, TRUE);
305 }
306
table_hash_search(const char * host,const char * ip,const char * db,const char * user,const char * tname,bool exact)307 inline GRANT_TABLE * table_hash_search(const char *host, const char *ip,
308 const char *db, const char *user,
309 const char *tname, bool exact)
310 {
311 return (GRANT_TABLE*) name_hash_search(&column_priv_hash, host, ip, db,
312 user, tname, exact, FALSE);
313 }
314
column_hash_search(GRANT_TABLE * t,const char * cname,size_t length)315 inline GRANT_COLUMN * column_hash_search(GRANT_TABLE *t, const char *cname,
316 size_t length)
317 {
318 return (GRANT_COLUMN*) my_hash_search(&t->hash_columns,
319 (uchar*) cname, length);
320 }
321
322 extern ACL_USER acl_utility_user;
323
324 #endif /* NO_EMBEDDED_ACCESS_CHECKS */
325
326 #endif /* SQL_USER_CACHE_INCLUDED */
327