From b09f930d2eec6ed2427786d9aa64c1206859774d Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Wed, 7 Jan 2009 13:09:21 +0000 Subject: [PATCH] Add hba parameter include_realm to krb5, gss and sspi authentication, used to pass the full username@realm string to the authentication instead of just the username. This makes it possible to use pg_ident.conf to authenticate users from multiple realms as different database users. --- doc/src/sgml/client-auth.sgml | 26 +++++++++++++++++++++++++- src/backend/libpq/auth.c | 34 ++++++++++++++++++++++++++++++---- src/backend/libpq/hba.c | 13 ++++++++++++- src/include/libpq/hba.h | 3 ++- 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml index 1d0ce45ce7..f5cc472910 100644 --- a/doc/src/sgml/client-auth.sgml +++ b/doc/src/sgml/client-auth.sgml @@ -1,4 +1,4 @@ - + Client Authentication @@ -785,6 +785,18 @@ omicron bryanh guest1 + + include_realm + + + Include the realm name from the authenticated user principal. This is useful + in combination with Username maps (See + for details), especially with regular expressions, to map users from + multiple realms. + + + + krb_realm @@ -846,6 +858,18 @@ omicron bryanh guest1 + + include_realm + + + Include the realm name from the authenticated user principal. This is useful + in combination with Username maps (See + for details), especially with regular expressions, to map users from + multiple realms. + + + + krb_realm diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 437061c21a..4b5773ab88 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.176 2009/01/07 12:38:11 mha Exp $ + * $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.177 2009/01/07 13:09:21 mha Exp $ * *------------------------------------------------------------------------- */ @@ -748,7 +748,13 @@ pg_krb5_recvauth(Port *port) cp = strchr(kusername, '@'); if (cp) { - *cp = '\0'; + /* + * If we are not going to include the realm in the username that is passed + * to the ident map, destructively modify it here to remove the realm. Then + * advance past the separator to check the realm. + */ + if (!port->hba->include_realm) + *cp = '\0'; cp++; if (realmmatch != NULL && strlen(realmmatch)) @@ -1040,7 +1046,13 @@ pg_GSS_recvauth(Port *port) { char *cp = strchr(gbuf.value, '@'); - *cp = '\0'; + /* + * If we are not going to include the realm in the username that is passed + * to the ident map, destructively modify it here to remove the realm. Then + * advance past the separator to check the realm. + */ + if (!port->hba->include_realm) + *cp = '\0'; cp++; if (realmmatch != NULL && strlen(realmmatch)) @@ -1361,8 +1373,22 @@ pg_SSPI_recvauth(Port *port) /* * We have the username (without domain/realm) in accountname, compare to * the supplied value. In SSPI, always compare case insensitive. + * + * If set to include realm, append it in @ format. */ - return check_usermap(port->hba->usermap, port->user_name, accountname, true); + if (port->hba->include_realm) + { + char *namebuf; + int retval; + + namebuf = palloc(strlen(accountname) + strlen(domainname) + 2); + sprintf(namebuf, "%s@%s", accountname, domainname); + retval = check_usermap(port->hba->usermap, port->user_name, namebuf, true); + pfree(namebuf); + return retval; + } + else + return check_usermap(port->hba->usermap, port->user_name, accountname, true); } #endif /* ENABLE_SSPI */ diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index e7068b10b2..c27e9f990b 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.179 2009/01/07 12:38:11 mha Exp $ + * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.180 2009/01/07 13:09:21 mha Exp $ * *------------------------------------------------------------------------- */ @@ -1053,6 +1053,17 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline) INVALID_AUTH_OPTION("krb_realm", "krb5, gssapi and sspi"); parsedline->krb_realm = pstrdup(c); } + else if (strcmp(token, "include_realm") == 0) + { + if (parsedline->auth_method != uaKrb5 && + parsedline->auth_method != uaGSS && + parsedline->auth_method != uaSSPI) + INVALID_AUTH_OPTION("include_realm", "krb5, gssapi and sspi"); + if (strcmp(c, "1") == 0) + parsedline->include_realm = true; + else + parsedline->include_realm = false; + } else { ereport(LOG, diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h index 53ecde2c16..56f9f4ba53 100644 --- a/src/include/libpq/hba.h +++ b/src/include/libpq/hba.h @@ -4,7 +4,7 @@ * Interface to hba.c * * - * $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.54 2009/01/07 12:38:11 mha Exp $ + * $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.55 2009/01/07 13:09:21 mha Exp $ * *------------------------------------------------------------------------- */ @@ -58,6 +58,7 @@ typedef struct bool clientcert; char *krb_server_hostname; char *krb_realm; + bool include_realm; } HbaLine; typedef struct Port hbaPort;