새로운 사용자가 왜 테이블을 만들 수 있습니까?


41

새로 만든 사용자가 데이터베이스에 연결 한 후 테이블을 만들 수있는 이유가 궁금합니다. 하나의 데이터베이스가 있습니다 project2_core.

postgres=# \l
                                          List of databases
     Name      |    Owner     | Encoding  |   Collate   |    Ctype    |       Access privileges       
---------------+--------------+-----------+-------------+-------------+-------------------------------
 postgres      | postgres     | SQL_ASCII | C           | C           | 
 project2_core | atm_project2 | UTF8      | de_DE.UTF-8 | de_DE.UTF-8 | project2=CTc/project2
 template0     | postgres     | SQL_ASCII | C           | C           | =c/postgres                  +
               |              |           |             |             | postgres=CTc/postgres
 template1     | postgres     | SQL_ASCII | C           | C           | =c/postgres                  +
               |              |           |             |             | postgres=CTc/postgres
(5 rows)

여태까지는 그런대로 잘됐다. 이제 사용자를 만듭니다.

postgres=# CREATE ROLE dietrich ENCRYPTED PASSWORD 'md5XXX' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER

괜찮아. 데이터베이스에 연결하려고 할 때 사용자는 그렇게 할 수 없습니다.

$ psql -h localhost -p 5432 -U dietrich -W project2_core
Password for user dietrich: 
psql: FATAL:  permission denied for database "project2_core"
DETAIL:  User does not have CONNECT privilege.

이것이 내가 기대 한 것입니다. 이제 이상한 것들이 시작됩니다. 사용자에게 권한을 부여합니다 CONNECT.

postgres=# GRANT CONNECT ON DATABASE project2_core TO dietrich;
GRANT
postgres=# \l
                                          List of databases
     Name      |    Owner     | Encoding  |   Collate   |    Ctype    |       Access privileges       
---------------+--------------+-----------+-------------+-------------+-------------------------------
 postgres      | postgres     | SQL_ASCII | C           | C           | 
 project2_core | atm_project2 | UTF8      | de_DE.UTF-8 | de_DE.UTF-8 | project2=CTc/project2+
               |              |           |             |             | dietrich=c/project2
 template0     | postgres     | SQL_ASCII | C           | C           | =c/postgres                  +
               |              |           |             |             | postgres=CTc/postgres
 template1     | postgres     | SQL_ASCII | C           | C           | =c/postgres                  +
               |              |           |             |             | postgres=CTc/postgres
(5 rows)

추가 권한이 없으면 사용자는 테이블을 만들 수 있습니다.

$ psql -h localhost -p 5432 -U dietrich -W project2_core
Password for user dietrich: 
psql (9.2.3)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.

project2_core=> create table adsf ();
CREATE TABLE
project2_core=> \d
        List of relations
 Schema | Name | Type  |  Owner   
--------+------+-------+----------
 public | adsf | table | dietrich
(1 row)

GRANT USAGE스키마와 GRANT SELECT테이블에서 명시 적으로 수행하기 전에 사용자가 아무것도 할 수 없다고 기대했을 것 입니다.

내 실수는 어디입니까? 내가 무엇을 잘못하고 있지? 원하는 것을 어떻게 달성 할 수 있습니까 (새 사용자가 적절한 권한을 명시 적으로 부여하기 전에는 아무 것도 할 수 없음)

나는 길을 잃었고, 당신의 도움은 크게 감사합니다 :)

편집 @ daniel-verite의 조언에 따라 데이터베이스를 만든 직후 모든 내용을 수정 했습니다. 사용자 dietrich 는 더 이상 테이블을 만들 수 없습니다. 좋은. 그러나 : 데이터베이스 소유자 인 project2도 테이블을 작성할 수 없습니다. 심지어 실행 한 후 GRANT ALL PRIVILEGES ON DATABASE project2_core TO project2GRANT ALL PRIVILEGES ON SCHEMA public TO project2, 나는 오류 얻을 에는 스키마에서 만들 수를 선택하지 않았습니다 : ERROR를 , 내가 특별히하려고 할 때 CREATE TABLE public.WHATEVER ();, 나는 얻을 ERROR : 스키마 공개 거부 권한을 . 내가 무엇을 잘못하고 있지?

답변:


38

새 데이터베이스를 만들면 모든 역할이 public스키마 에서 개체를 만들 수 있습니다 . 이 가능성을 제거하기 위해 데이터베이스 작성 직후에 발행 할 수 있습니다.

REVOKE ALL ON schema public FROM public;

편집 : 위의 명령 후에 수퍼 유저 만 public스키마 내에 새 객체를 만들 수 있지만 실용적이지 않습니다. 수퍼 유저 foo_user가 아닌 사용자 에게이 권한이 부여되어야 한다고 가정하면 다음을 수행해야합니다.

GRANT ALL ON schema public TO foo_user;

ALL스키마의 의미 를 알기 위해서는 doc에서 GRANT를 참조해야합니다 . 스키마의 경우 CREATE와 의미 USAGE합니다.

반면에 and 및 GRANT ALL PRIVILEGES ON DATABASE...을 부여 하지만 이 컨텍스트에서는 영구 테이블이 아닌 스키마와 관련됩니다.CONNECTCREATETEMPCREATE

