Re: Grant read-only access to exactly one database amongst many

2024-02-05 Thread Graham Leggett
On 05 Feb 2024, at 00:54, David G. Johnston  wrote:

> I have a postgresql 15 instance with two databases in it, and I have a need 
> to grant read-only access to one of those databases to a given user.
>> 
>> To do this I created a dedicated role for readonly access to the database 
>> db1:
>> 
>> CREATE ROLE "dv_read_db1"
>> GRANT CONNECT ON DATABASE db1 TO dv_read_db1
> 
> This grant is basically pointless since by default all roles can connect 
> everywhere via the PUBLIC pseudo-role.  You need to revoke that grant, or 
> even alter it being given out by default.

More on this point at the end…

>> Trouble is, I can create tables in db1 which is write access.
> 
> Since in v15 PUBLIC also gets CREATE on the public schema.

…ouch…

>> I can also connect to db2 (bad),
> 
> See my comment regarding the pointless grant in a default setup.
> 
>> and I can enumerate the tables in db2 (bad),
> 
> Connect privilege grants reading all catalog data by design.
> 
>> 
>> I appears the mechanism I am using above has insecure side effects.
> 
> It has, from your expectation, insecure defaults which you never changed.  We 
> changed public schema in v16 but the ease-of-use database connecting remains.

It looks like changing these defaults is likely to be difficult, which is why I 
posted here.

I want to optionally allow user minfrin to access both databases by doing this:

CREATE USER minfrin LOGIN;
GRANT dv_read_db1 TO minfrin;
GRANT dv_read_db2 TO minfrin;

If I am understanding you correctly to prevent dv_read_db1 from connecting to 
db2, I need to actively revoke access to db2. Also, to prevent dv_read_db2 from 
connecting to db1, I need to actively revoke access to db1.

Would the two grants above dv_read_db1 and dv_read_db2 not cause the unintended 
side effect of revoking access to each other, resulting in no access being 
allowed at all?

Also, how do you handle the race condition between the time a database db3 is 
created, and the the time all readonly users have their access revoked to db3?

Regards,
Graham
—



Grant read-only access to exactly one database amongst many

2024-02-04 Thread Graham Leggett
Hi all,

I have a postgresql 15 instance with two databases in it, and I have a need to 
grant read-only access to one of those databases to a given user.

To do this I created a dedicated role for readonly access to the database db1:

CREATE ROLE "dv_read_db1"
GRANT CONNECT ON DATABASE db1 TO dv_read_db1
GRANT USAGE ON SCHEMA public TO “dv_read_db1"
GRANT SELECT ON ALL TABLES IN SCHEMA public TO “dv_read_db1"
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO 
“dv_read_db1"

CREATE USER minfrin LOGIN;
GRANT dv_read_db1 TO minfrin;

On the surface this works, I get readonly access to db1.

Trouble is, I can create tables in db1 which is write access. I can also 
connect to db2 (bad), and I can enumerate the tables in db2 (bad), although the 
queries of the contents say access is denied.

I appears the mechanism I am using above has insecure side effects.

What is the way to grant read only access to a single database, without 
exposing other databases, and being futureproof against future features 
offering potential write access to a read only user?

Regards,
Graham
—





Re: [PATCH] Log details for client certificate failures

2022-07-09 Thread Graham Leggett
On 01 Jul 2022, at 22:59, Jacob Champion  wrote:

>> I added this to httpd a while back:
>> 
>> SSL_CLIENT_CERT_RFC4523_CEA
>> 
>> It would be good to interoperate.
> 
> What kind of interoperation did you have in mind? Are there existing
> tools that want to scrape this information for observability?

This is for human troubleshooting.

> I think the CEA syntax might not be a good fit for this particular
> patch: first, we haven't actually verified the certificate, so no one
> should be using it to assert certificate equality (and I'm truncating
> the Issuer anyway, to avoid letting someone flood the logs). Second,
> this is designed to be human-readable rather than machine-readable.

This is what a CEA looks like:

