Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
e0c908eb
Commit
e0c908eb
authored
Oct 17, 2013
by
Vicențiu Ciorbaru
Committed by
Sergei Golubchik
Oct 17, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changed acl_roles to be stored into a HASH.
There is an issue with correct searching of keys in the HASH.
parent
334860cc
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
71 additions
and
27 deletions
+71
-27
sql/sql_acl.cc
sql/sql_acl.cc
+71
-27
No files found.
sql/sql_acl.cc
View file @
e0c908eb
...
@@ -51,6 +51,7 @@
...
@@ -51,6 +51,7 @@
#include "hostname.h"
#include "hostname.h"
#include "sql_db.h"
#include "sql_db.h"
#include "sql_array.h"
#include "sql_array.h"
#include "sql_hset.h"
#include "sql_plugin_compat.h"
#include "sql_plugin_compat.h"
...
@@ -520,6 +521,13 @@ static uchar* acl_entry_get_key(acl_entry *entry, size_t *length,
...
@@ -520,6 +521,13 @@ static uchar* acl_entry_get_key(acl_entry *entry, size_t *length,
return
(
uchar
*
)
entry
->
key
;
return
(
uchar
*
)
entry
->
key
;
}
}
uchar
*
acl_role_get_key
(
ACL_USER
*
entry
,
size_t
*
length
,
my_bool
not_used
__attribute__
((
unused
)))
{
*
length
=
(
uint
)
(
entry
->
user
?
strlen
(
entry
->
user
)
:
0
);
return
(
uchar
*
)
entry
->
user
;
}
#define IP_ADDR_STRLEN (3 + 1 + 3 + 1 + 3 + 1 + 3)
#define IP_ADDR_STRLEN (3 + 1 + 3 + 1 + 3 + 1 + 3)
#define ACL_KEY_LENGTH (IP_ADDR_STRLEN + 1 + NAME_LEN + \
#define ACL_KEY_LENGTH (IP_ADDR_STRLEN + 1 + NAME_LEN + \
1 + USERNAME_LENGTH + 1)
1 + USERNAME_LENGTH + 1)
...
@@ -542,7 +550,10 @@ static uchar* acl_entry_get_key(acl_entry *entry, size_t *length,
...
@@ -542,7 +550,10 @@ static uchar* acl_entry_get_key(acl_entry *entry, size_t *length,
#endif
/* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
#endif
/* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
#define NORMAL_HANDSHAKE_SIZE 6
#define NORMAL_HANDSHAKE_SIZE 6
static
DYNAMIC_ARRAY
acl_hosts
,
acl_users
,
acl_dbs
,
acl_proxy_users
,
acl_roles
;
#define ROLE_ASSIGN_COLUMN_IDX 42
static
DYNAMIC_ARRAY
acl_hosts
,
acl_users
,
acl_dbs
,
acl_proxy_users
;
static
HASH
acl_roles
;
/* XXX
/* XXX
***** Potential optimization *****
***** Potential optimization *****
role_grants could potentially be a HASH with keys as usernames and values
role_grants could potentially be a HASH with keys as usernames and values
...
@@ -560,14 +571,14 @@ static DYNAMIC_ARRAY acl_wild_hosts;
...
@@ -560,14 +571,14 @@ static DYNAMIC_ARRAY acl_wild_hosts;
static
hash_filo
*
acl_cache
;
static
hash_filo
*
acl_cache
;
static
uint
grant_version
=
0
;
/* Version of priv tables. incremented by acl_load */
static
uint
grant_version
=
0
;
/* Version of priv tables. incremented by acl_load */
static
ulong
get_access
(
TABLE
*
form
,
uint
fieldnr
,
uint
*
next_field
=
0
);
static
ulong
get_access
(
TABLE
*
form
,
uint
fieldnr
,
uint
*
next_field
=
0
);
static
bool
check_is_role
(
TABLE
*
form
);
static
int
acl_compare
(
ACL_ACCESS
*
a
,
ACL_ACCESS
*
b
);
static
int
acl_compare
(
ACL_ACCESS
*
a
,
ACL_ACCESS
*
b
);
static
ulong
get_sort
(
uint
count
,...);
static
ulong
get_sort
(
uint
count
,...);
static
void
init_check_host
(
void
);
static
void
init_check_host
(
void
);
static
void
rebuild_check_host
(
void
);
static
void
rebuild_check_host
(
void
);
static
ACL_USER
*
find_acl_user
(
const
char
*
host
,
const
char
*
user
,
static
ACL_USER
*
find_acl_user
(
const
char
*
host
,
const
char
*
user
,
my_bool
exact
);
my_bool
exact
);
static
ACL_USER
*
find_acl_role
(
const
char
*
host
,
const
char
*
user
,
static
ACL_USER
*
find_acl_role
(
const
char
*
user
);
my_bool
exact
);
static
bool
update_user_table
(
THD
*
thd
,
TABLE
*
table
,
const
char
*
host
,
static
bool
update_user_table
(
THD
*
thd
,
TABLE
*
table
,
const
char
*
host
,
const
char
*
user
,
const
char
*
new_password
,
const
char
*
user
,
const
char
*
new_password
,
uint
new_password_len
);
uint
new_password_len
);
...
@@ -847,7 +858,9 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
...
@@ -847,7 +858,9 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
table
->
use_all_columns
();
table
->
use_all_columns
();
(
void
)
my_init_dynamic_array
(
&
acl_users
,
sizeof
(
ACL_USER
),
50
,
100
,
MYF
(
0
));
(
void
)
my_init_dynamic_array
(
&
acl_users
,
sizeof
(
ACL_USER
),
50
,
100
,
MYF
(
0
));
(
void
)
my_init_dynamic_array
(
&
acl_roles
,
sizeof
(
ACL_USER
),
50
,
100
,
MYF
(
0
));
(
void
)
my_hash_init2
(
&
acl_roles
,
50
,
system_charset_info
,
0
,
0
,
0
,
(
my_hash_get_key
)
acl_role_get_key
,
0
,
0
);
username_char_length
=
min
(
table
->
field
[
1
]
->
char_length
(),
USERNAME_CHAR_LENGTH
);
username_char_length
=
min
(
table
->
field
[
1
]
->
char_length
(),
USERNAME_CHAR_LENGTH
);
password_length
=
table
->
field
[
2
]
->
field_length
/
password_length
=
table
->
field
[
2
]
->
field_length
/
table
->
field
[
2
]
->
charset
()
->
mbmaxlen
;
table
->
field
[
2
]
->
charset
()
->
mbmaxlen
;
...
@@ -902,9 +915,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
...
@@ -902,9 +915,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
/* If the user entry is a role, skip password and hostname checks
/* If the user entry is a role, skip password and hostname checks
A user can not log in with a role so some checks are not necessary
A user can not log in with a role so some checks are not necessary
*/
*/
if
(
!
user
.
host
.
hostname
)
{
is_role
=
check_is_role
(
table
);
is_role
=
TRUE
;
}
if
(
!
is_role
&&
check_no_resolve
&&
if
(
!
is_role
&&
check_no_resolve
&&
hostname_requires_resolving
(
user
.
host
.
hostname
))
hostname_requires_resolving
(
user
.
host
.
hostname
))
...
@@ -1046,7 +1057,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
...
@@ -1046,7 +1057,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
}
}
if
(
is_role
)
{
if
(
is_role
)
{
sql_print_information
(
"Found role %s"
,
user
.
user
);
sql_print_information
(
"Found role %s"
,
user
.
user
);
(
void
)
push_dynamic
(
&
acl_roles
,
(
uchar
*
)
&
user
);
my_hash_insert
(
&
acl_roles
,
(
uchar
*
)
&
user
);
}
}
else
else
{
{
...
@@ -1169,7 +1180,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
...
@@ -1169,7 +1180,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
table
->
use_all_columns
();
table
->
use_all_columns
();
/* account for every role mapping */
/* account for every role mapping */
/* acquire lock for the find_acl_user
/role
functions
/* acquire lock for the find_acl_user functions
XXX
XXX
Perhaps new wrapper functions should be created that do not check
Perhaps new wrapper functions should be created that do not check
for the lock in this case as it either is already taken or
for the lock in this case as it either is already taken or
...
@@ -1186,12 +1197,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
...
@@ -1186,12 +1197,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
p
.
user_username
=
get_field
(
&
mem
,
table
->
field
[
1
]);
p
.
user_username
=
get_field
(
&
mem
,
table
->
field
[
1
]);
p
.
role_hostname
=
get_field
(
&
mem
,
table
->
field
[
2
]);
p
.
role_hostname
=
get_field
(
&
mem
,
table
->
field
[
2
]);
p
.
role_username
=
get_field
(
&
mem
,
table
->
field
[
3
]);
p
.
role_username
=
get_field
(
&
mem
,
table
->
field
[
3
]);
ACL_USER
*
user
=
find_acl_user
((
p
.
user_hostname
)
?
p
.
user_hostname
:
""
,
ACL_USER
*
user
=
find_acl_user
((
p
.
user_hostname
)
?
p
.
user_hostname
:
""
,
(
p
.
user_username
)
?
p
.
user_username
:
""
,
(
p
.
user_username
)
?
p
.
user_username
:
""
,
TRUE
);
TRUE
);
ACL_USER
*
role
=
find_acl_role
((
p
.
role_hostname
)
?
p
.
role_hostname
:
""
,
ACL_USER
*
role
=
find_acl_role
(
p
.
role_username
?
p
.
role_username
:
""
);
(
p
.
role_username
)
?
p
.
role_username
:
""
,
TRUE
);
if
(
user
==
NULL
||
role
==
NULL
)
if
(
user
==
NULL
||
role
==
NULL
)
{
{
sql_print_error
(
"Invalid roles_mapping table entry '%s@%s', '%s@%s'"
,
sql_print_error
(
"Invalid roles_mapping table entry '%s@%s', '%s@%s'"
,
...
@@ -1397,6 +1406,38 @@ static ulong get_access(TABLE *form, uint fieldnr, uint *next_field)
...
@@ -1397,6 +1406,38 @@ static ulong get_access(TABLE *form, uint fieldnr, uint *next_field)
return
access_bits
;
return
access_bits
;
}
}
/*
Check if a user entry in the user table is marked as being a role entry
IMPLEMENTATION
Access the coresponding column and check the coresponding ENUM of the form
ENUM('N', 'Y')
SYNOPSIS
check_is_role()
form an open table to read the entry from.
The record should be already read in table->record[0]
RETURN VALUE
TRUE if the user is marked as a role
FALSE otherwise
*/
static
inline
bool
check_is_role
(
TABLE
*
form
)
{
char
buff
[
2
];
String
res
(
buff
,
sizeof
(
buff
),
&
my_charset_latin1
);
/* Table version does not support roles */
if
(
form
->
s
->
fields
<=
42
)
return
FALSE
;
form
->
field
[
ROLE_ASSIGN_COLUMN_IDX
]
->
val_str
(
&
res
);
if
(
my_toupper
(
&
my_charset_latin1
,
res
[
0
])
==
'Y'
)
return
TRUE
;
return
FALSE
;
}
/*
/*
Return a number which, if sorted 'desc', puts strings in this order:
Return a number which, if sorted 'desc', puts strings in this order:
...
@@ -2138,22 +2179,19 @@ bool is_acl_user(const char *host, const char *user)
...
@@ -2138,22 +2179,19 @@ bool is_acl_user(const char *host, const char *user)
/*
/*
Find first entry that matches the current user
or role
Find first entry that matches the current user
*/
*/
static
ACL_USER
*
static
ACL_USER
*
find_acl_user_table_entry
(
const
char
*
host
,
const
char
*
user
,
my_bool
exact
,
find_acl_user
(
const
char
*
host
,
const
char
*
user
,
my_bool
exact
)
my_bool
is_role
)
{
{
DBUG_ENTER
(
"find_acl_user"
);
DBUG_ENTER
(
"find_acl_user"
);
DBUG_PRINT
(
"enter"
,(
"host: '%s' user: '%s'"
,
host
,
user
));
DBUG_PRINT
(
"enter"
,(
"host: '%s' user: '%s'"
,
host
,
user
));
mysql_mutex_assert_owner
(
&
acl_cache
->
lock
);
mysql_mutex_assert_owner
(
&
acl_cache
->
lock
);
DYNAMIC_ARRAY
*
target
=
(
is_role
)
?
&
acl_roles
:
&
acl_users
;
for
(
uint
i
=
0
;
i
<
acl_users
.
elements
;
i
++
)
for
(
uint
i
=
0
;
i
<
target
->
elements
;
i
++
)
{
{
ACL_USER
*
acl_user
=
dynamic_element
(
target
,
i
,
ACL_USER
*
);
ACL_USER
*
acl_user
=
dynamic_element
(
&
acl_users
,
i
,
ACL_USER
*
);
DBUG_PRINT
(
"info"
,(
"strcmp('%s','%s'), compare_hostname('%s','%s'),"
,
DBUG_PRINT
(
"info"
,(
"strcmp('%s','%s'), compare_hostname('%s','%s'),"
,
user
,
acl_user
->
user
?
acl_user
->
user
:
""
,
user
,
acl_user
->
user
?
acl_user
->
user
:
""
,
host
,
host
,
...
@@ -2174,18 +2212,24 @@ find_acl_user_table_entry(const char *host, const char *user, my_bool exact,
...
@@ -2174,18 +2212,24 @@ find_acl_user_table_entry(const char *host, const char *user, my_bool exact,
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
/*
Find first entry that matches the current user
*/
static
ACL_USER
*
static
ACL_USER
*
find_acl_role
(
const
char
*
host
,
const
char
*
user
,
my_bool
exact
)
find_acl_role
(
const
char
*
user
)
{
return
find_acl_user_table_entry
(
host
,
user
,
exact
,
TRUE
);
}
static
ACL_USER
*
find_acl_user
(
const
char
*
host
,
const
char
*
user
,
my_bool
exact
)
{
{
return
find_acl_user_table_entry
(
host
,
user
,
exact
,
FALSE
);
DBUG_ENTER
(
"find_acl_role"
);
DBUG_PRINT
(
"enter"
,(
"user: '%s'"
,
user
));
mysql_mutex_assert_owner
(
&
acl_cache
->
lock
);
DBUG_RETURN
((
ACL_USER
*
)
my_hash_search
(
&
acl_roles
,
(
uchar
*
)
user
,
user
?
strlen
(
user
)
:
0
));
}
}
/*
/*
Comparing of hostnames
Comparing of hostnames
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment