I was looking at this TODO item from 2009: https://www.postgresql.org/message-id/4AA7B197.70002%40usit.uio.no
I have implemented this in the attached patch. It does two things: o compares words in columns that can only support keywords as case-insensitive, double-quoted or not o compares words in columns that can contain user/db names or keywords as case-sensitive if double-quoted, case-insensitive if not Here is the 'local' line we install during initdb, and a newly identically-behaving line: # TYPE DATABASE USER ADDRESS METHOD local all all trust "LOCAL" ALL ALL TRUST This 9.6 line: local Test all trust would have to be represented in PG 10 as: local "Test" all trust -- Bruce Momjian <br...@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + As you are, so once was I. As I am, so you will be. + + Ancient Roman grave inscription +
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml new file mode 100644 index ca262d9..66a54ef *** a/doc/src/sgml/client-auth.sgml --- b/doc/src/sgml/client-auth.sgml *************** hostnossl <replaceable>database</replac *** 195,200 **** --- 195,201 ---- replication connections do not specify any particular database). Otherwise, this is the name of a specific <productname>PostgreSQL</productname> database. + Non-keyword values are compared as lower-case, unless double-quoted. Multiple database names can be supplied by separating them with commas. A separate file containing database names can be specified by preceding the file name with <literal>@</>. *************** hostnossl <replaceable>database</replac *** 218,223 **** --- 219,225 ---- considered to be a member of a role if they are explicitly a member of the role, directly or indirectly, and not just by virtue of being a superuser. + Non-keyword values are compared as lower-case, unless double-quoted. Multiple user names can be supplied by separating them with commas. A separate file containing user names can be specified by preceding the file name with <literal>@</>. diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c new file mode 100644 index 1b4bbce..fc8d5a0 *** a/src/backend/libpq/hba.c --- b/src/backend/libpq/hba.c *************** typedef struct check_network_data *** 61,68 **** } check_network_data; ! #define token_is_keyword(t, k) (!t->quoted && strcmp(t->string, k) == 0) ! #define token_matches(t, k) (strcmp(t->string, k) == 0) /* * A single string token lexed from the HBA config file, together with whether --- 61,69 ---- } check_network_data; ! #define token_is_keyword(t, k) (!t->quoted && strcasecmp(t->string, k) == 0) ! /* case-insensitive comparison for unquoted strings */ ! #define token_matches(t, k) (t->quoted ? (strcmp(t->string, k) == 0) : (strcasecmp(t->string, k) == 0)) /* * A single string token lexed from the HBA config file, together with whether *************** parse_hba_line(List *line, int line_num, *** 851,857 **** return NULL; } token = linitial(tokens); ! if (strcmp(token->string, "local") == 0) { #ifdef HAVE_UNIX_SOCKETS parsedline->conntype = ctLocal; --- 852,858 ---- return NULL; } token = linitial(tokens); ! if (strcasecmp(token->string, "local") == 0) { #ifdef HAVE_UNIX_SOCKETS parsedline->conntype = ctLocal; *************** parse_hba_line(List *line, int line_num, *** 864,872 **** return NULL; #endif } ! else if (strcmp(token->string, "host") == 0 || ! strcmp(token->string, "hostssl") == 0 || ! strcmp(token->string, "hostnossl") == 0) { if (token->string[4] == 's') /* "hostssl" */ --- 865,873 ---- return NULL; #endif } ! else if (strcasecmp(token->string, "host") == 0 || ! strcasecmp(token->string, "hostssl") == 0 || ! strcasecmp(token->string, "hostnossl") == 0) { if (token->string[4] == 's') /* "hostssl" */ *************** parse_hba_line(List *line, int line_num, *** 1149,1177 **** token = linitial(tokens); unsupauth = NULL; ! if (strcmp(token->string, "trust") == 0) parsedline->auth_method = uaTrust; ! else if (strcmp(token->string, "ident") == 0) parsedline->auth_method = uaIdent; ! else if (strcmp(token->string, "peer") == 0) parsedline->auth_method = uaPeer; ! else if (strcmp(token->string, "password") == 0) parsedline->auth_method = uaPassword; ! else if (strcmp(token->string, "gss") == 0) #ifdef ENABLE_GSS parsedline->auth_method = uaGSS; #else unsupauth = "gss"; #endif ! else if (strcmp(token->string, "sspi") == 0) #ifdef ENABLE_SSPI parsedline->auth_method = uaSSPI; #else unsupauth = "sspi"; #endif ! else if (strcmp(token->string, "reject") == 0) parsedline->auth_method = uaReject; ! else if (strcmp(token->string, "md5") == 0) { if (Db_user_namespace) { --- 1150,1178 ---- token = linitial(tokens); unsupauth = NULL; ! if (strcasecmp(token->string, "trust") == 0) parsedline->auth_method = uaTrust; ! else if (strcasecmp(token->string, "ident") == 0) parsedline->auth_method = uaIdent; ! else if (strcasecmp(token->string, "peer") == 0) parsedline->auth_method = uaPeer; ! else if (strcasecmp(token->string, "password") == 0) parsedline->auth_method = uaPassword; ! else if (strcasecmp(token->string, "gss") == 0) #ifdef ENABLE_GSS parsedline->auth_method = uaGSS; #else unsupauth = "gss"; #endif ! else if (strcasecmp(token->string, "sspi") == 0) #ifdef ENABLE_SSPI parsedline->auth_method = uaSSPI; #else unsupauth = "sspi"; #endif ! else if (strcasecmp(token->string, "reject") == 0) parsedline->auth_method = uaReject; ! else if (strcasecmp(token->string, "md5") == 0) { if (Db_user_namespace) { *************** parse_hba_line(List *line, int line_num, *** 1184,1214 **** } parsedline->auth_method = uaMD5; } ! else if (strcmp(token->string, "pam") == 0) #ifdef USE_PAM parsedline->auth_method = uaPAM; #else unsupauth = "pam"; #endif ! else if (strcmp(token->string, "bsd") == 0) #ifdef USE_BSD_AUTH parsedline->auth_method = uaBSD; #else unsupauth = "bsd"; #endif ! else if (strcmp(token->string, "ldap") == 0) #ifdef USE_LDAP parsedline->auth_method = uaLDAP; #else unsupauth = "ldap"; #endif ! else if (strcmp(token->string, "cert") == 0) #ifdef USE_SSL parsedline->auth_method = uaCert; #else unsupauth = "cert"; #endif ! else if (strcmp(token->string, "radius") == 0) parsedline->auth_method = uaRADIUS; else { --- 1185,1215 ---- } parsedline->auth_method = uaMD5; } ! else if (strcasecmp(token->string, "pam") == 0) #ifdef USE_PAM parsedline->auth_method = uaPAM; #else unsupauth = "pam"; #endif ! else if (strcasecmp(token->string, "bsd") == 0) #ifdef USE_BSD_AUTH parsedline->auth_method = uaBSD; #else unsupauth = "bsd"; #endif ! else if (strcasecmp(token->string, "ldap") == 0) #ifdef USE_LDAP parsedline->auth_method = uaLDAP; #else unsupauth = "ldap"; #endif ! else if (strcasecmp(token->string, "cert") == 0) #ifdef USE_SSL parsedline->auth_method = uaCert; #else unsupauth = "cert"; #endif ! else if (strcasecmp(token->string, "radius") == 0) parsedline->auth_method = uaRADIUS; else { *************** parse_hba_auth_opt(char *name, char *val *** 1406,1412 **** hbaline->ldapscope = LDAP_SCOPE_SUBTREE; #endif ! if (strcmp(name, "map") == 0) { if (hbaline->auth_method != uaIdent && hbaline->auth_method != uaPeer && --- 1407,1413 ---- hbaline->ldapscope = LDAP_SCOPE_SUBTREE; #endif ! if (strcasecmp(name, "map") == 0) { if (hbaline->auth_method != uaIdent && hbaline->auth_method != uaPeer && *************** parse_hba_auth_opt(char *name, char *val *** 1416,1422 **** INVALID_AUTH_OPTION("map", gettext_noop("ident, peer, gssapi, sspi, and cert")); hbaline->usermap = pstrdup(val); } ! else if (strcmp(name, "clientcert") == 0) { /* * Since we require ctHostSSL, this really can never happen on --- 1417,1423 ---- INVALID_AUTH_OPTION("map", gettext_noop("ident, peer, gssapi, sspi, and cert")); hbaline->usermap = pstrdup(val); } ! else if (strcasecmp(name, "clientcert") == 0) { /* * Since we require ctHostSSL, this really can never happen on *************** parse_hba_auth_opt(char *name, char *val *** 1431,1437 **** line_num, HbaFileName))); return false; } ! if (strcmp(val, "1") == 0) { if (!secure_loaded_verify_locations()) { --- 1432,1438 ---- line_num, HbaFileName))); return false; } ! if (strcasecmp(val, "1") == 0) { if (!secure_loaded_verify_locations()) { *************** parse_hba_auth_opt(char *name, char *val *** 1459,1479 **** hbaline->clientcert = false; } } ! else if (strcmp(name, "pamservice") == 0) { REQUIRE_AUTH_OPTION(uaPAM, "pamservice", "pam"); hbaline->pamservice = pstrdup(val); } ! else if (strcmp(name, "pam_use_hostname") == 0) { REQUIRE_AUTH_OPTION(uaPAM, "pam_use_hostname", "pam"); ! if (strcmp(val, "1") == 0) hbaline->pam_use_hostname = true; else hbaline->pam_use_hostname = false; } ! else if (strcmp(name, "ldapurl") == 0) { #ifdef LDAP_API_FEATURE_X_OPENLDAP LDAPURLDesc *urldata; --- 1460,1480 ---- hbaline->clientcert = false; } } ! else if (strcasecmp(name, "pamservice") == 0) { REQUIRE_AUTH_OPTION(uaPAM, "pamservice", "pam"); hbaline->pamservice = pstrdup(val); } ! else if (strcasecmp(name, "pam_use_hostname") == 0) { REQUIRE_AUTH_OPTION(uaPAM, "pam_use_hostname", "pam"); ! if (strcasecmp(val, "1") == 0) hbaline->pam_use_hostname = true; else hbaline->pam_use_hostname = false; } ! else if (strcasecmp(name, "ldapurl") == 0) { #ifdef LDAP_API_FEATURE_X_OPENLDAP LDAPURLDesc *urldata; *************** parse_hba_auth_opt(char *name, char *val *** 1491,1497 **** return false; } ! if (strcmp(urldata->lud_scheme, "ldap") != 0) { ereport(LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), --- 1492,1498 ---- return false; } ! if (strcasecmp(urldata->lud_scheme, "ldap") != 0) { ereport(LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), *************** parse_hba_auth_opt(char *name, char *val *** 1522,1541 **** errmsg("LDAP URLs not supported on this platform"))); #endif /* not OpenLDAP */ } ! else if (strcmp(name, "ldaptls") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldaptls", "ldap"); ! if (strcmp(val, "1") == 0) hbaline->ldaptls = true; else hbaline->ldaptls = false; } ! else if (strcmp(name, "ldapserver") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapserver", "ldap"); hbaline->ldapserver = pstrdup(val); } ! else if (strcmp(name, "ldapport") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapport", "ldap"); hbaline->ldapport = atoi(val); --- 1523,1542 ---- errmsg("LDAP URLs not supported on this platform"))); #endif /* not OpenLDAP */ } ! else if (strcasecmp(name, "ldaptls") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldaptls", "ldap"); ! if (strcasecmp(val, "1") == 0) hbaline->ldaptls = true; else hbaline->ldaptls = false; } ! else if (strcasecmp(name, "ldapserver") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapserver", "ldap"); hbaline->ldapserver = pstrdup(val); } ! else if (strcasecmp(name, "ldapport") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapport", "ldap"); hbaline->ldapport = atoi(val); *************** parse_hba_auth_opt(char *name, char *val *** 1549,1620 **** return false; } } ! else if (strcmp(name, "ldapbinddn") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapbinddn", "ldap"); hbaline->ldapbinddn = pstrdup(val); } ! else if (strcmp(name, "ldapbindpasswd") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapbindpasswd", "ldap"); hbaline->ldapbindpasswd = pstrdup(val); } ! else if (strcmp(name, "ldapsearchattribute") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapsearchattribute", "ldap"); hbaline->ldapsearchattribute = pstrdup(val); } ! else if (strcmp(name, "ldapbasedn") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapbasedn", "ldap"); hbaline->ldapbasedn = pstrdup(val); } ! else if (strcmp(name, "ldapprefix") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapprefix", "ldap"); hbaline->ldapprefix = pstrdup(val); } ! else if (strcmp(name, "ldapsuffix") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapsuffix", "ldap"); hbaline->ldapsuffix = pstrdup(val); } ! else if (strcmp(name, "krb_realm") == 0) { if (hbaline->auth_method != uaGSS && hbaline->auth_method != uaSSPI) INVALID_AUTH_OPTION("krb_realm", gettext_noop("gssapi and sspi")); hbaline->krb_realm = pstrdup(val); } ! else if (strcmp(name, "include_realm") == 0) { if (hbaline->auth_method != uaGSS && hbaline->auth_method != uaSSPI) INVALID_AUTH_OPTION("include_realm", gettext_noop("gssapi and sspi")); ! if (strcmp(val, "1") == 0) hbaline->include_realm = true; else hbaline->include_realm = false; } ! else if (strcmp(name, "compat_realm") == 0) { if (hbaline->auth_method != uaSSPI) INVALID_AUTH_OPTION("compat_realm", gettext_noop("sspi")); ! if (strcmp(val, "1") == 0) hbaline->compat_realm = true; else hbaline->compat_realm = false; } ! else if (strcmp(name, "upn_username") == 0) { if (hbaline->auth_method != uaSSPI) INVALID_AUTH_OPTION("upn_username", gettext_noop("sspi")); ! if (strcmp(val, "1") == 0) hbaline->upn_username = true; else hbaline->upn_username = false; } ! else if (strcmp(name, "radiusserver") == 0) { struct addrinfo *gai_result; struct addrinfo hints; --- 1550,1621 ---- return false; } } ! else if (strcasecmp(name, "ldapbinddn") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapbinddn", "ldap"); hbaline->ldapbinddn = pstrdup(val); } ! else if (strcasecmp(name, "ldapbindpasswd") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapbindpasswd", "ldap"); hbaline->ldapbindpasswd = pstrdup(val); } ! else if (strcasecmp(name, "ldapsearchattribute") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapsearchattribute", "ldap"); hbaline->ldapsearchattribute = pstrdup(val); } ! else if (strcasecmp(name, "ldapbasedn") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapbasedn", "ldap"); hbaline->ldapbasedn = pstrdup(val); } ! else if (strcasecmp(name, "ldapprefix") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapprefix", "ldap"); hbaline->ldapprefix = pstrdup(val); } ! else if (strcasecmp(name, "ldapsuffix") == 0) { REQUIRE_AUTH_OPTION(uaLDAP, "ldapsuffix", "ldap"); hbaline->ldapsuffix = pstrdup(val); } ! else if (strcasecmp(name, "krb_realm") == 0) { if (hbaline->auth_method != uaGSS && hbaline->auth_method != uaSSPI) INVALID_AUTH_OPTION("krb_realm", gettext_noop("gssapi and sspi")); hbaline->krb_realm = pstrdup(val); } ! else if (strcasecmp(name, "include_realm") == 0) { if (hbaline->auth_method != uaGSS && hbaline->auth_method != uaSSPI) INVALID_AUTH_OPTION("include_realm", gettext_noop("gssapi and sspi")); ! if (strcasecmp(val, "1") == 0) hbaline->include_realm = true; else hbaline->include_realm = false; } ! else if (strcasecmp(name, "compat_realm") == 0) { if (hbaline->auth_method != uaSSPI) INVALID_AUTH_OPTION("compat_realm", gettext_noop("sspi")); ! if (strcasecmp(val, "1") == 0) hbaline->compat_realm = true; else hbaline->compat_realm = false; } ! else if (strcasecmp(name, "upn_username") == 0) { if (hbaline->auth_method != uaSSPI) INVALID_AUTH_OPTION("upn_username", gettext_noop("sspi")); ! if (strcasecmp(val, "1") == 0) hbaline->upn_username = true; else hbaline->upn_username = false; } ! else if (strcasecmp(name, "radiusserver") == 0) { struct addrinfo *gai_result; struct addrinfo hints; *************** parse_hba_auth_opt(char *name, char *val *** 1642,1648 **** pg_freeaddrinfo_all(hints.ai_family, gai_result); hbaline->radiusserver = pstrdup(val); } ! else if (strcmp(name, "radiusport") == 0) { REQUIRE_AUTH_OPTION(uaRADIUS, "radiusport", "radius"); hbaline->radiusport = atoi(val); --- 1643,1649 ---- pg_freeaddrinfo_all(hints.ai_family, gai_result); hbaline->radiusserver = pstrdup(val); } ! else if (strcasecmp(name, "radiusport") == 0) { REQUIRE_AUTH_OPTION(uaRADIUS, "radiusport", "radius"); hbaline->radiusport = atoi(val); *************** parse_hba_auth_opt(char *name, char *val *** 1656,1667 **** return false; } } ! else if (strcmp(name, "radiussecret") == 0) { REQUIRE_AUTH_OPTION(uaRADIUS, "radiussecret", "radius"); hbaline->radiussecret = pstrdup(val); } ! else if (strcmp(name, "radiusidentifier") == 0) { REQUIRE_AUTH_OPTION(uaRADIUS, "radiusidentifier", "radius"); hbaline->radiusidentifier = pstrdup(val); --- 1657,1668 ---- return false; } } ! else if (strcasecmp(name, "radiussecret") == 0) { REQUIRE_AUTH_OPTION(uaRADIUS, "radiussecret", "radius"); hbaline->radiussecret = pstrdup(val); } ! else if (strcasecmp(name, "radiusidentifier") == 0) { REQUIRE_AUTH_OPTION(uaRADIUS, "radiusidentifier", "radius"); hbaline->radiusidentifier = pstrdup(val); diff --git a/src/backend/libpq/pg_hba.conf.sample b/src/backend/libpq/pg_hba.conf.sample new file mode 100644 index 86a89ed..f9a2be2 *** a/src/backend/libpq/pg_hba.conf.sample --- b/src/backend/libpq/pg_hba.conf.sample *************** *** 53,63 **** # section in the documentation for a list of which options are # available for which authentication methods. # ! # Database and user names containing spaces, commas, quotes and other ! # special characters must be quoted. Quoting one of the keywords ! # "all", "sameuser", "samerole" or "replication" makes the name lose ! # its special character, and just match a database or username with ! # that name. # # This file is read on server startup and when the postmaster receives # a SIGHUP signal. If you edit the file on a running system, you have --- 53,64 ---- # section in the documentation for a list of which options are # available for which authentication methods. # ! # Database and user names are compared as lower-case, unless ! # double-quoted. Database and user names containing spaces, commas, ! # quotes and other special characters must be double-quoted. Quoting ! # one of the keywords "all", "sameuser", "samerole" or "replication" ! # makes the name lose its special meaning, and just case-sensitive ! # matches a database or username. # # This file is read on server startup and when the postmaster receives # a SIGHUP signal. If you edit the file on a running system, you have
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers