mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Allow krb_realm (krb5, gssapi and sspi) and krb_server_hostname (krb5 only)
authentication options to be set in pg_hba.conf on a per-line basis, to override the defaults set in postgresql.conf.
This commit is contained in:
parent
af26089841
commit
32c469d7b1
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.115 2009/01/02 11:51:53 mha Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.116 2009/01/07 12:38:10 mha Exp $ -->
|
||||||
|
|
||||||
<chapter id="client-authentication">
|
<chapter id="client-authentication">
|
||||||
<title>Client Authentication</title>
|
<title>Client Authentication</title>
|
||||||
@ -784,6 +784,26 @@ omicron bryanh guest1
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>krb_realm</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Overrides the <xref linkend="guc-krb-realm"> parameter, setting which realm
|
||||||
|
to verify the authenticated user principal against.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>krb_server_hostname</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Overrides the <xref linkend="guc-krb-server-hostname"> parameter, setting which
|
||||||
|
hostname will be used for the server principal when using Kerberos.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
@ -825,6 +845,16 @@ omicron bryanh guest1
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>krb_realm</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Overrides the <xref linkend="guc-krb-realm"> parameter, setting which realm
|
||||||
|
to verify the authenticated user principal against.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.175 2009/01/01 17:23:42 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.176 2009/01/07 12:38:11 mha Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -611,7 +611,7 @@ recv_and_check_password_packet(Port *port)
|
|||||||
#ifdef KRB5
|
#ifdef KRB5
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pg_krb5_init(void)
|
pg_krb5_init(Port *port)
|
||||||
{
|
{
|
||||||
krb5_error_code retval;
|
krb5_error_code retval;
|
||||||
char *khostname;
|
char *khostname;
|
||||||
@ -645,7 +645,10 @@ pg_krb5_init(void)
|
|||||||
* If no hostname was specified, pg_krb_server_hostname is already NULL.
|
* If no hostname was specified, pg_krb_server_hostname is already NULL.
|
||||||
* If it's set to blank, force it to NULL.
|
* If it's set to blank, force it to NULL.
|
||||||
*/
|
*/
|
||||||
khostname = pg_krb_server_hostname;
|
if (port->hba->krb_server_hostname)
|
||||||
|
khostname = port->hba->krb_server_hostname;
|
||||||
|
else
|
||||||
|
khostname = pg_krb_server_hostname;
|
||||||
if (khostname && khostname[0] == '\0')
|
if (khostname && khostname[0] == '\0')
|
||||||
khostname = NULL;
|
khostname = NULL;
|
||||||
|
|
||||||
@ -691,11 +694,12 @@ pg_krb5_recvauth(Port *port)
|
|||||||
krb5_ticket *ticket;
|
krb5_ticket *ticket;
|
||||||
char *kusername;
|
char *kusername;
|
||||||
char *cp;
|
char *cp;
|
||||||
|
char *realmmatch;
|
||||||
|
|
||||||
if (get_role_line(port->user_name) == NULL)
|
if (get_role_line(port->user_name) == NULL)
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
|
|
||||||
ret = pg_krb5_init();
|
ret = pg_krb5_init(port);
|
||||||
if (ret != STATUS_OK)
|
if (ret != STATUS_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -736,25 +740,30 @@ pg_krb5_recvauth(Port *port)
|
|||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (port->hba->krb_realm)
|
||||||
|
realmmatch = port->hba->krb_realm;
|
||||||
|
else
|
||||||
|
realmmatch = pg_krb_realm;
|
||||||
|
|
||||||
cp = strchr(kusername, '@');
|
cp = strchr(kusername, '@');
|
||||||
if (cp)
|
if (cp)
|
||||||
{
|
{
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
cp++;
|
cp++;
|
||||||
|
|
||||||
if (pg_krb_realm != NULL && strlen(pg_krb_realm))
|
if (realmmatch != NULL && strlen(realmmatch))
|
||||||
{
|
{
|
||||||
/* Match realm against configured */
|
/* Match realm against configured */
|
||||||
if (pg_krb_caseins_users)
|
if (pg_krb_caseins_users)
|
||||||
ret = pg_strcasecmp(pg_krb_realm, cp);
|
ret = pg_strcasecmp(realmmatch, cp);
|
||||||
else
|
else
|
||||||
ret = strcmp(pg_krb_realm, cp);
|
ret = strcmp(realmmatch, cp);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
elog(DEBUG2,
|
elog(DEBUG2,
|
||||||
"krb5 realm (%s) and configured realm (%s) don't match",
|
"krb5 realm (%s) and configured realm (%s) don't match",
|
||||||
cp, pg_krb_realm);
|
cp, realmmatch);
|
||||||
|
|
||||||
krb5_free_ticket(pg_krb5_context, ticket);
|
krb5_free_ticket(pg_krb5_context, ticket);
|
||||||
krb5_auth_con_free(pg_krb5_context, auth_context);
|
krb5_auth_con_free(pg_krb5_context, auth_context);
|
||||||
@ -762,7 +771,7 @@ pg_krb5_recvauth(Port *port)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pg_krb_realm && strlen(pg_krb_realm))
|
else if (realmmatch && strlen(realmmatch))
|
||||||
{
|
{
|
||||||
elog(DEBUG2,
|
elog(DEBUG2,
|
||||||
"krb5 did not return realm but realm matching was requested");
|
"krb5 did not return realm but realm matching was requested");
|
||||||
@ -859,6 +868,7 @@ pg_GSS_recvauth(Port *port)
|
|||||||
int ret;
|
int ret;
|
||||||
StringInfoData buf;
|
StringInfoData buf;
|
||||||
gss_buffer_desc gbuf;
|
gss_buffer_desc gbuf;
|
||||||
|
char *realmmatch;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GSS auth is not supported for protocol versions before 3, because it
|
* GSS auth is not supported for protocol versions before 3, because it
|
||||||
@ -1018,6 +1028,11 @@ pg_GSS_recvauth(Port *port)
|
|||||||
gettext_noop("retrieving GSS user name failed"),
|
gettext_noop("retrieving GSS user name failed"),
|
||||||
maj_stat, min_stat);
|
maj_stat, min_stat);
|
||||||
|
|
||||||
|
if (port->hba->krb_realm)
|
||||||
|
realmmatch = port->hba->krb_realm;
|
||||||
|
else
|
||||||
|
realmmatch = pg_krb_realm;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Split the username at the realm separator
|
* Split the username at the realm separator
|
||||||
*/
|
*/
|
||||||
@ -1028,28 +1043,28 @@ pg_GSS_recvauth(Port *port)
|
|||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
cp++;
|
cp++;
|
||||||
|
|
||||||
if (pg_krb_realm != NULL && strlen(pg_krb_realm))
|
if (realmmatch != NULL && strlen(realmmatch))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Match the realm part of the name first
|
* Match the realm part of the name first
|
||||||
*/
|
*/
|
||||||
if (pg_krb_caseins_users)
|
if (pg_krb_caseins_users)
|
||||||
ret = pg_strcasecmp(pg_krb_realm, cp);
|
ret = pg_strcasecmp(realmmatch, cp);
|
||||||
else
|
else
|
||||||
ret = strcmp(pg_krb_realm, cp);
|
ret = strcmp(realmmatch, cp);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
/* GSS realm does not match */
|
/* GSS realm does not match */
|
||||||
elog(DEBUG2,
|
elog(DEBUG2,
|
||||||
"GSSAPI realm (%s) and configured realm (%s) don't match",
|
"GSSAPI realm (%s) and configured realm (%s) don't match",
|
||||||
cp, pg_krb_realm);
|
cp, realmmatch);
|
||||||
gss_release_buffer(&lmin_s, &gbuf);
|
gss_release_buffer(&lmin_s, &gbuf);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pg_krb_realm && strlen(pg_krb_realm))
|
else if (realmmatch && strlen(realmmatch))
|
||||||
{
|
{
|
||||||
elog(DEBUG2,
|
elog(DEBUG2,
|
||||||
"GSSAPI did not return realm but realm matching was requested");
|
"GSSAPI did not return realm but realm matching was requested");
|
||||||
@ -1113,6 +1128,7 @@ pg_SSPI_recvauth(Port *port)
|
|||||||
SID_NAME_USE accountnameuse;
|
SID_NAME_USE accountnameuse;
|
||||||
HMODULE secur32;
|
HMODULE secur32;
|
||||||
QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;
|
QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;
|
||||||
|
char *realmmatch;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SSPI auth is not supported for protocol versions before 3, because it
|
* SSPI auth is not supported for protocol versions before 3, because it
|
||||||
@ -1325,13 +1341,18 @@ pg_SSPI_recvauth(Port *port)
|
|||||||
* Compare realm/domain if requested. In SSPI, always compare case
|
* Compare realm/domain if requested. In SSPI, always compare case
|
||||||
* insensitive.
|
* insensitive.
|
||||||
*/
|
*/
|
||||||
if (pg_krb_realm && strlen(pg_krb_realm))
|
if (port->hba->krb_realm)
|
||||||
|
realmmatch = port->hba->krb_realm;
|
||||||
|
else
|
||||||
|
realmmatch = pg_krb_realm;
|
||||||
|
|
||||||
|
if (realmmatch && strlen(realmmatch))
|
||||||
{
|
{
|
||||||
if (pg_strcasecmp(pg_krb_realm, domainname))
|
if (pg_strcasecmp(realmmatch, domainname))
|
||||||
{
|
{
|
||||||
elog(DEBUG2,
|
elog(DEBUG2,
|
||||||
"SSPI domain (%s) and configured domain (%s) don't match",
|
"SSPI domain (%s) and configured domain (%s) don't match",
|
||||||
domainname, pg_krb_realm);
|
domainname, realmmatch);
|
||||||
|
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.178 2009/01/02 11:34:03 mha Exp $
|
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.179 2009/01/07 12:38:11 mha Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1040,6 +1040,19 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
|
|||||||
REQUIRE_AUTH_OPTION(uaLDAP, "ldapsuffix", "ldap");
|
REQUIRE_AUTH_OPTION(uaLDAP, "ldapsuffix", "ldap");
|
||||||
parsedline->ldapsuffix = pstrdup(c);
|
parsedline->ldapsuffix = pstrdup(c);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(token, "krb_server_hostname") == 0)
|
||||||
|
{
|
||||||
|
REQUIRE_AUTH_OPTION(uaKrb5, "krb_server_hostname", "krb5");
|
||||||
|
parsedline->krb_server_hostname = pstrdup(c);
|
||||||
|
}
|
||||||
|
else if (strcmp(token, "krb_realm") == 0)
|
||||||
|
{
|
||||||
|
if (parsedline->auth_method != uaKrb5 &&
|
||||||
|
parsedline->auth_method != uaGSS &&
|
||||||
|
parsedline->auth_method != uaSSPI)
|
||||||
|
INVALID_AUTH_OPTION("krb_realm", "krb5, gssapi and sspi");
|
||||||
|
parsedline->krb_realm = pstrdup(c);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ereport(LOG,
|
ereport(LOG,
|
||||||
@ -1242,6 +1255,10 @@ free_hba_record(HbaLine *record)
|
|||||||
pfree(record->ldapprefix);
|
pfree(record->ldapprefix);
|
||||||
if (record->ldapsuffix)
|
if (record->ldapsuffix)
|
||||||
pfree(record->ldapsuffix);
|
pfree(record->ldapsuffix);
|
||||||
|
if (record->krb_server_hostname)
|
||||||
|
pfree(record->krb_server_hostname);
|
||||||
|
if (record->krb_realm)
|
||||||
|
pfree(record->krb_realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* Interface to hba.c
|
* Interface to hba.c
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.53 2008/11/20 11:48:26 mha Exp $
|
* $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.54 2009/01/07 12:38:11 mha Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -56,6 +56,8 @@ typedef struct
|
|||||||
char *ldapprefix;
|
char *ldapprefix;
|
||||||
char *ldapsuffix;
|
char *ldapsuffix;
|
||||||
bool clientcert;
|
bool clientcert;
|
||||||
|
char *krb_server_hostname;
|
||||||
|
char *krb_realm;
|
||||||
} HbaLine;
|
} HbaLine;
|
||||||
|
|
||||||
typedef struct Port hbaPort;
|
typedef struct Port hbaPort;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user