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

news2024/11/26 8:30:25

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);

结果
在这里插入图片描述
查看namespace视图:
在这里插入图片描述
这种情况下,添加两种权限都可以访问函数:

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

在这里插入图片描述

这里我们看到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授权:
在这里插入图片描述

(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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1048273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

@SpringBootApplication注解的理解——如何排除自动装配 分布式情况下如何自动加载 nacos是怎么被发现的

前言 spring作为主流的 Java Web 开发的开源框架&#xff0c;是Java 世界最为成功的框架&#xff0c;持续不断深入认识spring框架是Java程序员不变的追求。 本篇博客介绍SpringBootApplicant注解的自动加载相关内容 其他相关的Spring博客文章列表如下&#xff1a; Spring基…

ubuntu20.04 jammy 安装ros2

ubunut22.04 jammy&#xff08;5.15&#xff09; ros2版本: humble 安装参考&#xff1a; Ubuntu (Debian packages) — ROS 2 Documentation: Humble documentationl 按照官方给的操作指南进行操作即可&#xff0c;到安装软件包的时候&#xff0c;若只为开发&#xff0…

C++中实现雪花算法来在秒级以及毫秒及时间内生成唯一id

1、雪花算法原理 雪花算法&#xff08;Snowflake Algorithm&#xff09;是一种用于生成唯一ID的算法&#xff0c;通常用于分布式系统中&#xff0c;以确保生成的ID在整个分布式系统中具有唯一性。它的名称来源于雪花的形状&#xff0c;因为生成的ID通常是64位的整数&#xff0…

【小白专属02】SpringBoot集成MybatisPlus

目录 前言 一、添加依赖项 二、配置数据库连接信息 三、数据库创建表 四、创建实体表 五、编写Mapper接口 六、功能测试 前言 上节回顾 上一节我们对SpringBoot框架进行了搭建&#xff0c;其实按照流程走问题不大。最主要的部分我们把下载SpringBoot demo的网址换成了…

编程每日一练(多语言实现)基础篇:百元买百鸡

文章目录 一、实例描述二、技术要点三、代码实现3.1 C 语言实现3.2 Python 语言实现3.3 Java 语言实现3.4 JavaScript 语言实现 一、实例描述 中国古代数学家张丘建在他的 《算经》 中提出了一个著名的 "百钱买百鸡问题"&#xff0c; 鸡翁一&#xff0c;值钱五&…

重新定义旅行,AnyGo for Mac让你畅享虚拟GPS位置的无限可能!

旅行是一种令人兴奋和激动人心的体验&#xff0c;而现在有了AnyGo for Mac这款强大的虚拟GPS位置工具&#xff0c;你将能够重新定义旅行&#xff0c;尽情探索全新的地理环境和体验&#xff01; AnyGo for Mac为你带来了全新的旅行方式。无需离开家门&#xff0c;你就可以通过模…

基于php的物流信息公共平台设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于php的物流信息公共平…

面对海量数据挑战,企业怎样进行数据处理?

海量数据给企业带来机遇的同时&#xff0c;也给企业带来了一定的挑战。怎样高效处理海量数据也是成为了企业面临的重要问题。 一&#xff1a;数据采集 数据采集是数据处理的第一步。企业需要进行数据采集&#xff0c;但是要保证数据的准确性以及安全性。同时需要注意&#xf…

PgSQL-向量数据库插件-lantern

PgSQL-向量数据库插件-lantern 即pgvector、pg_embedding 后又一向量数据库扩展Lantern问世了。当然也为向量列提供了hnsw索引以加速ORDER BY... LIMIT查询。Lantern使用usearch实现hnsw。 使用方法 保留了标准PgSQL接口&#xff0c;兼容其生态工具。首先需要安装该插件&#x…

服务器基础知识:raid卡有什么优势?

当今直播电商、短视频呈现热火朝天的趋势&#xff0c;是近两年的商业热门议题&#xff0c;以淘宝天猫、拼多多、抖音、小红书、视频号为代表的平台数据量呈现爆炸性的增长。据IDC预测&#xff0c;2025年全球数据总量将增至175ZB&#xff08;1ZB1万亿GB&#xff09;&#xff0c;…

数字电视码流分析仪通用规范

声明 本文是学习GB-T 26274-2010 数字电视码流分析仪通用规范. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了数字电视码流分析仪(以下简称码流分析仪)的技术要求、试验方法、检验规则及标 志、包装、运输、贮存等。 本标准适…

C++代码示例:组合数简单生成工具

文章目录 前言代码仓库内容代码&#xff08;有详细注释&#xff09;编译和运行命令结果总结参考资料作者的话 前言 C代码示例&#xff1a;组合数简单生成工具。 代码仓库 yezhening/Programming-examples: 编程实例 (github.com)Programming-examples: 编程实例 (gitee.com) …

echarts 折线组件

echarts 折线组件 <template><div class"lineChartsTemplate" :id"chartsId"></div> </template><script> export default {name: "lineChartsTemplate",components: {},props: {xData: {type: Array,default: ()…

个人在运行python代码过程中的坑230928

0关于GPT和百度使用的区别 就我个人使用经验而言&#xff0c;我觉得百度、知乎、csdn更是直接奔着解决问题去的&#xff0c;直接方便快捷&#xff0c;不需要你再对信息进行加工&#xff0c;可以直接找到经验。 GPT则是需要我们给他一个输入&#xff0c;给他一个提示&#xff0…

提高网申通过率的秘籍,校园招聘之春招秋招都有效

提高网申通过率的秘籍&#xff01;校园招聘&#xff08;校招-春招-秋招&#xff09;都有效。 网申&#xff0c;指的是在网上申请招聘企业的岗位&#xff0c;每年春招秋招&#xff0c;都是毕业生们的重点大事&#xff0c;如何把握好机会&#xff0c;就在于各个环节的细节之处&…

联盟 | 彩漩 X HelpLook,AI技术赋能企业效率提升

近日&#xff0c;AI 驱动的 PPT 协作分享平台「 彩漩 」与 AI 知识库搭建工具「 HelpLook」&#xff0c;携手为用户工作流注入更多智能和创造力&#xff0c;全面拥抱 AIGC 时代带来的机遇&#xff0c;致力于提供前沿的智能解决方案。 彩 漩 彩漩是一个以 AI 技术为基础、贯彻 …

排雷Jmeter分布式性能测试,为什么要用分布式?这些易错点特别危险!

01、为什么要使用分布式 做性能测试时&#xff0c;如果被测系统性能比较好&#xff0c;或者系统项目比较大&#xff0c;那么一般都会要求能支持比较高的并发用户数。而我们做性能测试时&#xff0c;发起请求的机器&#xff0c;硬件资源是一定的&#xff0c;不可能配置无限大。…

基于Linux socket聊天室-多线程服务器模型(01)

​前言 socket在实际系统程序开发当中&#xff0c;应用非常广泛&#xff0c;也非常重要。实际应用中服务器经常需要支持多个客户端连接&#xff0c;实现高并发服务器模型显得尤为重要。高并发服务器从简单的循环服务器模型处理少量网络并发请求&#xff0c;演进到解决C10K&…

如何爬取动态加载的图片数据

百度图片是一个非常受欢迎的图片分享平台&#xff0c;其中包含了大量的图片资源。然而&#xff0c;百度图片使用了动态加载技术&#xff0c;使得Python爬虫在获取百度动态加载图片时面临一定的难度。百度图片使用了动态加载技术&#xff0c;这意味着图片并不是一次性全部加载出…

2.安装conda python库

centos 显卡驱动、cuda、cudnn安装参考地址&#xff1a; 1.centos7 安装显卡驱动、cuda、cudnn-CSDN博客 3.Cenots Swin-Transformer-Object-Detection环境配置-CSDN博客 1.安装anaconda 步骤1&#xff1a;下载 下载地址&#xff1a; Index of / 下载版本 步骤2&#xf…