Thread: BUG #4824: KRB5/GSSAPI authentication fails when user != principal
The following bug has been logged online: Bug reference: 4824 Logged by: Peter Koczan Email address: pjkoczan@gmail.com PostgreSQL version: 8.4beta2 Operating system: Red Hat Enterprise Linux 5.3 Description: KRB5/GSSAPI authentication fails when user != principal Details: When authenticating with Kerberos/GSSAPI, if the Kerberos principal is not the same as the shell user, authentication fails. For instance, as root (for local fs access) with other tickets (for database and network fs access). Note: runauth is our homegrown utility to get stashed kerberos tickets. [root@mitchell ~]# /s/std/bin/runauth -a -l postgres /s/postgresql-8.4-beta/bin/psql -h mitchell -p 49173 postgres psql: FATAL: role "root" does not exist It appears to assume that the shell user is the user to connect as. However, using an 8.3 client works as previously expected. [root@mitchell ~]# /s/std/bin/runauth -a -l postgres /s/postgresql-8.3/bin/psql -h mitchell -p 49173 postgres Welcome to psql 8.3.6 (server 8.4beta2), the PostgreSQL interactive terminal. ... postgres=# select current_role; current_user -------------- postgres (1 row) This is a difference on the client side. Even if this is newly expected behavior, it is a change and I could not find any reference to it in the release notes. Peter
"Peter Koczan" <pjkoczan@gmail.com> writes: > PostgreSQL version: 8.4beta2 > Description: KRB5/GSSAPI authentication fails when user != principal > When authenticating with Kerberos/GSSAPI, if the Kerberos principal is not > the same as the shell user, authentication fails. > It appears to assume that the shell user is the user to connect as. However, > using an 8.3 client works as previously expected. This is an intentional change. It is mentioned in the release notes, though perhaps not too helpfully: Make Kerberos connections use the same method to determine the username of the client as all other authentication methods (Magnus) Previously a special Kerberos-only API was used. We should probably at least clarify this release note. Do you want to make an argument that this is a fundamental breakage and we need to revert it? If so, what's the argument? regards, tom lane
> We should probably at least clarify this release note. =A0Do you want > to make an argument that this is a fundamental breakage and we need > to revert it? =A0If so, what's the argument? Certainly. It seems like with the changes in 8.4, krb5/gssapi auth looks for a valid ticket, and if it finds one, connects without regard for the principal in that ticket. This is a gaping security hole, because it is very nearly the same as trust authentication. I'm me... [koczan@mitchell] ~ $ klist ... Default principal: koczan@CS.WISC.EDU ... I connect as me... [koczan@mitchell] ~ $ /s/postgresql-8.4-beta/bin/psql -h mitchell -p 49173 postgres psql (8.4beta2) SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) Type "help" for help. postgres=3D> select current_role; current_user -------------- koczan (1 row) Now, I connect as someone else... [koczan@mitchell] ~ $ /s/postgresql-8.4-beta/bin/psql -h mitchell -p 49173 -U strivia postgres psql (8.4beta2) SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) Type "help" for help. postgres=3D> select current_role; current_user -------------- strivia (1 row) Now, I connect as superuser... [koczan@mitchell] ~ $ /s/postgresql-8.4-beta/bin/psql -h mitchell -p 49173 -U postgres postgres psql (8.4beta2) SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) Type "help" for help. postgres=3D# select current_role; current_user -------------- postgres (1 row) Old clients also exhibit this behavior, so it's also a server-side issue. [koczan@mitchell] ~ $ /s/postgresql-8.3.6/bin/psql -h mitchell -p 49173 -U postgres postgres Welcome to psql 8.3.6 (server 8.4beta2), the PostgreSQL interactive termina= l. Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit WARNING: You are connected to a server with major version 8.4, but your psql client is major version 8.3. Some backslash commands, such as \d, might not work properly. SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) postgres=3D# select current_role; current_user -------------- postgres (1 row) And just to show you that there is no trickery, I will attempt to connect without Kerberos tickets. bash-3.2$ whoami koczan bash-3.2$ klist klist: No credentials cache found (ticket cache FILE:/var/adm/krb5/tmp/tkt/krb5cc_0_N26236) ... bash-3.2$ /s/postgresql-8.4-beta/bin/psql -h mitchell -p 49173 postgrespsql: GSSAPI continuation error: Unspecified GSS failure. Minor code may provide more information GSSAPI continuation error: Unknown code krb5 195 bash-3.2$ /s/postgresql-8.4-beta/bin/psql -h mitchell -p 49173 -U postgres postgres psql: GSSAPI continuation error: Unspecified GSS failure. Minor code may provide more information GSSAPI continuation error: Unknown code krb5 195 This is trust authentication with one rather inconsequential bit of verification, that's a fundamental breakage. One of the major points of Kerberos is that, for anything that talks Kerberos, you are the principal in that ticket. I understand the desire to change some of that old code, but why is that principal being ignored? Peter
Peter Koczan <pjkoczan@gmail.com> writes: > This is trust authentication with one rather inconsequential bit of > verification, that's a fundamental breakage. One of the major points > of Kerberos is that, for anything that talks Kerberos, you are the > principal in that ticket. I understand the desire to change some of > that old code, but why is that principal being ignored? Well, the reason for that change was that the libpq code was absorbing userid from any available Kerberos ticket, even if the server subsequently issued a non-Kerberos authentication challenge. I still think that was wrong. What your complaint seems to suggest is that the server-side Kerberos auth code should be insisting that the supplied principal's first component match the requested database userid. I kinda thought we *had* been doing that, but can't claim to have read that code closely. Magnus? regards, tom lane
* Tom Lane (tgl@sss.pgh.pa.us) wrote: > Peter Koczan <pjkoczan@gmail.com> writes: > > This is trust authentication with one rather inconsequential bit of > > verification, that's a fundamental breakage. One of the major points > > of Kerberos is that, for anything that talks Kerberos, you are the > > principal in that ticket. I understand the desire to change some of > > that old code, but why is that principal being ignored? >=20 > Well, the reason for that change was that the libpq code was absorbing > userid from any available Kerberos ticket, even if the server > subsequently issued a non-Kerberos authentication challenge. I still > think that was wrong. What your complaint seems to suggest is that > the server-side Kerberos auth code should be insisting that the supplied > principal's first component match the requested database userid. > I kinda thought we *had* been doing that, but can't claim to have read > that code closely. Magnus? We should certainly either be requiring the princ match the user in the database, or that it is allowed through a username mapping where a mapping table has been supplied, ala ident. Stephen
Tom Lane wrote: > Peter Koczan <pjkoczan@gmail.com> writes: >> This is trust authentication with one rather inconsequential bit of >> verification, that's a fundamental breakage. One of the major points >> of Kerberos is that, for anything that talks Kerberos, you are the >> principal in that ticket. I understand the desire to change some of >> that old code, but why is that principal being ignored? > > Well, the reason for that change was that the libpq code was absorbing > userid from any available Kerberos ticket, even if the server > subsequently issued a non-Kerberos authentication challenge. I still > think that was wrong. What your complaint seems to suggest is that > the server-side Kerberos auth code should be insisting that the supplied > principal's first component match the requested database userid. > I kinda thought we *had* been doing that, but can't claim to have read > that code closely. Magnus? We are certainly *supposed* to do that. And we have been doing that. So if that's not done, it's been broken in 8.4 (most likely by me). Peter, are you using gssapi or krb5? Only krb5 has changed wrt libpq, but from your messages it looks like you have gssapi? Can you show us your pg_hba.conf file, and all lines with krb in them from postgresql.conf? Also, can you try it with the server set to log at DEBUG4, and let us know what output you get? -- Magnus Hagander Self: http://www.hagander.net/ Work: http://www.redpill-linpro.com/
Magnus Hagander wrote: > Tom Lane wrote: >> Peter Koczan <pjkoczan@gmail.com> writes: >>> This is trust authentication with one rather inconsequential bit of >>> verification, that's a fundamental breakage. One of the major points >>> of Kerberos is that, for anything that talks Kerberos, you are the >>> principal in that ticket. I understand the desire to change some of >>> that old code, but why is that principal being ignored? >> Well, the reason for that change was that the libpq code was absorbing >> userid from any available Kerberos ticket, even if the server >> subsequently issued a non-Kerberos authentication challenge. I still >> think that was wrong. What your complaint seems to suggest is that >> the server-side Kerberos auth code should be insisting that the supplied >> principal's first component match the requested database userid. >> I kinda thought we *had* been doing that, but can't claim to have read >> that code closely. Magnus? > > We are certainly *supposed* to do that. And we have been doing that. So > if that's not done, it's been broken in 8.4 (most likely by me). > > Peter, are you using gssapi or krb5? Only krb5 has changed wrt libpq, > but from your messages it looks like you have gssapi? > > Can you show us your pg_hba.conf file, and all lines with krb in them > from postgresql.conf? > > Also, can you try it with the server set to log at DEBUG4, and let us > know what output you get? Crap, I think I found the problem. Tom, or someone else... auth.c line 1076. I'm pretty sure that should be "return ret" not "return STATUS_OK". Wow, that's a bad bug :-O //Magnus
Peter Koczan wrote: > I don't know if it's much use now, but here you go. <snip> > May 27 15:37:29 mitchell postgres[30609]: [629-1] LOG: provided > username (koczan) and authenticated username (strivia) don't match > May 27 15:37:29 mitchell postgres[30609]: [630-1] LOG: connection > authorized: user=strivia database=postgres This seems to confirm my suspicions. We detect that the username is wrong, but we still don't reject the connection. //Magnus
Magnus Hagander <magnus@hagander.net> writes: > Tom, or someone else... auth.c line 1076. I'm pretty sure that should be > "return ret" not "return STATUS_OK". Doh. > Wow, that's a bad bug :-O Hey, that's what beta is for ;-) You might want to take a quick look for copy-and-pastes of same error. I see none offhand, but ... regards, tom lane
Tom Lane wrote: > Magnus Hagander <magnus@hagander.net> writes: >> Tom, or someone else... auth.c line 1076. I'm pretty sure that should be >> "return ret" not "return STATUS_OK". > > Doh. yeah. WIll apply patch. >> Wow, that's a bad bug :-O > > Hey, that's what beta is for ;-) :-) Do we need to announce it somehow? > You might want to take a quick look for copy-and-pastes of same error. > I see none offhand, but ... Yeah, I looked over the other similar places and didn't find anything. //Magnus
I don't know if it's much use now, but here you go. On Wed, May 27, 2009 at 3:15 PM, Magnus Hagander <magnus@hagander.net> wrote: > We are certainly *supposed* to do that. And we have been doing that. So > if that's not done, it's been broken in 8.4 (most likely by me). > > Peter, are you using gssapi or krb5? Only krb5 has changed wrt libpq, > but from your messages it looks like you have gssapi? gssapi > Can you show us your pg_hba.conf file, and all lines with krb in them > from postgresql.conf? pg_hba.conf # this part disables remote "postgres" superuser connections hostssl all postgres 127.0.0.1/32 gss hostssl all postgres 128.105.207.19/32 gss hostssl all postgres 128.105.0.0/16 reject hostssl all postgres 198.133.224.0/24 reject # this part enables non-superuser connections hostssl all nobody 128.105.0.0/16 trust hostssl all nobody 198.133.224.0/24 trust hostssl all all 128.105.0.0/16 gss hostssl all all 198.133.224.0/24 gss postgresql.conf # Kerberos and GSSAPI krb_server_keyfile = '/etc/v5srvtab.postgres' #krb_srvname = 'postgres' # (Kerberos only) #krb_caseins_users = off > Also, can you try it with the server set to log at DEBUG4, and let us > know what output you get? Connecting like this... [koczan@ator] koczan $ /s/postgresql-8.4-beta/bin/psql -h mitchell -p 49173 -U strivia postgres Produced this in the syslog. May 27 15:37:29 mitchell postgres[30574]: [624-1] DEBUG: forked new backend, pid=30609 socket=8 May 27 15:37:29 mitchell postgres[30609]: [624-1] LOG: connection received: host=ator.cs.wisc.edu port=44228 May 27 15:37:29 mitchell postgres[30609]: [625-1] DEBUG: SSL connection from "(anonymous)" May 27 15:37:29 mitchell postgres[30609]: [626-1] DEBUG: Processing received GSS token of length 477 May 27 15:37:29 mitchell postgres[30609]: [627-1] DEBUG: sending GSS response token of length 114 May 27 15:37:29 mitchell postgres[30609]: [628-1] DEBUG: sending GSS token of length 114 May 27 15:37:29 mitchell postgres[30609]: [629-1] LOG: provided username (koczan) and authenticated username (strivia) don't match May 27 15:37:29 mitchell postgres[30609]: [630-1] LOG: connection authorized: user=strivia database=postgres May 27 15:37:29 mitchell postgres[30609]: [631-1] DEBUG: postgres child[30609]: starting with ( May 27 15:37:29 mitchell postgres[30609]: [632-1] DEBUG: postgres May 27 15:37:29 mitchell postgres[30609]: [633-1] DEBUG: -v196608 May 27 15:37:29 mitchell postgres[30609]: [634-1] DEBUG: -y May 27 15:37:29 mitchell postgres[30609]: [635-1] DEBUG: postgres May 27 15:37:29 mitchell postgres[30609]: [636-1] DEBUG: ) May 27 15:37:29 mitchell postgres[30609]: [637-1] DEBUG: InitPostgres May 27 15:37:29 mitchell postgres[30609]: [638-1] DEBUG: my backend id is 1 May 27 15:37:29 mitchell postgres[30609]: [639-1] DEBUG: StartTransaction May 27 15:37:29 mitchell postgres[30609]: [640-1] DEBUG: name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: May 27 15:37:29 mitchell postgres[30609]: [641-1] DEBUG: CommitTransaction May 27 15:37:29 mitchell postgres[30609]: [642-1] DEBUG: name: unnamed; blockState: STARTED; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: .... May 27 15:37:55 mitchell postgres[30574]: [625-1] DEBUG: reaping dead processes May 27 15:37:55 mitchell postgres[30574]: [626-1] DEBUG: server process (PID 30612) exited with exit code 0 May 27 15:38:24 mitchell postgres[30609]: [643-1] DEBUG: shmem_exit(0) May 27 15:38:24 mitchell postgres[30609]: [644-1] DEBUG: proc_exit(0) May 27 15:38:24 mitchell postgres[30609]: [645-1] LOG: disconnection: session time: 0:00:54.389 user=strivia database=postgres host=ator.cs.wisc.edu port=44228 May 27 15:38:24 mitchell postgres[30609]: [646-1] DEBUG: SSL: write alert (0x0100) May 27 15:38:24 mitchell postgres[30609]: [647-1] DEBUG: exit(0) May 27 15:38:24 mitchell postgres[30609]: [648-1] DEBUG: shmem_exit(-1) May 27 15:38:24 mitchell postgres[30609]: [649-1] DEBUG: proc_exit(-1) Peter
Magnus Hagander wrote: > Tom Lane wrote: >> Magnus Hagander <magnus@hagander.net> writes: >>> Tom, or someone else... auth.c line 1076. I'm pretty sure that should be >>> "return ret" not "return STATUS_OK". >> Doh. > > yeah. WIll apply patch. And, applied. -- Magnus Hagander Self: http://www.hagander.net/ Work: http://www.redpill-linpro.com/
Magnus Hagander <magnus@hagander.net> writes: > Magnus Hagander wrote: >> Tom Lane wrote: >>> Magnus Hagander <magnus@hagander.net> writes: >>>> Tom, or someone else... auth.c line 1076. I'm pretty sure that should be >>>> "return ret" not "return STATUS_OK". >>> Doh. >> >> yeah. WIll apply patch. > And, applied. I have also patched the release notes to better explain the intentional change that I initially thought Peter was complaining about: diff -r1.6 release-8.4.sgml 2706,2707c2706,2707 < Make Kerberos connections use the same method to determine the < username of the client as all other authentication methods (Magnus) --- > Do not rely on Kerberos tickets to determine the default database > username (Magnus) 2711c2711,2717 < Previously a special Kerberos-only API was used. --- > Previously, a Kerberos-capable build of libpq would use the > principal name from any available Kerberos ticket as default > database username, even if the connection wasn't using Kerberos > authentication. This was deemed inconsistent and confusing. > The default username is now determined the same way with or > without Kerberos. Note however that the database username must still > match the ticket when Kerberos authentication is used. What this still leaves us with is whether that change is a bad idea or not. I still think it's OK, but maybe Peter can point to something else. regards, tom lane
On Wed, May 27, 2009 at 5:16 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > What this still leaves us with is whether that change is a bad idea or > not. =A0I still think it's OK, but maybe Peter can point to something > else. I recompiled postgres with the auth.c patch. This is only an issue if you are trying to connect as a principal that's not the same as your current username. Where I work, we have security and mode bits set up on Kerberos tickets and keytabs such that you either have to be the user in question or root to get those credentials. And we only have a couple of things that run as root with others' principals. There is a workaround to get the "expected behavior", just specify the proper username in the connection parameters. This should be explicitly said in the release notes. /s/std/bin/runauth -a -l postgres /s/postgresql-8.4-beta/bin/psql -h mitchell -p 49173 postgres psql: FATAL: GSSAPI authentication failed for user "root" FATAL: no pg_hba.conf entry for host "128.105.207.19", user "root", database "postgres", SSL off [root@mitchell ~]# /s/std/bin/runauth -a -l postgres /s/postgresql-8.4-beta/bin/psql -h mitchell -p 49173 -U postgres postgres psql (8.4beta2) SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) Type "help" for help. postgres=3D# I should also point out that old clients still exhibit the old behavior. [root@mitchell ~]# /s/std/bin/runauth -a -l postgres /s/postgresql-8.3.6/bin/psql -h mitchell -p 49173 postgres Welcome to psql 8.3.6 (server 8.4beta2), the PostgreSQL interactive termina= l. Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit WARNING: You are connected to a server with major version 8.4, but your psql client is major version 8.3. Some backslash commands, such as \d, might not work properly. SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) postgres=3D# It was rather convenient to know that whatever Kerberos principal was used was going to be the database user. The old behavior is more in line with other Kerberos'd systems like AFS or NFSv4 that take their authentication from the Kerberos principal (through an AFS token or LDAP), sometimes regardless of the shell user. Of course, file systems are different animals than DBMS's since they need to "always be on" instead of requiring explicit connections every time you authenticate. I can't think of any other major services that explicitly use Kerberos, so I'm not sure how many other models exist. =46rom a practical standpoint, I can accept this change since there is a simple workaround and since Kerberos is properly verifying the user. Though it would be nice to make the assumption that the principal is the user for Kerberos/GSSAPI connections, I don't think it's worth it to differently handle that rare case where it would actually make a difference. Peter
Peter Koczan <pjkoczan@gmail.com> writes: > I should also point out that old clients still exhibit the old behavior. Sure, because this is a libpq change. > It was rather convenient to know that whatever Kerberos principal was > used was going to be the database user. Isn't that still true? (Modulo the auth.c bug fix of course.) The only issue here is where the default guess for a not-explicitly-specified username comes from, not whether you'll be allowed to connect or not. regards, tom lane
On Thu, May 28, 2009 at 1:30 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > Peter Koczan <pjkoczan@gmail.com> writes: >> It was rather convenient to know that whatever Kerberos principal was >> used was going to be the database user. > > Isn't that still true? =A0(Modulo the auth.c bug fix of course.) =A0The o= nly > issue here is where the default guess for a not-explicitly-specified > username comes from, not whether you'll be allowed to connect or not. That's what I meant. It was convenient to have the default guess be the Kerberos principal for krb5/gss connections. This is still the case in the vast majority of connections, so it's probably not worth bending over backwards to satisfy these edge cases. Sorry for the confusion. Peter
On Thu, May 28, 2009 at 2:07 PM, Peter Koczan <pjkoczan@gmail.com> wrote: > On Thu, May 28, 2009 at 1:30 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> Peter Koczan <pjkoczan@gmail.com> writes: >>> It was rather convenient to know that whatever Kerberos principal was >>> used was going to be the database user. >> >> Isn't that still true? =A0(Modulo the auth.c bug fix of course.) =A0The = only >> issue here is where the default guess for a not-explicitly-specified >> username comes from, not whether you'll be allowed to connect or not. > > That's what I meant. It was convenient to have the default guess be > the Kerberos principal for krb5/gss connections. This is still the > case in the vast majority of connections, so it's probably not worth > bending over backwards to satisfy these edge cases. And by "this is still the case", I mean that the principal name and the username line up and exhibit the same overt behavior. Not that the principal forces the username. I need a break. :-) Peter