DNA遗传哲学? - 数据库里schema应该属于谁?

标签

PostgreSQL , schema , template


背景

混沌初开

安装好PostgreSQL软件后,需要调用initdb,或者pg_ctl初始化数据库实例,初始化数据库实例时,通过bki接口(脚本),建立数据库元数据。

初始化后,数据库有了数据文件、日志文件、控制文件、CLOG、WAL等一系列数据库的文件。

同时会创建模板库template0, template1, 以及数据库postgres。

模板库内,默认会有一个public schema,owner是谁?是初始化时数据库的超级用户。例如初始化数据库集群时,超级用户为postgres,那么模板库属于postgres,模板库里的schema(public)也属于postgres。

基因传递

接下来,用户可以使用PostgreSQL数据库从模板库创建更多数据块。

通过模板库创建的新的数据库,里面也会带有模板库所有的一切,包括schmea,这些对象属于谁呢?

owner是postgres还是新建数据库的用户(或者指定的数据库owner呢?)

目前,不管你用什么用户新建数据库,新数据库的权限,OWNER都会和模板库保持原样。

例如,template1的public属于postgres用户

template1=# \dn
  List of schemas
  Name  |  Owner
--------+----------
 public | postgres
(1 row)

使用另一个用户,创建一个数据库,并将新的数据库的owner设置为新用户。但是这个新数据库内的public schema owner依旧是postgres。

template1=# create role digoal superuser login;
CREATE ROLE
template1=# \c postgres
You are now connected to database "postgres" as user "test".
postgres=# create database db1 with template template1 owner digoal;
CREATE DATABASE
postgres=# \c db1
You are now connected to database "db1" as user "test".
db1=# \dn
  List of schemas
  Name  |  Owner
--------+----------
 public | postgres
(1 row)

为什么要基因?

假设不继承模板库的权限,而是将schema或者对象的权限或者OWNER直接转嫁给数据库的owner,会有什么风险呢?

风险如下:

一个有create database权限的普通用户,它可以利用这种方法,窥探其他数据库的它看不到的内容。

创建一个普通用户,带有create database权限
db1=# create role r1 createdb login;
CREATE ROLE  

连接到template1库,使用超级用户postgres创建一个测试表和测试数据
template1=> \c template1 postgres
You are now connected to database "template1" as user "postgres".
template1=# create table test(id int);
CREATE TABLE
template1=# insert into test values (1);
INSERT 0 1  

普通用户无法访问这张测试表
template1=# \c template1 r1
You are now connected to database "template1" as user "r1".
template1=> select * from test;
ERROR:  permission denied for relation test
以template1为模板,新建一个数据库,OWNER为自己。
template1=> \c postgres r1
You are now connected to database "postgres" as user "r1".
postgres=> create database db3 with template template1 owner r1;
CREATE DATABASE  

由于权限继承,所以新建的数据库,OWENR依然没有权限查询这张表
postgres=> \c db3 r1
You are now connected to database "db3" as user "r1".
db3=> \dn
  List of schemas
  Name  |  Owner
--------+----------
 public | postgres
(1 row)
db3=> select * from test;
ERROR:  permission denied for relation test

PostgreSQL 权限继承的方法充分考虑了这一点,避免了安全风险问题。

有什么更好的方法呢?

实际上用户的想法和PostgreSQL实施的安全防护不一致,例如用户创建了一个模板库,并希望其他人通过这个模板库创建的数据库,里面的对象OWNER也改成建库的OWNER。

create database db1 with template template1 owner newrole;  

用户也许希望db1里面包含的模板库中的schema public也转给newrole

如何改变现状呢?

1. 既然owner改变不了,那么可以使用权限来控制,模板建好后,把模板中的对象权限赋予给public角色。

\c template1 postgres  

grant all on schema public to public;

2. 还有更人性化的方法,例如新增SQL语法:

给schema,table,view等对象增加一个权限选项(允许用户选择),作为模板创建时,OWNER是否跟随数据库的owner。

3. 当以template0为模板创建数据库时,建议public的owner可以改为数据库的owner,同样需要社区代码层面的支持。

4. 当用户新建了数据库后,再使用超级用户,将新库的public schema赋予给新库的owner.

\c new_db superuser

alter schema public owner to db_user;

注意,schema owner有这个schema的绝对管理权限,包括删除其他人在这个schema创建的对象。

所以千万不要把自己的对象创建到别人的schema下面,那很危险。

《PostgreSQL 逻辑结构 和 权限体系 介绍》

参考

https://www.postgresql.org/docs/9.6/static/sql-createdatabase.html

