mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Support suffix matching of host names in pg_hba.conf
A name starting with a dot can be used to match a suffix of the actual host name (e.g., .example.com matches foo.example.com).
This commit is contained in:
		@@ -282,6 +282,14 @@ hostnossl  <replaceable>database</replaceable>  <replaceable>user</replaceable>
 | 
				
			|||||||
       to resolve an IP address.)
 | 
					       to resolve an IP address.)
 | 
				
			||||||
      </para>
 | 
					      </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <para>
 | 
				
			||||||
 | 
					       A host name specification that starts with a dot
 | 
				
			||||||
 | 
					       (<literal>.</literal>) matches a suffix of the actual host
 | 
				
			||||||
 | 
					       name.  So <literal>.example.com</literal> would match
 | 
				
			||||||
 | 
					       <literal>foo.example.com</literal> (but not just
 | 
				
			||||||
 | 
					       <literal>example.com</literal>).
 | 
				
			||||||
 | 
					      </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <para>
 | 
					      <para>
 | 
				
			||||||
       When host names are specified
 | 
					       When host names are specified
 | 
				
			||||||
       in <filename>pg_hba.conf</filename>, you should make sure that
 | 
					       in <filename>pg_hba.conf</filename>, you should make sure that
 | 
				
			||||||
@@ -310,6 +318,12 @@ hostnossl  <replaceable>database</replaceable>  <replaceable>user</replaceable>
 | 
				
			|||||||
        everyone's problem.
 | 
					        everyone's problem.
 | 
				
			||||||
       </para>
 | 
					       </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       <para>
 | 
				
			||||||
 | 
					        Also, a reverse lookup is necessary to implement the suffix
 | 
				
			||||||
 | 
					        matching feature, because the actual client host name needs to
 | 
				
			||||||
 | 
					        be known in order to match it against the pattern.
 | 
				
			||||||
 | 
					       </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
       <para>
 | 
					       <para>
 | 
				
			||||||
        Note that this behavior is consistent with other popular
 | 
					        Note that this behavior is consistent with other popular
 | 
				
			||||||
        implementations of host name-based access control, such as the
 | 
					        implementations of host name-based access control, such as the
 | 
				
			||||||
@@ -605,6 +619,12 @@ host    postgres        all             192.168.93.0/24         ident
 | 
				
			|||||||
# TYPE  DATABASE        USER            ADDRESS                 METHOD
 | 
					# TYPE  DATABASE        USER            ADDRESS                 METHOD
 | 
				
			||||||
host    postgres        all             192.168.12.10/32        md5
 | 
					host    postgres        all             192.168.12.10/32        md5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Allow any user from hosts in the example.com domain to connect to
 | 
				
			||||||
 | 
					# any database if the user's password is correctly supplied.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# TYPE  DATABASE        USER            ADDRESS                 METHOD
 | 
				
			||||||
 | 
					host    all             all             .example.com            md5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# In the absence of preceding "host" lines, these two lines will
 | 
					# In the absence of preceding "host" lines, these two lines will
 | 
				
			||||||
# reject all connections from 192.168.54.1 (since that entry will be
 | 
					# reject all connections from 192.168.54.1 (since that entry will be
 | 
				
			||||||
# matched first), but allow Kerberos 5 connections from anywhere else
 | 
					# matched first), but allow Kerberos 5 connections from anywhere else
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -564,6 +564,26 @@ ipv6eq(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#endif /* HAVE_IPV6 */
 | 
					#endif /* HAVE_IPV6 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Check whether host name matches pattern.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static bool
 | 
				
			||||||
 | 
					hostname_match(const char *pattern, const char *actual_hostname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (pattern[0] == '.')		/* suffix match */
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							size_t plen = strlen(pattern);
 | 
				
			||||||
 | 
							size_t hlen = strlen(actual_hostname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (hlen < plen)
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return (pg_strcasecmp(pattern, actual_hostname + (hlen - plen)) == 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return (pg_strcasecmp(pattern, actual_hostname) == 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Check to see if a connecting IP matches a given host name.
 | 
					 * Check to see if a connecting IP matches a given host name.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -588,7 +608,7 @@ check_hostname(hbaPort *port, const char *hostname)
 | 
				
			|||||||
		port->remote_hostname = pstrdup(remote_hostname);
 | 
							port->remote_hostname = pstrdup(remote_hostname);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pg_strcasecmp(port->remote_hostname, hostname) != 0)
 | 
						if (!hostname_match(hostname, port->remote_hostname))
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Lookup IP from host name and check against original IP */
 | 
						/* Lookup IP from host name and check against original IP */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,7 +32,8 @@
 | 
				
			|||||||
# ADDRESS specifies the set of hosts the record matches.  It can be a
 | 
					# ADDRESS specifies the set of hosts the record matches.  It can be a
 | 
				
			||||||
# host name, or it is made up of an IP address and a CIDR mask that is
 | 
					# host name, or it is made up of an IP address and a CIDR mask that is
 | 
				
			||||||
# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that
 | 
					# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that
 | 
				
			||||||
# specifies the number of significant bits in the mask.
 | 
					# specifies the number of significant bits in the mask.  A host name
 | 
				
			||||||
 | 
					# that starts with a dot (.) matches a suffix of the actual host name.
 | 
				
			||||||
# Alternatively, you can write an IP address and netmask in separate
 | 
					# Alternatively, you can write an IP address and netmask in separate
 | 
				
			||||||
# columns to specify the set of hosts.  Instead of a CIDR-address, you
 | 
					# columns to specify the set of hosts.  Instead of a CIDR-address, you
 | 
				
			||||||
# can write "samehost" to match any of the server's own IP addresses,
 | 
					# can write "samehost" to match any of the server's own IP addresses,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user