이 오류와 관련하여 : ERROR: no schema has been selected to create in은 (와 create table foo(...)) 스키마 한정없이 객체를 만들려고하지만의 스키마에서 객체 를 만들 수있는 권한이없는 경우에 발생합니다 search_path.


작동 :) 그러나 나는 여전히 이해하지 못한다 : 나는 이미 시도했다 REVOKE ALL ON DATABASE project2_core FROM PUBLIC;. 왜 이것이 효과가 없었습니까?
andreas-h

hh. 이제 데이터베이스 소유자는 CREATE TABLE더 이상 허용되지 않습니다 . 위의 편집 내용을 참조하십시오.
andreas-h

@ andreas-h : 자세한 내용으로 답을 편집 함
Daniel Vérité

오류와 관련하여 질문과 REVOKE 명령을 순서대로 실행하면 쉽게 재현 할 수 있습니다. :)
dezso

@ DanielVérité 나는 당신을 보완하기 위해 새로운 답변으로 이것의 뒤에 개념에 대해 자세히 설명했습니다. 위생 검사가 중요합니다.
Craig Ringer

19

여기서 이해해야 할 중요한 일이 있다는 것입니다 권한이 heirachical하지 되며 객체를 포함에서 상속되지 않습니다 . ALL이 개체에 대한 모든 권한이 없는 이 개체에 대한 모든 권한과 모든 포함 된 개체 .

ALL데이터베이스 를 부여하면을 부여하게 됩니다 CREATE, CONNECT, TEMP. 이들은 데이터베이스 객체 자체에 대한 조치입니다.

  • CONNECT: DB에 연결
  • CREATE: 크리에이트 스키마 ( 하지 테이블)
  • TEMP: 임시 테이블을 포함하여 (이에 국한되지는 않음) 임시 객체 생성

이제 기본적으로 각 PostgreSQL 데이터베이스 public에는 데이터베이스가 생성 될 때 생성 되는 스키마가 있습니다. 이 스키마는 모든 사용자 public가 내재적으로 구성원 인 역할에 대한 모든 권한을 갖습니다 . 스키마의 경우 다음을 ALL의미합니다 CREATE, USAGE.

  • CREATE:이 스키마 내에서 오브젝트 (테이블 포함) 작성
  • USAGE: 스키마에 객체를 나열하고 권한이 허용되는 경우 액세스

테이블과 같은 오브젝트를 작성하기 위해 스키마를 지정하지 않으면 데이터베이스 엔진은을 사용하고 search_path기본적으로 public스키마가 맨 앞에 search_path있으므로 테이블이 작성됩니다. 모든 사람은 public기본적으로 권한이 있으므로 생성이 허용됩니다. 데이터베이스에 대한 사용자의 권한은이 시점에서 관련이 없습니다. 사용자가 데이터베이스 개체 자체에 대해 아무것도하지 않고 스키마 자체 만 수행하기 때문입니다.

스키마는 모든 사용자가 기본적으로 테이블을 작성할 수 있도록 허용 CONNECT하므로 데이터베이스에 권한 부여 이외의 권한을 사용자에게 부여하지 않아도 public됩니다. 다니엘은 원한다면 그 권리를 철회하는 방법을 이미 설명했다.

모든 권한을 명시 적으로 위임하려면 공개에서 모든 권한을 취소하거나 공개 스키마를 삭제하십시오. 원하는 경우이 변경 사항을 적용하여 새 템플릿 데이터베이스를 만들 수 있습니다. 또는에 적용 할 수 template1있지만 public존재하고 쓸 수 있다고 가정하는 많은 타사 코드가 손상 될 수 있습니다 .


파일 시스템 비유를 보면 더 의미가있을 수 있습니다.

디렉토리 구조가있는 경우 (현재 사용자에게 적용되는 모드 만 표시하도록 단순화 된 모드) :

/dir1           mode=r-x
/dir1/dir2      mode=rwx

/dir1쓰기 권한이 없기 때문에에 아무 것도 만들 수 없습니다 . 따라서 touch /dir1/somefile권한 거부 오류가 발생합니다.

그러나 내부를 살펴보고 포함 된 파일 및 디렉토리에 액세스 할 있는 권한 있습니다 . 에 대한 쓰기 권한이 있습니다 . 에 대한 쓰기 권한이 없어도 성공할 것 입니다./dir1/dir1/dir2dir2touch /dir1/dir2/somefiledir1

데이터베이스와 스키마도 마찬가지입니다.


7

새 사용자 만 테이블을 작성하지 못하게하려면 다음 명령을 실행해야합니다.

REVOKE CREATE ON SCHEMA public FROM public;

당신이 경우 REVOKE ALL(다른 답변이 제안하는대로), 당신은 또한 않아도 사용자를 방지 할 USAGE권한을. USAGE즉, 사용자는 자신에게 할당 된 권한을 사용할 수 있으므로 해당 권한을 제거하면 사용자가 액세스 할 수있는 테이블을 나열하거나 액세스 할 수 없습니다.

또는 REVOKE CREATE특정 사용자를 위해 다음을 수행 할 수도 있습니다 .

REVOKE CREATE ON schema public FROM myuser;

PostgreSQL로 읽기 전용 사용자를 만드는 방법 도 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.