Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc1c88bf

Browse files
committed
Fix assorted issues in backend's GSSAPI encryption support.
Unrecoverable errors detected by GSSAPI encryption can't just bereported with elog(ERROR) or elog(FATAL), because attempting tosend the error report to the client is likely to lead to infiniterecursion or loss of protocol sync. Instead make this code do whatthe SSL encryption code has long done, which is to just report anysuch failure to the server log (with elevel COMMERROR), then pretendwe've lost the connection by returning errno = ECONNRESET.Along the way, fix confusion about whether message translation is doneby pg_GSS_error() or its callers (the latter should do it), and makethe backend version of that function work more like the frontendversion.Avoid allocating the port->gss struct until it's needed; we surelydon't need to allocate it in the postmaster.Improve logging of "connection authorized" messages with GSS enabled.(As part of this, I back-patched the code changes from dc11f31a1.)Make BackendStatusShmemSize() account for the GSS-related space thatwill be allocated by CreateSharedBackendStatus(). This omissioncould possibly cause out-of-shared-memory problems with very highmax_connections settings.Remove arbitrary, pointless restriction that only GSS authenticationcan be used on a GSS-encrypted connection.Improve documentation; notably, document the fact that libpq nowprefers GSS encryption over SSL encryption if both are possible.Per report from Mikael Gustavsson. Back-patch to v12 wherethis code was introduced.Discussion:https://postgr.es/m/e5b0b6ed05764324a2f3fe7acfc766d5@smhi.se
1 parent06b844c commitc1c88bf

File tree

15 files changed

+322
-253
lines changed

15 files changed

+322
-253
lines changed

‎doc/src/sgml/client-auth.sgml

Lines changed: 64 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,6 @@ hostnogssenc <replaceable>database</replaceable> <replaceable>user</replaceabl
196196
the <literal>hostgssenc</literal> record is ignored except for logging
197197
a warning that it cannot match any connections.
198198
</para>
199-
200-
<para>
201-
Note that the only supported
202-
<link linkend="auth-methods">authentication methods</link> for use
203-
with <acronym>GSSAPI</acronym> encryption
204-
are <literal>gss</literal>, <literal>reject</literal>,
205-
and <literal>trust</literal>.
206-
</para>
207199
</listitem>
208200
</varlistentry>
209201

@@ -1196,15 +1188,15 @@ omicron bryanh guest1
11961188

11971189
<para>
11981190
<productname>GSSAPI</productname> is an industry-standard protocol
1199-
for secure authentication defined in RFC 2743.
1200-
1191+
for secure authentication defined in
1192+
<ulink url="https://tools.ietf.org/html/rfc2743">RFC 2743</ulink>.
12011193
<productname>PostgreSQL</productname>
1202-
supports <productname>GSSAPI</productname> foruse as either an encrypted,
1203-
authenticated layer, orfor authentication only.
1194+
supports <productname>GSSAPI</productname> forauthentication,
1195+
communications encryption, orboth.
12041196
<productname>GSSAPI</productname> provides automatic authentication
12051197
(single sign-on) for systems that support it. The authentication itself is
12061198
secure. If <productname>GSSAPI</productname> encryption
1207-
(see <literal>hostgssenc</literal>)or <acronym>SSL</acronym> encryptionare
1199+
or <acronym>SSL</acronym> encryptionis
12081200
used, the data sent along the database connection will be encrypted;
12091201
otherwise, it will not.
12101202
</para>
@@ -1216,37 +1208,46 @@ omicron bryanh guest1
12161208

