mirror of
https://github.com/postgres/postgres.git
synced 2025-07-11 10:01:57 +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:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
|
||||
static int
|
||||
pg_krb5_init(void)
|
||||
pg_krb5_init(Port *port)
|
||||
{
|
||||
krb5_error_code retval;
|
||||
char *khostname;
|
||||
@ -645,7 +645,10 @@ pg_krb5_init(void)
|
||||
* If no hostname was specified, pg_krb_server_hostname is already 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')
|
||||
khostname = NULL;
|
||||
|
||||
@ -691,11 +694,12 @@ pg_krb5_recvauth(Port *port)
|
||||
krb5_ticket *ticket;
|
||||
char *kusername;
|
||||
char *cp;
|
||||
char *realmmatch;
|
||||
|
||||
if (get_role_line(port->user_name) == NULL)
|
||||
return STATUS_ERROR;
|
||||
|
||||
ret = pg_krb5_init();
|
||||
ret = pg_krb5_init(port);
|
||||
if (ret != STATUS_OK)
|
||||
return ret;
|
||||
|
||||
@ -736,25 +740,30 @@ pg_krb5_recvauth(Port *port)
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if (port->hba->krb_realm)
|
||||
realmmatch = port->hba->krb_realm;
|
||||
else
|
||||
realmmatch = pg_krb_realm;
|
||||
|
||||
cp = strchr(kusername, '@');
|
||||
if (cp)
|
||||
{
|
||||
*cp = '\0';
|
||||
cp++;
|
||||
|
||||
if (pg_krb_realm != NULL && strlen(pg_krb_realm))
|
||||
if (realmmatch != NULL && strlen(realmmatch))
|
||||
{
|
||||
/* Match realm against configured */
|
||||
if (pg_krb_caseins_users)
|
||||
ret = pg_strcasecmp(pg_krb_realm, cp);
|
||||
ret = pg_strcasecmp(realmmatch, cp);
|
||||
else
|
||||
ret = strcmp(pg_krb_realm, cp);
|
||||
ret = strcmp(realmmatch, cp);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
elog(DEBUG2,
|
||||
"krb5 realm (%s) and configured realm (%s) don't match",
|
||||
cp, pg_krb_realm);
|
||||
cp, realmmatch);
|
||||
|
||||
krb5_free_ticket(pg_krb5_context, ticket);
|
||||
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,
|
||||
"krb5 did not return realm but realm matching was requested");
|
||||
@ -859,6 +868,7 @@ pg_GSS_recvauth(Port *port)
|
||||
int ret;
|
||||
StringInfoData buf;
|
||||
gss_buffer_desc gbuf;
|
||||
char *realmmatch;
|
||||
|
||||
/*
|
||||
* 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"),
|
||||
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
|
||||
*/
|
||||
@ -1028,28 +1043,28 @@ pg_GSS_recvauth(Port *port)
|
||||
*cp = '\0';
|
||||
cp++;
|
||||
|
||||
if (pg_krb_realm != NULL && strlen(pg_krb_realm))
|
||||
if (realmmatch != NULL && strlen(realmmatch))
|
||||
{
|
||||
/*
|
||||
* Match the realm part of the name first
|
||||
*/
|
||||
if (pg_krb_caseins_users)
|
||||
ret = pg_strcasecmp(pg_krb_realm, cp);
|
||||
ret = pg_strcasecmp(realmmatch, cp);
|
||||
else
|
||||
ret = strcmp(pg_krb_realm, cp);
|
||||
ret = strcmp(realmmatch, cp);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
/* GSS realm does not match */
|
||||
elog(DEBUG2,
|
||||
"GSSAPI realm (%s) and configured realm (%s) don't match",
|
||||
cp, pg_krb_realm);
|
||||
cp, realmmatch);
|
||||
gss_release_buffer(&lmin_s, &gbuf);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pg_krb_realm && strlen(pg_krb_realm))
|
||||
else if (realmmatch && strlen(realmmatch))
|
||||
{
|
||||
elog(DEBUG2,
|
||||
"GSSAPI did not return realm but realm matching was requested");
|
||||
@ -1113,6 +1128,7 @@ pg_SSPI_recvauth(Port *port)
|
||||
SID_NAME_USE accountnameuse;
|
||||
HMODULE secur32;
|
||||
QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;
|
||||
char *realmmatch;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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,
|
||||
"SSPI domain (%s) and configured domain (%s) don't match",
|
||||
domainname, pg_krb_realm);
|
||||
domainname, realmmatch);
|
||||
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
Reference in New Issue
Block a user