Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jeafZ-0000SV-N0 for pgsql-admin@arkaria.postgresql.org; Fri, 29 May 2020 08:47:13 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jeafV-0005l3-Bx for pgsql-admin@arkaria.postgresql.org; Fri, 29 May 2020 08:47:09 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jeafU-0005kv-Mb for pgsql-admin@lists.postgresql.org; Fri, 29 May 2020 08:47:08 +0000 Received: from mailgw99.suva.ch ([195.65.221.20]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jeafQ-0006gE-QY for pgsql-admin@lists.postgresql.org; Fri, 29 May 2020 08:47:07 +0000 From: "Rainer Floegel (Suva)" To: "'pgsql-admin@lists.postgresql.org'" Subject: Policy function not working (IN parameter not passed) Thread-Topic: Policy function not working (IN parameter not passed) Thread-Index: AdY1lTx0uUTWN390TDK9dU9RQg1GLg== Date: Fri, 29 May 2020 08:47:00 +0000 Message-ID: <7ed1216700e24d76aebe2ff59089e775@suva.ch> Accept-Language: en-US, de-CH Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.93.103.200] X-SM-outgoing: yes MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg="sha-256"; boundary="----5E305EE44433C86C92E7F6EA7A950678" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is an S/MIME signed message ------5E305EE44433C86C92E7F6EA7A950678 Content-Type: multipart/alternative; boundary="_000_7ed1216700e24d76aebe2ff59089e775suvach_" MIME-version: 1.0 --_000_7ed1216700e24d76aebe2ff59089e775suvach_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hello alltogether, I'm pretty much a newbie to Postgresql having spent the last 20 years almost exclusively with Oracle. When trying to set up row level policy in Postgres, got stuck with the issue mentioned at the end of this post. The testcase provided is reduced as much as possible in order not to distract from the issue. Tests were performed in PG 12.2 and 12.3. The test PG Cluster version 12.3 was installed from scratch. Yet, same outcome as in 12.2 -- as postgres create database db1; create user db1_owner password 'db1_owner'; alter database db1 owner to db1_owner; grant all privileges on database db1 to db1_owner; -- as db1_owner in db1 create schema policy_test; -- drop table policy_test.partners; create table policy_test.partners(business_partner text); insert into policy_test.partners ( business_partner) values ('125210000'); insert into policy_test.partners ( business_partner) values ('125210001'); -- alter table policy_test.partners disable row level security; alter table policy_test.partners enable row level security; -- drop function policy_test.get_partners(text); create or replace function policy_test.get_partners(text) returns boolean as $$ declare is_true boolean :=3D FALSE; the_count integer :=3D 0; begin select count(*) into the_count from policy_test.partners a where a.business_partner =3D '125210000' and a.business_partner =3D $1; if the_count =3D 1 then is_true :=3D TRUE; end if; return is_true; end; $$ language plpgsql; -- drop policy test_partner_policy on policy_test.partners; create policy test_partner_policy on policy_test.partners using (policy_test.get_partners(business_partner)); -- as postgres create pol_ex user; create user pol_ex password 'pol_ex'; -- as db1_owner in db1 grant usage on schema policy_test to pol_ex; grant select on policy_test.partners to pol_ex; psql -U pol_ex -d db1 -- connect as pol_ex (ex here stands for "external" user) select * from policy_test.partners; Above select throws numerous lines shown underneath; sometimes in between t= he echoed SQL error message max_stack_depth exceeded occurs. Beyond that no other error m= essages appear. Whatever I tried the function does not accept / resolve the business_partne= r argument. Is there a special way of indicating that this argument should be the table= s' current row attribute? Many examples on the Internet just pass the argument the way I tried. Tried with prefixing scheme / table name to the argument, explict argument = name instead of $ notation, returning table of business_partners instead of boolean and so on, no avail= . Granting execute on the policy function to pol_ex did not help either. I suspect a very basic issue due to my inexperience with Postgres. If anyone of the seasoned Postgres Admins quickly can see what I did wrong,= I'd be grateful for a hint. Thank you very much Rainer Floegel -- "Output" when running select * from policy_test.partners; (as pol_ex use= r) SQL statement "select count(*) from policy_test.partners a where a.business_partner =3D '125210000' and a.business_partner =3D $1" PL/pgSQL function policy_test.get_partners(text) line 9 at SQL statement SQL statement "select count(*) from policy_test.partners a where a.business_partner =3D '125210000' and a.business_partner =3D $1" PL/pgSQL function policy_test.get_partners(text) line 9 at SQL statement and so on [HTML tutorial] Coronavirus Informationen f?r unsere Kunden Informations actuelles destin?es ? nos clients Informazioni aggiornate per i nostri clienti www.suva.ch/covid-19 ________________________________ Disclaimer: Diese Nachricht und ihr eventuell angeh?ngte Dateien sind nur f?r den Adres= saten bestimmt. Sie kann vertrauliche oder gesetzlich gesch?tzte Daten oder= Informationen beinhalten. Falls Sie diese Nachricht irrt?mlich erreicht ha= t, bitten wir Sie h?flich, diese unter Ausschluss jeglicher Reproduktion zu= l?schen und die absendende Person zu benachrichtigen. Danke f?r Ihre Hilfe= . This message and any attached files are for the sole use of the recipient n= amed above. It may contain confidential or legally protected data or inform= ation. If you have received this message in error, please delete it without= making any copies whatsoever and notify the sender. Thank you for your ass= istance. --_000_7ed1216700e24d76aebe2ff59089e775suvach_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Hello alltogether,

 