12171209
<para>
12181210
When <productname>GSSAPI</productname> uses
1219-
<productname>Kerberos</productname>, it uses a standardprincipal
1220-
in the format
1211+
<productname>Kerberos</productname>, it uses a standardservice
1212+
principal (authentication identity) namein the format
12211213
<literal><replaceable>servicename</replaceable>/<replaceable>hostname</replaceable>@<replaceable>realm</replaceable></literal>.
1222-
The PostgreSQL server will accept any principal that is included in the keytab used by
1223-
the server, but care needs to be taken to specify the correct principal details when
1224-
making the connection from the client using the <literal>krbsrvname</literal> connection parameter. (See
1225-
also <xref linkend="libpq-paramkeywords"/>.) The installation default can be
1226-
changed from the default <literal>postgres</literal> at build time using
1227-
<literal>./configure --with-krb-srvnam=</literal><replaceable>whatever</replaceable>.
1228-
In most environments,
1229-
this parameter never needs to be changed.
1230-
Some Kerberos implementations might require a different service name,
1231-
such as Microsoft Active Directory which requires the service name
1232-
to be in upper case (<literal>POSTGRES</literal>).
1233-
</para>
1234-
<para>
1235-
<replaceable>hostname</replaceable> is the fully qualified host name of the
1236-
server machine. The service principal's realm is the preferred realm
1237-
of the server machine.
1238-
</para>
1239-
1240-
<para>
1241-
Client principals can be mapped to different <productname>PostgreSQL</productname>
1242-
database user names with <filename>pg_ident.conf</filename>. For example,
1214+
The principal name used by a particular installation is not encoded in
1215+
the <productname>PostgreSQL</productname> server in any way; rather it
1216+
is specified in the <firstterm>keytab</firstterm> file that the server
1217+
reads to determine its identity. If multiple principals are listed in
1218+
the keytab file, the server will accept any one of them.
1219+
The server's realm name is the preferred realm specified in the Kerberos
1220+
configuration file(s) accessible to the server.
1221+
</para>
1222+
1223+
<para>
1224+
When connecting, the client must know the principal name of the server
1225+
it intends to connect to. The <replaceable>servicename</replaceable>
1226+
part of the principal is ordinarily <literal>postgres</literal>,
1227+
but another value can be selected via <application>libpq</application>'s
1228+
<xref linkend="libpq-connect-krbsrvname"/> connection parameter.
1229+
The <replaceable>hostname</replaceable> part is the fully qualified
1230+
host name that <application>libpq</application> is told to connect to.
1231+
The realm name is the preferred realm specified in the Kerberos
1232+
configuration file(s) accessible to the client.
1233+
</para>
1234+
1235+
<para>
1236+
The client will also have a principal name for its own identity
1237+
(and it must have a valid ticket for this principal). To
1238+
use <productname>GSSAPI</productname> for authentication, the client
1239+
principal must be associated with
1240+
a <productname>PostgreSQL</productname> database user name.
1241+
The <filename>pg_ident.conf</filename> configuration file can be used
1242+
to map principals to user names; for example,
12431243
<literal>pgusername@realm</literal> could be mapped to just <literal>pgusername</literal>.
12441244
Alternatively, you can use the full <literal>username@realm</literal> principal as
12451245
the role name in <productname>PostgreSQL</productname> without any mapping.
12461246
</para>
12471247

12481248
<para>
1249-
<productname>PostgreSQL</productname> also supports a parameter to strip the realm from
1249+
<productname>PostgreSQL</productname> also supports mapping
1250+
client principals to user names by just stripping the realm from
12501251
the principal. This method is supported for backwards compatibility and is
12511252
strongly discouraged as it is then impossible to distinguish different users
12521253
with the same user name but coming from different realms. To enable this,
@@ -1260,39 +1261,34 @@ omicron bryanh guest1
12601261
</para>
12611262

12621263
<para>
1263-
Make sure that your server keytab file is readable (and preferably
1264-
only readable, not writable) by the <productname>PostgreSQL</productname>
1265-
server account. (See also <xref linkend="postgres-user"/>.) The location
1266-
of the key file is specified by the <xref
1264+
The location of the server's keytab file is specified by the <xref
12671265
linkend="guc-krb-server-keyfile"/> configuration
12681266
parameter. The default is
1269-
<filename>/usr/local/pgsql/etc/krb5.keytab</filename> (or whatever
1270-
directory was specified as <varname>sysconfdir</varname> at build time).
1267+
<filename>FILE:/usr/local/pgsql/etc/krb5.keytab</filename>
1268+
(where the directory part is whatever was specified
1269+
as <varname>sysconfdir</varname> at build time).
12711270
For security reasons, it is recommended to use a separate keytab
12721271
just for the <productname>PostgreSQL</productname> server rather
1273-
than opening up permissions on the system keytab file.
1272+
than allowing the server to read the system keytab file.
1273+
Make sure that your server keytab file is readable (and preferably
1274+
only readable, not writable) by the <productname>PostgreSQL</productname>
1275+
server account. (See also <xref linkend="postgres-user"/>.)
12741276
</para>
1277+
12751278
<para>
1276-
The keytab file is generated by the Kerberos software; see the
1277-
Kerberos documentation for details. The following example is
1278-
for MIT-compatible Kerberos 5 implementations:
1279+
The keytab file is generated using the Kerberos software; see the
1280+
Kerberos documentation for details. The following example shows
1281+
doing this using the <application>kadmin</application> tool of
1282+
MIT-compatible Kerberos 5 implementations:
12791283
<screen>
1280-
<prompt>kadmin% </prompt><userinput>ank -randkey postgres/server.my.domain.org</userinput>
1284+
<prompt>kadmin% </prompt><userinput>addprinc -randkey postgres/server.my.domain.org</userinput>
12811285
<prompt>kadmin% </prompt><userinput>ktadd -k krb5.keytab postgres/server.my.domain.org</userinput>
12821286
</screen>
12831287
</para>
12841288

