Second patch applied:
Add GUC krb_server_hostname so the server hostname can be specified as
part of service principal. If not set, any service principal matching
an entry in the keytab can be used.
I updated your documentation to reflect this.
Thanks.
---------------------------------------------------------------------------
Todd Kover wrote:
> > Todd Kover <[EMAIL PROTECTED]> writes:
> >
> > > The attached patch adds a directive to the config file,
> > > krb_server_hostname that allows the hostname that service tickets
> > > are obtained against to be different from the hostname of the db
> > > server.
> >
> > Why is this necessary?
>
> It's largely useful in combination with restricting the interfaces
> listened to via the listen_addresses directive in the config file. As
> the code works now you can only connect via kerberos with a service
> principal derived from the hostname of the box rather than any dns name
> associated with any of the box's interfaces.
>
> For example, if the server is named server0.example.com, but the db is
> bound to db.example.com via the listen_addresses directive, the pgsql
> server won't authenticate properly.
>
> Similarly, if server0.example.com is one interface and
> server1.example.com is another, and the hostname is server.example.com
> but doesn't correspond to any interfaces, connecting to neither will
> work.
>
> > If it is necessary, wouldn't something similar be needed at the
> > client end as well?
>
> No. The decision of which principal to obtain a service ticket for is
> based on what it connects to.
>
> In the first above example, if running:
>
> psql -h server0.example.com
>
> the client would obtain a service ticket for
> postgres/server0.example.com. If running:
>
> psql -h db.example.com
>
> it would obtain a service ticket for postgres/db.example.com, and
> without the directive I'm adding, it would fail to establish a
> connection because the server wouldn't be expecting that. Of course,
> adding the directive would make the first case fail and the second
> pass. This works fine for our environment since we're binding to
> db.example.com.
>
> (as an aside, it's actually a bit more complicated then this since the
> way the kerberos libraries are used, db.example.com is canonicalized, so
> if it were a CNAME for server0.example.com it would do the right thing,
> but we're using an A record).
>
> > I'd have thought that host information would be established by some
> > sort of system-wide configuration file, not by per-program options.
>
> Different applications can use different service principals. The use
> of the hostname in the principal name at all is an application-specific
> decision. The krb5 api encourages it to be a DNS hostname pretty
> strongly in the way it works, but it's not cast in stone.
>
> However, other kerberos clients will accept using any kerberos principal
> in the keytab but postgresql as shipped requires it to match the
> hostname. If you want that behavior instead, then change pg_krb5_server
> to NULL when calling krb5_recvauth in src/backend/libpq/auth.c and it
> won't require that the hostnames match. (but it's still necessary for
> something to match).
>
> The second patch (kovert-krb5-patch-newbehavior.txt) makes the default
> behavior to accept any principal in the keytab. This means that people
> using kerberos will continue to work, but they'll be slightly more broad
> in what they accept as a valid service principal (I suspect there's very
> few people in the world who care about this since it still needs to be
> something in the keytab).
>
> I left the implementation of krb_server_hostname so that someone can
> define this if they want. (and if they want to make it behave like
> versions of pgsql up until now, they'd need to set it to the hostname).
>
> The second patch's default case makes pgsql match the behavior of
> eklogind (kerberized rlogind that ships with MIT kerberos) and the
> gssapi/krb5-aware version of sshd and probably numerous other things.
>
> > Also, the available documentation says that PG_KRB_SRVNAM is a
> > service name, not a host name, so I feel like there's something wrong
> > with your description of what you're doing.
>
> indeed, there was something wrong with what I was doing. PG_KRB_SRVNAM
> defaults to 'postgres' rather than the hostname. This was fallout from
> when I was first developing the patch.
>
> The absence of the krb_server_hostname config flag should have left the
> default behavior in place, it wasn't. I just tested this patch against
> both cases on a dev box and it works as expected.
>
> both patches are against 8.0.0rc3. The first implements what I
> originally was doing without changing the default, the second changes
> the default to be more accepting and also implements the directive in
> case someone wants to go back to the old behavior.
>
> -Todd
>
> Index: doc/src/sgml/runtime.sgml
> ===================================================================
> RCS file: postgresql-8.0.0rc3/doc/src/sgml/runtime.sgml,v
> retrieving revision 1.1.1.1
> retrieving revision 1.2
> diff -u -r1.1.1.1 -r1.2
> --- doc/src/sgml/runtime.sgml 26 Dec 2004 23:06:56 -0000 1.1.1.1
> +++ doc/src/sgml/runtime.sgml 3 Jan 2005 23:18:44 -0000 1.2
> @@ -952,6 +952,20 @@
> </listitem>
> </varlistentry>
>
> + <varlistentry id="guc-krb_server_hostname"
> xreflabel="krb_server_hostname">
> + <term><varname>krb_server_hostname</varname>
> (<type>string</type>)</term>
> + <indexterm>
> + <primary><varname>krb_server_hostname</> configuration
> parameter</primary>
> + </indexterm>
> + <listitem>
> + <para>
> + Sets the hostname that service tickets will be obtained against
> + (defaults to the hostname of the postgresql server)
> + <xref linkend="kerberos-auth"> for details.
> + </para>
> + </listitem>
> + </varlistentry>
> +
> <varlistentry id="guc-db-user-namespace" xreflabel="db_user_namespace">
> <term><varname>db_user_namespace</varname>
> (<type>boolean</type>)</term>
> <indexterm>
> Index: src/backend/libpq/auth.c
> ===================================================================
> RCS file: postgresql-8.0.0rc3/src/backend/libpq/auth.c,v
> retrieving revision 1.1.1.1
> retrieving revision 1.3
> diff -u -r1.1.1.1 -r1.3
> --- src/backend/libpq/auth.c 31 Dec 2004 21:59:50 -0000 1.1.1.1
> +++ src/backend/libpq/auth.c 4 Jan 2005 11:14:08 -0000 1.3
> @@ -41,6 +41,7 @@
> static int recv_and_check_password_packet(Port *port);
>
> char *pg_krb_server_keyfile;
> +char *pg_krb_server_hostname = NULL;
>
> #ifdef USE_PAM
> #ifdef HAVE_PAM_PAM_APPL_H
> @@ -215,9 +222,10 @@
> return STATUS_ERROR;
> }
>
> - retval = krb5_sname_to_principal(pg_krb5_context, NULL, PG_KRB_SRVNAM,
> -
> KRB5_NT_SRV_HST, &pg_krb5_server);
> - if (retval)
> + retval = krb5_sname_to_principal(pg_krb5_context,
> + pg_krb_server_hostname, PG_KRB_SRVNAM,
> + KRB5_NT_SRV_HST, &pg_krb5_server);
> + if (retval)
> {
> ereport(LOG,
> (errmsg("Kerberos sname_to_principal(\"%s\") returned error
> %d",
> Index: src/backend/utils/misc/guc.c
> ===================================================================
> RCS file: postgresql-8.0.0rc3/src/backend/utils/misc/guc.c,v
> retrieving revision 1.1.1.1
> retrieving revision 1.2
> diff -u -r1.1.1.1 -r1.2
> --- src/backend/utils/misc/guc.c 20 Dec 2004 18:15:07 -0000 1.1.1.1
> +++ src/backend/utils/misc/guc.c 3 Jan 2005 14:59:45 -0000 1.2
> @@ -1546,6 +1546,15 @@
> },
>
> {
> + {"krb_server_hostname", PGC_POSTMASTER, CONN_AUTH_SECURITY,
> + gettext_noop("Sets the hostname of the Kerberos
> server."),
> + NULL
> + },
> + &pg_krb_server_hostname,
> + NULL, NULL, NULL
> + },
> +
> + {
> {"rendezvous_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
> gettext_noop("Sets the Rendezvous broadcast service
> name."),
> NULL
> Index: src/bin/psql/tab-complete.c
> ===================================================================
> RCS file: postgresql-8.0.0rc3/src/bin/psql/tab-complete.c,v
> retrieving revision 1.1.1.1
> retrieving revision 1.2
> diff -u -r1.1.1.1 -r1.2
> --- src/bin/psql/tab-complete.c 24 Dec 2004 15:42:05 -0000 1.1.1.1
> +++ src/bin/psql/tab-complete.c 3 Jan 2005 14:59:46 -0000 1.2
> @@ -552,6 +552,7 @@
> "geqo_threshold",
> "join_collapse_limit",
> "krb_server_keyfile",
> + "krb_server_hostname",
> "lc_messages",
> "lc_monetary",
> "lc_numeric",
> Index: src/include/libpq/auth.h
> ===================================================================
> RCS file: postgresql-8.0.0rc3/src/include/libpq/auth.h,v
> retrieving revision 1.1.1.1
> retrieving revision 1.2
> diff -u -r1.1.1.1 -r1.2
> --- src/include/libpq/auth.h 31 Dec 2004 22:03:32 -0000 1.1.1.1
> +++ src/include/libpq/auth.h 3 Jan 2005 14:59:47 -0000 1.2
> @@ -27,5 +27,6 @@
> #define PG_KRB5_VERSION "PGVER5.1"
>
> extern char *pg_krb_server_keyfile;
> +extern char *pg_krb_server_hostname;
>
> #endif /* AUTH_H */
> Index: doc/src/sgml/runtime.sgml
> ===================================================================
> RCS file: postgresql-8.0.0rc3/doc/src/sgml/runtime.sgml,v
> retrieving revision 1.1.1.1
> retrieving revision 1.2
> diff -u -r1.1.1.1 -r1.2
> --- doc/src/sgml/runtime.sgml 26 Dec 2004 23:06:56 -0000 1.1.1.1
> +++ doc/src/sgml/runtime.sgml 3 Jan 2005 23:18:44 -0000 1.2
> @@ -952,6 +952,20 @@
> </listitem>
> </varlistentry>
>
> + <varlistentry id="guc-krb_server_hostname"
> xreflabel="krb_server_hostname">
> + <term><varname>krb_server_hostname</varname>
> (<type>string</type>)</term>
> + <indexterm>
> + <primary><varname>krb_server_hostname</> configuration
> parameter</primary>
> + </indexterm>
> + <listitem>
> + <para>
> + Sets the hostname that service tickets will be obtained against
> + (the default is any accept any service principal in the keytab)
> + <xref linkend="kerberos-auth"> for details.
> + </para>
> + </listitem>
> + </varlistentry>
> +
> <varlistentry id="guc-db-user-namespace" xreflabel="db_user_namespace">
> <term><varname>db_user_namespace</varname>
> (<type>boolean</type>)</term>
> <indexterm>
> Index: src/backend/libpq/auth.c
> ===================================================================
> RCS file: postgresql-8.0.0rc3/src/backend/libpq/auth.c,v
> retrieving revision 1.1.1.1
> diff -u -r1.1.1.1 auth.c
> --- src/backend/libpq/auth.c 31 Dec 2004 21:59:50 -0000 1.1.1.1
> +++ src/backend/libpq/auth.c 4 Jan 2005 12:09:45 -0000
> @@ -41,6 +41,7 @@
> static int recv_and_check_password_packet(Port *port);
>
> char *pg_krb_server_keyfile;
> +char *pg_krb_server_hostname = NULL;
>
> #ifdef USE_PAM
> #ifdef HAVE_PAM_PAM_APPL_H
> @@ -215,19 +216,24 @@
> return STATUS_ERROR;
> }
>
> - retval = krb5_sname_to_principal(pg_krb5_context, NULL, PG_KRB_SRVNAM,
> -
> KRB5_NT_SRV_HST, &pg_krb5_server);
> - if (retval)
> - {
> - ereport(LOG,
> - (errmsg("Kerberos sname_to_principal(\"%s\") returned error
> %d",
> - PG_KRB_SRVNAM, retval)));
> - com_err("postgres", retval,
> - "while getting server principal for service
> \"%s\"",
> - PG_KRB_SRVNAM);
> - krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
> - krb5_free_context(pg_krb5_context);
> - return STATUS_ERROR;
> + if(pg_krb_server_hostname) {
> + retval = krb5_sname_to_principal(pg_krb5_context,
> + pg_krb_server_hostname, PG_KRB_SRVNAM,
> + KRB5_NT_SRV_HST, &pg_krb5_server);
> + if (retval)
> + {
> + ereport(LOG,
> + (errmsg("Kerberos sname_to_principal(\"%s\") returned
> error %d",
> + PG_KRB_SRVNAM, retval)));
> + com_err("postgres", retval,
> + "while getting server principal for
> service \"%s\"",
> + PG_KRB_SRVNAM);
> + krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
> + krb5_free_context(pg_krb5_context);
> + return STATUS_ERROR;
> + }
> + } else {
> + pg_krb5_server = NULL;
> }
>
> pg_krb5_initialised = 1;
> Index: src/backend/utils/misc/guc.c
> ===================================================================
> RCS file: postgresql-8.0.0rc3/src/backend/utils/misc/guc.c,v
> retrieving revision 1.1.1.1
> retrieving revision 1.2
> diff -u -r1.1.1.1 -r1.2
> --- src/backend/utils/misc/guc.c 20 Dec 2004 18:15:07 -0000 1.1.1.1
> +++ src/backend/utils/misc/guc.c 3 Jan 2005 14:59:45 -0000 1.2
> @@ -1546,6 +1546,15 @@
> },
>
> {
> + {"krb_server_hostname", PGC_POSTMASTER, CONN_AUTH_SECURITY,
> + gettext_noop("Sets the hostname of the Kerberos
> server."),
> + NULL
> + },
> + &pg_krb_server_hostname,
> + NULL, NULL, NULL
> + },
> +
> + {
> {"rendezvous_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
> gettext_noop("Sets the Rendezvous broadcast service
> name."),
> NULL
> Index: src/bin/psql/tab-complete.c
> ===================================================================
> RCS file: postgresql-8.0.0rc3/src/bin/psql/tab-complete.c,v
> retrieving revision 1.1.1.1
> retrieving revision 1.2
> diff -u -r1.1.1.1 -r1.2
> --- src/bin/psql/tab-complete.c 24 Dec 2004 15:42:05 -0000 1.1.1.1
> +++ src/bin/psql/tab-complete.c 3 Jan 2005 14:59:46 -0000 1.2
> @@ -552,6 +552,7 @@
> "geqo_threshold",
> "join_collapse_limit",
> "krb_server_keyfile",
> + "krb_server_hostname",
> "lc_messages",
> "lc_monetary",
> "lc_numeric",
> Index: src/include/libpq/auth.h
> ===================================================================
> RCS file: postgresql-8.0.0rc3/src/include/libpq/auth.h,v
> retrieving revision 1.1.1.1
> retrieving revision 1.2
> diff -u -r1.1.1.1 -r1.2
> --- src/include/libpq/auth.h 31 Dec 2004 22:03:32 -0000 1.1.1.1
> +++ src/include/libpq/auth.h 3 Jan 2005 14:59:47 -0000 1.2
> @@ -27,5 +27,6 @@
> #define PG_KRB5_VERSION "PGVER5.1"
>
> extern char *pg_krb_server_keyfile;
> +extern char *pg_krb_server_hostname;
>
> #endif /* AUTH_H */
>
> ---------------------------(end of broadcast)---------------------------
> TIP 8: explain analyze is your friend
--
Bruce Momjian | http://candle.pha.pa.us
[email protected] | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Index: doc/src/sgml/runtime.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v
retrieving revision 1.325
diff -c -c -r1.325 runtime.sgml
*** doc/src/sgml/runtime.sgml 13 Jun 2005 02:40:06 -0000 1.325
--- doc/src/sgml/runtime.sgml 14 Jun 2005 17:39:22 -0000
***************
*** 969,992 ****
<listitem>
<para>
Sets the Kerberos service name. See <xref linkend="kerberos-auth">
! for details. This parameter can only be set at server start.
</para>
</listitem>
</varlistentry>
! <varlistentry id="guc-krb-caseins-users" xreflabel="krb_caseins_users">
! <term><varname>krb_caseins_users</varname>
(<type>boolean</type>)</term>
! <indexterm>
! <primary><varname>krb_caseins_users</varname> configuration
parameter</primary>
</indexterm>
! <listitem>
! <para>
! Sets if Kerberos usernames should be treated case-insensitive.
! The default is off (case sensitive). This parameter can only be
! set at server start.
</para>
! </listitem>
! </varlistentry>
<varlistentry id="guc-db-user-namespace" xreflabel="db_user_namespace">
<term><varname>db_user_namespace</varname> (<type>boolean</type>)</term>
--- 969,1012 ----
<listitem>
<para>
Sets the Kerberos service name. See <xref linkend="kerberos-auth">
! for details. This parameter can only be set at server start.
</para>
</listitem>
</varlistentry>
! <varlistentry id="guc-krb-caseins-users" xreflabel="krb_caseins_users">
! <term><varname>krb_caseins_users</varname> (<type>boolean</type>)</term>
! <indexterm>
! <primary><varname>krb_caseins_users</varname> configuration
parameter</primary>
</indexterm>
! <listitem>
! <para>
! Sets if Kerberos usernames should be treated case-insensitive.
! The default is off (case sensitive). This parameter can only be
! set at server start.
</para>
! </listitem>
! </varlistentry>
!
! <varlistentry id="guc-krb-server-hostname"
xreflabel="krb_server_hostname">
! <term><varname>krb_server_hostname</varname>
(<type>string</type>)</term>
! <indexterm>
! <primary><varname>krb_server_hostname</> configuration
parameter</primary>
! </indexterm>
! <listitem>
! <para>
! Sets the hostname part of the service principal.
! This, combined with <varname>krb_srvname</>, is used to generate
! the complete service principal, i.e.
!
<varname>krb_server_hostname</><literal>/</><varname>krb_server_hostname</><literal>@</>REALM.
! </para>
! <para>
! If not set, the default is to allow any service principal matching an
entry
! in the keytab. See <xref linkend="kerberos-auth"> for details.
! This parameter can only be set at server start.
! </para>
! </listitem>
! </varlistentry>
<varlistentry id="guc-db-user-namespace" xreflabel="db_user_namespace">
<term><varname>db_user_namespace</varname> (<type>boolean</type>)</term>
Index: src/backend/libpq/auth.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/libpq/auth.c,v
retrieving revision 1.124
diff -c -c -r1.124 auth.c
*** src/backend/libpq/auth.c 4 Jun 2005 20:42:42 -0000 1.124
--- src/backend/libpq/auth.c 14 Jun 2005 17:39:23 -0000
***************
*** 43,48 ****
--- 43,49 ----
char *pg_krb_server_keyfile;
char *pg_krb_srvnam;
bool pg_krb_caseins_users;
+ char *pg_krb_server_hostname = NULL;
#ifdef USE_PAM
#ifdef HAVE_PAM_PAM_APPL_H
***************
*** 221,240 ****
return STATUS_ERROR;
}
! retval = krb5_sname_to_principal(pg_krb5_context, NULL, pg_krb_srvnam,
!
KRB5_NT_SRV_HST, &pg_krb5_server);
! if (retval)
{
! ereport(LOG,
! (errmsg("Kerberos sname_to_principal(\"%s\") returned error
%d",
! pg_krb_srvnam, retval)));
! com_err("postgres", retval,
! "while getting server principal for service
\"%s\"",
! pg_krb_srvnam);
! krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
! krb5_free_context(pg_krb5_context);
! return STATUS_ERROR;
! }
pg_krb5_initialised = 1;
return STATUS_OK;
--- 222,246 ----
return STATUS_ERROR;
}
! if (pg_krb_server_hostname)
{
! retval = krb5_sname_to_principal(pg_krb5_context,
! pg_krb_server_hostname, pg_krb_srvnam,
! KRB5_NT_SRV_HST, &pg_krb5_server);
! if (retval)
! {
! ereport(LOG,
! (errmsg("Kerberos sname_to_principal(\"%s\") returned
error %d",
! pg_krb_srvnam, retval)));
! com_err("postgres", retval,
! "while getting server principal for
service \"%s\"",
! pg_krb_srvnam);
! krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
! krb5_free_context(pg_krb5_context);
! return STATUS_ERROR;
! }
! } else
! pg_krb5_server = NULL;
pg_krb5_initialised = 1;
return STATUS_OK;
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.264
diff -c -c -r1.264 guc.c
*** src/backend/utils/misc/guc.c 4 Jun 2005 20:42:42 -0000 1.264
--- src/backend/utils/misc/guc.c 14 Jun 2005 17:39:27 -0000
***************
*** 1594,1599 ****
--- 1594,1608 ----
},
{
+ {"krb_server_hostname", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ gettext_noop("Sets the hostname of the Kerberos
server."),
+ NULL
+ },
+ &pg_krb_server_hostname,
+ NULL, NULL, NULL
+ },
+
+ {
{"bonjour_name", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
gettext_noop("Sets the Bonjour broadcast service
name."),
NULL
Index: src/bin/psql/tab-complete.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v
retrieving revision 1.130
diff -c -c -r1.130 tab-complete.c
*** src/bin/psql/tab-complete.c 25 May 2005 22:12:05 -0000 1.130
--- src/bin/psql/tab-complete.c 14 Jun 2005 17:39:28 -0000
***************
*** 559,565 ****
"geqo_selection_bias",
"geqo_threshold",
"join_collapse_limit",
- "krb_server_keyfile",
"lc_messages",
"lc_monetary",
"lc_numeric",
--- 559,564 ----
Index: src/include/libpq/auth.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/libpq/auth.h,v
retrieving revision 1.27
diff -c -c -r1.27 auth.h
*** src/include/libpq/auth.h 4 Jun 2005 20:42:42 -0000 1.27
--- src/include/libpq/auth.h 14 Jun 2005 17:39:29 -0000
***************
*** 29,33 ****
--- 29,34 ----
extern char *pg_krb_server_keyfile;
extern char *pg_krb_srvnam;
extern bool pg_krb_caseins_users;
+ extern char *pg_krb_server_hostname;
#endif /* AUTH_H */
---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]