I'm pretty much a newbie to Postgresql having spent the la= st 20 years

almost exclusively with Oracle. When trying to set up row = level policy

in Postgres, got stuck with the issue mentioned at the end= of this post.

 

The testcase provided is reduced as much as possible in or= der not to

distract from the issue.

 

 

Tests were performed in PG 12.2 and 12.3.

The test PG Cluster version 12.3 was installed from scratc= h.

Yet, same outcome as in 12.2

 

 

-- as postgres

 

create database db1;

 

create user db1_owner password 'db1_owner';

 

alter database db1 owner to db1_owner;

 

 

grant all privileges on database db1 to db1_owner;

 

 

 

 

 

-- as db1_owner in db1

 

create schema policy_test;

 

 

-- drop table policy_test.partners;

 

create table policy_test.partners(business_partner text);<= o:p>

 

 

insert into policy_test.partners ( business_partner) value= s ('125210000');

insert into policy_test.partners ( business_partner) value= s ('125210001');

 

 

-- alter table policy_test.partners disable row level secu= rity;

alter table policy_test.partners enable row level security= ;

 

 

-- drop function policy_test.get_partners(text);

create or replace function policy_test.get_partners(text)

  returns boolean as

$$

declare

 

  is_true   boolean :=3D FALSE;<= /span>

  the_count integer :=3D 0;

 

begin

 

   select  count(*)

     into  the_count

     from  policy_test.partners a=

    where  a.business_partner =3D '125= 210000'

      and  a.business_partne= r =3D $1;

 

   if the_count =3D 1 then

     is_true :=3D TRUE;

   end if;

 

   return is_true;

 

end;

$$ language plpgsql;

 

 

-- drop policy test_partner_policy on policy_test.partners= ;

create policy test_partner_policy on policy_test.partners<= o:p>

  using (policy_test.get_partners(business_partner));=

 

 

-- as postgres create pol_ex user;

 

create user pol_ex password 'pol_ex';

 

 

-- as db1_owner in db1

grant usage on schema policy_test to pol_ex;

grant select on policy_test.partners to pol_ex;=

 

 

 

psql -U pol_ex -d db1

