save_untruncated_names.patch

text/plain

Filename: save_untruncated_names.patch
Type: text/plain
Part: 0
Message: Re: BUG #18711: Attempting a connection with a database name longer than 63 characters now fails

Patch

Format: unified
File+
src/backend/libpq/auth.c 5 5
src/backend/tcop/backend_startup.c 16 0
src/backend/utils/init/miscinit.c 2 1
src/backend/utils/init/postinit.c 4 2
src/include/libpq/libpq-be.h 3 0
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 47e8c91606..d81c3eeba9 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -320,7 +320,7 @@ auth_failed(Port *port, int status, const char *logdetail)
 
 	ereport(FATAL,
 			(errcode(errcode_return),
-			 errmsg(errstr, port->user_name),
+			 errmsg(errstr, port->user_name_raw),
 			 logdetail ? errdetail_log("%s", logdetail) : 0));
 
 	/* doesn't return */
@@ -459,14 +459,14 @@ ClientAuthentication(Port *port)
 							(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
 					/* translator: last %s describes encryption state */
 							 errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
-									hostinfo, port->user_name,
+									hostinfo, port->user_name_raw,
 									encryption_state)));
 				else
 					ereport(FATAL,
 							(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
 					/* translator: last %s describes encryption state */
 							 errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
-									hostinfo, port->user_name,
+									hostinfo, port->user_name_raw,
 									port->database_name,
 									encryption_state)));
 				break;
@@ -526,7 +526,7 @@ ClientAuthentication(Port *port)
 							(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
 					/* translator: last %s describes encryption state */
 							 errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
-									hostinfo, port->user_name,
+									hostinfo, port->user_name_raw,
 									encryption_state),
 							 HOSTNAME_LOOKUP_DETAIL(port)));
 				else
@@ -534,7 +534,7 @@ ClientAuthentication(Port *port)
 							(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
 					/* translator: last %s describes encryption state */
 							 errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
-									hostinfo, port->user_name,
+									hostinfo, port->user_name_raw,
 									port->database_name,
 									encryption_state),
 							 HOSTNAME_LOOKUP_DETAIL(port)));
diff --git a/src/backend/tcop/backend_startup.c b/src/backend/tcop/backend_startup.c
index 2a96c81f92..3b60559ae9 100644
--- a/src/backend/tcop/backend_startup.c
+++ b/src/backend/tcop/backend_startup.c
@@ -830,6 +830,22 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
 	if (port->database_name == NULL || port->database_name[0] == '\0')
 		port->database_name = pstrdup(port->user_name);
 
+	/*
+	 * Prior to truncating, save the raw database and user names for log
+	 * messages.
+	 */
+	port->database_name_raw = pstrdup(port->database_name);
+	port->user_name_raw = pstrdup(port->user_name);
+
+	/*
+	 * Truncate given database and user names to length of a Postgres name.
+	 * This avoids lookup failures when overlength names are given.
+	 */
+	if (strlen(port->database_name) >= NAMEDATALEN)
+		port->database_name[NAMEDATALEN - 1] = '\0';
+	if (strlen(port->user_name) >= NAMEDATALEN)
+		port->user_name[NAMEDATALEN - 1] = '\0';
+
 	if (am_walsender)
 		MyBackendType = B_WAL_SENDER;
 	else
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 3b7b2ebec0..7e3740fa0f 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -798,7 +798,8 @@ InitializeSessionUserId(const char *rolename, Oid roleid, bool bypass_login_chec
 				return;
 			ereport(FATAL,
 					(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
-					 errmsg("role \"%s\" does not exist", rolename)));
+					 errmsg("role \"%s\" does not exist",
+							MyProcPort ? MyProcPort->user_name_raw : rolename)));
 		}
 	}
 	else
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 5b657a3f13..4f949a8f2d 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -1008,7 +1008,8 @@ InitPostgres(const char *in_dbname, Oid dboid,
 		if (!HeapTupleIsValid(tuple))
 			ereport(FATAL,
 					(errcode(ERRCODE_UNDEFINED_DATABASE),
-					 errmsg("database \"%s\" does not exist", in_dbname)));
+					 errmsg("database \"%s\" does not exist",
+							MyProcPort ? MyProcPort->database_name_raw : in_dbname)));
 		dbform = (Form_pg_database) GETSTRUCT(tuple);
 		dboid = dbform->oid;
 	}
@@ -1072,7 +1073,8 @@ InitPostgres(const char *in_dbname, Oid dboid,
 			if (in_dbname)
 				ereport(FATAL,
 						(errcode(ERRCODE_UNDEFINED_DATABASE),
-						 errmsg("database \"%s\" does not exist", in_dbname),
+						 errmsg("database \"%s\" does not exist",
+								MyProcPort ? MyProcPort->database_name_raw : in_dbname),
 						 errdetail("It seems to have just been dropped or renamed.")));
 			else
 				ereport(FATAL,
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 9109b2c334..9031cabfc7 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -232,6 +232,9 @@ typedef struct Port
 	char	   *raw_buf;
 	ssize_t		raw_buf_consumed,
 				raw_buf_remaining;
+
+	char	   *database_name_raw;
+	char	   *user_name_raw;
 } Port;
 
 /*