2021-05-07 16:56:14 +02:00
|
|
|
|
2024-01-04 02:49:05 +01:00
|
|
|
# Copyright (c) 2021-2024, PostgreSQL Global Development Group
|
2021-05-07 16:56:14 +02:00
|
|
|
|
2019-04-20 03:22:22 +02:00
|
|
|
# Sets up a KDC and then runs a variety of tests to make sure that the
|
|
|
|
# GSSAPI/Kerberos authentication and encryption are working properly,
|
|
|
|
# that the options in pg_hba.conf and pg_ident.conf are handled correctly,
|
Introduce SYSTEM_USER
SYSTEM_USER is a reserved keyword of the SQL specification that,
roughly described, is aimed at reporting some information about the
system user who has connected to the database server. It may include
implementation-specific information about the means by the user
connected, like an authentication method.
This commit implements SYSTEM_USER as of auth_method:identity, where
"auth_method" is a keyword about the authentication method used to log
into the server (like peer, md5, scram-sha-256, gss, etc.) and
"identity" is the authentication identity as introduced by 9afffcb (peer
sets authn to the OS user name, gss to the user principal, etc.). This
format has been suggested by Tom Lane.
Note that thanks to d951052, SYSTEM_USER is available to parallel
workers.
Bump catalog version.
Author: Bertrand Drouvot
Reviewed-by: Jacob Champion, Joe Conway, Álvaro Herrera, Michael Paquier
Discussion: https://postgr.es/m/7e692b8c-0b11-45db-1cad-3afc5b57409f@amazon.com
2022-09-29 08:05:40 +02:00
|
|
|
# that the server-side pg_stat_gssapi view reports what we expect to
|
|
|
|
# see for each test and that SYSTEM_USER returns what we expect to see.
|
2019-04-20 03:22:22 +02:00
|
|
|
#
|
2023-04-13 14:55:07 +02:00
|
|
|
# Also test that GSSAPI delegation is working properly and that those
|
|
|
|
# credentials can be used to make dblink / postgres_fdw connections.
|
|
|
|
#
|
2019-04-20 03:22:22 +02:00
|
|
|
# Since this requires setting up a full KDC, it doesn't make much sense
|
|
|
|
# to have multiple test scripts (since they'd have to also create their
|
|
|
|
# own KDC and that could cause race conditions or other problems)- so
|
|
|
|
# just add whatever other tests are needed to here.
|
|
|
|
#
|
|
|
|
# See the README for additional information.
|
|
|
|
|
2018-03-05 20:42:11 +01:00
|
|
|
use strict;
|
2023-12-29 18:01:53 +01:00
|
|
|
use warnings FATAL => 'all';
|
2021-10-24 16:28:19 +02:00
|
|
|
use PostgreSQL::Test::Utils;
|
|
|
|
use PostgreSQL::Test::Cluster;
|
2018-03-05 20:42:11 +01:00
|
|
|
use Test::More;
|
2020-12-02 20:41:53 +01:00
|
|
|
use Time::HiRes qw(usleep);
|
2018-03-05 20:42:11 +01:00
|
|
|
|
2022-02-11 20:54:44 +01:00
|
|
|
if ($ENV{with_gssapi} ne 'yes')
|
2018-03-05 20:42:11 +01:00
|
|
|
{
|
|
|
|
plan skip_all => 'GSSAPI/Kerberos not supported by this build';
|
|
|
|
}
|
2023-12-29 23:54:40 +01:00
|
|
|
elsif (!$ENV{PG_TEST_EXTRA} || $ENV{PG_TEST_EXTRA} !~ /\bkerberos\b/)
|
2022-09-20 20:09:30 +02:00
|
|
|
{
|
|
|
|
plan skip_all =>
|
|
|
|
'Potentially unsafe test GSSAPI/Kerberos not enabled in PG_TEST_EXTRA';
|
|
|
|
}
|
2018-03-05 20:42:11 +01:00
|
|
|
|
|
|
|
my ($krb5_bin_dir, $krb5_sbin_dir);
|
|
|
|
|
2022-12-31 22:45:18 +01:00
|
|
|
if ($^O eq 'darwin' && -d "/opt/homebrew")
|
2018-03-05 20:42:11 +01:00
|
|
|
{
|
2022-12-31 22:45:18 +01:00
|
|
|
# typical paths for Homebrew on ARM
|
|
|
|
$krb5_bin_dir = '/opt/homebrew/opt/krb5/bin';
|
|
|
|
$krb5_sbin_dir = '/opt/homebrew/opt/krb5/sbin';
|
|
|
|
}
|
|
|
|
elsif ($^O eq 'darwin')
|
|
|
|
{
|
|
|
|
# typical paths for Homebrew on Intel
|
2018-03-05 20:42:11 +01:00
|
|
|
$krb5_bin_dir = '/usr/local/opt/krb5/bin';
|
|
|
|
$krb5_sbin_dir = '/usr/local/opt/krb5/sbin';
|
|
|
|
}
|
|
|
|
elsif ($^O eq 'freebsd')
|
|
|
|
{
|
|
|
|
$krb5_bin_dir = '/usr/local/bin';
|
|
|
|
$krb5_sbin_dir = '/usr/local/sbin';
|
|
|
|
}
|
|
|
|
elsif ($^O eq 'linux')
|
|
|
|
{
|
|
|
|
$krb5_sbin_dir = '/usr/sbin';
|
|
|
|
}
|
|
|
|
|
|
|
|
my $krb5_config = 'krb5-config';
|
|
|
|
my $kinit = 'kinit';
|
2023-04-13 14:55:07 +02:00
|
|
|
my $klist = 'klist';
|
2018-03-05 20:42:11 +01:00
|
|
|
my $kdb5_util = 'kdb5_util';
|
|
|
|
my $kadmin_local = 'kadmin.local';
|
|
|
|
my $krb5kdc = 'krb5kdc';
|
|
|
|
|
|
|
|
if ($krb5_bin_dir && -d $krb5_bin_dir)
|
|
|
|
{
|
|
|
|
$krb5_config = $krb5_bin_dir . '/' . $krb5_config;
|
|
|
|
$kinit = $krb5_bin_dir . '/' . $kinit;
|
2023-04-13 14:55:07 +02:00
|
|
|
$klist = $krb5_bin_dir . '/' . $klist;
|
2018-03-05 20:42:11 +01:00
|
|
|
}
|
|
|
|
if ($krb5_sbin_dir && -d $krb5_sbin_dir)
|
|
|
|
{
|
|
|
|
$kdb5_util = $krb5_sbin_dir . '/' . $kdb5_util;
|
|
|
|
$kadmin_local = $krb5_sbin_dir . '/' . $kadmin_local;
|
|
|
|
$krb5kdc = $krb5_sbin_dir . '/' . $krb5kdc;
|
|
|
|
}
|
|
|
|
|
2018-08-04 05:53:25 +02:00
|
|
|
my $host = 'auth-test-localhost.postgresql.example.com';
|
|
|
|
my $hostaddr = '127.0.0.1';
|
2019-04-20 03:22:22 +02:00
|
|
|
my $realm = 'EXAMPLE.COM';
|
2023-05-19 23:24:48 +02:00
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
my $krb5_conf = "${PostgreSQL::Test::Utils::tmp_check}/krb5.conf";
|
|
|
|
my $kdc_conf = "${PostgreSQL::Test::Utils::tmp_check}/kdc.conf";
|
|
|
|
my $krb5_cache = "${PostgreSQL::Test::Utils::tmp_check}/krb5cc";
|
|
|
|
my $krb5_log = "${PostgreSQL::Test::Utils::log_path}/krb5libs.log";
|
|
|
|
my $kdc_log = "${PostgreSQL::Test::Utils::log_path}/krb5kdc.log";
|
|
|
|
my $kdc_port = PostgreSQL::Test::Cluster::get_free_port();
|
|
|
|
my $kdc_datadir = "${PostgreSQL::Test::Utils::tmp_check}/krb5kdc";
|
|
|
|
my $kdc_pidfile = "${PostgreSQL::Test::Utils::tmp_check}/krb5kdc.pid";
|
|
|
|
my $keytab = "${PostgreSQL::Test::Utils::tmp_check}/krb5.keytab";
|
2018-03-05 20:42:11 +01:00
|
|
|
|
2023-04-13 14:55:07 +02:00
|
|
|
my $pgpass = "${PostgreSQL::Test::Utils::tmp_check}/.pgpass";
|
|
|
|
|
2020-12-02 20:41:53 +01:00
|
|
|
my $dbname = 'postgres';
|
|
|
|
my $username = 'test1';
|
|
|
|
my $application = '001_auth.pl';
|
|
|
|
|
2018-03-05 20:42:11 +01:00
|
|
|
note "setting up Kerberos";
|
|
|
|
|
|
|
|
my ($stdout, $krb5_version);
|
|
|
|
run_log [ $krb5_config, '--version' ], '>', \$stdout
|
|
|
|
or BAIL_OUT("could not execute krb5-config");
|
|
|
|
BAIL_OUT("Heimdal is not supported") if $stdout =~ m/heimdal/;
|
|
|
|
$stdout =~ m/Kerberos 5 release ([0-9]+\.[0-9]+)/
|
|
|
|
or BAIL_OUT("could not get Kerberos version");
|
|
|
|
$krb5_version = $1;
|
|
|
|
|
2023-04-13 14:55:07 +02:00
|
|
|
# Construct a pgpass file to make sure we don't use it
|
|
|
|
append_to_file($pgpass, '*:*:*:*:abc123');
|
|
|
|
|
Activate perlcritic InputOutput::RequireCheckedSyscalls and fix resulting warnings
This checks that certain I/O-related Perl functions properly check
their return value. Some parts of the PostgreSQL code had been a bit
sloppy about that. The new perlcritic warnings are fixed here. I
didn't design any beautiful error messages, mostly just used "or die
$!", which mostly matches existing code, and also this is
developer-level code, so having the system error plus source code
reference should be ok.
Initially, we only activate this check for a subset of what the
perlcritic check would warn about. The effective list is
chmod flock open read rename seek symlink system
The initial set of functions is picked because most existing code
already checked the return value of those, so any omissions are
probably unintended, or because it seems important for test
correctness.
The actual perlcritic configuration is written as an exclude list.
That seems better so that we are clear on what we are currently not
checking. Maybe future patches want to investigate checking some of
the other functions. (In principle, we might eventually want to check
all of them, but since this is test and build support code, not
production code, there are probably some reasonable compromises to be
made.)
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://www.postgresql.org/message-id/flat/88b7d4f2-46d9-4cc7-b1f7-613c90f9a76a%40eisentraut.org
2024-03-19 07:01:22 +01:00
|
|
|
chmod 0600, $pgpass or die $!;
|
2023-04-13 14:55:07 +02:00
|
|
|
|
2023-03-09 16:32:49 +01:00
|
|
|
# Build the krb5.conf to use.
|
|
|
|
#
|
|
|
|
# Explicitly specify the default (test) realm and the KDC for
|
|
|
|
# that realm to avoid the Kerberos library trying to look up
|
|
|
|
# that information in DNS, and also because we're using a
|
|
|
|
# non-standard KDC port.
|
|
|
|
#
|
2023-04-08 01:36:46 +02:00
|
|
|
# Also explicitly disable DNS lookups since this isn't really
|
|
|
|
# our domain and we shouldn't be causing random DNS requests
|
|
|
|
# to be sent out (not to mention that broken DNS environments
|
|
|
|
# can cause the tests to take an extra long time and timeout).
|
|
|
|
#
|
2023-03-09 16:32:49 +01:00
|
|
|
# Reverse DNS is explicitly disabled to avoid any issue with a
|
|
|
|
# captive portal or other cases where the reverse DNS succeeds
|
|
|
|
# and the Kerberos library uses that as the canonical name of
|
|
|
|
# the host and then tries to acquire a cross-realm ticket.
|
2018-03-05 20:42:11 +01:00
|
|
|
append_to_file(
|
|
|
|
$krb5_conf,
|
|
|
|
qq![logging]
|
|
|
|
default = FILE:$krb5_log
|
|
|
|
kdc = FILE:$kdc_log
|
|
|
|
|
|
|
|
[libdefaults]
|
2023-04-08 01:36:46 +02:00
|
|
|
dns_lookup_realm = false
|
|
|
|
dns_lookup_kdc = false
|
2018-03-05 20:42:11 +01:00
|
|
|
default_realm = $realm
|
2023-04-13 14:55:07 +02:00
|
|
|
forwardable = false
|
2023-03-09 16:32:49 +01:00
|
|
|
rdns = false
|
2018-03-05 20:42:11 +01:00
|
|
|
|
|
|
|
[realms]
|
|
|
|
$realm = {
|
2018-08-04 05:53:25 +02:00
|
|
|
kdc = $hostaddr:$kdc_port
|
2023-04-13 14:55:07 +02:00
|
|
|
}
|
|
|
|
!);
|
2018-03-05 20:42:11 +01:00
|
|
|
|
|
|
|
append_to_file(
|
|
|
|
$kdc_conf,
|
|
|
|
qq![kdcdefaults]
|
|
|
|
!);
|
2018-04-25 20:00:19 +02:00
|
|
|
|
2018-03-05 20:42:11 +01:00
|
|
|
# For new-enough versions of krb5, use the _listen settings rather
|
|
|
|
# than the _ports settings so that we can bind to localhost only.
|
|
|
|
if ($krb5_version >= 1.15)
|
|
|
|
{
|
|
|
|
append_to_file(
|
|
|
|
$kdc_conf,
|
2018-08-04 05:53:25 +02:00
|
|
|
qq!kdc_listen = $hostaddr:$kdc_port
|
|
|
|
kdc_tcp_listen = $hostaddr:$kdc_port
|
2018-03-05 20:42:11 +01:00
|
|
|
!);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
append_to_file(
|
|
|
|
$kdc_conf,
|
|
|
|
qq!kdc_ports = $kdc_port
|
|
|
|
kdc_tcp_ports = $kdc_port
|
|
|
|
!);
|
|
|
|
}
|
|
|
|
append_to_file(
|
|
|
|
$kdc_conf,
|
|
|
|
qq!
|
|
|
|
[realms]
|
|
|
|
$realm = {
|
|
|
|
database_name = $kdc_datadir/principal
|
|
|
|
admin_keytab = FILE:$kdc_datadir/kadm5.keytab
|
|
|
|
acl_file = $kdc_datadir/kadm5.acl
|
|
|
|
key_stash_file = $kdc_datadir/_k5.$realm
|
|
|
|
}!);
|
|
|
|
|
|
|
|
mkdir $kdc_datadir or die;
|
|
|
|
|
2021-01-25 20:53:13 +01:00
|
|
|
# Ensure that we use test's config and cache files, not global ones.
|
2018-03-05 20:42:11 +01:00
|
|
|
$ENV{'KRB5_CONFIG'} = $krb5_conf;
|
|
|
|
$ENV{'KRB5_KDC_PROFILE'} = $kdc_conf;
|
2021-01-25 20:53:13 +01:00
|
|
|
$ENV{'KRB5CCNAME'} = $krb5_cache;
|
2018-03-05 20:42:11 +01:00
|
|
|
|
2018-08-04 05:53:25 +02:00
|
|
|
my $service_principal = "$ENV{with_krb_srvnam}/$host";
|
2018-03-05 20:42:11 +01:00
|
|
|
|
|
|
|
system_or_bail $kdb5_util, 'create', '-s', '-P', 'secret0';
|
|
|
|
|
|
|
|
my $test1_password = 'secret1';
|
|
|
|
system_or_bail $kadmin_local, '-q', "addprinc -pw $test1_password test1";
|
|
|
|
|
|
|
|
system_or_bail $kadmin_local, '-q', "addprinc -randkey $service_principal";
|
|
|
|
system_or_bail $kadmin_local, '-q', "ktadd -k $keytab $service_principal";
|
|
|
|
|
|
|
|
system_or_bail $krb5kdc, '-P', $kdc_pidfile;
|
|
|
|
|
|
|
|
END
|
|
|
|
{
|
2024-04-07 19:21:27 +02:00
|
|
|
# take care not to change the script's exit value
|
|
|
|
my $exit_code = $?;
|
|
|
|
|
2023-12-29 23:54:40 +01:00
|
|
|
kill 'INT', `cat $kdc_pidfile` if defined($kdc_pidfile) && -f $kdc_pidfile;
|
2024-04-07 19:21:27 +02:00
|
|
|
|
|
|
|
$? = $exit_code;
|
2018-03-05 20:42:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
note "setting up PostgreSQL instance";
|
|
|
|
|
2021-10-24 16:28:19 +02:00
|
|
|
my $node = PostgreSQL::Test::Cluster->new('node');
|
2018-03-05 20:42:11 +01:00
|
|
|
$node->init;
|
2020-12-25 03:37:46 +01:00
|
|
|
$node->append_conf(
|
|
|
|
'postgresql.conf', qq{
|
|
|
|
listen_addresses = '$hostaddr'
|
|
|
|
krb_server_keyfile = '$keytab'
|
|
|
|
log_connections = on
|
|
|
|
lc_messages = 'C'
|
|
|
|
});
|
2018-03-05 20:42:11 +01:00
|
|
|
$node->start;
|
|
|
|
|
2023-04-13 14:55:07 +02:00
|
|
|
my $port = $node->port();
|
|
|
|
|
2018-03-05 20:42:11 +01:00
|
|
|
$node->safe_psql('postgres', 'CREATE USER test1;');
|
2023-04-13 14:55:07 +02:00
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"CREATE USER test2 WITH ENCRYPTED PASSWORD 'abc123';");
|
|
|
|
$node->safe_psql('postgres', 'CREATE EXTENSION postgres_fdw;');
|
|
|
|
$node->safe_psql('postgres', 'CREATE EXTENSION dblink;');
|
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"CREATE SERVER s1 FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host '$host', hostaddr '$hostaddr', port '$port', dbname 'postgres');"
|
|
|
|
);
|
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"CREATE SERVER s2 FOREIGN DATA WRAPPER postgres_fdw OPTIONS (port '$port', dbname 'postgres', passfile '$pgpass');"
|
|
|
|
);
|
|
|
|
|
|
|
|
$node->safe_psql('postgres', 'GRANT USAGE ON FOREIGN SERVER s1 TO test1;');
|
|
|
|
|
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"CREATE USER MAPPING FOR test1 SERVER s1 OPTIONS (user 'test1');");
|
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"CREATE USER MAPPING FOR test1 SERVER s2 OPTIONS (user 'test2');");
|
|
|
|
|
|
|
|
$node->safe_psql('postgres', "CREATE TABLE t1 (c1 int);");
|
|
|
|
$node->safe_psql('postgres', "INSERT INTO t1 VALUES (1);");
|
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"CREATE FOREIGN TABLE tf1 (c1 int) SERVER s1 OPTIONS (schema_name 'public', table_name 't1');"
|
|
|
|
);
|
|
|
|
$node->safe_psql('postgres', "GRANT SELECT ON t1 TO test1;");
|
|
|
|
$node->safe_psql('postgres', "GRANT SELECT ON tf1 TO test1;");
|
|
|
|
|
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"CREATE FOREIGN TABLE tf2 (c1 int) SERVER s2 OPTIONS (schema_name 'public', table_name 't1');"
|
|
|
|
);
|
|
|
|
$node->safe_psql('postgres', "GRANT SELECT ON tf2 TO test1;");
|
2018-03-05 20:42:11 +01:00
|
|
|
|
Introduce SYSTEM_USER
SYSTEM_USER is a reserved keyword of the SQL specification that,
roughly described, is aimed at reporting some information about the
system user who has connected to the database server. It may include
implementation-specific information about the means by the user
connected, like an authentication method.
This commit implements SYSTEM_USER as of auth_method:identity, where
"auth_method" is a keyword about the authentication method used to log
into the server (like peer, md5, scram-sha-256, gss, etc.) and
"identity" is the authentication identity as introduced by 9afffcb (peer
sets authn to the OS user name, gss to the user principal, etc.). This
format has been suggested by Tom Lane.
Note that thanks to d951052, SYSTEM_USER is available to parallel
workers.
Bump catalog version.
Author: Bertrand Drouvot
Reviewed-by: Jacob Champion, Joe Conway, Álvaro Herrera, Michael Paquier
Discussion: https://postgr.es/m/7e692b8c-0b11-45db-1cad-3afc5b57409f@amazon.com
2022-09-29 08:05:40 +02:00
|
|
|
# Set up a table for SYSTEM_USER parallel worker testing.
|
|
|
|
$node->safe_psql('postgres',
|
|
|
|
"CREATE TABLE ids (id) AS SELECT 'gss:test1\@$realm' FROM generate_series(1, 10);"
|
|
|
|
);
|
|
|
|
|
|
|
|
$node->safe_psql('postgres', 'GRANT SELECT ON ids TO public;');
|
|
|
|
|
2018-03-05 20:42:11 +01:00
|
|
|
note "running tests";
|
|
|
|
|
2020-01-11 23:14:08 +01:00
|
|
|
# Test connection success or failure, and if success, that query returns true.
|
2018-03-05 20:42:11 +01:00
|
|
|
sub test_access
|
|
|
|
{
|
2021-09-23 22:49:20 +02:00
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
my ($node, $role, $query, $expected_res, $gssencmode, $test_name,
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
@expect_log_msgs)
|
2021-04-05 03:13:57 +02:00
|
|
|
= @_;
|
2018-03-05 20:42:11 +01:00
|
|
|
|
|
|
|
# need to connect over TCP/IP for Kerberos
|
2021-04-05 03:13:57 +02:00
|
|
|
my $connstr = $node->connstr('postgres')
|
|
|
|
. " user=$role host=$host hostaddr=$hostaddr $gssencmode";
|
|
|
|
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
my %params = (sql => $query,);
|
|
|
|
|
|
|
|
if (@expect_log_msgs)
|
|
|
|
{
|
|
|
|
# Match every message literally.
|
|
|
|
my @regexes = map { qr/\Q$_\E/ } @expect_log_msgs;
|
|
|
|
|
|
|
|
$params{log_like} = \@regexes;
|
|
|
|
}
|
|
|
|
|
2021-04-05 03:13:57 +02:00
|
|
|
if ($expected_res eq 0)
|
2019-04-20 03:22:22 +02:00
|
|
|
{
|
2021-04-05 03:13:57 +02:00
|
|
|
# The result is assumed to match "true", or "t", here.
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
$params{expected_stdout} = qr/^t$/;
|
|
|
|
|
|
|
|
$node->connect_ok($connstr, $test_name, %params);
|
2019-04-20 03:22:22 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
$node->connect_fails($connstr, $test_name, %params);
|
2019-04-20 03:22:22 +02:00
|
|
|
}
|
2018-03-05 20:42:11 +01:00
|
|
|
}
|
|
|
|
|
2020-01-11 23:14:08 +01:00
|
|
|
# As above, but test for an arbitrary query result.
|
|
|
|
sub test_query
|
|
|
|
{
|
2021-10-12 04:15:44 +02:00
|
|
|
local $Test::Builder::Level = $Test::Builder::Level + 1;
|
|
|
|
|
2020-01-11 23:14:08 +01:00
|
|
|
my ($node, $role, $query, $expected, $gssencmode, $test_name) = @_;
|
|
|
|
|
|
|
|
# need to connect over TCP/IP for Kerberos
|
2021-04-05 03:13:57 +02:00
|
|
|
my $connstr = $node->connstr('postgres')
|
|
|
|
. " user=$role host=$host hostaddr=$hostaddr $gssencmode";
|
|
|
|
|
2021-04-06 06:23:57 +02:00
|
|
|
$node->connect_ok(
|
|
|
|
$connstr, $test_name,
|
|
|
|
sql => $query,
|
|
|
|
expected_stdout => $expected);
|
2020-01-11 23:14:08 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-05 20:42:11 +01:00
|
|
|
unlink($node->data_dir . '/pg_hba.conf');
|
2018-08-04 05:53:25 +02:00
|
|
|
$node->append_conf(
|
|
|
|
'pg_hba.conf',
|
2023-04-13 14:55:07 +02:00
|
|
|
qq{
|
|
|
|
local all test2 scram-sha-256
|
|
|
|
host all all $hostaddr/32 gss map=mymap
|
|
|
|
});
|
2018-03-05 20:42:11 +01:00
|
|
|
$node->restart;
|
|
|
|
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
test_access($node, 'test1', 'SELECT true', 2, '', 'fails without ticket');
|
2018-03-05 20:42:11 +01:00
|
|
|
|
|
|
|
run_log [ $kinit, 'test1' ], \$test1_password or BAIL_OUT($?);
|
2023-04-13 14:55:07 +02:00
|
|
|
run_log [ $klist, '-f' ] or BAIL_OUT($?);
|
2018-03-05 20:42:11 +01:00
|
|
|
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
'SELECT true',
|
|
|
|
2,
|
|
|
|
'',
|
|
|
|
'fails without mapping',
|
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
|
|
|
"no match in usermap \"mymap\" for user \"test1\"");
|
2018-03-05 20:42:11 +01:00
|
|
|
|
|
|
|
$node->append_conf('pg_ident.conf', qq{mymap /^(.*)\@$realm\$ \\1});
|
|
|
|
$node->restart;
|
|
|
|
|
2019-04-20 03:22:22 +02:00
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated FROM pg_stat_gssapi WHERE pid = pg_backend_pid();',
|
2019-04-20 03:22:22 +02:00
|
|
|
0,
|
|
|
|
'',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with mapping with default gssencmode and host hba, ticket not forwardable',
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2020-12-02 20:41:53 +01:00
|
|
|
);
|
|
|
|
|
2019-04-20 03:22:22 +02:00
|
|
|
test_access(
|
|
|
|
$node,
|
2020-12-02 20:41:53 +01:00
|
|
|
'test1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated FROM pg_stat_gssapi WHERE pid = pg_backend_pid();',
|
2019-04-20 03:22:22 +02:00
|
|
|
0,
|
2020-12-02 20:41:53 +01:00
|
|
|
'gssencmode=prefer',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access preferred with host hba, ticket not forwardable',
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2020-12-02 20:41:53 +01:00
|
|
|
);
|
2023-04-13 14:55:07 +02:00
|
|
|
|
2019-04-20 03:22:22 +02:00
|
|
|
test_access(
|
|
|
|
$node,
|
2020-12-02 20:41:53 +01:00
|
|
|
'test1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated FROM pg_stat_gssapi WHERE pid = pg_backend_pid();',
|
2019-04-20 03:22:22 +02:00
|
|
|
0,
|
2020-12-02 20:41:53 +01:00
|
|
|
'gssencmode=require',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access required with host hba, ticket not forwardable',
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2020-12-02 20:41:53 +01:00
|
|
|
);
|
2019-04-20 03:22:22 +02:00
|
|
|
|
2023-04-13 14:55:07 +02:00
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated FROM pg_stat_gssapi WHERE pid = pg_backend_pid();',
|
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=prefer gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access preferred with host hba and credentials not delegated even though asked for (ticket not forwardable)',
|
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2023-04-13 14:55:07 +02:00
|
|
|
);
|
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated FROM pg_stat_gssapi WHERE pid = pg_backend_pid();',
|
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=require gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access required with host hba and credentials not delegated even though asked for (ticket not forwardable)',
|
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2023-04-13 14:55:07 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
|
2020-01-11 23:14:08 +01:00
|
|
|
# Test that we can transport a reasonable amount of data.
|
|
|
|
test_query(
|
|
|
|
$node,
|
2020-12-02 20:41:53 +01:00
|
|
|
'test1',
|
2020-01-11 23:14:08 +01:00
|
|
|
'SELECT * FROM generate_series(1, 100000);',
|
|
|
|
qr/^1\n.*\n1024\n.*\n9999\n.*\n100000$/s,
|
2020-12-02 20:41:53 +01:00
|
|
|
'gssencmode=require',
|
|
|
|
'receiving 100K lines works');
|
2020-01-11 23:14:08 +01:00
|
|
|
|
|
|
|
test_query(
|
|
|
|
$node,
|
2020-12-02 20:41:53 +01:00
|
|
|
'test1',
|
2021-09-10 09:44:01 +02:00
|
|
|
"CREATE TEMP TABLE mytab (f1 int primary key);\n"
|
2020-01-11 23:14:08 +01:00
|
|
|
. "COPY mytab FROM STDIN;\n"
|
|
|
|
. join("\n", (1 .. 100000))
|
|
|
|
. "\n\\.\n"
|
|
|
|
. "SELECT COUNT(*) FROM mytab;",
|
|
|
|
qr/^100000$/s,
|
2020-12-02 20:41:53 +01:00
|
|
|
'gssencmode=require',
|
|
|
|
'sending 100K lines works');
|
2020-01-11 23:14:08 +01:00
|
|
|
|
libpq: Add support for require_auth to control authorized auth methods
The new connection parameter require_auth allows a libpq client to
define a list of comma-separated acceptable authentication types for use
with the server. There is no negotiation: if the server does not
present one of the allowed authentication requests, the connection
attempt done by the client fails.
The following keywords can be defined in the list:
- password, for AUTH_REQ_PASSWORD.
- md5, for AUTH_REQ_MD5.
- gss, for AUTH_REQ_GSS[_CONT].
- sspi, for AUTH_REQ_SSPI and AUTH_REQ_GSS_CONT.
- scram-sha-256, for AUTH_REQ_SASL[_CONT|_FIN].
- creds, for AUTH_REQ_SCM_CREDS (perhaps this should be removed entirely
now).
- none, to control unauthenticated connections.
All the methods that can be defined in the list can be negated, like
"!password", in which case the server must NOT use the listed
authentication type. The special method "none" allows/disallows the use
of unauthenticated connections (but it does not govern transport-level
authentication via TLS or GSSAPI).
Internally, the patch logic is tied to check_expected_areq(), that was
used for channel_binding, ensuring that an incoming request is
compatible with conn->require_auth. It also introduces a new flag,
conn->client_finished_auth, which is set by various authentication
routines when the client side of the handshake is finished. This
signals to check_expected_areq() that an AUTH_REQ_OK from the server is
expected, and allows the client to complain if the server bypasses
authentication entirely, with for example the reception of a too-early
AUTH_REQ_OK message.
Regression tests are added in authentication TAP tests for all the
keywords supported (except "creds", because it is around only for
compatibility reasons). A new TAP script has been added for SSPI, as
there was no script dedicated to it yet. It relies on SSPI being the
default authentication method on Windows, as set by pg_regress.
Author: Jacob Champion
Reviewed-by: Peter Eisentraut, David G. Johnston, Michael Paquier
Discussion: https://postgr.es/m/9e5a8ccddb8355ea9fa4b75a1e3a9edc88a70cd3.camel@vmware.com
2023-03-14 06:00:05 +01:00
|
|
|
# require_auth=gss succeeds if required.
|
|
|
|
$node->connect_ok(
|
|
|
|
$node->connstr('postgres')
|
|
|
|
. " user=test1 host=$host hostaddr=$hostaddr gssencmode=disable require_auth=gss",
|
2023-04-18 03:23:23 +02:00
|
|
|
"GSS authentication requested, works with non-encrypted GSS");
|
libpq: Add support for require_auth to control authorized auth methods
The new connection parameter require_auth allows a libpq client to
define a list of comma-separated acceptable authentication types for use
with the server. There is no negotiation: if the server does not
present one of the allowed authentication requests, the connection
attempt done by the client fails.
The following keywords can be defined in the list:
- password, for AUTH_REQ_PASSWORD.
- md5, for AUTH_REQ_MD5.
- gss, for AUTH_REQ_GSS[_CONT].
- sspi, for AUTH_REQ_SSPI and AUTH_REQ_GSS_CONT.
- scram-sha-256, for AUTH_REQ_SASL[_CONT|_FIN].
- creds, for AUTH_REQ_SCM_CREDS (perhaps this should be removed entirely
now).
- none, to control unauthenticated connections.
All the methods that can be defined in the list can be negated, like
"!password", in which case the server must NOT use the listed
authentication type. The special method "none" allows/disallows the use
of unauthenticated connections (but it does not govern transport-level
authentication via TLS or GSSAPI).
Internally, the patch logic is tied to check_expected_areq(), that was
used for channel_binding, ensuring that an incoming request is
compatible with conn->require_auth. It also introduces a new flag,
conn->client_finished_auth, which is set by various authentication
routines when the client side of the handshake is finished. This
signals to check_expected_areq() that an AUTH_REQ_OK from the server is
expected, and allows the client to complain if the server bypasses
authentication entirely, with for example the reception of a too-early
AUTH_REQ_OK message.
Regression tests are added in authentication TAP tests for all the
keywords supported (except "creds", because it is around only for
compatibility reasons). A new TAP script has been added for SSPI, as
there was no script dedicated to it yet. It relies on SSPI being the
default authentication method on Windows, as set by pg_regress.
Author: Jacob Champion
Reviewed-by: Peter Eisentraut, David G. Johnston, Michael Paquier
Discussion: https://postgr.es/m/9e5a8ccddb8355ea9fa4b75a1e3a9edc88a70cd3.camel@vmware.com
2023-03-14 06:00:05 +01:00
|
|
|
$node->connect_ok(
|
|
|
|
$node->connstr('postgres')
|
|
|
|
. " user=test1 host=$host hostaddr=$hostaddr gssencmode=require require_auth=gss",
|
|
|
|
"GSS authentication requested, works with encrypted GSS auth");
|
|
|
|
|
|
|
|
# require_auth=sspi fails if required.
|
|
|
|
$node->connect_fails(
|
|
|
|
$node->connstr('postgres')
|
|
|
|
. " user=test1 host=$host hostaddr=$hostaddr gssencmode=disable require_auth=sspi",
|
|
|
|
"SSPI authentication requested, fails with non-encrypted GSS",
|
|
|
|
expected_stderr =>
|
2023-05-16 08:59:34 +02:00
|
|
|
qr/authentication method requirement "sspi" failed: server requested GSSAPI authentication/
|
libpq: Add support for require_auth to control authorized auth methods
The new connection parameter require_auth allows a libpq client to
define a list of comma-separated acceptable authentication types for use
with the server. There is no negotiation: if the server does not
present one of the allowed authentication requests, the connection
attempt done by the client fails.
The following keywords can be defined in the list:
- password, for AUTH_REQ_PASSWORD.
- md5, for AUTH_REQ_MD5.
- gss, for AUTH_REQ_GSS[_CONT].
- sspi, for AUTH_REQ_SSPI and AUTH_REQ_GSS_CONT.
- scram-sha-256, for AUTH_REQ_SASL[_CONT|_FIN].
- creds, for AUTH_REQ_SCM_CREDS (perhaps this should be removed entirely
now).
- none, to control unauthenticated connections.
All the methods that can be defined in the list can be negated, like
"!password", in which case the server must NOT use the listed
authentication type. The special method "none" allows/disallows the use
of unauthenticated connections (but it does not govern transport-level
authentication via TLS or GSSAPI).
Internally, the patch logic is tied to check_expected_areq(), that was
used for channel_binding, ensuring that an incoming request is
compatible with conn->require_auth. It also introduces a new flag,
conn->client_finished_auth, which is set by various authentication
routines when the client side of the handshake is finished. This
signals to check_expected_areq() that an AUTH_REQ_OK from the server is
expected, and allows the client to complain if the server bypasses
authentication entirely, with for example the reception of a too-early
AUTH_REQ_OK message.
Regression tests are added in authentication TAP tests for all the
keywords supported (except "creds", because it is around only for
compatibility reasons). A new TAP script has been added for SSPI, as
there was no script dedicated to it yet. It relies on SSPI being the
default authentication method on Windows, as set by pg_regress.
Author: Jacob Champion
Reviewed-by: Peter Eisentraut, David G. Johnston, Michael Paquier
Discussion: https://postgr.es/m/9e5a8ccddb8355ea9fa4b75a1e3a9edc88a70cd3.camel@vmware.com
2023-03-14 06:00:05 +01:00
|
|
|
);
|
|
|
|
$node->connect_fails(
|
|
|
|
$node->connstr('postgres')
|
|
|
|
. " user=test1 host=$host hostaddr=$hostaddr gssencmode=require require_auth=sspi",
|
|
|
|
"SSPI authentication requested, fails with encrypted GSS",
|
|
|
|
expected_stderr =>
|
2023-05-16 08:59:34 +02:00
|
|
|
qr/authentication method requirement "sspi" failed: server did not complete authentication/
|
libpq: Add support for require_auth to control authorized auth methods
The new connection parameter require_auth allows a libpq client to
define a list of comma-separated acceptable authentication types for use
with the server. There is no negotiation: if the server does not
present one of the allowed authentication requests, the connection
attempt done by the client fails.
The following keywords can be defined in the list:
- password, for AUTH_REQ_PASSWORD.
- md5, for AUTH_REQ_MD5.
- gss, for AUTH_REQ_GSS[_CONT].
- sspi, for AUTH_REQ_SSPI and AUTH_REQ_GSS_CONT.
- scram-sha-256, for AUTH_REQ_SASL[_CONT|_FIN].
- creds, for AUTH_REQ_SCM_CREDS (perhaps this should be removed entirely
now).
- none, to control unauthenticated connections.
All the methods that can be defined in the list can be negated, like
"!password", in which case the server must NOT use the listed
authentication type. The special method "none" allows/disallows the use
of unauthenticated connections (but it does not govern transport-level
authentication via TLS or GSSAPI).
Internally, the patch logic is tied to check_expected_areq(), that was
used for channel_binding, ensuring that an incoming request is
compatible with conn->require_auth. It also introduces a new flag,
conn->client_finished_auth, which is set by various authentication
routines when the client side of the handshake is finished. This
signals to check_expected_areq() that an AUTH_REQ_OK from the server is
expected, and allows the client to complain if the server bypasses
authentication entirely, with for example the reception of a too-early
AUTH_REQ_OK message.
Regression tests are added in authentication TAP tests for all the
keywords supported (except "creds", because it is around only for
compatibility reasons). A new TAP script has been added for SSPI, as
there was no script dedicated to it yet. It relies on SSPI being the
default authentication method on Windows, as set by pg_regress.
Author: Jacob Champion
Reviewed-by: Peter Eisentraut, David G. Johnston, Michael Paquier
Discussion: https://postgr.es/m/9e5a8ccddb8355ea9fa4b75a1e3a9edc88a70cd3.camel@vmware.com
2023-03-14 06:00:05 +01:00
|
|
|
);
|
|
|
|
|
Introduce SYSTEM_USER
SYSTEM_USER is a reserved keyword of the SQL specification that,
roughly described, is aimed at reporting some information about the
system user who has connected to the database server. It may include
implementation-specific information about the means by the user
connected, like an authentication method.
This commit implements SYSTEM_USER as of auth_method:identity, where
"auth_method" is a keyword about the authentication method used to log
into the server (like peer, md5, scram-sha-256, gss, etc.) and
"identity" is the authentication identity as introduced by 9afffcb (peer
sets authn to the OS user name, gss to the user principal, etc.). This
format has been suggested by Tom Lane.
Note that thanks to d951052, SYSTEM_USER is available to parallel
workers.
Bump catalog version.
Author: Bertrand Drouvot
Reviewed-by: Jacob Champion, Joe Conway, Álvaro Herrera, Michael Paquier
Discussion: https://postgr.es/m/7e692b8c-0b11-45db-1cad-3afc5b57409f@amazon.com
2022-09-29 08:05:40 +02:00
|
|
|
# Test that SYSTEM_USER works.
|
|
|
|
test_query($node, 'test1', 'SELECT SYSTEM_USER;',
|
|
|
|
qr/^gss:test1\@$realm$/s, 'gssencmode=require', 'testing system_user');
|
|
|
|
|
|
|
|
# Test that SYSTEM_USER works with parallel workers.
|
|
|
|
test_query(
|
|
|
|
$node,
|
|
|
|
'test1', qq(
|
|
|
|
SET min_parallel_table_scan_size TO 0;
|
|
|
|
SET parallel_setup_cost TO 0;
|
|
|
|
SET parallel_tuple_cost TO 0;
|
|
|
|
SET max_parallel_workers_per_gather TO 2;
|
|
|
|
SELECT bool_and(SYSTEM_USER = id) FROM ids;),
|
|
|
|
qr/^t$/s,
|
|
|
|
'gssencmode=require',
|
|
|
|
'testing system_user with parallel workers');
|
|
|
|
|
2019-04-20 03:22:22 +02:00
|
|
|
unlink($node->data_dir . '/pg_hba.conf');
|
|
|
|
$node->append_conf(
|
|
|
|
'pg_hba.conf',
|
2023-04-13 14:55:07 +02:00
|
|
|
qq{
|
|
|
|
local all test2 scram-sha-256
|
|
|
|
hostgssenc all all $hostaddr/32 gss map=mymap
|
|
|
|
});
|
|
|
|
|
|
|
|
string_replace_file($krb5_conf, "forwardable = false", "forwardable = true");
|
|
|
|
|
|
|
|
run_log [ $kinit, 'test1' ], \$test1_password or BAIL_OUT($?);
|
|
|
|
run_log [ $klist, '-f' ] or BAIL_OUT($?);
|
|
|
|
|
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated from pg_stat_gssapi where pid = pg_backend_pid();',
|
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=prefer gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access preferred and hostgssenc hba and credentials not forwarded (server does not accept them, default)',
|
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2023-04-13 14:55:07 +02:00
|
|
|
);
|
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated from pg_stat_gssapi where pid = pg_backend_pid();',
|
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=require gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access required and hostgssenc hba and credentials not forwarded (server does not accept them, default)',
|
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2023-04-13 14:55:07 +02:00
|
|
|
);
|
|
|
|
|
2023-05-21 05:18:51 +02:00
|
|
|
$node->append_conf('postgresql.conf', qq{gss_accept_delegation=off});
|
2023-04-13 14:55:07 +02:00
|
|
|
$node->restart;
|
|
|
|
|
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated from pg_stat_gssapi where pid = pg_backend_pid();',
|
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=prefer gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access preferred and hostgssenc hba and credentials not forwarded (server does not accept them, explicitly disabled)',
|
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2023-04-13 14:55:07 +02:00
|
|
|
);
|
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated from pg_stat_gssapi where pid = pg_backend_pid();',
|
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=require gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access required and hostgssenc hba and credentials not forwarded (server does not accept them, explicitly disabled)',
|
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2023-04-13 14:55:07 +02:00
|
|
|
);
|
|
|
|
|
2023-05-21 05:18:51 +02:00
|
|
|
$node->append_conf('postgresql.conf', qq{gss_accept_delegation=on});
|
2019-04-20 03:22:22 +02:00
|
|
|
$node->restart;
|
|
|
|
|
|
|
|
test_access(
|
|
|
|
$node,
|
2020-12-02 20:41:53 +01:00
|
|
|
'test1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'SELECT gss_authenticated AND encrypted AND credentials_delegated from pg_stat_gssapi where pid = pg_backend_pid();',
|
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=prefer gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access preferred and hostgssenc hba and credentials forwarded',
|
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=yes, principal=test1\@$realm)"
|
2023-04-13 14:55:07 +02:00
|
|
|
);
|
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
'SELECT gss_authenticated AND encrypted AND credentials_delegated from pg_stat_gssapi where pid = pg_backend_pid();',
|
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=require gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access required and hostgssenc hba and credentials forwarded',
|
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=yes, principal=test1\@$realm)"
|
2023-04-13 14:55:07 +02:00
|
|
|
);
|
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated FROM pg_stat_gssapi WHERE pid = pg_backend_pid();',
|
2019-04-20 03:22:22 +02:00
|
|
|
0,
|
2020-12-02 20:41:53 +01:00
|
|
|
'gssencmode=prefer',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access preferred and hostgssenc hba and credentials not forwarded',
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2020-12-02 20:41:53 +01:00
|
|
|
);
|
2019-04-20 03:22:22 +02:00
|
|
|
test_access(
|
|
|
|
$node,
|
2020-12-02 20:41:53 +01:00
|
|
|
'test1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'SELECT gss_authenticated AND encrypted AND NOT credentials_delegated FROM pg_stat_gssapi WHERE pid = pg_backend_pid();',
|
2019-04-20 03:22:22 +02:00
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=require gssdelegation=0',
|
2023-04-13 14:55:07 +02:00
|
|
|
'succeeds with GSS-encrypted access required and hostgssenc hba and credentials explicitly not forwarded',
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=no, principal=test1\@$realm)"
|
2023-04-13 14:55:07 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
my $psql_out = '';
|
|
|
|
my $psql_stderr = '';
|
|
|
|
my $psql_rc = '';
|
|
|
|
|
|
|
|
$psql_rc = $node->psql(
|
|
|
|
'postgres',
|
|
|
|
"SELECT * FROM dblink('user=test1 dbname=$dbname host=$host hostaddr=$hostaddr port=$port','select 1') as t1(c1 int);",
|
|
|
|
connstr =>
|
2023-05-22 17:50:20 +02:00
|
|
|
"user=test1 host=$host hostaddr=$hostaddr gssencmode=require gssdelegation=0",
|
2023-04-13 14:55:07 +02:00
|
|
|
stdout => \$psql_out,
|
|
|
|
stderr => \$psql_stderr);
|
|
|
|
is($psql_rc, '3', 'dblink attempt fails without delegated credentials');
|
|
|
|
like(
|
|
|
|
$psql_stderr,
|
|
|
|
qr/password or GSSAPI delegated credentials required/,
|
|
|
|
'dblink does not work without delegated credentials');
|
|
|
|
like($psql_out, qr/^$/, 'dblink does not work without delegated credentials');
|
|
|
|
|
|
|
|
$psql_out = '';
|
|
|
|
$psql_stderr = '';
|
|
|
|
|
|
|
|
$psql_rc = $node->psql(
|
|
|
|
'postgres',
|
|
|
|
"SELECT * FROM dblink('user=test2 dbname=$dbname port=$port passfile=$pgpass','select 1') as t1(c1 int);",
|
|
|
|
connstr =>
|
2023-05-22 17:50:20 +02:00
|
|
|
"user=test1 host=$host hostaddr=$hostaddr gssencmode=require gssdelegation=0",
|
2023-04-13 14:55:07 +02:00
|
|
|
stdout => \$psql_out,
|
|
|
|
stderr => \$psql_stderr);
|
|
|
|
is($psql_rc, '3',
|
|
|
|
'dblink does not work without delegated credentials and with passfile');
|
|
|
|
like(
|
|
|
|
$psql_stderr,
|
|
|
|
qr/password or GSSAPI delegated credentials required/,
|
|
|
|
'dblink does not work without delegated credentials and with passfile');
|
|
|
|
like($psql_out, qr/^$/,
|
|
|
|
'dblink does not work without delegated credentials and with passfile');
|
|
|
|
|
|
|
|
$psql_out = '';
|
|
|
|
$psql_stderr = '';
|
|
|
|
|
|
|
|
$psql_rc = $node->psql(
|
|
|
|
'postgres',
|
|
|
|
"TABLE tf1;",
|
|
|
|
connstr =>
|
2023-05-22 17:50:20 +02:00
|
|
|
"user=test1 host=$host hostaddr=$hostaddr gssencmode=require gssdelegation=0",
|
2023-04-13 14:55:07 +02:00
|
|
|
stdout => \$psql_out,
|
|
|
|
stderr => \$psql_stderr);
|
|
|
|
is($psql_rc, '3', 'postgres_fdw does not work without delegated credentials');
|
|
|
|
like(
|
|
|
|
$psql_stderr,
|
|
|
|
qr/password or GSSAPI delegated credentials required/,
|
|
|
|
'postgres_fdw does not work without delegated credentials');
|
|
|
|
like($psql_out, qr/^$/,
|
|
|
|
'postgres_fdw does not work without delegated credentials');
|
|
|
|
|
|
|
|
$psql_out = '';
|
|
|
|
$psql_stderr = '';
|
|
|
|
|
|
|
|
$psql_rc = $node->psql(
|
|
|
|
'postgres',
|
|
|
|
"TABLE tf2;",
|
|
|
|
connstr =>
|
2023-05-22 17:50:20 +02:00
|
|
|
"user=test1 host=$host hostaddr=$hostaddr gssencmode=require gssdelegation=0",
|
2023-04-13 14:55:07 +02:00
|
|
|
stdout => \$psql_out,
|
|
|
|
stderr => \$psql_stderr);
|
|
|
|
is($psql_rc, '3',
|
|
|
|
'postgres_fdw does not work without delegated credentials and with passfile'
|
2023-05-19 23:24:48 +02:00
|
|
|
);
|
|
|
|
like(
|
2023-04-13 14:55:07 +02:00
|
|
|
$psql_stderr,
|
|
|
|
qr/password or GSSAPI delegated credentials required/,
|
|
|
|
'postgres_fdw does not work without delegated credentials and with passfile'
|
2023-05-19 23:24:48 +02:00
|
|
|
);
|
2023-04-13 14:55:07 +02:00
|
|
|
like($psql_out, qr/^$/,
|
|
|
|
'postgres_fdw does not work without delegated credentials and with passfile'
|
|
|
|
);
|
|
|
|
|
2020-12-02 20:41:53 +01:00
|
|
|
test_access($node, 'test1', 'SELECT true', 2, 'gssencmode=disable',
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
'fails with GSS encryption disabled and hostgssenc hba');
|
2019-04-20 03:22:22 +02:00
|
|
|
|
libpq: Add support for require_auth to control authorized auth methods
The new connection parameter require_auth allows a libpq client to
define a list of comma-separated acceptable authentication types for use
with the server. There is no negotiation: if the server does not
present one of the allowed authentication requests, the connection
attempt done by the client fails.
The following keywords can be defined in the list:
- password, for AUTH_REQ_PASSWORD.
- md5, for AUTH_REQ_MD5.
- gss, for AUTH_REQ_GSS[_CONT].
- sspi, for AUTH_REQ_SSPI and AUTH_REQ_GSS_CONT.
- scram-sha-256, for AUTH_REQ_SASL[_CONT|_FIN].
- creds, for AUTH_REQ_SCM_CREDS (perhaps this should be removed entirely
now).
- none, to control unauthenticated connections.
All the methods that can be defined in the list can be negated, like
"!password", in which case the server must NOT use the listed
authentication type. The special method "none" allows/disallows the use
of unauthenticated connections (but it does not govern transport-level
authentication via TLS or GSSAPI).
Internally, the patch logic is tied to check_expected_areq(), that was
used for channel_binding, ensuring that an incoming request is
compatible with conn->require_auth. It also introduces a new flag,
conn->client_finished_auth, which is set by various authentication
routines when the client side of the handshake is finished. This
signals to check_expected_areq() that an AUTH_REQ_OK from the server is
expected, and allows the client to complain if the server bypasses
authentication entirely, with for example the reception of a too-early
AUTH_REQ_OK message.
Regression tests are added in authentication TAP tests for all the
keywords supported (except "creds", because it is around only for
compatibility reasons). A new TAP script has been added for SSPI, as
there was no script dedicated to it yet. It relies on SSPI being the
default authentication method on Windows, as set by pg_regress.
Author: Jacob Champion
Reviewed-by: Peter Eisentraut, David G. Johnston, Michael Paquier
Discussion: https://postgr.es/m/9e5a8ccddb8355ea9fa4b75a1e3a9edc88a70cd3.camel@vmware.com
2023-03-14 06:00:05 +01:00
|
|
|
# require_auth=gss succeeds if required.
|
|
|
|
$node->connect_ok(
|
|
|
|
$node->connstr('postgres')
|
|
|
|
. " user=test1 host=$host hostaddr=$hostaddr gssencmode=require require_auth=gss",
|
|
|
|
"GSS authentication requested, works with GSS encryption");
|
|
|
|
$node->connect_ok(
|
|
|
|
$node->connstr('postgres')
|
|
|
|
. " user=test1 host=$host hostaddr=$hostaddr gssencmode=require require_auth=gss,scram-sha-256",
|
|
|
|
"multiple authentication types requested, works with GSS encryption");
|
|
|
|
|
2019-04-20 03:22:22 +02:00
|
|
|
unlink($node->data_dir . '/pg_hba.conf');
|
|
|
|
$node->append_conf(
|
|
|
|
'pg_hba.conf',
|
2023-04-13 14:55:07 +02:00
|
|
|
qq{
|
|
|
|
local all test2 scram-sha-256
|
|
|
|
hostnogssenc all all $hostaddr/32 gss map=mymap
|
|
|
|
});
|
2019-04-20 03:22:22 +02:00
|
|
|
$node->restart;
|
|
|
|
|
|
|
|
test_access(
|
|
|
|
$node,
|
2020-12-02 20:41:53 +01:00
|
|
|
'test1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'SELECT gss_authenticated AND NOT encrypted AND credentials_delegated FROM pg_stat_gssapi WHERE pid = pg_backend_pid();',
|
2019-04-20 03:22:22 +02:00
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=prefer gssdelegation=1',
|
2020-12-02 20:41:53 +01:00
|
|
|
'succeeds with GSS-encrypted access preferred and hostnogssenc hba, but no encryption',
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=no, delegated_credentials=yes, principal=test1\@$realm)"
|
2019-04-20 03:22:22 +02:00
|
|
|
);
|
2020-12-02 20:41:53 +01:00
|
|
|
test_access($node, 'test1', 'SELECT true', 2, 'gssencmode=require',
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
'fails with GSS-encrypted access required and hostnogssenc hba');
|
2019-04-20 03:22:22 +02:00
|
|
|
test_access(
|
|
|
|
$node,
|
2020-12-02 20:41:53 +01:00
|
|
|
'test1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'SELECT gss_authenticated AND NOT encrypted AND credentials_delegated FROM pg_stat_gssapi WHERE pid = pg_backend_pid();',
|
2019-04-20 03:22:22 +02:00
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=disable gssdelegation=1',
|
2020-12-02 20:41:53 +01:00
|
|
|
'succeeds with GSS encryption disabled and hostnogssenc hba',
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=no, delegated_credentials=yes, principal=test1\@$realm)"
|
2023-04-13 14:55:07 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
test_query(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
"SELECT * FROM dblink('user=test1 dbname=$dbname host=$host hostaddr=$hostaddr port=$port','select 1') as t1(c1 int);",
|
|
|
|
qr/^1$/s,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=prefer gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'dblink works not-encrypted (server not configured to accept encrypted GSSAPI connections)'
|
|
|
|
);
|
|
|
|
|
|
|
|
test_query(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
"TABLE tf1;",
|
|
|
|
qr/^1$/s,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=prefer gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'postgres_fdw works not-encrypted (server not configured to accept encrypted GSSAPI connections)'
|
|
|
|
);
|
|
|
|
|
|
|
|
$psql_out = '';
|
|
|
|
$psql_stderr = '';
|
|
|
|
|
|
|
|
$psql_rc = $node->psql(
|
|
|
|
'postgres',
|
|
|
|
"SELECT * FROM dblink('user=test2 dbname=$dbname port=$port passfile=$pgpass','select 1') as t1(c1 int);",
|
|
|
|
connstr =>
|
2023-05-22 17:50:20 +02:00
|
|
|
"user=test1 host=$host hostaddr=$hostaddr gssencmode=prefer gssdelegation=1",
|
2023-04-13 14:55:07 +02:00
|
|
|
stdout => \$psql_out,
|
|
|
|
stderr => \$psql_stderr);
|
|
|
|
is($psql_rc, '3',
|
|
|
|
'dblink does not work with delegated credentials and with passfile');
|
|
|
|
like(
|
|
|
|
$psql_stderr,
|
|
|
|
qr/password or GSSAPI delegated credentials required/,
|
|
|
|
'dblink does not work with delegated credentials and with passfile');
|
|
|
|
like($psql_out, qr/^$/,
|
|
|
|
'dblink does not work with delegated credentials and with passfile');
|
|
|
|
|
|
|
|
$psql_out = '';
|
|
|
|
$psql_stderr = '';
|
|
|
|
|
|
|
|
$psql_rc = $node->psql(
|
|
|
|
'postgres',
|
|
|
|
"TABLE tf2;",
|
|
|
|
connstr =>
|
2023-05-22 17:50:20 +02:00
|
|
|
"user=test1 host=$host hostaddr=$hostaddr gssencmode=prefer gssdelegation=1",
|
2023-04-13 14:55:07 +02:00
|
|
|
stdout => \$psql_out,
|
|
|
|
stderr => \$psql_stderr);
|
|
|
|
is($psql_rc, '3',
|
|
|
|
'postgres_fdw does not work with delegated credentials and with passfile'
|
2023-05-19 23:24:48 +02:00
|
|
|
);
|
|
|
|
like(
|
2023-04-13 14:55:07 +02:00
|
|
|
$psql_stderr,
|
|
|
|
qr/password or GSSAPI delegated credentials required/,
|
|
|
|
'postgres_fdw does not work with delegated credentials and with passfile'
|
2023-05-19 23:24:48 +02:00
|
|
|
);
|
2023-04-13 14:55:07 +02:00
|
|
|
like($psql_out, qr/^$/,
|
|
|
|
'postgres_fdw does not work with delegated credentials and with passfile'
|
2020-12-02 20:41:53 +01:00
|
|
|
);
|
2018-03-05 20:42:11 +01:00
|
|
|
|
|
|
|
truncate($node->data_dir . '/pg_ident.conf', 0);
|
|
|
|
unlink($node->data_dir . '/pg_hba.conf');
|
|
|
|
$node->append_conf(
|
|
|
|
'pg_hba.conf',
|
2023-04-13 14:55:07 +02:00
|
|
|
qq{
|
|
|
|
local all test2 scram-sha-256
|
|
|
|
host all all $hostaddr/32 gss include_realm=0
|
|
|
|
});
|
2018-03-05 20:42:11 +01:00
|
|
|
$node->restart;
|
|
|
|
|
2019-04-20 03:22:22 +02:00
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'SELECT gss_authenticated AND encrypted AND credentials_delegated FROM pg_stat_gssapi WHERE pid = pg_backend_pid();',
|
2019-04-20 03:22:22 +02:00
|
|
|
0,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssdelegation=1',
|
2020-12-02 20:41:53 +01:00
|
|
|
'succeeds with include_realm=0 and defaults',
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss",
|
2023-05-21 16:55:18 +02:00
|
|
|
"connection authorized: user=$username database=$dbname application_name=$application GSS (authenticated=yes, encrypted=yes, delegated_credentials=yes, principal=test1\@$realm)"
|
2020-12-02 20:41:53 +01:00
|
|
|
);
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
|
2023-04-13 14:55:07 +02:00
|
|
|
test_query(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
"SELECT * FROM dblink('user=test1 dbname=$dbname host=$host hostaddr=$hostaddr port=$port password=1234','select 1') as t1(c1 int);",
|
|
|
|
qr/^1$/s,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=require gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'dblink works encrypted');
|
|
|
|
|
|
|
|
test_query(
|
|
|
|
$node, 'test1', "TABLE tf1;", qr/^1$/s,
|
2023-05-22 17:50:20 +02:00
|
|
|
'gssencmode=require gssdelegation=1',
|
2023-04-13 14:55:07 +02:00
|
|
|
'postgres_fdw works encrypted');
|
|
|
|
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
# Reset pg_hba.conf, and cause a usermap failure with an authentication
|
|
|
|
# that has passed.
|
|
|
|
unlink($node->data_dir . '/pg_hba.conf');
|
|
|
|
$node->append_conf(
|
|
|
|
'pg_hba.conf',
|
2023-04-13 14:55:07 +02:00
|
|
|
qq{
|
|
|
|
local all test2 scram-sha-256
|
|
|
|
host all all $hostaddr/32 gss include_realm=0 krb_realm=EXAMPLE.ORG
|
|
|
|
});
|
Add some information about authenticated identity via log_connections
The "authenticated identity" is the string used by an authentication
method to identify a particular user. In many common cases, this is the
same as the PostgreSQL username, but for some third-party authentication
methods, the identifier in use may be shortened or otherwise translated
(e.g. through pg_ident user mappings) before the server stores it.
To help administrators see who has actually interacted with the system,
this commit adds the capability to store the original identity when
authentication succeeds within the backend's Port, and generates a log
entry when log_connections is enabled. The log entries generated look
something like this (where a local user named "foouser" is connecting to
the database as the database user called "admin"):
LOG: connection received: host=[local]
LOG: connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88)
LOG: connection authorized: user=admin database=postgres application_name=psql
Port->authn_id is set according to the authentication method:
bsd: the PostgreSQL username (aka the local username)
cert: the client's Subject DN
gss: the user principal
ident: the remote username
ldap: the final bind DN
pam: the PostgreSQL username (aka PAM username)
password (and all pw-challenge methods): the PostgreSQL username
peer: the peer's pw_name
radius: the PostgreSQL username (aka the RADIUS username)
sspi: either the down-level (SAM-compatible) logon name, if
compat_realm=1, or the User Principal Name if compat_realm=0
The trust auth method does not set an authenticated identity. Neither
does clientcert=verify-full.
Port->authn_id could be used for other purposes, like a superuser-only
extra column in pg_stat_activity, but this is left as future work.
PostgresNode::connect_{ok,fails}() have been modified to let tests check
the backend log files for required or prohibited patterns, using the
new log_like and log_unlike parameters. This uses a method based on a
truncation of the existing server log file, like issues_sql_like().
Tests are added to the ldap, kerberos, authentication and SSL test
suites.
Author: Jacob Champion
Reviewed-by: Stephen Frost, Magnus Hagander, Tom Lane, Michael Paquier
Discussion: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com
2021-04-07 03:16:39 +02:00
|
|
|
$node->restart;
|
|
|
|
|
|
|
|
test_access(
|
|
|
|
$node,
|
|
|
|
'test1',
|
|
|
|
'SELECT true',
|
|
|
|
2,
|
|
|
|
'',
|
|
|
|
'fails with wrong krb_realm, but still authenticates',
|
|
|
|
"connection authenticated: identity=\"test1\@$realm\" method=gss");
|
2022-02-11 20:54:44 +01:00
|
|
|
|
|
|
|
done_testing();
|