From d121f818cb0364e1ad006de4ae92c7472bc21878 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 6 Aug 2019 20:41:19 +0200 Subject: [PATCH v1] Allow cluster owner to bypass authentication --- doc/src/sgml/client-auth.sgml | 29 +++++++++++++++++++ doc/src/sgml/config.sgml | 21 ++++++++++++++ src/backend/libpq/auth.c | 22 +++++++++++++- src/backend/utils/misc/guc.c | 9 ++++++ src/backend/utils/misc/postgresql.conf.sample | 1 + src/include/libpq/auth.h | 1 + src/test/perl/PostgresNode.pm | 1 + 7 files changed, 83 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml index fada7289d4..c84565a115 100644 --- a/doc/src/sgml/client-auth.sgml +++ b/doc/src/sgml/client-auth.sgml @@ -54,6 +54,35 @@ Client Authentication database user names and OS user names. + + Cluster Owner Authentication + + + When connecting over the Unix-domain socket, if the client user is the same + as the user that runs the database server (which is also the same as the + owner of the data directory), then access is immediately granted without + further checking. This allows a database cluster owner to connect to + their own database server without being subject to the rest of client + authentication (described in the rest of this chapter). + + + + This mechanism is only available on operating systems providing the + getpeereid() function, the + SO_PEERCRED socket parameter, or similar mechanisms. + Currently that includes Linux, most + flavors of BSD including + macOS, and Solaris. If it is not available, then cluster + owner connections are subject to the normal client authentication. + + + + This mechanism can be disabled using the configuration parameter . + + + The <filename>pg_hba.conf</filename> File diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index cdc30fa5e3..df2a08bb16 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1099,6 +1099,27 @@ Authentication + + + cluster_owner_bypass_auth (boolean) + + cluster_owner_bypass_auth configuration parameter + + + + + If enabled, when connecting over the Unix-domain socket, if the client + user is the same as the user that runs the database server, then + access is immediately granted without further checking. See . This is enabled by default and + usually very useful. A possible reason to turn it off might be if all + authentication is through PAM with auditing and one wants even cluster + owner access to go through auditing that way. Another reason to turn + this off is to be able to test a pg_hba.conf + configuration more easily. + + + diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 0e0a6d8752..af75170606 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -160,11 +160,12 @@ static int CheckCertAuth(Port *port); /*---------------------------------------------------------------- - * Kerberos and GSSAPI GUCs + * GUCs *---------------------------------------------------------------- */ char *pg_krb_server_keyfile; bool pg_krb_caseins_users; +bool cluster_owner_bypass_auth; /*---------------------------------------------------------------- @@ -345,6 +346,25 @@ ClientAuthentication(Port *port) int status = STATUS_ERROR; char *logdetail = NULL; + /* + * If connecting over Unix-domain socket and peer uid matches current + * process uid, then allow connection immediately. + */ + if (cluster_owner_bypass_auth && + IS_AF_UNIX(port->raddr.addr.ss_family)) + { + uid_t peer_uid = -1; + gid_t peer_gid = -1; + int res; + + res = getpeereid(port->sock, &peer_uid, &peer_gid); + if (res == 0 && peer_uid == geteuid()) + { + sendAuthRequest(port, AUTH_REQ_OK, NULL, 0); + return; + } + } + /* * Get the authentication method to use for this frontend/database * combination. Note: we do not parse the file at this point; this has diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index eb78522053..7ea2bf5074 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -1952,6 +1952,15 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"cluster_owner_bypass_auth", PGC_SIGHUP, CONN_AUTH_AUTH, + gettext_noop("Whether cluster owner connecting over Unix-domain socket bypasses authentication."), + }, + &cluster_owner_bypass_auth, + true, + NULL, NULL, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 65a6da18b3..65ffb88952 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -90,6 +90,7 @@ #authentication_timeout = 1min # 1s-600s #password_encryption = md5 # md5 or scram-sha-256 #db_user_namespace = off +#cluster_owner_bypass_auth = on # GSSAPI using Kerberos #krb_server_keyfile = '' diff --git a/src/include/libpq/auth.h b/src/include/libpq/auth.h index 405fd43487..82d65b37b6 100644 --- a/src/include/libpq/auth.h +++ b/src/include/libpq/auth.h @@ -19,6 +19,7 @@ extern char *pg_krb_server_keyfile; extern bool pg_krb_caseins_users; extern char *pg_krb_realm; +extern bool cluster_owner_bypass_auth; extern void ClientAuthentication(Port *port); diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm index 270bd6c856..b42af2bd24 100644 --- a/src/test/perl/PostgresNode.pm +++ b/src/test/perl/PostgresNode.pm @@ -447,6 +447,7 @@ sub init print $conf "log_statement = all\n"; print $conf "log_replication_commands = on\n"; print $conf "wal_retrieve_retry_interval = '500ms'\n"; + print $conf "cluster_owner_bypass_auth = off\n"; # to enable testing hba etc. # If a setting tends to affect whether tests pass or fail, print it after # TEMP_CONFIG. Otherwise, print it before TEMP_CONFIG, thereby permitting base-commit: fded4773eb60541c6e7dbcf09c9bcb1cd36a063b -- 2.22.0