原作者:高云龙
距离上一篇涉及用户的介绍 PostgreSQL 与 MogDB/openGauss 之 角色 已经差不多一年的时间了,但是在日常使用中还是或多或少遇到用户及权限的问题,这里继续汇总总结一下。
#### 环境信息
OS: centos 7
MogDB: 3.0.4
#### 数据库准备
```
–创建用户
create user su1 identified by ‘Su1@123456’;
create user tu1 identified by ‘Tu1@123456’;
–创建数据库
create database fdb;
–创建schema
create schema fs authorization su1;
–赋权
grant usage,create on schema su1 to tu1;
grant usage,create on schema fs to tu1;
–tu1用户建表
create table fs.tt(id int);
create table su1.tt(id int);
```
#### current user does not have privilege to role su1
```
[mogdblmt@lmt-0001 ~]$ gsql postgres -p 36000 -r -Utu1
Password for user tu1:
gsql ((MogDB 3.0.4 build cc068866) compiled at 2023-03-03 17:47:05 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type “help” for help.
MogDB=>
MogDB=> create table su1.tt(id int);
ERROR: current user does not have privilege to role su1
MogDB=> create table fs.tt(id int);
CREATE TABLE
```
当我们创建用户时,默认会在当前数据库下创建一个与用户同名的schema,这里不确定是不是这个特性限制,所以我们换一个数据库试试,手工创建schema。
```
MogDB=# c fdb
Non-SSL connection (SSL connection is recommended when requiring high-security)
You are now connected to database “fdb” as user “mogdblmt”.
fdb=#
fdb=# create schema su1 authorization su1;
CREATE SCHEMA
fdb=#
fdb=# grant usage,create on schema su1 to tu1;
GRANT
–tu1用户登录
MogDB=> c fdb
Password for user tu1:
Non-SSL connection (SSL connection is recommended when requiring high-security)
You are now connected to database “fdb” as user “tu1”.
fdb=> create table su1.tt(id int);
ERROR: current user does not have privilege to role su1
```
看一下数据库源码,schema和owner相同的情况下,会将owner的oid与当前用户的oid进行判断,如果不一样就会提示没有权限
### 绕过报错
既然内核里做了限制,但是可以用一种方法绕过去,就是将目标用户(tu1)加入owner(su1)的组里,因为在MogDB/openGauss/PG里,user等于带login属性的role,我们来试试
```
–将tu1 加入到su1 组
fdb=# grant su1 to tu1;
GRANT ROLE
–再次用tu1 用户执行建表
fdb=> create table su1.tt(id int);
ERROR: current user does not have privilege to role su1
fdb=>
fdb=> create table su1.tt(id int);
CREATE TABLE
```
我们通过角色成员关系表也可以看到继承关系,但是有一点需要注意,虽然tu1继承了su1的权限,可以进行数据库对象创建,但对象的owner依然是su1,而不是tu1。
```
fdb=# select roleid,member,grantor,admin_option from pg_auth_members;
roleid | member | grantor | admin_option
--------±-------±--------±-------------
16776 | 16780 | 10 | f
(1 row)
fdb=# select usesysid,usename from pg_user where usesysid in(16776,16780,10);
usesysid | usename
----------±---------
10 | mogdblmt
16776 | su1
16780 | tu1
(3 rows)
–tu1用户查看表的owner,发现是空
fdb=> dt+ su1.tt
List of relations
Schema | Name | Type | Owner | Size | Storage | Description
--------±-----±------±------±--------±---------------------------------±------------
su1 | tt | table | | 0 bytes | {orientation=row,compression=no} |
–用超户查看
fdb=# dt su1.*
List of relations
Schema | Name | Type | Owner | Storage
--------±-----±------±------±---------------------------------
su1 | tt | table | su1 | {orientation=row,compression=no}
```
这种赋权操作风险是非常大的,谨慎使用,甚至在建表之初就选用与用户名不一致的schema。