-- connect as pol_ex (ex here stands for "external&qu= ot; user)

select * from policy_test.partners;

 

 

 

Above select throws numerous lines shown underneath; somet= imes in between the echoed SQL

error message max_stack_depth exceeded occurs. Beyond that= no other error messages appear.

 

Whatever I tried the function does not accept / resolve th= e business_partner argument.

Is there a special way of indicating that this argument sh= ould be the tables' current row attribute?

Many examples on the Internet just pass the argument the w= ay I tried.

 

Tried with prefixing scheme / table name to the argument, = explict argument name instead of $ notation,

returning table of business_partners instead of boolean an= d so on, no avail.

Granting execute on the policy function to pol_ex did not = help either.

 

I suspect a very basic issue due to my inexperience with P= ostgres.

If anyone of the seasoned Postgres Admins quickly can see = what I did wrong, I'd be grateful for

a hint.

 

Thank you very much

 

Rainer Floegel

 

 

 

-- "Output" when running select * from policy_te= st.partners; (as pol_ex user)

 

SQL statement "select  count(*)

         &nbs= p;            &= nbsp;   from  policy_test.partners a<= /p>

    where  a.business_partner =3D '125= 210000'

      and  a.business_partne= r =3D $1"

PL/pgSQL function policy_test.get_partners(text) line 9 at= SQL statement

SQL statement "select  count(*)

         &nbs= p;            &= nbsp;   from  policy_test.partners a<= /p>

    where  a.business_partner =3D '125= 210000'

      and  a.business_partne= r =3D $1"

PL/pgSQL function policy_test.get_partners(text) line 9 at= SQL statement

 

and so on



3D"HTML

Coronavirus

Informationen für unsere Kunden
Informations actuelles destinées à nos clients
Informazioni aggiornate per i nostri clienti

www.suva.ch/covid-19






Disclaimer:

Diese Nachricht und ihr eventuell angehängte Dateien sind nur für= den Adressaten bestimmt. Sie kann vertrauliche oder gesetzlich geschü= tzte Daten oder Informationen beinhalten. Falls Sie diese Nachricht irrt&uu= ml;mlich erreicht hat, bitten wir Sie höflich, diese unter Ausschluss jeglicher Reproduktion zu löschen und die absendende= Person zu benachrichtigen. Danke für Ihre Hilfe.

This message and any attached files are for the sole use of the recipient n= amed above. It may contain confidential or legally protected data or inform= ation. If you have received this message in error, please delete it without= making any copies whatsoever and notify the sender. Thank you for your assistance.
--_000_7ed1216700e24d76aebe2ff59089e775suvach_-- ------5E305EE44433C86C92E7F6EA7A950678 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" 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 vKK8v12qICt7HDhNNsRBspHvPCIKzNV6ZHKytH/grwimBhGzajiPonwNZ6XE5MUR ydeLNahXnfZpattgXv0CDCVkQN/3uMBTEv+1hw3bJoD9eCH1SdpIFEYWercmEcaA De0RhhhJBmsoA44q/kecxb62hD+N984M7p6Q4U4YOzACLleU0qR59f4LIxrCrnkj vNqRrzQvzaWkdvEdHoDfSgmTO54wqPfcvck6T24bqGERolLHexaT4BpWRf9dfDEl FP0QvVMpoHVmzfMnMPyhbKt6caS1ZDg7PvfCsggz9TPge4oTtLrp8Bo+qh4y4LDV 7ILRPnQuEhlvAgMBAAGjggFvMIIBazAfBgNVHSMEGDAWgBQGbLPpz+A7cF0eebe+ 8PZtfTaIIjB3BggrBgEFBQcBAQRrMGkwOAYIKwYBBQUHMAKGLGh0dHA6Ly90cnVz dC5xdW92YWRpc2dsb2JhbC5jb20vcXZjaGFkZzMuY3J0MC0GCCsGAQUFBzABhiFo dHRwOi8vdXcub2NzcC5xdW92YWRpc2dsb2JhbC5jb20wTgYDVR0gBEcwRTBDBgkr BgEEAb5YAWQwNjA0BggrBgEFBQcCARYoaHR0cDovL3d3dy5xdW92YWRpc2dsb2Jh bC5jb20vcmVwb3NpdG9yeTATBgNVHSUEDDAKBggrBgEFBQcDBDA7BgNVHR8ENDAy MDCgLqAshipodHRwOi8vY3JsLnF1b3ZhZGlzZ2xvYmFsLmNvbS9xdmNoYWRnMy5j cmwwHQYDVR0OBBYEFEkoibvjQkA29JcWnb0bZMVHvJ6JMA4GA1UdDwEB/wQEAwIF oDANBgkqhkiG9w0BAQsFAAOCAgEAVUySaj55WppfWQL8zqOFby4P4CwSzJiBP1ka ZOui/udgW0dzylYnMtkFP0n9GTnBKnc8kVldBxJNRL/rG9aHFjmHnMYs+5b6w/mp IH5ktUGRDBGf1nXKw6Hfd8t6XHkDrMt+/J9HKLvUowItDDZugGEthsaZCnjvFVMA dLuRlpgD4uLqn+GdO1ZXATawOKaXxjgW2PPxMz8XwzG5Oxk76re3sW4Fe5QNfQT2 ALHKrbjuf5577RmO9lvbyPQL+RhTfkOhxUiXjPNUVxam0F5+7p6rFyPTHnnbg+lr /LH2/2VTCYCXkmyQWmwbC9aNBjPpqPBEb1dqhLd8Icf0+sDmljO7uRGMOynVovc9 TxsKOZ6sMDDYUjNoMzQueC7FfhDNeg708BiREab54JIQkhBv3jAn2EPYG6Je5U+e zm4nXAcNWOJ3c7mpZVv1jeqVeJsy9WTrpdE50/ZrDqrGGXZNkw2A8L19STyF/2wY G73nLtmYBGKc91/IEB9v+xy/aUfZzV1ubvJvfjqyfdGWYI+1PsmhR4bddxe+97dW HJ5E49oqu4SJD24j83QHfor0/QOMPBFdk4VswwNxXKnHWcCAObE3PUQlb51qL4SO Oi9OnkW6mP6J/8qKmX4/sxYesU91Wp8enMBONzq5iTUQY5QTdO+w/BT2nWXIWEoo +05ZrRMwggbwMIIE2KADAgECAhRB6J7TViFJyJS923ve3X7FacckkDANBgkqhkiG 9w0BAQsFADBIMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRl ZDEeMBwGA1UEAxMVUXVvVmFkaXMgUm9vdCBDQSAxIEczMB4XDTE4MDIxMzEzNTEw N1oXDTI4MDIxMTEzNTEwN1owfTELMAkGA1UEBhMCQ0gxHjAcBgNVBGEMFU5UUkNI LUNIRS0xMTIuMjEwLjM0OTEmMCQGA1UECgwdUXVvVmFkaXMgVHJ1c3RsaW5rIFNj aHdlaXogQUcxJjAkBgNVBAMMHVF1b1ZhZGlzIFN3aXNzIEFkdmFuY2VkIENBIEcz MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA329pdBtbr7lHwGdxzEJH 91mAnkWzHXLckl5mhgxX2cEc1AS3GqWjGBfoZmWwO1ORIRh0xxjM4gqSD1K94oSd kGvUJDqzM1bTtmzrVFrUiORzVMVjpZjGshmZuxFDekd7dS9poW2Lfsqx58uf/Qqg 4rNacAZv8tAavzaXCUSWEvOm/26jp6pad28aDoP+2y03jfkS2svKx1JT9ZjqUi/c WbW5RubZNGehq9YcQTR/UmAKs7qNd07bwVgnZ0sD4U45dg07T/URRwVg0BfUxqX4 /1ovfVW/Ezcnm684IbPCvUUFLUfMc+hEdvUJA+9gEgxBXDrlaQMcAamCznyFpQcg F+CA9iAxNHhe1iAvDxR4YchjBI27jg27zNd2QOq37V4/jg1yTAy7TrAjvczwWhXs dqhKnj/H43ogifK8NC7noXxmecciRdRwyVlhs4BZGTNzS0bAsRnVOzPp6hyYCtu9 oU9QW6GdJkUY7qc67vP0w05bP0qic4HQShmXunrvA3MjLQeLlNbShdsL+IAVKqZ5 kGO5EXPNPls2zW5wfyQAzmBeV3MfelEbutH6PryonKa51WJB3PLPXZEW3ub3ccOB ZOl0+mHVPLC9VOn+Jl0Yop3KvstNzAQ4t4kujuh5u8e2LgRL6GquWduLM11DSPHf VDvOVowzFPOFqFi6i9+mCM0CAwEAAaOCAZswggGXMBIGA1UdEwEB/wQIMAYBAf8C AQAwHwYDVR0jBBgwFoAUo5fW816iEOGrRZ88F2Q87gFwnMwwdAYIKwYBBQUHAQEE aDBmMDgGCCsGAQUFBzAChixodHRwOi8vdHJ1c3QucXVvdmFkaXNnbG9iYWwuY29t L3F2cmNhMWczLmNydDAqBggrBgEFBQcwAYYeaHR0cDovL29jc3AucXVvdmFkaXNn bG9iYWwuY29tMEkGA1UdIARCMEAwPgYEVR0gADA2MDQGCCsGAQUFBwIBFihodHRw Oi8vd3d3LnF1b3ZhZGlzZ2xvYmFsLmNvbS9yZXBvc2l0b3J5MDMGA1UdJQQsMCoG CCsGAQUFBwMCBggrBgEFBQcDBAYKKwYBBAGCNwoDDAYIKwYBBQUHAwkwOwYDVR0f BDQwMjAwoC6gLIYqaHR0cDovL2NybC5xdW92YWRpc2dsb2JhbC5jb20vcXZyY2Ex ZzMuY3JsMB0GA1UdDgQWBBQGbLPpz+A7cF0eebe+8PZtfTaIIjAOBgNVHQ8BAf8E BAMCAQYwDQYJKoZIhvcNAQELBQADggIBAGUd5HwFhK7lhaX0dd1QfDyKeDum1bFF phRmkJUMUnY0f+kfLwu4EEzpFZ1Bz6UMREnC1kVgkLj1bpqFPX6XB0AvCjcbPmMA WYrk8H/3PcJ0LxwK3uwAWXPeS1R1o3QV9OBALnRRNpfqdcSSVFs8kaaX36OQiQhq GtTK6YcGG0quRENym/ZRVMRoOmNsbcaUc3hSPTzRqMF7VPV2vGqqrnwzW74pxzKS neoWW96dfjZ80gV6Shx/x6xb/g/pYdQQLriPqLP0dgvPt7iESXHEmHY4rzwxVlHY KPJBQhXA0f+6yUE4UaV1RNVnMCeQGRS1HL9KyK3v8/AFWxW9akiBV0ROqRw6A/q7 iWIcRKaxilm7scN6cCWty6W1Y26dJ6Xlb5QuIUZhYbPQuWMOSwOVTvcaU+zPfeJz cTlOu/dg+ZCGrXd5lx1S5exROVA5SnnZmzSc7L0BiInhLeLg9EGHz92a9yBAuOcM mOMhuCiU52LFFxeU6as1Ulm4QvJLdj3GOu2VWopArGE2M2Mj+ydBoes7q62dkmJZ QP1RQgI8Owi/oyoQEvDQt9IDcSoFf3hHn7KCTjj1TWlGmUtyC7kA5gjcJ6IDxkEk e5o60zQSXP885OybmWs/Ggs6TR6VWTQO1xr323Wned72KieH8L/qAWRHJx+EN9Hn CAtE5x0DMCDrMYICpjCCAqICAQEwgZUwfTELMAkGA1UEBhMCQ0gxHjAcBgNVBGEM FU5UUkNILUNIRS0xMTIuMjEwLjM0OTEmMCQGA1UECgwdUXVvVmFkaXMgVHJ1c3Rs aW5rIFNjaHdlaXogQUcxJjAkBgNVBAMMHVF1b1ZhZGlzIFN3aXNzIEFkdmFuY2Vk IENBIEczAhRCWTItkdUS+hyvhN0jH7cydhHB7TALBglghkgBZQMEAgGggeQwGAYJ KoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjAwNTI5MDg0 NzAyWjAvBgkqhkiG9w0BCQQxIgQgpUOkTvPO+l7njyX/Mk0NSXJSlHV33E5ORumv s5L3+lgweQYJKoZIhvcNAQkPMWwwajALBglghkgBZQMEASowCwYJYIZIAWUDBAEW MAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZI hvcNAwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwDQYJKoZIhvcNAQEBBQAE ggEAa1aMi4ZkqyETzfYVC0UlxB/um15NzCTbSMVOdwy4vWKMcZ84/t9rFLF/BJ5Y fw3Ed8tIV4pNydA4N4vUTd2VyYOxBdRC6EjxQe0aKMvMKaI2mzqIoLZmiQN6YXa9 8dRzlscpTkrOPRe7A6hRbI9jPZsdjzpNCfPCD9mIv//0CCr4oZLny5lvCKfSjm/L bA44uesrTy5nm8ww5QQWV8IOWsHIZg6PrbxKb4JabLGKZvhu5b2Yy95J3S1k6Nel 7CjH/P19nHShKctBhaHapniyFvlcdRvG+W9CTGi6SNSPLwCkboSMmkH4UFs8p9k5 sRNRa1AjlH75dDLIN8KporHnEg== ------5E305EE44433C86C92E7F6EA7A950678--