*** a/doc/src/sgml/client-auth.sgml
--- b/doc/src/sgml/client-auth.sgml
***************
*** 784,789 **** omicron bryanh guest1
--- 784,809 ----
+
+
+ krb_realm
+
+
+ Overrides the parameter, setting which realm
+ to verify the authenticated user principal against.
+
+
+
+
+
+ krb_server_hostname
+
+
+ Overrides the parameter, setting which
+ hostname will be used for the server principal when using Kerberos.
+
+
+
***************
*** 825,830 **** omicron bryanh guest1
--- 845,860 ----
+
+
+ krb_realm
+
+
+ Overrides the parameter, setting which realm
+ to verify the authenticated user principal against.
+
+
+
*** a/src/backend/libpq/auth.c
--- b/src/backend/libpq/auth.c
***************
*** 611,617 **** recv_and_check_password_packet(Port *port)
#ifdef KRB5
static int
! pg_krb5_init(void)
{
krb5_error_code retval;
char *khostname;
--- 611,617 ----
#ifdef KRB5
static int
! pg_krb5_init(Port *port)
{
krb5_error_code retval;
char *khostname;
***************
*** 645,651 **** 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 (khostname && khostname[0] == '\0')
khostname = NULL;
--- 645,654 ----
* If no hostname was specified, pg_krb_server_hostname is already NULL.
* If it's set to blank, force it to NULL.
*/
! 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,701 **** pg_krb5_recvauth(Port *port)
krb5_ticket *ticket;
char *kusername;
char *cp;
if (get_role_line(port->user_name) == NULL)
return STATUS_ERROR;
! ret = pg_krb5_init();
if (ret != STATUS_OK)
return ret;
--- 694,705 ----
krb5_ticket *ticket;
char *kusername;
char *cp;
+ char *realmmatch;
if (get_role_line(port->user_name) == NULL)
return STATUS_ERROR;
! ret = pg_krb5_init(port);
if (ret != STATUS_OK)
return ret;
***************
*** 736,760 **** pg_krb5_recvauth(Port *port)
return STATUS_ERROR;
}
cp = strchr(kusername, '@');
if (cp)
{
*cp = '\0';
cp++;
! if (pg_krb_realm != NULL && strlen(pg_krb_realm))
{
/* Match realm against configured */
if (pg_krb_caseins_users)
! ret = pg_strcasecmp(pg_krb_realm, cp);
else
! ret = strcmp(pg_krb_realm, cp);
if (ret)
{
elog(DEBUG2,
"krb5 realm (%s) and configured realm (%s) don't match",
! cp, pg_krb_realm);
krb5_free_ticket(pg_krb5_context, ticket);
krb5_auth_con_free(pg_krb5_context, auth_context);
--- 740,769 ----
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 (realmmatch != NULL && strlen(realmmatch))
{
/* Match realm against configured */
if (pg_krb_caseins_users)
! ret = pg_strcasecmp(realmmatch, cp);
else
! ret = strcmp(realmmatch, cp);
if (ret)
{
elog(DEBUG2,
"krb5 realm (%s) and configured realm (%s) don't match",
! cp, realmmatch);
krb5_free_ticket(pg_krb5_context, ticket);
krb5_auth_con_free(pg_krb5_context, auth_context);
***************
*** 762,768 **** pg_krb5_recvauth(Port *port)
}
}
}
! else if (pg_krb_realm && strlen(pg_krb_realm))
{
elog(DEBUG2,
"krb5 did not return realm but realm matching was requested");
--- 771,777 ----
}
}
}
! else if (realmmatch && strlen(realmmatch))
{
elog(DEBUG2,
"krb5 did not return realm but realm matching was requested");
***************
*** 859,864 **** pg_GSS_recvauth(Port *port)
--- 868,874 ----
int ret;
StringInfoData buf;
gss_buffer_desc gbuf;
+ char *realmmatch;
/*
* GSS auth is not supported for protocol versions before 3, because it
***************
*** 1018,1023 **** pg_GSS_recvauth(Port *port)
--- 1028,1038 ----
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,1055 **** pg_GSS_recvauth(Port *port)
*cp = '\0';
cp++;
! if (pg_krb_realm != NULL && strlen(pg_krb_realm))
{
/*
* Match the realm part of the name first
*/
if (pg_krb_caseins_users)
! ret = pg_strcasecmp(pg_krb_realm, cp);
else
! ret = strcmp(pg_krb_realm, cp);
if (ret)
{
/* GSS realm does not match */
elog(DEBUG2,
"GSSAPI realm (%s) and configured realm (%s) don't match",
! cp, pg_krb_realm);
gss_release_buffer(&lmin_s, &gbuf);
return STATUS_ERROR;
}
}
}
! else if (pg_krb_realm && strlen(pg_krb_realm))
{
elog(DEBUG2,
"GSSAPI did not return realm but realm matching was requested");
--- 1043,1070 ----
*cp = '\0';
cp++;
! if (realmmatch != NULL && strlen(realmmatch))
{
/*
* Match the realm part of the name first
*/
if (pg_krb_caseins_users)
! ret = pg_strcasecmp(realmmatch, cp);
else
! ret = strcmp(realmmatch, cp);
if (ret)
{
/* GSS realm does not match */
elog(DEBUG2,
"GSSAPI realm (%s) and configured realm (%s) don't match",
! cp, realmmatch);
gss_release_buffer(&lmin_s, &gbuf);
return STATUS_ERROR;
}
}
}
! else if (realmmatch && strlen(realmmatch))
{
elog(DEBUG2,
"GSSAPI did not return realm but realm matching was requested");
***************
*** 1113,1118 **** pg_SSPI_recvauth(Port *port)
--- 1128,1134 ----
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,1337 **** 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 (pg_strcasecmp(pg_krb_realm, domainname))
{
elog(DEBUG2,
"SSPI domain (%s) and configured domain (%s) don't match",
! domainname, pg_krb_realm);
return STATUS_ERROR;
}
--- 1341,1358 ----
* Compare realm/domain if requested. In SSPI, always compare case
* insensitive.
*/
! if (port->hba->krb_realm)
! realmmatch = port->hba->krb_realm;
! else
! realmmatch = pg_krb_realm;
!
! if (realmmatch && strlen(realmmatch))
{
! if (pg_strcasecmp(realmmatch, domainname))
{
elog(DEBUG2,
"SSPI domain (%s) and configured domain (%s) don't match",
! domainname, realmmatch);
return STATUS_ERROR;
}
*** a/src/backend/libpq/hba.c
--- b/src/backend/libpq/hba.c
***************
*** 1040,1045 **** parse_hba_line(List *line, int line_num, HbaLine *parsedline)
--- 1040,1060 ----
REQUIRE_AUTH_OPTION(uaLDAP, "ldapsuffix", "ldap");
parsedline->ldapsuffix = pstrdup(c);
}
+ else if (strcmp(token, "krb_server_hostname") == 0)
+ {
+ if (parsedline->auth_method != uaKrb5 &&
+ parsedline->auth_method != uaGSS)
+ INVALID_AUTH_OPTION("krb_server_hostname", "krb5 and gssapi");
+ 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
{
ereport(LOG,
***************
*** 1242,1247 **** free_hba_record(HbaLine *record)
--- 1257,1266 ----
pfree(record->ldapprefix);
if (record->ldapsuffix)
pfree(record->ldapsuffix);
+ if (record->krb_server_hostname)
+ pfree(record->krb_server_hostname);
+ if (record->krb_realm)
+ pfree(record->krb_realm);
}
/*
*** a/src/include/libpq/hba.h
--- b/src/include/libpq/hba.h
***************
*** 56,61 **** typedef struct
--- 56,63 ----
char *ldapprefix;
char *ldapsuffix;
bool clientcert;
+ char *krb_server_hostname;
+ char *krb_realm;
} HbaLine;
typedef struct Port hbaPort;