12851289
<para>
1286-
When connecting to the database make sure you have a ticket for a
1287-
principal matching the requested database user name. For example, for
1288-
database user name <literal>fred</literal>, principal
1289-
<literal>fred@EXAMPLE.COM</literal> would be able to connect. To also allow
1290-
principal <literal>fred/users.example.com@EXAMPLE.COM</literal>, use a user name
1291-
map, as described in <xref linkend="auth-username-maps"/>.
1292-
</para>
1293-
1294-
<para>
1295-
The following configuration options are supported for <productname>GSSAPI</productname>:
1290+
The following authentication options are supported for
1291+
the <productname>GSSAPI</productname> authentication method:
12961292
<variablelist>
12971293
<varlistentry>
12981294
<term><literal>include_realm</literal></term>
@@ -1315,7 +1311,7 @@ omicron bryanh guest1
13151311
<term><literal>map</literal></term>
13161312
<listitem>
13171313
<para>
1318-
Allowsformappingbetween system and database user names. See
1314+
Allows mappingfrom client principals to database user names. See
13191315
<xref linkend="auth-username-maps"/> for details. For a GSSAPI/Kerberos
13201316
principal, such as <literal>username@EXAMPLE.COM</literal> (or, less
13211317
commonly, <literal>username/hostbased@EXAMPLE.COM</literal>), the
@@ -1342,6 +1338,15 @@ omicron bryanh guest1
13421338
</varlistentry>
13431339
</variablelist>
13441340
</para>
1341+
1342+
<para>
1343+
In addition to these settings, which can be different for
1344+
different <filename>pg_hba.conf</filename> entries, there is the
1345+
server-wide <xref linkend="guc-krb-caseins-users"/> configuration
1346+
parameter. If that is set to true, client principals are matched to
1347+
user map entries case-insensitively. <literal>krb_realm</literal>, if
1348+
set, is also matched case-insensitively.
1349+
</para>
13451350
</sect1>
13461351

13471352
<sect1 id="sspi-auth">

‎doc/src/sgml/libpq.sgml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,6 +1577,16 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
15771577
connection.<indexterm><primary>SSL</primary><secondary
15781578
sortas="libpq">with libpq</secondary></indexterm>
15791579
</para>
1580+
1581+
<para>
1582+
Note that if <acronym>GSSAPI</acronym> encryption is possible,
1583+
that will be used in preference to <acronym>SSL</acronym>
1584+
encryption, regardless of the value of <literal>sslmode</literal>.
1585+
To force use of <acronym>SSL</acronym> encryption in an
1586+
environment that has working <acronym>GSSAPI</acronym>
1587+
infrastructure (such as a Kerberos server), also
1588+
set <literal>gssencmode</literal> to <literal>disable</literal>.
1589+
</para>
15801590
</listitem>
15811591
</varlistentry>
15821592

@@ -1778,6 +1788,15 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
17781788
This must match the service name specified in the server
17791789
configuration for Kerberos authentication to succeed. (See also
17801790
<xref linkend="gssapi-auth"/>.)
1791+
The default value is normally <literal>postgres</literal>,
1792+
but that can be changed when
1793+
building <productname>PostgreSQL</productname> via
1794+
the <option>--with-krb-srvnam</option> option
1795+
of <application>configure</application>.
1796+
In most environments, this parameter never needs to be changed.
1797+
Some Kerberos implementations might require a different service name,
1798+
such as Microsoft Active Directory which requires the service name
1799+
to be in upper case (<literal>POSTGRES</literal>).
17811800
</para>
17821801
</listitem>
17831802
</varlistentry>

