Re: patch to add krb_server_hostname to postgresql.conf - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: patch to add krb_server_hostname to postgresql.conf
Date
Msg-id 200506050202.j55228J15896@candle.pha.pa.us
Whole thread Raw
In response to Re: patch to add krb_server_hostname to postgresql.conf  (Todd Kover <kovert@omniscient.com>)
List pgsql-patches
Addition to postgresql.conf.sample is missing.  I will add it.

Your patch has been added to the PostgreSQL unapplied patches list at:

    http://momjian.postgresql.org/cgi-bin/pgpatches

It will be applied as soon as one of the PostgreSQL committers reviews
and approves it.

---------------------------------------------------------------------------


Todd Kover wrote:
>  > Todd Kover <kovert@omniscient.com> 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
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: uptime function to postmaster
Next
From: Bruce Momjian
Date:
Subject: Re: patch to add krb_server_hostname to postgresql.conf