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
ee9528b0
Commit
ee9528b0
authored
Sep 08, 2008
by
Martin Hansson
Browse files
Options
Browse Files
Download
Plain Diff
Bug#36086: Auto merge.
parents
860f74a8
3bad2119
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
362 additions
and
83 deletions
+362
-83
mysql-test/include/grant_cache.inc
mysql-test/include/grant_cache.inc
+1
-1
mysql-test/r/grant2.result
mysql-test/r/grant2.result
+1
-1
mysql-test/r/grant_cache_no_prot.result
mysql-test/r/grant_cache_no_prot.result
+1
-1
mysql-test/r/grant_cache_ps_prot.result
mysql-test/r/grant_cache_ps_prot.result
+1
-1
mysql-test/r/view_grant.result
mysql-test/r/view_grant.result
+32
-0
mysql-test/t/grant2.test
mysql-test/t/grant2.test
+1
-1
mysql-test/t/view_grant.test
mysql-test/t/view_grant.test
+68
-0
sql/item.cc
sql/item.cc
+2
-10
sql/sql_acl.cc
sql/sql_acl.cc
+33
-21
sql/sql_base.cc
sql/sql_base.cc
+32
-7
sql/sql_cache.cc
sql/sql_cache.cc
+1
-1
sql/sql_derived.cc
sql/sql_derived.cc
+53
-23
sql/sql_parse.cc
sql/sql_parse.cc
+3
-1
sql/table.cc
sql/table.cc
+21
-10
sql/table.h
sql/table.h
+112
-5
No files found.
mysql-test/include/grant_cache.inc
View file @
ee9528b0
...
@@ -136,7 +136,7 @@ connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
...
@@ -136,7 +136,7 @@ connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
connection
user3
;
connection
user3
;
select
"user3"
;
select
"user3"
;
--
replace_result
127.0
.
0.1
localhost
--
replace_result
127.0
.
0.1
localhost
--
error
ER_
COLUMN
ACCESS_DENIED_ERROR
--
error
ER_
TABLE
ACCESS_DENIED_ERROR
select
*
from
t1
;
select
*
from
t1
;
select
a
from
t1
;
select
a
from
t1
;
--
replace_result
127.0
.
0.1
localhost
--
replace_result
127.0
.
0.1
localhost
...
...
mysql-test/r/grant2.result
View file @
ee9528b0
...
@@ -434,7 +434,7 @@ USE db1;
...
@@ -434,7 +434,7 @@ USE db1;
SELECT c FROM t2;
SELECT c FROM t2;
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
SELECT * FROM t2;
SELECT * FROM t2;
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for
column 'c' in
table 't2'
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for table 't2'
SELECT * FROM t1 JOIN t2 USING (b);
SELECT * FROM t1 JOIN t2 USING (b);
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
DROP TABLE db1.t1, db1.t2;
DROP TABLE db1.t1, db1.t2;
...
...
mysql-test/r/grant_cache_no_prot.result
View file @
ee9528b0
...
@@ -155,7 +155,7 @@ select "user3";
...
@@ -155,7 +155,7 @@ select "user3";
user3
user3
user3
user3
select * from t1;
select * from t1;
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for
column 'b' in
table 't1'
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 't1'
select a from t1;
select a from t1;
a
a
1
1
...
...
mysql-test/r/grant_cache_ps_prot.result
View file @
ee9528b0
...
@@ -155,7 +155,7 @@ select "user3";
...
@@ -155,7 +155,7 @@ select "user3";
user3
user3
user3
user3
select * from t1;
select * from t1;
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for
column 'b' in
table 't1'
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 't1'
select a from t1;
select a from t1;
a
a
1
1
...
...
mysql-test/r/view_grant.result
View file @
ee9528b0
...
@@ -957,3 +957,35 @@ Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function
...
@@ -957,3 +957,35 @@ Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function
DROP VIEW v1;
DROP VIEW v1;
DROP TABLE t1;
DROP TABLE t1;
End of 5.1 tests.
End of 5.1 tests.
CREATE USER mysqluser1@localhost;
CREATE DATABASE mysqltest1;
USE mysqltest1;
CREATE TABLE t1 ( a INT, b INT );
CREATE TABLE t2 ( a INT, b INT );
CREATE VIEW v1 AS SELECT a, b FROM t1;
GRANT SELECT( a ) ON v1 TO mysqluser1@localhost;
GRANT UPDATE( b ) ON t2 TO mysqluser1@localhost;
SELECT * FROM mysqltest1.v1;
ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v1'
CREATE VIEW v1 AS SELECT * FROM mysqltest1.t2;
ERROR 42000: ANY command denied to user 'mysqluser1'@'localhost' for table 't2'
DROP TABLE t1, t2;
DROP VIEW v1;
DROP DATABASE mysqltest1;
DROP USER mysqluser1@localhost;
CREATE USER mysqluser1@localhost;
CREATE DATABASE mysqltest1;
USE mysqltest1;
CREATE VIEW v1 AS SELECT * FROM information_schema.tables LIMIT 1;
CREATE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT 1 AS A;
GRANT SELECT ON mysqltest1.* to mysqluser1@localhost;
PREPARE stmt_v1 FROM "SELECT * FROM mysqltest1.v1";
PREPARE stmt_v2 FROM "SELECT * FROM mysqltest1.v2";
REVOKE SELECT ON mysqltest1.* FROM mysqluser1@localhost;
EXECUTE stmt_v1;
ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v1'
EXECUTE stmt_v2;
ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v2'
DROP VIEW v1, v2;
DROP DATABASE mysqltest1;
DROP USER mysqluser1@localhost;
mysql-test/t/grant2.test
View file @
ee9528b0
...
@@ -605,7 +605,7 @@ connection conn1;
...
@@ -605,7 +605,7 @@ connection conn1;
USE
db1
;
USE
db1
;
--
error
ER_COLUMNACCESS_DENIED_ERROR
--
error
ER_COLUMNACCESS_DENIED_ERROR
SELECT
c
FROM
t2
;
SELECT
c
FROM
t2
;
--
error
ER_
COLUMN
ACCESS_DENIED_ERROR
--
error
ER_
TABLE
ACCESS_DENIED_ERROR
SELECT
*
FROM
t2
;
SELECT
*
FROM
t2
;
--
error
ER_COLUMNACCESS_DENIED_ERROR
--
error
ER_COLUMNACCESS_DENIED_ERROR
SELECT
*
FROM
t1
JOIN
t2
USING
(
b
);
SELECT
*
FROM
t1
JOIN
t2
USING
(
b
);
...
...
mysql-test/t/view_grant.test
View file @
ee9528b0
...
@@ -1219,3 +1219,71 @@ DROP VIEW v1;
...
@@ -1219,3 +1219,71 @@ DROP VIEW v1;
DROP
TABLE
t1
;
DROP
TABLE
t1
;
--
echo
End
of
5.1
tests
.
--
echo
End
of
5.1
tests
.
#
# Bug#36086: SELECT * from views don't check column grants
#
CREATE
USER
mysqluser1
@
localhost
;
CREATE
DATABASE
mysqltest1
;
USE
mysqltest1
;
CREATE
TABLE
t1
(
a
INT
,
b
INT
);
CREATE
TABLE
t2
(
a
INT
,
b
INT
);
CREATE
VIEW
v1
AS
SELECT
a
,
b
FROM
t1
;
GRANT
SELECT
(
a
)
ON
v1
TO
mysqluser1
@
localhost
;
GRANT
UPDATE
(
b
)
ON
t2
TO
mysqluser1
@
localhost
;
--
connect
(
connection1
,
localhost
,
mysqluser1
,
,
test
)
--
error
ER_TABLEACCESS_DENIED_ERROR
SELECT
*
FROM
mysqltest1
.
v1
;
--
error
ER_TABLEACCESS_DENIED_ERROR
CREATE
VIEW
v1
AS
SELECT
*
FROM
mysqltest1
.
t2
;
--
disconnect
connection1
--
connection
default
DROP
TABLE
t1
,
t2
;
DROP
VIEW
v1
;
DROP
DATABASE
mysqltest1
;
DROP
USER
mysqluser1
@
localhost
;
#
# Bug#35600: Security breach via view, I_S table and prepared
# statement/stored procedure
#
CREATE
USER
mysqluser1
@
localhost
;
CREATE
DATABASE
mysqltest1
;
USE
mysqltest1
;
CREATE
VIEW
v1
AS
SELECT
*
FROM
information_schema
.
tables
LIMIT
1
;
CREATE
ALGORITHM
=
TEMPTABLE
VIEW
v2
AS
SELECT
1
AS
A
;
--
connection
default
GRANT
SELECT
ON
mysqltest1
.*
to
mysqluser1
@
localhost
;
--
connect
(
connection1
,
localhost
,
mysqluser1
,
,
test
)
PREPARE
stmt_v1
FROM
"SELECT * FROM mysqltest1.v1"
;
PREPARE
stmt_v2
FROM
"SELECT * FROM mysqltest1.v2"
;
--
connection
default
REVOKE
SELECT
ON
mysqltest1
.*
FROM
mysqluser1
@
localhost
;
--
connection
connection1
--
error
ER_TABLEACCESS_DENIED_ERROR
EXECUTE
stmt_v1
;
--
error
ER_TABLEACCESS_DENIED_ERROR
EXECUTE
stmt_v2
;
--
disconnect
connection1
--
connection
default
DROP
VIEW
v1
,
v2
;
DROP
DATABASE
mysqltest1
;
DROP
USER
mysqluser1
@
localhost
;
sql/item.cc
View file @
ee9528b0
...
@@ -4120,16 +4120,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
...
@@ -4120,16 +4120,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if
(
any_privileges
)
if
(
any_privileges
)
{
{
char
*
db
,
*
tab
;
char
*
db
,
*
tab
;
if
(
cached_table
->
view
)
db
=
cached_table
->
get_db_name
();
{
tab
=
cached_table
->
get_table_name
();
db
=
cached_table
->
view_db
.
str
;
tab
=
cached_table
->
view_name
.
str
;
}
else
{
db
=
cached_table
->
db
;
tab
=
cached_table
->
table_name
;
}
if
(
!
(
have_privileges
=
(
get_column_grant
(
thd
,
&
field
->
table
->
grant
,
if
(
!
(
have_privileges
=
(
get_column_grant
(
thd
,
&
field
->
table
->
grant
,
db
,
tab
,
field_name
)
&
db
,
tab
,
field_name
)
&
VIEW_ANY_ACL
)))
VIEW_ANY_ACL
)))
...
...
sql/sql_acl.cc
View file @
ee9528b0
...
@@ -3092,12 +3092,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
...
@@ -3092,12 +3092,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
continue
;
// Add next user
continue
;
// Add next user
}
}
db_name
=
(
table_list
->
view_db
.
length
?
db_name
=
table_list
->
get_db_name
();
table_list
->
view_db
.
str
:
table_name
=
table_list
->
get_table_name
();
table_list
->
db
);
table_name
=
(
table_list
->
view_name
.
length
?
table_list
->
view_name
.
str
:
table_list
->
table_name
);
/* Find/create cached table grant */
/* Find/create cached table grant */
grant_table
=
table_hash_search
(
Str
->
host
.
str
,
NullS
,
db_name
,
grant_table
=
table_hash_search
(
Str
->
host
.
str
,
NullS
,
db_name
,
...
@@ -3908,7 +3904,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
...
@@ -3908,7 +3904,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
continue
;
// ok
continue
;
// ok
if
(
!
(
~
table
->
grant
.
privilege
&
want_access
)
||
if
(
!
(
~
table
->
grant
.
privilege
&
want_access
)
||
table
->
derived
||
table
->
schema_table
)
table
->
is_anonymous_derived_table
()
||
table
->
schema_table
)
{
{
/*
/*
It is subquery in the FROM clause. VIEW set table->derived after
It is subquery in the FROM clause. VIEW set table->derived after
...
@@ -3926,8 +3922,8 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
...
@@ -3926,8 +3922,8 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
continue
;
continue
;
}
}
if
(
!
(
grant_table
=
table_hash_search
(
sctx
->
host
,
sctx
->
ip
,
if
(
!
(
grant_table
=
table_hash_search
(
sctx
->
host
,
sctx
->
ip
,
table
->
db
,
sctx
->
priv_user
,
table
->
get_db_name
()
,
sctx
->
priv_user
,
table
->
table_name
,
0
)))
table
->
get_table_name
(),
FALSE
)))
{
{
want_access
&=
~
table
->
grant
.
privilege
;
want_access
&=
~
table
->
grant
.
privilege
;
goto
err
;
// No grants
goto
err
;
// No grants
...
@@ -3963,7 +3959,7 @@ err:
...
@@ -3963,7 +3959,7 @@ err:
command
,
command
,
sctx
->
priv_user
,
sctx
->
priv_user
,
sctx
->
host_or_ip
,
sctx
->
host_or_ip
,
table
?
table
->
table_name
:
"unknown"
);
table
?
table
->
get_table_name
()
:
"unknown"
);
}
}
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
}
...
@@ -4118,7 +4114,7 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
...
@@ -4118,7 +4114,7 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
@retval 1 Falure
@retval 1 Falure
@details This function walks over the columns of a table reference
@details This function walks over the columns of a table reference
The columns may originate from different tables, depending on the kind of
The columns may originate from different tables, depending on the kind of
table reference, e.g. join.
table reference, e.g. join
, view
.
For each table it will retrieve the grant information and will use it
For each table it will retrieve the grant information and will use it
to check the required access privileges for the fields requested from it.
to check the required access privileges for the fields requested from it.
*/
*/
...
@@ -4133,6 +4129,11 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
...
@@ -4133,6 +4129,11 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
GRANT_INFO
*
grant
;
GRANT_INFO
*
grant
;
/* Initialized only to make gcc happy */
/* Initialized only to make gcc happy */
GRANT_TABLE
*
grant_table
=
NULL
;
GRANT_TABLE
*
grant_table
=
NULL
;
/*
Flag that gets set if privilege checking has to be performed on column
level.
*/
bool
using_column_privileges
=
FALSE
;
rw_rdlock
(
&
LOCK_grant
);
rw_rdlock
(
&
LOCK_grant
);
...
@@ -4140,10 +4141,10 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
...
@@ -4140,10 +4141,10 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
{
{
const
char
*
field_name
=
fields
->
name
();
const
char
*
field_name
=
fields
->
name
();
if
(
table_name
!=
fields
->
table_name
())
if
(
table_name
!=
fields
->
get_
table_name
())
{
{
table_name
=
fields
->
table_name
();
table_name
=
fields
->
get_
table_name
();
db_name
=
fields
->
db_name
();
db_name
=
fields
->
get_
db_name
();
grant
=
fields
->
grant
();
grant
=
fields
->
grant
();
/* get a fresh one for each table */
/* get a fresh one for each table */
want_access
=
want_access_arg
&
~
grant
->
privilege
;
want_access
=
want_access_arg
&
~
grant
->
privilege
;
...
@@ -4169,6 +4170,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
...
@@ -4169,6 +4170,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
GRANT_COLUMN
*
grant_column
=
GRANT_COLUMN
*
grant_column
=
column_hash_search
(
grant_table
,
field_name
,
column_hash_search
(
grant_table
,
field_name
,
(
uint
)
strlen
(
field_name
));
(
uint
)
strlen
(
field_name
));
if
(
grant_column
)
using_column_privileges
=
TRUE
;
if
(
!
grant_column
||
(
~
grant_column
->
rights
&
want_access
))
if
(
!
grant_column
||
(
~
grant_column
->
rights
&
want_access
))
goto
err
;
goto
err
;
}
}
...
@@ -4181,6 +4184,15 @@ err:
...
@@ -4181,6 +4184,15 @@ err:
char
command
[
128
];
char
command
[
128
];
get_privilege_desc
(
command
,
sizeof
(
command
),
want_access
);
get_privilege_desc
(
command
,
sizeof
(
command
),
want_access
);
/*
Do not give an error message listing a column name unless the user has
privilege to see all columns.
*/
if
(
using_column_privileges
)
my_error
(
ER_TABLEACCESS_DENIED_ERROR
,
MYF
(
0
),
command
,
sctx
->
priv_user
,
sctx
->
host_or_ip
,
table_name
);
else
my_error
(
ER_COLUMNACCESS_DENIED_ERROR
,
MYF
(
0
),
my_error
(
ER_COLUMNACCESS_DENIED_ERROR
,
MYF
(
0
),
command
,
command
,
sctx
->
priv_user
,
sctx
->
priv_user
,
...
...
sql/sql_base.cc
View file @
ee9528b0
...
@@ -7620,9 +7620,34 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
...
@@ -7620,9 +7620,34 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
continue
;
continue
;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Ensure that we have access rights to all fields to be inserted. */
/*
if
(
!
((
table
&&
(
table
->
grant
.
privilege
&
SELECT_ACL
)
||
Ensure that we have access rights to all fields to be inserted. Under
tables
->
view
&&
(
tables
->
grant
.
privilege
&
SELECT_ACL
)))
&&
some circumstances, this check may be skipped.
- If any_privileges is true, skip the check.
- If the SELECT privilege has been found as fulfilled already for both
the TABLE and TABLE_LIST objects (and both of these exist, of
course), the check is skipped.
- If the SELECT privilege has been found fulfilled for the TABLE object
and the TABLE_LIST represents a derived table other than a view (see
below), the check is skipped.
- If the TABLE_LIST object represents a view, we may skip checking if
the SELECT privilege has been found fulfilled for it, regardless of
the TABLE object.
- If there is no TABLE object, the test is skipped if either
* the TABLE_LIST does not represent a view, or
* the SELECT privilege has been found fulfilled.
A TABLE_LIST that is not a view may be a subquery, an
information_schema table, or a nested table reference. See the comment
for TABLE_LIST.
*/
if
(
!
(
table
&&
!
tables
->
view
&&
(
table
->
grant
.
privilege
&
SELECT_ACL
)
||
tables
->
view
&&
(
tables
->
grant
.
privilege
&
SELECT_ACL
))
&&
!
any_privileges
)
!
any_privileges
)
{
{
field_iterator
.
set
(
tables
);
field_iterator
.
set
(
tables
);
...
@@ -7676,19 +7701,19 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
...
@@ -7676,19 +7701,19 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
tables
->
is_natural_join
);
tables
->
is_natural_join
);
DBUG_ASSERT
(
item
->
type
()
==
Item
::
FIELD_ITEM
);
DBUG_ASSERT
(
item
->
type
()
==
Item
::
FIELD_ITEM
);
Item_field
*
fld
=
(
Item_field
*
)
item
;
Item_field
*
fld
=
(
Item_field
*
)
item
;
const
char
*
field_table_name
=
field_iterator
.
table_name
();
const
char
*
field_table_name
=
field_iterator
.
get_
table_name
();
if
(
!
tables
->
schema_table
&&
if
(
!
tables
->
schema_table
&&
!
(
fld
->
have_privileges
=
!
(
fld
->
have_privileges
=
(
get_column_grant
(
thd
,
field_iterator
.
grant
(),
(
get_column_grant
(
thd
,
field_iterator
.
grant
(),
field_iterator
.
db_name
(),
field_iterator
.
get_
db_name
(),
field_table_name
,
fld
->
field_name
)
&
field_table_name
,
fld
->
field_name
)
&
VIEW_ANY_ACL
)))
VIEW_ANY_ACL
)))
{
{
my_error
(
ER_
COLUMN
ACCESS_DENIED_ERROR
,
MYF
(
0
),
"ANY"
,
my_error
(
ER_
TABLE
ACCESS_DENIED_ERROR
,
MYF
(
0
),
"ANY"
,
thd
->
security_ctx
->
priv_user
,
thd
->
security_ctx
->
priv_user
,
thd
->
security_ctx
->
host_or_ip
,
thd
->
security_ctx
->
host_or_ip
,
f
ld
->
field_name
,
f
ield_table_name
);
field_table_name
);
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
TRUE
);
}
}
}
}
...
...
sql/sql_cache.cc
View file @
ee9528b0
...
@@ -2633,7 +2633,7 @@ Query_cache::register_tables_from_list(TABLE_LIST *tables_used,
...
@@ -2633,7 +2633,7 @@ Query_cache::register_tables_from_list(TABLE_LIST *tables_used,
tables_used
;
tables_used
;
tables_used
=
tables_used
->
next_global
,
n
++
,
block_table
++
)
tables_used
=
tables_used
->
next_global
,
n
++
,
block_table
++
)
{
{
if
(
tables_used
->
derived
&&
!
tables_used
->
view
)
if
(
tables_used
->
is_anonymous_derived_table
()
)
{
{
DBUG_PRINT
(
"qcache"
,
(
"derived table skipped"
));
DBUG_PRINT
(
"qcache"
,
(
"derived table skipped"
));
n
--
;
n
--
;
...
...
sql/sql_derived.cc
View file @
ee9528b0
...
@@ -73,29 +73,59 @@ out:
...
@@ -73,29 +73,59 @@ out:
}
}
/*
/**
Create temporary table structure (but do not fill it)
@brief Create temporary table structure (but do not fill it).
SYNOPSIS
@param thd Thread handle
mysql_derived_prepare()
@param lex LEX for this thread
thd Thread handle
@param orig_table_list TABLE_LIST for the upper SELECT
lex LEX for this thread
orig_table_list TABLE_LIST for the upper SELECT
@details
IMPLEMENTATION
This function is called before any command containing derived tables is
Derived table is resolved with temporary table.
executed. Currently the function is used for derived tables, i.e.
After table creation, the above TABLE_LIST is updated with a new table.
- Anonymous derived tables, or
- Named derived tables (aka views) with the @c TEMPTABLE algorithm.
This function is called before any command containing derived table
is executed.
The table reference, contained in @c orig_table_list, is updated with the
fields of a new temporary table.
Derived tables is stored in thd->derived_tables and freed in
close_thread_tables()
Derived tables are stored in @c thd->derived_tables and closed by
close_thread_tables().
RETURN
FALSE OK
This function is part of the procedure that starts in
TRUE Error
open_and_lock_tables(), a procedure that - among other things - introduces
new table and table reference objects (to represent derived tables) that
don't exist in the privilege database. This means that normal privilege
checking cannot handle them. Hence this function does some extra tricks in
order to bypass normal privilege checking, by exploiting the fact that the
current state of privilege verification is attached as GRANT_INFO structures
on the relevant TABLE and TABLE_REF objects.
For table references, the current state of accrued access is stored inside
TABLE_LIST::grant. Hence this function must update the state of fulfilled
privileges for the new TABLE_LIST, an operation which is normally performed
exclusively by the table and database access checking functions,
check_access() and check_grant(), respectively. This modification is done
for both views and anonymous derived tables: The @c SELECT privilege is set
as fulfilled by the user. However, if a view is referenced and the table
reference is queried against directly (see TABLE_LIST::referencing_view),
the state of privilege checking (GRANT_INFO struct) is copied as-is to the
temporary table.
This function implements a signature called "derived table processor", and
is passed as a function pointer to mysql_handle_derived().
@note This function sets @c SELECT_ACL for @c TEMPTABLE views as well as
anonymous derived tables, but this is ok since later access checking will
distinguish between them.
@see mysql_handle_derived(), mysql_derived_filling(), GRANT_INFO
@return
false OK
true Error
*/
*/
bool
mysql_derived_prepare
(
THD
*
thd
,
LEX
*
lex
,
TABLE_LIST
*
orig_table_list
)
bool
mysql_derived_prepare
(
THD
*
thd
,
LEX
*
lex
,
TABLE_LIST
*
orig_table_list
)
...
...
sql/sql_parse.cc
View file @
ee9528b0
...
@@ -4872,6 +4872,8 @@ bool check_single_table_access(THD *thd, ulong privilege,
...
@@ -4872,6 +4872,8 @@ bool check_single_table_access(THD *thd, ulong privilege,
/* Show only 1 table for check_grant */
/* Show only 1 table for check_grant */
if
(
!
(
all_tables
->
belong_to_view
&&
if
(
!
(
all_tables
->
belong_to_view
&&
(
thd
->
lex
->
sql_command
==
SQLCOM_SHOW_FIELDS
))
&&
(
thd
->
lex
->
sql_command
==
SQLCOM_SHOW_FIELDS
))
&&
!
(
all_tables
->
view
&&
all_tables
->
effective_algorithm
==
VIEW_ALGORITHM_TMPTABLE
)
&&
check_grant
(
thd
,
privilege
,
all_tables
,
0
,
1
,
no_errors
))
check_grant
(
thd
,
privilege
,
all_tables
,
0
,
1
,
no_errors
))
goto
deny
;
goto
deny
;
...
@@ -5184,7 +5186,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
...
@@ -5184,7 +5186,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
continue
;
continue
;
}
}
if
(
tables
->
derived
||
if
(
tables
->
is_anonymous_derived_table
()
||
(
tables
->
table
&&
(
int
)
tables
->
table
->
s
->
tmp_table
))
(
tables
->
table
&&
(
int
)
tables
->
table
->
s
->
tmp_table
))
continue
;
continue
;
thd
->
security_ctx
=
sctx
;
thd
->
security_ctx
=
sctx
;
...
...
sql/table.cc
View file @
ee9528b0
...
@@ -2993,16 +2993,27 @@ void TABLE_LIST::calc_md5(char *buffer)
...
@@ -2993,16 +2993,27 @@ void TABLE_LIST::calc_md5(char *buffer)
}
}
/*
/*
*
set underlying TABLE for table place holder of VIEW
@brief Set underlying table for table place holder of view.
DESCRIPTION
@details
Replace all views that only uses one table with the table itself.
This allows us to treat the view as a simple table and even update
it (it is a kind of optimisation)
SYNOPSIS
Replace all views that only use one table with the table itself. This
TABLE_LIST::set_underlying_merge()
allows us to treat the view as a simple table and even update it (it is a
kind of optimization).
@note
This optimization is potentially dangerous as it makes views
masquerade as base tables: Views don't have the pointer TABLE_LIST::table
set to non-@c NULL.
We may have the case where a view accesses tables not normally accessible
in the current Security_context (only in the definer's
Security_context). According to the table's GRANT_INFO (TABLE::grant),
access is fulfilled, but this is implicitly meant in the definer's security
context. Hence we must never look at only a TABLE's GRANT_INFO without
looking at the one of the referring TABLE_LIST.
*/
*/
void
TABLE_LIST
::
set_underlying_merge
()
void
TABLE_LIST
::
set_underlying_merge
()
...
@@ -4082,7 +4093,7 @@ void Field_iterator_table_ref::next()
...
@@ -4082,7 +4093,7 @@ void Field_iterator_table_ref::next()
}
}
const
char
*
Field_iterator_table_ref
::
table_name
()
const
char
*
Field_iterator_table_ref
::
get_
table_name
()
{
{
if
(
table_ref
->
view
)
if
(
table_ref
->
view
)
return
table_ref
->
view_name
.
str
;
return
table_ref
->
view_name
.
str
;
...
@@ -4095,7 +4106,7 @@ const char *Field_iterator_table_ref::table_name()
...
@@ -4095,7 +4106,7 @@ const char *Field_iterator_table_ref::table_name()
}
}
const
char
*
Field_iterator_table_ref
::
db_name
()
const
char
*
Field_iterator_table_ref
::
get_
db_name
()
{
{
if
(
table_ref
->
view
)
if
(
table_ref
->
view
)
return
table_ref
->
view_db
.
str
;
return
table_ref
->
view_db
.
str
;
...
...
sql/table.h
View file @
ee9528b0
...
@@ -66,13 +66,63 @@ typedef struct st_order {
...
@@ -66,13 +66,63 @@ typedef struct st_order {
table_map
used
,
depend_map
;
table_map
used
,
depend_map
;
}
ORDER
;
}
ORDER
;
/**
@brief The current state of the privilege checking process for the current
user, SQL statement and SQL object.
@details The privilege checking process is divided into phases depending on
the level of the privilege to be checked and the type of object to be
accessed. Due to the mentioned scattering of privilege checking
functionality, it is necessary to keep track of the state of the
process. This information is stored in privilege, want_privilege, and
orig_want_privilege.
A GRANT_INFO also serves as a cache of the privilege hash tables. Relevant
members are grant_table and version.
*/
typedef
struct
st_grant_info
typedef
struct
st_grant_info
{
{
/**
@brief A copy of the privilege information regarding the current host,
database, object and user.
@details The version of this copy is found in GRANT_INFO::version.
*/
GRANT_TABLE
*
grant_table
;
GRANT_TABLE
*
grant_table
;
/**
@brief Used for cache invalidation when caching privilege information.
@details The privilege information is stored on disk, with dedicated
caches residing in memory: table-level and column-level privileges,
respectively, have their own dedicated caches.
The GRANT_INFO works as a level 1 cache with this member updated to the
current value of the global variable @c grant_version (@c static variable
in sql_acl.cc). It is updated Whenever the GRANT_INFO is refreshed from
the level 2 cache. The level 2 cache is the @c column_priv_hash structure
(@c static variable in sql_acl.cc)
@see grant_version
*/
uint
version
;
uint
version
;
/**
@brief The set of privileges that the current user has fulfilled for a
certain host, database, and object.
@details This field is continually updated throughout the access checking
process. In each step the "wanted privilege" is checked against the
fulfilled privileges. When/if the intersection of these sets is empty,
access is granted.
The set is implemented as a bitmap, with the bits defined in sql_acl.h.
*/
ulong
privilege
;
ulong
privilege
;
/**
@brief the set of privileges that the current user needs to fulfil in
order to carry out the requested operation.
*/
ulong
want_privilege
;
ulong
want_privilege
;
/*
/*
*
Stores the requested access acl of top level tables list. Is used to
Stores the requested access acl of top level tables list. Is used to
check access rights to the underlying tables of a view.
check access rights to the underlying tables of a view.
*/
*/
...
@@ -1104,6 +1154,27 @@ struct TABLE_LIST
...
@@ -1104,6 +1154,27 @@ struct TABLE_LIST
can see this lists can't be merged)
can see this lists can't be merged)
*/
*/
TABLE_LIST
*
correspondent_table
;
TABLE_LIST
*
correspondent_table
;
/**
@brief Normally, this field is non-null for anonymous derived tables only.
@details This field is set to non-null for
- Anonymous derived tables, In this case it points to the SELECT_LEX_UNIT
representing the derived table. E.g. for a query
@verbatim SELECT * FROM (SELECT a FROM t1) b @endverbatim
For the @c TABLE_LIST representing the derived table @c b, @c derived
points to the SELECT_LEX_UNIT representing the result of the query within
parenteses.
- Views. This is set for views with @verbatim ALGORITHM = TEMPTABLE
@endverbatim by mysql_make_view().
@note Inside views, a subquery in the @c FROM clause is not allowed.
@note Do not use this field to separate views/base tables/anonymous
derived tables. Use TABLE_LIST::is_anonymous_derived_table().
*/
st_select_lex_unit
*
derived
;
/* SELECT_LEX_UNIT of derived table */
st_select_lex_unit
*
derived
;
/* SELECT_LEX_UNIT of derived table */
ST_SCHEMA_TABLE
*
schema_table
;
/* Information_schema table */
ST_SCHEMA_TABLE
*
schema_table
;
/* Information_schema table */
st_select_lex
*
schema_select_lex
;
st_select_lex
*
schema_select_lex
;
...
@@ -1169,7 +1240,15 @@ struct TABLE_LIST
...
@@ -1169,7 +1240,15 @@ struct TABLE_LIST
ulonglong
file_version
;
/* version of file's field set */
ulonglong
file_version
;
/* version of file's field set */
ulonglong
updatable_view
;
/* VIEW can be updated */
ulonglong
updatable_view
;
/* VIEW can be updated */
ulonglong
revision
;
/* revision control number */
ulonglong
revision
;
/* revision control number */
ulonglong
algorithm
;
/* 0 any, 1 tmp tables , 2 merging */
/**
@brief The declared algorithm, if this is a view.
@details One of
- VIEW_ALGORITHM_UNDEFINED
- VIEW_ALGORITHM_TMPTABLE
- VIEW_ALGORITHM_MERGE
@to do Replace with an enum
*/
ulonglong
algorithm
;
ulonglong
view_suid
;
/* view is suid (TRUE dy default) */
ulonglong
view_suid
;
/* view is suid (TRUE dy default) */
ulonglong
with_check
;
/* WITH CHECK OPTION */
ulonglong
with_check
;
/* WITH CHECK OPTION */
/*
/*
...
@@ -1177,7 +1256,15 @@ struct TABLE_LIST
...
@@ -1177,7 +1256,15 @@ struct TABLE_LIST
algorithm)
algorithm)
*/
*/
uint8
effective_with_check
;
uint8
effective_with_check
;
uint8
effective_algorithm
;
/* which algorithm was really used */
/**
@brief The view algorithm that is actually used, if this is a view.
@details One of
- VIEW_ALGORITHM_UNDEFINED
- VIEW_ALGORITHM_TMPTABLE
- VIEW_ALGORITHM_MERGE
@to do Replace with an enum
*/
uint8
effective_algorithm
;
GRANT_INFO
grant
;
GRANT_INFO
grant
;
/* data need by some engines in query cache*/
/* data need by some engines in query cache*/
ulonglong
engine_data
;
ulonglong
engine_data
;
...
@@ -1362,6 +1449,26 @@ struct TABLE_LIST
...
@@ -1362,6 +1449,26 @@ struct TABLE_LIST
m_table_ref_version
=
s
->
get_table_ref_version
();
m_table_ref_version
=
s
->
get_table_ref_version
();
}
}
/**
@brief True if this TABLE_LIST represents an anonymous derived table,
i.e. the result of a subquery.
*/
bool
is_anonymous_derived_table
()
const
{
return
derived
&&
!
view
;
}
/**
@brief Returns the name of the database that the referenced table belongs
to.
*/
char
*
get_db_name
()
{
return
view
!=
NULL
?
view_db
.
str
:
db
;
}
/**
@brief Returns the name of the table that this TABLE_LIST represents.
@details The unqualified table name or view name for a table or view,
respectively.
*/
char
*
get_table_name
()
{
return
view
!=
NULL
?
view_name
.
str
:
table_name
;
}
private:
private:
bool
prep_check_option
(
THD
*
thd
,
uint8
check_opt_type
);
bool
prep_check_option
(
THD
*
thd
,
uint8
check_opt_type
);
bool
prep_where
(
THD
*
thd
,
Item
**
conds
,
bool
no_where_clause
);
bool
prep_where
(
THD
*
thd
,
Item
**
conds
,
bool
no_where_clause
);
...
@@ -1491,8 +1598,8 @@ public:
...
@@ -1491,8 +1598,8 @@ public:
bool
end_of_fields
()
bool
end_of_fields
()
{
return
(
table_ref
==
last_leaf
&&
field_it
->
end_of_fields
());
}
{
return
(
table_ref
==
last_leaf
&&
field_it
->
end_of_fields
());
}
const
char
*
name
()
{
return
field_it
->
name
();
}
const
char
*
name
()
{
return
field_it
->
name
();
}
const
char
*
table_name
();
const
char
*
get_
table_name
();
const
char
*
db_name
();
const
char
*
get_
db_name
();
GRANT_INFO
*
grant
();
GRANT_INFO
*
grant
();
Item
*
create_item
(
THD
*
thd
)
{
return
field_it
->
create_item
(
thd
);
}
Item
*
create_item
(
THD
*
thd
)
{
return
field_it
->
create_item
(
thd
);
}
Field
*
field
()
{
return
field_it
->
field
();
}
Field
*
field
()
{
return
field_it
->
field
();
}
...
...
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