‎doc/src/sgml/protocol.sgml

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,10 @@ SELCT 1/0;<!-- this typo is intentional -->
14541454
<acronym>SSL</acronym>-encrypted. To continue after
14551455
<literal>N</literal>, send the usual StartupMessage and proceed without
14561456
encryption.
1457+
(Alternatively, it is permissible to issue a GSSENCRequest message
1458+
after an <literal>N</literal> response to try to
1459+
use <acronym>GSSAPI</acronym> encryption instead
1460+
of <acronym>SSL</acronym>.)
14571461
</para>
14581462

14591463
<para>
@@ -1508,20 +1512,14 @@ SELCT 1/0;<!-- this typo is intentional -->
15081512
result from the server, until it returns no output. When sending the
15091513
results of <function>gss_init_sec_context()</function> to the server,
15101514
prepend the length of the message as a four byte integer in network byte
1511-
order. If this is successful, then use <function>gss_wrap()</function> to
1512-
encrypt the usual StartupMessage and all subsequent data, prepending the
1513-
length of the result from <function>gss_wrap()</function> as a four byte
1514-
integer in network byte order to the actual encrypted payload. Note that
1515-
the server will only accept encrypted packets from the client which are less
1516-
than 16kB; <function>gss_wrap_size_limit()</function> should be used by the
1517-
client to determine the size of the unencrypted message which will fit
1518-
within this limit and larger messages should be broken up into multiple
1519-
<function>gss_wrap()</function> calls. Typical segments are 8kB of
1520-
unencrypted data, resulting in encrypted packets of slightly larger than 8kB
1521-
but well within the 16kB maximum. The server can be expected to not send
1522-
encrypted packets of larger than 16kB to the client. To continue after
1515+
order.
1516+
To continue after
15231517
<literal>N</literal>, send the usual StartupMessage and proceed without
15241518
encryption.
1519+
(Alternatively, it is permissible to issue an SSLRequest message
1520+
after an <literal>N</literal> response to try to
1521+
use <acronym>SSL</acronym> encryption instead
1522+
of <acronym>GSSAPI</acronym>.)
15251523
</para>
15261524

15271525
<para>
@@ -1531,16 +1529,30 @@ SELCT 1/0;<!-- this typo is intentional -->
15311529
support to <productname>PostgreSQL</productname>. In this case the
15321530
connection must be closed, but the frontend might choose to open a fresh
15331531
connection and proceed without requesting <acronym>GSSAPI</acronym>
1534-
encryption. Given the length limits specified above, the ErrorMessage can
1535-
not be confused with a proper response from the server with an appropriate
1536-
length.
1532+
encryption.
15371533
</para>
15381534

15391535
<para>
15401536
An initial GSSENCRequest can also be used in a connection that is being
15411537
opened to send a CancelRequest message.
15421538
</para>
15431539

1540+
<para>
1541+
Once <acronym>GSSAPI</acronym> encryption has been successfully
1542+
established, use <function>gss_wrap()</function> to
1543+
encrypt the usual StartupMessage and all subsequent data, prepending the
1544+
length of the result from <function>gss_wrap()</function> as a four byte
1545+
integer in network byte order to the actual encrypted payload. Note that
1546+
the server will only accept encrypted packets from the client which are less
1547+
than 16kB; <function>gss_wrap_size_limit()</function> should be used by the
1548+
client to determine the size of the unencrypted message which will fit
1549+
within this limit and larger messages should be broken up into multiple
1550+
<function>gss_wrap()</function> calls. Typical segments are 8kB of
1551+
unencrypted data, resulting in encrypted packets of slightly larger than 8kB
1552+
but well within the 16kB maximum. The server can be expected to not send
1553+
encrypted packets of larger than 16kB to the client.
1554+
</para>
1555+
15441556
<para>
15451557
While the protocol itself does not provide a way for the server to
15461558
force <acronym>GSSAPI</acronym> encryption, the administrator can