时间: 2024-10-29 02:49:30

DNA遗传哲学? - 数据库里schema应该属于谁?的相关文章

net-登陆密码错误 数据库里的用户和密码明明都是对的 怎么破怎么破 跪求大神帮助

问题描述 登陆密码错误 数据库里的用户和密码明明都是对的 怎么破怎么破 跪求大神帮助 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using Web.Bll; using Web.Mod; public partial class _Default : System

asp.net-登陆密码错误 数据库里的用户和密码明明都是对的 怎么破怎么破 跪求大神帮助

问题描述 登陆密码错误 数据库里的用户和密码明明都是对的 怎么破怎么破 跪求大神帮助 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="login.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&qu

三种东西永远不要放到数据库里

改进你的系统的最好的方法是先避免做"蠢事". 我并不是说你或你开发的东西"蠢",只是有些决定很容易被人们忽略掉其暗含的牵连, 认识不到这样做对系统维护尤其是系统升级带来多大的麻烦. 作为一个顾问,像这样的事情我到处都能见到,我还从来没有见过做出这样的决定的人有过好的结果的. 图片,文件,二进制数据 既然数据库支持BLOB类型的数据,把文件塞进BLOB字段里一定没有错了!?错,不是这样的! 别的先不提,在很多数据库语言里,处理大字段都不是很容易. 把文件存放在数据库里

将图片储存在MySQL数据库里

如果你想把二进制的数据,比如说图片文件和HTML文件,直接保存在你的MySQL数据库,那么这篇文章就是为你而写的!我将告诉你怎样通过HTML表单来储存这些文件,怎样访问和使用这些文件. 本文概述: .在mysql中建立一个新的数据库 .一个怎样储存文件的例子程序 .一个怎样访问文件的例子程序 在mysql中建立一个新的database 首先,你必须在你的mysql中建立一个新的数据库,我们将会把那些二进制文件储存在这个数据库里.在例子中我会使用下列结构,为了建立数据库, 你必须做下列步骤: .进

详解:——如何将图片储存在数据库里

如果你想把二进制的数据,比如说图片文件和HTML文件,直接保存在你的MySQL数据库,那么这篇文章就是为你而写的!我将告诉你怎样通过HTML表单来储存这些文件,怎样访问和使用这些文件. 本文概述: .在mysql中建立一个新的数据库 .一个怎样储存文件的例子程序 .一个怎样访问文件的例子程序 在mysql中建立一个新的database 首先,你必须在你的mysql中建立一个新的数据库,我们将会把那些二进制文件储存在这个数据库里.在例子中我会使用下列结构,为了建立数据库, 你必须做下列步骤: .进

如何把视频文件直接存储到mysql数据库里

测试一下如何把视频文件存放在mysql数据里,当然不建议直接存放,因为迁移会很麻烦而且容易出现问题,以下只是测试功能,导入jpg.png等图片类似. 创建一个测试表test,使用longblob或者mediumblob CREATE TABLE test (id INTEGER NOT NULL PRIMARY KEY,name VARCHAR (20),movie LONGBLOB); 然后把视频文件导入 INSERT INTO test VALUES(1, 'titanic', LOAD_F

Asp.net将数据库里的记录转换成json

在前面我已经写了asp的版本,最近一个项目中正好需要用json来填充下拉框,所以写了一个asp.net的将数据库里的记录转换成json,代码如下: 以下是引用片段: using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; namespace OTC.Utility ...{ public sealed class JSONH

servlet-求助啊怎么将数据库里读出的价格gprice显示到这个购物车的jsp页面中

问题描述 求助啊怎么将数据库里读出的价格gprice显示到这个购物车的jsp页面中 这是我的代码,但是不会修改价格那个label,应该将我自己数据库的数据怎么贴进去,当我点击+或者-来选择数量的时候,后面的价格会跟着变,总价也会跟着变呢 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@page import="Db.Db&q

统计图-怎样把数据库里的数据用图表显示在手机上

问题描述 怎样把数据库里的数据用图表显示在手机上 我们公司有一些业务数据,希望能够通过简单一点的实现方式,对数据进行汇总统计,然后用图表显示出来,最好在手机上也可以查看.想问一下需要做些什么?实现起来难不难? 解决方案 最简单的就是直接看网页,第二种是做一个APP 解决方案二: echarts用的canvas绘图,移动端浏览器主流浏览器都支持canvas 解决方案三: 这种当然是通过web页面了,服务器提供.然后用各种图标控件,比如百度的echarts可以很好的画出各种图形.客户端只要有浏览器就