From ff27fcfa0affe16405e801ed55fed10e7bc75216 Mon Sep 17 00:00:00 2001 From: Stephen Frost Date: Fri, 26 Sep 2014 12:46:26 -0400 Subject: Fix relcache for policies, and doc updates Andres pointed out that there was an extra ';' in equalPolicies, which made me realize that my prior testing with CLOBBER_CACHE_ALWAYS was insufficient (it didn't always catch the issue, just most of the time). Thanks to that, a different issue was discovered, specifically in equalRSDescs. This change corrects eqaulRSDescs to return 'true' once all policies have been confirmed logically identical. After stepping through both functions to ensure correct behavior, I ran this for about 12 hours of CLOBBER_CACHE_ALWAYS runs of the regression tests with no failures. In addition, correct a few typos in the documentation which were pointed out by Thom Brown (thanks!) and improve the policy documentation further by adding a flushed out usage example based on a unix passwd file. Lastly, clean up a few comments in the regression tests and pg_dump.h. --- doc/src/sgml/ddl.sgml | 111 +++++++++++++++++++++++++++++++++++- doc/src/sgml/ref/alter_policy.sgml | 2 +- doc/src/sgml/ref/create_policy.sgml | 6 +- 3 files changed, 114 insertions(+), 5 deletions(-) (limited to 'doc/src') diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index 98e897aeb6c..f9dc151a0cc 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -1615,7 +1615,7 @@ REVOKE ALL ON accounts FROM PUBLIC; and foreign key references, will bypass row security to ensure that data integrity is maintained. Care must be taken when developing schemas and row level policies to avoid a "covert channel" leak of - information through these referntial integrity checks. + information through these referential integrity checks. @@ -1674,6 +1674,115 @@ CREATE POLICY user_policy ON users normal privileges system. + + Below is a larger example of how this feature can be used in + production environments, based on a unix password file. + + + +-- Simple passwd-file based example +CREATE TABLE passwd ( + username text UNIQUE NOT NULL, + pwhash text, + uid int PRIMARY KEY, + gid int NOT NULL, + real_name text NOT NULL, + home_phone text, + extra_info text, + home_dir text NOT NULL, + shell text NOT NULL +); + +CREATE ROLE admin; -- Administrator +CREATE ROLE bob; -- Normal user +CREATE ROLE alice; -- Normal user + +-- Populate the table +INSERT INTO passwd VALUES + ('admin','xxx',0,0,'Admin','111-222-3333',null,'/root','/bin/dash'); +INSERT INTO passwd VALUES + ('bob','xxx',1,1,'Bob','123-456-7890',null,'/home/bob','/bin/zsh'); +INSERT INTO passwd VALUES + ('alice','xxx',2,1,'Alice','098-765-4321',null,'/home/alice','/bin/zsh'); + +-- Be sure to enable row level security on the table +ALTER TABLE passwd ENABLE ROW LEVEL SECURITY; + +-- Create policies +-- Administrator can see all rows and add any rows +CREATE POLICY admin_all ON passwd TO admin USING (true) WITH CHECK (true); +-- Normal users can view all rows +CREATE POLICY all_view ON passwd FOR SELECT USING (true); +-- Normal users can update their own records, but +-- limit which shells a normal user is allowed to set +CREATE POLICY user_mod ON passwd FOR UPDATE + USING (current_user = username) + WITH CHECK ( + current_user = username AND + shell IN ('/bin/bash','/bin/sh','/bin/dash','/bin/zsh','/bin/tcsh') + ); + +-- Allow admin all normal rights +GRANT SELECT, INSERT, UPDATE, DELETE ON passwd TO admin; +-- Users only get select access on public columns +GRANT SELECT + (username, uid, gid, real_name, home_phone, extra_info, home_dir, shell) + ON passwd TO public; +-- Allow users to update certain columns +GRANT UPDATE + (pwhash, real_name, home_phone, extra_info, shell) + ON passwd TO public; + + + + As with any security settings, it's important to test and ensure that + the system is behaving as expected. Using the example above, this + demonstrates that the permission system is working properly. + + + +-- admin can view all rows and fields +postgres=> set role admin; +SET +postgres=> table passwd; + username | pwhash | uid | gid | real_name | home_phone | extra_info | home_dir | shell +----------+--------+-----+-----+-----------+--------------+------------+-------------+----------- + admin | xxx | 0 | 0 | Admin | 111-222-3333 | | /root | /bin/dash + bob | xxx | 1 | 1 | Bob | 123-456-7890 | | /home/bob | /bin/zsh + alice | xxx | 2 | 1 | Alice | 098-765-4321 | | /home/alice | /bin/zsh +(3 rows) + +-- Test what Alice is able to do +postgres=> set role alice; +SET +postgres=> table passwd; +ERROR: permission denied for relation passwd +postgres=> select username,real_name,home_phone,extra_info,home_dir,shell from passwd; + username | real_name | home_phone | extra_info | home_dir | shell +----------+-----------+--------------+------------+-------------+----------- + admin | Admin | 111-222-3333 | | /root | /bin/dash + bob | Bob | 123-456-7890 | | /home/bob | /bin/zsh + alice | Alice | 098-765-4321 | | /home/alice | /bin/zsh +(3 rows) + +postgres=> update passwd set username = 'joe'; +ERROR: permission denied for relation passwd +-- Allowed to change her own real_name, but no others +postgres=> update passwd set real_name = 'Alice Doe'; +UPDATE 1 +postgres=> update passwd set real_name = 'John Doe' where username = 'admin'; +UPDATE 0 +postgres=> update passwd set shell = '/bin/xx'; +ERROR: new row violates WITH CHECK OPTION for "passwd" +postgres=> delete from passwd; +ERROR: permission denied for relation passwd +postgres=> insert into passwd (username) values ('xxx'); +ERROR: permission denied for relation passwd +-- Alice can change her own password +postgres=> update passwd set pwhash = 'abc'; +UPDATE 1 + + diff --git a/doc/src/sgml/ref/alter_policy.sgml b/doc/src/sgml/ref/alter_policy.sgml index 37615fcab5d..ab717f31c51 100644 --- a/doc/src/sgml/ref/alter_policy.sgml +++ b/doc/src/sgml/ref/alter_policy.sgml @@ -94,7 +94,7 @@ ALTER POLICY name ON diff --git a/doc/src/sgml/ref/create_policy.sgml b/doc/src/sgml/ref/create_policy.sgml index 3c5bdc69cdc..eff062c114f 100644 --- a/doc/src/sgml/ref/create_policy.sgml +++ b/doc/src/sgml/ref/create_policy.sgml @@ -81,7 +81,7 @@ CREATE POLICY name ON @@ -218,7 +218,7 @@ CREATE POLICY name ON SELECT policy will be returned, even if other records exist in the relation. The SELECT policy only accepts the USING expression - as it only ever applies in cases where records are being retrived from + as it only ever applies in cases where records are being retrieved from the relation. @@ -272,7 +272,7 @@ CREATE POLICY name ON DELETE, and rows which are not visible through the SELECT policy may be deleted if they pass the DELETE USING policy. The - DELETE policy only accept the USING expression as + DELETE policy only accepts the USING expression as it only ever applies in cases where records are being extracted from the relation for deletion. -- cgit v1.2.3