剧透警告:我知道之前已经有人问过类似的问题,但我使用的是 Azure PosgreSQL 灵活服务器,这意味着我没有对 Postgresql 的超级用户访问权限(因为它是托管服务,只有 Azure 具有超级用户权限) )因此,一些可能对其他人有用的解决方案在这里不适用,托管 postgreSQL 服务器的行为也可能不同。
问题来了: 我们在 postgresql 中有一些动态创建的数据库角色,它们获得数据库的连接权限以及该数据库公共模式中所有表的附加权限(插入、更新等)。 用于这些角色的创建语句是:
CREATE USER "test" WITH LOGIN PASSWORD 'somepasswordyoudonotneedtoknow' VALID UNTIL '2024-05-03 20:02:25+00';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO "test";
GRANT CONNECT ON DATABASE "myDB" TO "test";
到目前为止,这似乎运作良好。 我们使用该角色连接到数据库并执行一些选择语句。 现在,在角色过期后,我们想通过撤销访问权限并删除角色来再次删除它:
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM "test";
REVOKE ALL PRIVILEGES ON DATABASE "myDB" FROM "test";
DROP ROLE IF EXISTS "test";
前两条语句执行时没有错误,但 DROP ROLE 失败并显示:
ERROR: privileges for database myDBrole "test" cannot be dropped because some objects depend on it
ERROR: role "test" cannot be dropped because some objects depend on it
SQL state: 2BP01
Detail: privileges for database myDB
这表明用户仍然对数据库本身拥有一些权限,但是 REVOKE ALL PRIVILEGES ON DATABASE 没有返回任何错误。
当我使用 pgAdmin (4.8) 检查数据库的权限时,我可以在数据库属性的安全选项卡上看到该角色仍然具有数据库的连接权限。 即使当我尝试删除此条目并保存(没有显示错误),然后再次打开属性时,该角色仍然具有“c”(连接)权限。
所以我不确定发生了什么,以及为什么没有显示错误然后尝试撤销对数据库的 CONNECT 访问。 我尝试转移该角色的所有所有者的所有其他语句都失败了,因为我确实需要超级用户权限,而 Azure 不会向托管解决方案中的客户端提供该权限。
有什么想法吗?
我还尝试获取用户所有权限的列表:
SELECT * FROM information_schema.role_table_grants WHERE grantee = 'test';
但是没有返回结果
在删除角色之前,您必须删除其所有对象的所有所有权(或将所有权转让给另一个人),并删除该角色对其他对象可能拥有的所有权利。是您面临错误的原因。
为了解决这个问题,您必须夺走任何对象的所有所有权(或将所有权授予其他人)并剥夺角色的权利。
REVOKE ALL PRIVILEGES ON DATABASE DBName FROM "USER";
REVOKE ALL PRIVILEGES ON SCHEMA SchemaNmae FROM "USER";
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA SchemaNmae FROM "USER";
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA SchemaNmae FROM "USER";
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA SchemaNmae FROM "USER";
REASSIGN OWNED BY ryan TO <newuser>;
DROP OWNED BY ryan;