GaussDB对象权限的注意事项
模式下的Usage权限
⭐️ 场景:访问其他Schema下的表或视图
scott用户的对象权限:
tpcc=# select grantee,owner,table_name,type,grantor,privilege,grantable from adm_tab_privs where grantee='scott';
grantee | owner | table_name | type | grantor | privilege | grantable
---------+--------+------------+--------+---------+-----------+-----------
scott | wolong | name | COLUMN | wolong | SELECT | NO
scott | wolong | name | COLUMN | wolong | COMMENT | NO
scott | wolong | age | COLUMN | wolong | SELECT | NO
scott | wolong | age | COLUMN | wolong | COMMENT | NO
scott | wolong | caocao | table | wolong | INSERT | NO
scott | wolong | caocao | table | wolong | SELECT | YES
scott | wolong | caocao | table | wolong | UPDATE | NO
scott | wolong | caocao | table | wolong | DELETE | NO
scott用户对表wolong.caocao
有查询权限,但是查询报错权限不足:
tpcc=> select * from wolong.caocao;
ERROR: permission denied for schema wolong
LINE 1: select * from wolong.caocao;
^
DETAIL: N/A
原因是缺少对wolong模式的USAGE权限:
grant usage on schema wolong to scott;
scott用户再次查询正常:
tpcc=> select * from wolong.caocao;
id | name | age
----+------+-----
(0 rows)
📖 跨Schema访问对象
- 将Schema中的表或者视图对象授权给其他用户或角色时,需要将表或视图所属Schema的USAGE权限同时授予该用户或角色。否则用户或角色将只能看到这些对象的名称,并不能实际进行对象访问。
模式下的Create权限
⭐️ 场景:在其他Schema下创建表或视图
scott用户的对象权限:
tpcc=# select grantee,owner,table_name,type,grantor,privilege,grantable from adm_tab_privs where grantee='scott';
grantee | owner | table_name | type | grantor | privilege | grantable
------------+--------+------------+--------+---------+-----------+-----------
scott | wolong | name | COLUMN | wolong | SELECT | NO
scott | wolong | name | COLUMN | wolong | COMMENT | NO
scott | wolong | age | COLUMN | wolong | SELECT | NO
scott | wolong | age | COLUMN | wolong | COMMENT | NO
scott | wolong | caocao | table | wolong | INSERT | NO
scott | wolong | caocao | table | wolong | SELECT | YES
scott | wolong | caocao | table | wolong | UPDATE | NO
scott | wolong | caocao | table | wolong | DELETE | NO
scott | wolong | wolong | SCHEMA | wolong | USAGE | NO
wolong模式下的表:
tpcc=# select schemaname,tablename,tableowner,tablespace from pg_tables where schemaname='wolong';
schemaname | tablename | tableowner | tablespace
------------+-----------+------------+------------
wolong | caocao | wolong |
wolong | simayi | wolong |
(2 rows)
scott用户在wolong模式下建表,但是报错权限不足:
create table if not exists wolong.t1 (
w_num integer not null,
w_id char(16) not null,
w_name varchar(20) unique,
w_state char(2) default 'NY',
w_offset decimal(5,2)
);
ERROR: permission denied for schema wolong
DETAIL: N/A
需要授予在wolong下创建对象的权限:
grant create on schema wolong to scott;
再次执行建表语句还是报错:
ERROR: current user does not have privilege to role wolong
授予wolong角色权限给scott:
tpcc=# grant wolong to scott;
GRANT ROLE
再次建表成功:
tpcc=> create table if not exists wolong.t1 (
w_num integer not null,
w_id char(16) not null,
w_name varchar(20) unique,
w_state char(2) default 'NY',
w_offset decimal(5,2)
);tpcc(> tpcc(> tpcc(> tpcc(> tpcc(> tpcc(>
NOTICE: CREATE TABLE / UNIQUE will create implicit index "t1_w_name_key" for table "t1"
CREATE TABLE
经测试无需额外授予CREATE ON SCHEMA权限。
📖 跨Schema创建对象
- 一个普通用户r1要在另一个普通用户r2的Schema下创建对象,需要拥有r2用户的角色权限。
- 由于获取了r2用户的角色权限,用户r1实际上获得了对用户r2下所有对象的操作权限(但不会继承r2拥有的系统权限),比如对r2模式下所有表的DML权限,这里出现了预期外的权限扩大。
- 另一种实现跨Schema创建对象的方法是授予CREATE ANY权限,被授权用户可以在当前数据库中所有模式下创建对象。这种方法会导致更大范围的权限扩大和安全隐患。
- 默认情况下,所有角色/用户都拥有当前数据库中public模式的USAGE权限,但是普通角色/用户没有在public模式下的CREATE权限。
数据库下的Create权限
⭐️ 场景:在其他Database下创建表或视图
创建一个新的数据库:
create database testdb dbcompatibility = 'A';
scott用户连接到该数据库后尝试建表会报错权限不足:
testdb=> create table if not exists t1 (
w_num integer not null,
w_id char(16) not null,
w_name varchar(20) unique
);testdb(> testdb(> testdb(> testdb(>
ERROR: permission denied for schema public
DETAIL: N/A
原因是用户在testdb数据库中没有自己的Schema,也没有对public模式的CREATE权限。
授予scott用户在testdb数据库下的Create权限:
testdb=# grant connect,create on database testdb to scott;
GRANT
testdb=# select grantee,owner,table_name,type,grantor,privilege,grantable from adm_tab_privs where grantee='scott';
grantee | owner | table_name | type | grantor | privilege | grantable
--------------+----------+------------+----------+----------+-----------+-----------
scott | rdsAdmin | testdb | DATABASE | rdsAdmin | CREATE | NO
scott | rdsAdmin | testdb | DATABASE | rdsAdmin | CONNECT | NO
(2 rows)
再次建表还是报错:
ERROR: permission denied for schema public
DETAIL: N/A
授予对public模式的CREATE权限后,可以在public模式下建表。
testdb=# grant create on schema public to scott;
GRANT
经测试无需额外授予CREATE ON DATABASE权限。
回收用户在testdb及其public模式下的CREATE权限:
testdb=# revoke create on database testdb from scott;
REVOKE
testdb=# revoke create on schema public from scott;
REVOKE
在testdb中为用户创建并授权同名Schema:
testdb=# create schema scott authorization scott;
CREATE SCHEMA
可以直接在自己的模式下创建表:
create table if not exists scott.t1_bench (
w_num integer not null,
w_id char(16) not null,
w_name varchar(20) unique
);
📖 在数据库中创建对象
- 不同于Schema只存在于单个Database中,GaussDB的用户/角色是存在于集群的所有Database中的。
- 普通用户要在一个新的数据库中创建对象,要么具有对目标数据库public模式的CREATE权限(不推荐),要么在目标数据库中有属于自己的Schema(推荐)。