Postgresql源码(114)视图权限授予逻辑

这篇具有很好参考价值的文章主要介绍了Postgresql源码(114)视图权限授予逻辑。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0 速查

被授权的对象在系统表中记录授权信息,例如pg_namespace中的nspacl列:

{mingjie=UC/mingjie,=UC/mingjie,pusr1=UC/mingjie}

pusr1=UC/mingjie的含义:

  • mingjie是赋予者
  • pusr1是被赋予者
  • UC是权限,表示USAGE和CREATE

1 视图权限案例

有时会遇到下面场景,访问一个视图没有权限:

drop schema sch1 cascade;
drop user pusr1;
drop user pusr2;

create user pusr1;
create user pusr2;

create schema sch1;

create procedure sch1.func1(i int) as $$
begin
  raise notice 'func1';
end;
$$ language plpgsql;

\c - pusr1
call sch1.func1(1);

结果
Postgresql源码(114)视图权限授予逻辑,pgsql,postgresql,数据库,grant
查看namespace视图:
Postgresql源码(114)视图权限授予逻辑,pgsql,postgresql,数据库,grant
这种情况下,添加两种权限都可以访问函数:

grant all on schema sch1 to public;
grant all on schema sch1 to pusr1;

Postgresql源码(114)视图权限授予逻辑,pgsql,postgresql,数据库,grant

这里我们看到namespace元数据增加了两条规则,对应两条grant:

grant all on schema sch1 to public;   →          =UC/mingjie           
grant all on schema sch1 to pusr1;    →     pusr1=UC/mingjie     

显然这两条规则就是权限判断的依据,下面分析这两条规则的使用流程。

2 权限判定流程分析

部分代码

static AclMode
pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
					 AclMode mask, AclMaskHow how)
{
	...
	...

查pg_namespace表:

	tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid));

检查owner是谁?

	ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;

拿到规则aclDatum:{mingjie=UC/mingjie,=UC/mingjie,pusr1=UC/mingjie}

	aclDatum = SysCacheGetAttr(NAMESPACEOID, tuple, Anum_pg_namespace_nspacl,
							   &isNull);

默认没grant的时候aclDatum字段是isNull,这时候owner有权限访问,其他没权限。

	if (isNull)
	{
		/* No ACL, so build default ACL */
		acl = acldefault(OBJECT_SCHEMA, ownerId);
		aclDatum = (Datum) 0;
	}

有grant后,aclDatum字段有值了,把{mingjie=UC/mingjie,=UC/mingjie,pusr1=UC/mingjie}传入,detoast后变成valena变长类型。

	else
	{
		/* detoast ACL if necessary */
		acl = DatumGetAclP(aclDatum);
	}

拿着acl进入aclmask处理,判断roleid是否有访问权限。

	result = aclmask(acl, roleid, ownerId, mask, how);

	...
	...

	return result;
}

aclmask函数

AclMode
aclmask(const Acl *acl, Oid roleid, Oid ownerId,
		AclMode mask, AclMaskHow how)
{

入参:

  • valena变量含义{mingjie=UC/mingjie,=UC/mingjie,pusr1=UC/mingjie}
  • roleid:24601表示pusr1。
  • ownerId:10表示建库的超级用户。
  • mask:256表示#define ACL_USAGE (1<<8) /* for various object types */
  • how:ACLMASK_ANY

	num = ACL_NUM(acl);
	aidat = ACL_DAT(acl);

num = 3
(gdb) p aidat[0]
$6 = {ai_grantee = 10, ai_grantor = 10, ai_privs = 768}
(gdb) p aidat[1
$7 = {ai_grantee = 0, ai_grantor = 10, ai_privs = 768}
(gdb) p aidat[2
$8 = {ai_grantee = 24601, ai_grantor = 10, ai_privs = 768}

这里解释下这三个数据的含义
$8 = {ai_grantee = 24601, ai_grantor = 10, ai_privs = 768}

10表示建库的超级用户,赋予,24601表示pusr1,768的权限
768 = 1100000000 = ACL_USAGE | ACL_CREATE
#define ACL_USAGE (1<<8) /* for various object types */
#define ACL_CREATE (1<<9) /* for namespaces and databases */

注意这里有一个特殊的ai_grantee:ACL_ID_PUBLIC=0,表示被授权者是任意用户。

下面循环就是对上述逻辑进行判断:

	/*
	 * Check privileges granted directly to roleid or to public
	 */
	for (i = 0; i < num; i++)
	{
		AclItem    *aidata = &aidat[i];

		if (aidata->ai_grantee == ACL_ID_PUBLIC ||
			aidata->ai_grantee == roleid)
		{
			result |= aidata->ai_privs & mask;
			if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))

返回256:ACL_USAGE

				return result;
		}
	}
	...
	...
}

