Commit 79f84fdc authored by Alexander Barkov's avatar Alexander Barkov

- Require FILE privilege for the file based TABLE_TYPEs

when FILE_NAME is specified

- Require FILE privileges for the TABLE_TYPEs that
  access to the underlying operating system:
  ODBC, MYSQL, DIR, MAC, WMI, OEM.

added:
  mysql-test/suite/connect/t/grant.inc
modified:
  mysql-test/suite/connect/r/bin.result
  mysql-test/suite/connect/t/bin.test
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
parent c52d8874
# #
# Testing grants
#
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
SELECT user();
user()
user@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=BIN;
Warnings:
Warning 1105 No file name. Table will use t1.BIN
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
a
10
UPDATE t1 SET a=20;
SELECT * FROM t1;
a
20
DELETE FROM t1;
SELECT * FROM t1;
a
INSERT INTO t1 VALUES(10);
TRUNCATE TABLE t1;
SELECT * FROM t1;
a
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=BIN FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=BIN FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
SELECT user();
user()
user@localhost
INSERT INTO t1 VALUES (10);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE t1 SET a=20;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
TRUNCATE TABLE t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
ALTER TABLE t1 READONLY=1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DROP TABLE t1;
DROP USER user@localhost;
#
# Testing errors # Testing errors
# #
CREATE TABLE t1 CREATE TABLE t1
......
let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_DATADIR= `select @@datadir`;
let $FILE_TYPE=BIN;
let $FILE_EXT=BIN;
--source grant.inc
--copy_file $MYSQL_TEST_DIR/suite/connect/std_data/Testbal.dat $MYSQLD_DATADIR/test/Testbal.dat --copy_file $MYSQL_TEST_DIR/suite/connect/std_data/Testbal.dat $MYSQLD_DATADIR/test/Testbal.dat
--echo # --echo #
......
--echo #
--echo # Testing grants
--echo #
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
--connect(user,localhost,user,,)
--connection user
SELECT user();
--eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=$FILE_TYPE
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
UPDATE t1 SET a=20;
SELECT * FROM t1;
DELETE FROM t1;
SELECT * FROM t1;
INSERT INTO t1 VALUES(10);
TRUNCATE TABLE t1;
SELECT * FROM t1;
# TODO: VIEW, LOCK, UNLOCK, REFERENCES, INDEX
DROP TABLE t1;
# Making sure DROP erased the data file
--error 1
--remove_file $MYSQLD_DATADIR/test/t1.$FILE_EXT
--error ER_ACCESS_DENIED_ERROR
--eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=$FILE_TYPE FILE_NAME='t1.EXT'
--connection default
SELECT user();
--eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=$FILE_TYPE FILE_NAME='t1.EXT'
INSERT INTO t1 VALUES (10);
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR
INSERT INTO t1 VALUES (10);
--error ER_ACCESS_DENIED_ERROR
SELECT * FROM t1;
--error ER_ACCESS_DENIED_ERROR
UPDATE t1 SET a=20;
--error ER_ACCESS_DENIED_ERROR
DELETE FROM t1;
--error ER_ACCESS_DENIED_ERROR
TRUNCATE TABLE t1;
--error ER_ACCESS_DENIED_ERROR
ALTER TABLE t1 READONLY=1;
# TODO: DROP
--disconnect user
--connection default
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.EXT
DROP USER user@localhost;
...@@ -2883,6 +2883,54 @@ int ha_connect::delete_all_rows() ...@@ -2883,6 +2883,54 @@ int ha_connect::delete_all_rows()
DBUG_RETURN(rc); DBUG_RETURN(rc);
} // end of delete_all_rows } // end of delete_all_rows
bool ha_connect::check_privileges(THD *thd, TABLE *table_arg)
{
PTOS options= GetTableOptionStruct(table_arg);
if (!options || !options->type)
goto err;
switch (GetTypeID(options->type))
{
case TAB_UNDEF:
case TAB_CATLG:
case TAB_PLG:
case TAB_JCT:
case TAB_DMY:
case TAB_NIY:
goto err;
case TAB_DOS:
case TAB_FIX:
case TAB_BIN:
case TAB_CSV:
case TAB_FMT:
case TAB_DBF:
case TAB_XML:
case TAB_INI:
case TAB_VEC:
return options->filename ?
check_access(thd, FILE_ACL, any_db, NULL, NULL, 0, 0) : false;
case TAB_ODBC:
case TAB_MYSQL:
case TAB_DIR:
case TAB_MAC:
case TAB_WMI:
case TAB_OEM:
return check_access(thd, FILE_ACL, any_db, NULL, NULL, 0, 0);
case TAB_TBL:
case TAB_PIVOT:
return false;
}
err:
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
return true;
}
/** /**
@brief @brief
This create a lock on the table. If you are implementing a storage engine This create a lock on the table. If you are implementing a storage engine
...@@ -2919,6 +2967,9 @@ int ha_connect::external_lock(THD *thd, int lock_type) ...@@ -2919,6 +2967,9 @@ int ha_connect::external_lock(THD *thd, int lock_type)
if (!g) if (!g)
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
if (lock_type != F_UNLCK && check_privileges(thd, table))
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
// Action will depend on lock_type // Action will depend on lock_type
switch (lock_type) { switch (lock_type) {
case F_WRLCK: case F_WRLCK:
...@@ -3836,6 +3887,9 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -3836,6 +3887,9 @@ int ha_connect::create(const char *name, TABLE *table_arg,
DBUG_ASSERT(options); DBUG_ASSERT(options);
type= GetTypeID(options->type); type= GetTypeID(options->type);
if (check_privileges(current_thd, table_arg))
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
if (options->data_charset) { if (options->data_charset) {
const CHARSET_INFO *data_charset; const CHARSET_INFO *data_charset;
......
...@@ -361,6 +361,7 @@ const char *GetValStr(OPVAL vop, bool neg); ...@@ -361,6 +361,7 @@ const char *GetValStr(OPVAL vop, bool neg);
int optimize(THD* thd, HA_CHECK_OPT* check_opt); int optimize(THD* thd, HA_CHECK_OPT* check_opt);
protected: protected:
bool check_privileges(THD *thd, TABLE *table_arg);
char *GetListOption(const char *opname, const char *oplist, const char *def= NULL); char *GetListOption(const char *opname, const char *oplist, const char *def= NULL);
#if defined(MARIADB) #if defined(MARIADB)
char *encode(PGLOBAL g, char *cnm); char *encode(PGLOBAL g, char *cnm);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment