Allow postgres_fdw passwordless non-superuser conns with priorsuperuser permission - Mailing list pgsql-hackers

From Craig Ringer
Subject Allow postgres_fdw passwordless non-superuser conns with priorsuperuser permission
Date
Msg-id CAMsr+YEDh6P5fH5x1Z5oSdbxEK2eoZMZsofUnVUjKz1X2wfSjg@mail.gmail.com
Whole thread Raw
Responses Re: Allow postgres_fdw passwordless non-superuser conns with priorsuperuser permission
Re: Allow postgres_fdw passwordless non-superuser conns with priorsuperuser permission
List pgsql-hackers
Hi all

Currently postgres_fdw cannot be used with 'cert' authentication, i.e. client-certificate validation and cert cn => postgres username mapping. You also can't use things like Kerberos, SSPI, etc with a superuser-created FDW and username map.

To permit this, I'd like to allow postgres_fdw user mappings to be created with a new 'permit_passwordless' option. Only the superuser is allowed to create such a mapping. If it's set to true, we bypass the check_conn_params(...) connection-string password check and the connect_pg_server(...) check for the conn using a password when a non-superuser establishes a connection.

This doesn't re-open CVE-2007-6601 because the superuser has to explicitly grant the access.

To make SSL client certs work properly with FDWs, I'd also like to add a libpq parameter 'sslpassword' parameter, which corresponds to the PgJDBC parameter of the same name. This lets the superuser create user mappings for ssl client cert auth that use a user-specific 'sslcert', 'sslkey', and 'sslpassword'. Users can't use each others' keys because they don't know the key password, and they can't create passwordless user mappings anyway. Without 'sslpassword' a non-superuser user could make a connection to an 'md5 clientcert=1' server using another users' client cert. It's a trivial change.

Patches to follow shortly. 



Detailed explanation.

postgres_fdw assumes that connections that do not specify a password in the connstr and connections that lack a password on the user mapping are insecure and rejects them for non-superusers with:

ERROR: password is required
DETAIL: Non-superuser cannot connect if the server does not request a password.
HINT: Target server's authentication method must be changed.

or

ERROR: password is required
DETAIL: Non-superusers must provide a password in the user mapping.

See check_conn_params and connect_pg_server in contrib/postgres_fdw/connection.c . 

This is because of CVE-2007-6601 for dblink.

It's assuming that connections without passwords must therefore not have anything to make sure the local postgres user is really the user authorized to access the remote end as that remote postgres user. It's trying to stop use of 'peer' or 'ident', which we shouldn't permit because we'd be allowing the non-superuser to potentially authenticate as the (usually) 'postgres' system-user and gain access to a 'postgres' superuser db account. Or the connection might be using a service file or .pgpass in the 'postgres' user's home directory, in which case again we don't want a non-superuser able to use it.

For 'cert' authentication you don't want to assume that the non-superuser should be allowed to use the client certificate's private key file from the file system. We don't provide a way to provide the ssl key as a literal in the postgres_fdw user mapping. Nor is there a way to store the ssl key encrypted, and put the ssl key passphrase in the user mapping, making sure that just the authorized user can access it.

The problem is that you can't then use 'cert' auth for postgres_fdw at all.

Nor can you authorize a non-superuser to use passwordless authentication if you know your local server is configured securely (no 'trust', 'peer' or 'ident') and you *want* to authorize the user to use a service file, pgpass, etc.

We should allow this if the user mapping creator is the superuser and they explicitly mark the mapping as permit_passwordless. That won't let normal users escalate.

If the superuser is the one creating the user mapping between local and remote user IDs, then they're the ones delegating the access. They can already GRANT mysuperuser TO public if they're feeling stupid; similarly,  if they CREATE USER MAPPING FOR public SERVER localhost OPTIONS ('permit_passwordless', 'true', ...) ... then it's on them if they have 'peer' or 'ident' enabled on the server.

--
 Craig Ringer                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services

pgsql-hackers by date:

Previous
From: "Bossart, Nathan"
Date:
Subject: Re: REINDEX and shared catalogs
Next
From: Paul Guo
Date:
Subject: Re: [Patch] Create a new session in postmaster by calling setsid()