3 系统schema的grant … to public是哪里赋值的?

注意到pg_catalog、public、information_schema三者都是有初始授权的,记录下赋值方法和位置。

postgres=> select * from pg_namespace ;
  oid  |      nspname       | nspowner |                            nspacl
-------+--------------------+----------+---------------------------------------------------------------
    99 | pg_toast           |       10 |
    11 | pg_catalog         |       10 | {mingjie=UC/mingjie,=U/mingjie}
  2200 | public             |     6171 | {pg_database_owner=UC/pg_database_owner,=U/pg_database_owner}
 13918 | information_schema |       10 | {mingjie=UC/mingjie,=U/mingjie}

information_schema

在information_schema.sql中赋权:

CREATE SCHEMA information_schema;
GRANT USAGE ON SCHEMA information_schema TO PUBLIC;
SET search_path TO information_schema;

pg_catalog / public

pg_namespace.dat里面插入pg_catalog的tuple,但没有权限信息:

[

{ oid => '11', oid_symbol => 'PG_CATALOG_NAMESPACE',
  descr => 'system catalog schema',
  nspname => 'pg_catalog', nspacl => '_null_' },
{ oid => '99', oid_symbol => 'PG_TOAST_NAMESPACE',
  descr => 'reserved schema for TOAST tables',
  nspname => 'pg_toast', nspacl => '_null_' },
# update dumpNamespace() if changing this descr
{ oid => '2200', oid_symbol => 'PG_PUBLIC_NAMESPACE',
  descr => 'standard public schema',
  nspname => 'public', nspowner => 'pg_database_owner', nspacl => '_null_' },

]

initdb初始化时在这里给pg_catalog授权:
Postgresql源码(114)视图权限授予逻辑,pgsql,postgresql,数据库,grant文章来源地址https://www.toymoban.com/news/detail-730735.html

(gdb) bt
#0  ExecGrant_common (istmt=0x7ffcc262d0c0, classid=2615, default_privs=768, object_check=0x0) at aclchk.c:2170
#1  0x000000000059d7d1 in ExecGrantStmt_oids (istmt=0x7ffcc262d0c0) at aclchk.c:625
#2  0x000000000059d6a6 in ExecuteGrantStmt (stmt=0x27458c8) at aclchk.c:583
#3  0x00000000009c0d56 in ProcessUtilitySlow (pstate=0x283fd28, pstmt=0x2745998, queryString=0x2744c88 "GRANT USAGE ON SCHEMA pg_catalog, public TO PUBLIC;\n", context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, dest=0xd64360 <debugtupDR>, qc=0x7ffcc262d890) at utility.c:1813
#4  0x00000000009bf16e in standard_ProcessUtility (pstmt=0x2745998, queryString=0x2744c88 "GRANT USAGE ON SCHEMA pg_catalog, public TO PUBLIC;\n", readOnlyTree=false, context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, dest=0xd64360 <debugtupDR>, qc=0x7ffcc262d890) at utility.c:977
#5  0x00000000009be69a in ProcessUtility (pstmt=0x2745998, queryString=0x2744c88 "GRANT USAGE ON SCHEMA pg_catalog, public TO PUBLIC;\n", readOnlyTree=false, context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, dest=0xd64360 <debugtupDR>, qc=0x7ffcc262d890) at utility.c:530
#6  0x00000000009bd2db in PortalRunUtility (portal=0x26f2bd8, pstmt=0x2745998, isTopLevel=true, setHoldSnapshot=false, dest=0xd64360 <debugtupDR>, qc=0x7ffcc262d890) at pquery.c:1158
#7  0x00000000009bd535 in PortalRunMulti (portal=0x26f2bd8, isTopLevel=true, setHoldSnapshot=false, dest=0xd64360 <debugtupDR>, altdest=0xd64360 <debugtupDR>, qc=0x7ffcc262d890) at pquery.c:1315
#8  0x00000000009bca6d in PortalRun (portal=0x26f2bd8, count=9223372036854775807, isTopLevel=true, run_once=true, dest=0xd64360 <debugtupDR>, altdest=0xd64360 <debugtupDR>, qc=0x7ffcc262d890) at pquery.c:791
#9  0x00000000009b6533 in exec_simple_query (query_string=0x2744c88 "GRANT USAGE ON SCHEMA pg_catalog, public TO PUBLIC;\n") at postgres.c:1274
#10 0x00000000009babc3 in PostgresMain (dbname=0x2699be0 "template1", username=0x2699350 "mingjie") at postgres.c:4637
#11 0x00000000009ba472 in PostgresSingleUserMain (argc=12, argv=0x2693a50, username=0x2699350 "mingjie") at postgres.c:4096
#12 0x00000000007b821e in main (argc=12, argv=0x2693a50) at main.c:195

