Re: BUG #4126: KRB5/GSSAPI authenication fails for multipart kerberos principals - Mailing list pgsql-bugs

From Peter Koczan
Subject Re: BUG #4126: KRB5/GSSAPI authenication fails for multipart kerberos principals
Date
Msg-id 4544e0330804241212ycc78530obaebdc7bf2c4a3ae@mail.gmail.com
Whole thread Raw
In response to BUG #4126: KRB5/GSSAPI authenication fails for multipart kerberos principals  ("Peter Koczan" <pjkoczan@gmail.com>)
List pgsql-bugs
> From: "Peter Koczan" <pjkoczan@gmail.com>
> To: pgsql-bugs@postgresql.org
> Date: Wed, 23 Apr 2008 17:17:01 GMT
> Subject: BUG #4126: KRB5/GSSAPI authenication fails for multipart kerberos principals
>
>  When trying to connect to an 8.3 server using a multipart Kerberos principal
>  (e.g. ator/wsbackup.cs.wisc.edu@CS.WISC.EDU or koczan/mail@CS.WISC.EDU
>  instead of wsbackup@CS.WISC.EDU or koczan@CS.WISC.EDU), the connection
>  fails, claiming a name mismatch. This is a change from 8.2 and I found
>  nothing in the changelog or documentation to suggest this change or offer a
>  workaround.

I poked around the code a bit, and found something interesting in
src/backend/libpq/auth.c. Apparently, in 8.2, the kerberos username
gets transformed from a full authentication name to a local
authentication name before being compared to the received name (using
pg_an_to_ln), but in 8.3, this transformation doesn't happen, causing
a name mismatch and therefore an authentication failure. Putting this
back in "worked", in that now the names match, and
"wsbackup/ator.cs.wisc.edu" connects to the database as "wsbackup."

Reading the comment for pg_an_to_ln, I understand that it might be
best in the long run for this behavior to change (some sort of
principal mapping or saying that multipart principals should have
different database roles). However, right now it is a bug because it's
an authentication failure with no discernible workaround. I tried
creating a "wsbackup/ator.cs.wisc.edu" role in my database, but it
still failed because it wasn't even getting to the point of checking
roles in the database.

In any case, here's a patch to src/backend/libpq/auth.c that puts back
the old behavior for krb5 and gss authentication. I didn't check or
modify other auth methods because I don't use them.

Peter

Index: src/backend/libpq/auth.c
===================================================================
RCS file: /s/postgresql-8.3.1/src/CVSROOT/postgresql-8.3.1/src/backend/libpq/auth.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 auth.c
*** src/backend/libpq/auth.c    31 Mar 2008 20:26:15 -0000      1.1.1.1
--- src/backend/libpq/auth.c    24 Apr 2008 18:00:59 -0000
***************
*** 104,109 ****
--- 104,132 ----
  #endif

  /*
+  * pg_an_to_ln -- return the local name corresponding to an authentication
+  *                              name
+  *
+  * XXX Assumes that the first aname component is the user name.  This is NOT
+  *       necessarily so, since an aname can actually be something out of your
+  *       worst X.400 nightmare, like
+  *              ORGANIZATION=U. C. Berkeley/NAME=Paul M. Aoki@CS.BERKELEY.EDU
+  *       Note that the MIT an_to_ln code does the same thing if you don't
+  *       provide an aname mapping database...it may be a better idea to use
+  *       krb5_an_to_ln, except that it punts if multiple components are found,
+  *       and we can't afford to punt.
+  */
+ static char *
+ pg_an_to_ln(char *aname)
+ {
+       char       *p;
+
+       if ((p = strchr(aname, '/')) || (p = strchr(aname, '@')))
+               *p = '\0';
+       return aname;
+ }
+
+ /*
   * Various krb5 state which is not connection specfic, and a flag to
   * indicate whether we have initialised it yet.
   */
***************
*** 275,280 ****
--- 298,304 ----
                return STATUS_ERROR;
        }

+       kusername = pg_an_to_ln(kusername);
        if (pg_krb_caseins_users)
                ret = pg_strncasecmp(port->user_name, kusername,
SM_DATABASE_USER);
        else
***************
*** 588,593 ****
--- 612,618 ----
                return STATUS_ERROR;
        }

+       gbuf.value = pg_an_to_ln(gbuf.value);
        if (pg_krb_caseins_users)
                ret = pg_strcasecmp(port->user_name, gbuf.value);
        else

pgsql-bugs by date:

Previous
From: Peter Eisentraut
Date:
Subject: Re: BUG #4128: The postmaster.opts.default file is begin ignored
Next
From: Tom Lane
Date:
Subject: Re: BUG #4128: The postmaster.opts.default file is begin ignored