{ serialNumber 400410167207191393705333222102472642510002355884, issuer 
rdnSequence:”CN=Foo UK G1,O=Foo,C=UK" }

Whitespace and escaping is important above.

When troubleshooting, you want a string like the above that you can cut and 
paste and search for in other systems and log files. The verification status of 
the cert isn’t an issue at this point, you have a system in front of you where 
it doesn’t work when it should, and you need to know exactly what’s connecting, 
not what you think you’re connecting to, and you need precise data.

Please don’t invent another format, or try and truncate the data. This is a 
huge headache when troubleshooting.

Regards,
Graham
—





Re: [PATCH] Log details for client certificate failures

2022-06-30 Thread Graham Leggett
On 30 Jun 2022, at 10:43, Peter Eisentraut  
wrote:

> I wrote that pg_stat_ssl uses the *issuer* plus serial number to identify a 
> certificate.  What your patch shows is the subject and the serial number, 
> which isn't the same thing.  Let's get that sorted out one way or the other.

Quick observation on this one, the string format of an issuer and serial number 
is defined as a “Certificate Exact Assertion” in RFC 4523.

I added this to httpd a while back:

SSL_CLIENT_CERT_RFC4523_CEA

It would be good to interoperate.

Regards,
Graham
—



Re: Feature: Use DNS SRV records for connecting

2019-08-13 Thread Graham Leggett
On 13 Aug 2019, at 11:50, Feike Steenbergen  wrote:

> I'd like to get some feedback on whether or not implementing a DNS SRV feature
> for connecting to PostgreSQL would be desirable/useful.

A big +1.

We currently use SRV records to tell postgresql what kind of server it is. This 
way all of our postgresql servers have an identical configuration, they just 
tailor themselves on startup as appropriate:

_postgresql-master._tcp.sql.example.com.

The above record in our case declares who the master is. If the postgresql 
startup says “hey, that’s me” it configures itself as a master. If the 
postgresql startup says “hey, that’s not me” it configures itself as a slave of 
the master.

We also use TXT records to define the databases we want (with protection 
against DNS security issues, we never remove a database based on a TXT record, 
but signed DNS records will help here).

_postgresql.sql.example.com TXT "v=PGSQL1;d=mydb;u=myuser"

We use a series of systemd “daemons” that are configured to run before and 
after postgresql to do the actual configuration on bootup, but it would be 
great if postgresql could just do this out the box.

Regards,
Graham
—



smime.p7s
Description: S/MIME cryptographic signature


Re: DNS SRV support for LDAP authentication

2019-02-02 Thread Graham Leggett
On 02 Feb 2019, at 01:57, Thomas Munro  wrote:

> On Sat, Feb 2, 2019 at 9:25 AM Graham Leggett  wrote:
>> On 25 Sep 2018, at 04:09, Thomas Munro  wrote:
>>> Some people like to use DNS SRV records to advertise LDAP servers on
>>> their network.  Microsoft Active Directory is usually (always?) set up
>>> that way.  Here is a patch to allow our LDAP auth module to support
>>> that kind of discovery.
>> 
>> Does this support SSL/TLS?
> 
> I didn't try it myself but I found several claims that it works.  I
> see complaints that it always looks for _ldap._tcp and not _ldaps._tcp
> as you might expect when using ldascheme=ldaps, but that doesn't seem
> to be a big problem.  As for ldaptls=1, that must work because it
> doesn't even negotiate that until after the connection is made.

If the LDAP server was bound to port 636, how would the client know to use a 
direct SSL/TLS connection and not STARTTLS?

Regards,
Graham
—




Re: DNS SRV support for LDAP authentication

2019-02-01 Thread Graham Leggett
On 25 Sep 2018, at 04:09, Thomas Munro  wrote:

> Some people like to use DNS SRV records to advertise LDAP servers on
> their network.  Microsoft Active Directory is usually (always?) set up
> that way.  Here is a patch to allow our LDAP auth module to support
> that kind of discovery.

Does this support SSL/TLS?

Regards,
Graham
—




Re: Is there a "right" way to test if a database is empty?

2018-01-17 Thread Graham Leggett
On 17 Jan 2018, at 6:34 PM, David G. Johnston  
wrote:

> ​That was my original thought - though comparing the size of template1 to the 
> target database should be reasonably safe...
> 
> If you do go for object detection you will want to ensure that no schemas 
> other than public exist in addition to ensuring that public is empty.  That 
> doesn't prevent people from installing stuff to pg_catalog but normally only 
> extensions would end up there.

What led me here was this, which didn’t work for me, although the idea to not 
just assume the default namespace is valid:

https://stackoverflow.com/questions/42692674/how-to-to-determine-if-a-postgresql-database-is-empty-the-correct-way

Would it be true to say that if this query returned more than zero rows the 
database is not empty?

db=# select distinct s.nspname from pg_class c join pg_namespace s on s.oid = 
c.relnamespace where s.nspname not in 
('pg_toast','information_schema','pg_catalog');
 nspname 
-
 public
(1 row)

Regards,
Graham
--



smime.p7s
Description: S/MIME cryptographic signature


Re: Is there a "right" way to test if a database is empty?

2018-01-17 Thread Graham Leggett
On 17 Jan 2018, at 5:47 PM, Graham Leggett  wrote:

> I need to test whether a database is empty, in other words “createdb” has 
> been executed but no data of any kind appears in that database.
> 
> What is the correct postgresql way to do this?
> 
> Is there a pg_isempty command or equivalent somewhere?

Does this query look right?

db=# select count(s.nspname) from pg_class c join pg_namespace s on s.oid = 
c.relnamespace where s.nspname in ('public');
 count 
---
 0
(1 row)

It is based on the idea that the database is not empty if there are any class 
entries in the “public” namespace?

Regards,
Graham
—



smime.p7s
Description: S/MIME cryptographic signature


Re: Is there a "right" way to test if a database is empty?

2018-01-17 Thread Graham Leggett
On 17 Jan 2018, at 6:01 PM, pinker  wrote:

> I always do: \l+ and then you can compare the size: new_one | postgres | UTF8 
> | en_US.UTF-8 | en_US.UTF-8 | | 7869 kB | pg_default | template0 | postgres | 
> UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +| 7869 kB | pg_default | | | 
> | | postgres=CTc/postgres | | | template1 | postgres | UTF8 | en_US.UTF-8 | 
> en_US.UTF-8 | =c/postgres +| 7869 kB | pg_default 

What I am after is something scriptable and data safe.

The size isn’t something I would be comfortable relying on.

Regards,
Graham
—



smime.p7s
Description: S/MIME cryptographic signature


Is there a "right" way to test if a database is empty?

2018-01-17 Thread Graham Leggett
Hi all,

I need to test whether a database is empty, in other words “createdb” has been 
executed but no data of any kind appears in that database.

What is the correct postgresql way to do this?

Is there a pg_isempty command or equivalent somewhere?

Regards,
Graham
—



smime.p7s
Description: S/MIME cryptographic signature