到了这里,关于Postgresql源码(114)视图权限授予逻辑的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PostgreSQL 查询数据表、视图信息

    --查询指定数据基表的列信息

    2024年02月12日
    浏览(62)
  • PostgreSQL-视图-03-查询对象依赖关系视图-dba_dependencies

    PostgreSQL查询对象依赖关系视图

    2024年02月15日
    浏览(47)
  • 《PostgreSQL 开发指南》第32篇 物化视图

    物化视图(Materialized View)是 PostgreSQL 提供的一个扩展功能,它是介于视图和表之间的一种对象。 物化视图和视图的最大区别是它不仅存储定义中的查询语句,而且可以像表一样存储数据。物化视图和表的最大区别是它不支持 INSERT、UPDATE、DELETE 以及 MERGE 语句,只能通过刷新

    2024年02月12日
    浏览(37)
  • PostgreSql 逻辑结构

    Database Cluser : 数据库集簇,一套服务器上安装部署完成的一套PostgreSql。在其中可创建数据库(Database)、用户(User)。 User : 数据库用户,用来连接访问数据库,可通过权限管理,控制其访问不同的数据。 Database : 数据库,数据库集簇(Database Cluser)下的逻辑隔离,一个数据

    2024年02月12日
    浏览(32)
  • PostgreSQL逻辑管理结构

    1.数据库逻辑结构介绍 2.数据库基本操作 2.1 创建数据库 参数说明如下。 ·OWNER [=] user_name:用于指定新建的数据库属于哪个用 户,如果不指定,新建的数据库就属于当前执行命令的用户。 ·TEMPLATE [=] template:模板名(从哪个模板创建新数据 库),如果不指定,将使用默认模

    2024年02月06日
    浏览(42)
  • PostgreSQL 逻辑复制模块(一)

    本文主要介绍 PostgreSQL 逻辑复制家族、核心技术、同步过程及同步原理,预知PostgreSQL 逻辑复制社区插件原理与功能、逻辑订阅处理流程解析、适应场景等等,点击PostgreSQL 逻辑复制模块(二)。 流复制 大家都知道Streaming Replication已经成为PostgreSQL的一部分,并且通常用于Po

    2024年02月08日
    浏览(39)
  • postgresql四种逻辑复制的状态

    CreateCheckpoint,或者bgwriter启动时,或者创建logicalreplicationslot时都会调用LogStandbySnapshot 记录一个XLOG_RUNNING_XACTS类型的日志。日志中记录了所有提交的事务的xid(HistoricSnapshot) 当接收端读到 XLOG_RUNNING_XACTS 时,调用SnapBuildProcessRunningXacts开始记录所有看到的日志,但此时只知道提交

    2024年02月14日
    浏览(46)
  • psql: error: connection to server on socket “/var/run/postgresql/.s.PGSQL.5432“ failed: No such file

    当我在linux debian版本安装postgres数据库遇到的问题: 帮我解决成功的方法如下:可以直接复制运行,需要看注释 步骤一: 步骤二: 注意这里的16是我postgres的版本,你要改成你对应的版本数字比如14就改成14,然后出现语言区域我一般默认直接回车 步骤三: 然后就成功了 引

    2024年02月02日
    浏览(46)
  • PostgreSql 用户及权限管理

      PostgreSQL 使用角色的概念管理数据库访问权限。角色是一系列相关权限的集合。为了管理方便,通常把一系列相关的数据库权限赋给一个角色,如果哪个用户需要这些权限,就把角色赋给相应的用户。由于用户也拥有一系列的相关权限,为了简化管理,在 PostgreSQL 中,角

    2024年02月16日
    浏览(54)
  • PostgreSQL16中的新增功能:双向逻辑复制

    在这篇博客中, 我们将深入探讨Postgres 16中引入的一些更高级的新功能 。为了更好地理解这些功能,读者应具备一些Linux、Postgres和SQL的基础知识,因为我们将深入探讨这些新功能并指导如何实现它们。 本博客以 在Ubuntu 23.04上运行的PostgreSQL 16(开发版)为基础进行编写 。首

    2024年01月17日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包