‎doc/src/sgml/runtime.sgml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2549,7 +2549,7 @@ openssl x509 -req -in server.csr -text -days 365 \
25492549
<productname>PostgreSQL</productname> also has native support for
25502550
using <acronym>GSSAPI</acronym> to encrypt client/server communications for
25512551
increased security. Support requires that a <acronym>GSSAPI</acronym>
2552-
implementation (such as MITkrb5) is installed on both client and server
2552+
implementation (such as MITKerberos) is installed on both client and server
25532553
systems, and that support in <productname>PostgreSQL</productname> is
25542554
enabled at build time (see <xref linkend="installation"/>).
25552555
</para>
@@ -2568,6 +2568,16 @@ openssl x509 -req -in server.csr -text -days 365 \
25682568
some or all connections.
25692569
</para>
25702570

2571+
<para>
2572+
When using <acronym>GSSAPI</acronym> for encryption, it is common to
2573+
use <acronym>GSSAPI</acronym> for authentication as well, since the
2574+
underlying mechanism will determine both client and server identities
2575+
(according to the <acronym>GSSAPI</acronym> implementation) in any
2576+
case. But this is not required;
2577+
another <productname>PostgreSQL</productname> authentication method
2578+
can be chosen to perform additional verification.
2579+
</para>
2580+
25712581
<para>
25722582
Other than configuration of the negotiation
25732583
behavior, <acronym>GSSAPI</acronym> encryption requires no setup beyond

‎src/backend/libpq/auth.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -382,17 +382,6 @@ ClientAuthentication(Port *port)
382382
errmsg("connection requires a valid client certificate")));
383383
}
384384

385-
#ifdefENABLE_GSS
386-
if (port->gss->enc&&port->hba->auth_method!=uaReject&&
387-
port->hba->auth_method!=uaImplicitReject&&
388-
port->hba->auth_method!=uaTrust&&
389-
port->hba->auth_method!=uaGSS)
390-
{
391-
ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
392-
errmsg("GSSAPI encryption can only be used with gss, trust, or reject authentication methods")));
393-
}
394-
#endif
395-
396385
/*
397386
* Now proceed to do the actual authentication check
398387
*/
@@ -533,7 +522,17 @@ ClientAuthentication(Port *port)
533522

534523
caseuaGSS:
535524
#ifdefENABLE_GSS
525+
/* We might or might not have the gss workspace already */
526+
if (port->gss==NULL)
527+
port->gss= (pg_gssinfo*)
528+
MemoryContextAllocZero(TopMemoryContext,
529+
sizeof(pg_gssinfo));
536530
port->gss->auth= true;
531+
532+
/*
533+
* If GSS state was set up while enabling encryption, we can just
534+
* check the client's principal. Otherwise, ask for it.
535+
*/
537536
if (port->gss->enc)
538537
status=pg_GSS_checkauth(port);
539538
else
@@ -548,6 +547,10 @@ ClientAuthentication(Port *port)
548547

549548
caseuaSSPI:
550549
#ifdefENABLE_SSPI
550+
if (port->gss==NULL)
551+
port->gss= (pg_gssinfo*)
552+
MemoryContextAllocZero(TopMemoryContext,
553+
sizeof(pg_gssinfo));
551554
sendAuthRequest(port,AUTH_REQ_SSPI,NULL,0);
552555
status=pg_SSPI_recvauth(port);
553556
#else
@@ -1185,9 +1188,9 @@ pg_GSS_recvauth(Port *port)
11851188
if (maj_stat!=GSS_S_COMPLETE&&maj_stat!=GSS_S_CONTINUE_NEEDED)
11861189
{
11871190
gss_delete_sec_context(&lmin_s,&port->gss->ctx,GSS_C_NO_BUFFER);
1188-
pg_GSS_error(ERROR,
1189-
_("accepting GSS security context failed"),
1191+
pg_GSS_error(_("accepting GSS security context failed"),
11901192
maj_stat,min_stat);
1193+
returnSTATUS_ERROR;
11911194
}
11921195

11931196
if (maj_stat==GSS_S_CONTINUE_NEEDED)
@@ -1224,9 +1227,11 @@ pg_GSS_checkauth(Port *port)
12241227
*/
12251228
maj_stat=gss_display_name(&min_stat,port->gss->name,&gbuf,NULL);
12261229
if (maj_stat!=GSS_S_COMPLETE)
1227-
pg_GSS_error(ERROR,
1228-
_("retrieving GSS user name failed"),
1230+
{
1231+
pg_GSS_error(_("retrieving GSS user name failed"),
12291232
maj_stat,min_stat);
1233+
returnSTATUS_ERROR;
1234+
}
12301235

12311236
/*
12321237
* Copy the original name of the authenticated principal into our backend

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp