*
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
 #ifdef KRB5
 
 static int
-pg_krb5_init(void)
+pg_krb5_init(Port *port)
 {
    krb5_error_code retval;
    char       *khostname;
     * 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;
 
    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;
 
        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);
            }
        }
    }
-   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");
    int         ret;
    StringInfoData buf;
    gss_buffer_desc gbuf;
+   char       *realmmatch;
 
    /*
     * GSS auth is not supported for protocol versions before 3, because it
                     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
     */
        *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");
    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
     * 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;
        }
 
  *
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
                REQUIRE_AUTH_OPTION(uaLDAP, "ldapsuffix", "ldap");
                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
            {
                ereport(LOG,
        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);
 }
 
 /*