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