diff --git a/src/common/backend/libpq/hba.cpp b/src/common/backend/libpq/hba.cpp index 5b87a3a974a48bbf7c99e3307e0420d030b4ec98..c074565e5f0681407c339b23402c28d6fd670001 100644 --- a/src/common/backend/libpq/hba.cpp +++ b/src/common/backend/libpq/hba.cpp @@ -2418,7 +2418,7 @@ char* MatchOtherUserHostName(const char* rolname, char* userHostName) return firstPrivName; } -char* GenUserHostName(hbaPort* port, const char* role) +char* GenUserHostName(hbaPort* port, const char* role, char** localhost) { if (!port) ereport(ERROR,(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),errmsg("The MyProcPort can't be NULL"))); @@ -2431,7 +2431,13 @@ char* GenUserHostName(hbaPort* port, const char* role) sizeof(remoteHostname)); errno_t rc = snprintf_s(userHostName, sizeof(userHostName), sizeof(userHostName) - 1, "%s@%s", role, remoteHostname); securec_check_ss(rc, "", ""); - return pstrdup(userHostName); + char* returnUserHost = pstrdup(userHostName); + if (pg_strcasecmp(remoteHostname, "127.0.0.1") == 0) { + rc = snprintf_s(userHostName, sizeof(userHostName), sizeof(userHostName) - 1, "%s@localhost", role); + securec_check_ss(rc, "", ""); + *localhost = pstrdup(userHostName); + } + return returnUserHost; } extern char* GetDatabaseCompatibility(const char* dbname); @@ -2439,14 +2445,19 @@ HeapTuple SearchUserHostName(const char* userName, Oid* oid) { char* userHostName = NULL; HeapTuple roleTup = NULL; - if (u_sess->attr.attr_common.b_compatibility_user_host_auth && !OidIsValid(u_sess->proc_cxt.MyDatabaseId) && u_sess->proc_cxt.MyProcPort) { + if (u_sess->attr.attr_common.b_compatibility_user_host_auth && (!OidIsValid(u_sess->proc_cxt.MyDatabaseId) || u_sess->proc_cxt.check_auth) && u_sess->proc_cxt.MyProcPort) { bool isBFormat = false; char* dbCompatibility = GetDatabaseCompatibility(u_sess->proc_cxt.MyProcPort->database_name); if (dbCompatibility) isBFormat = (pg_strcasecmp(dbCompatibility, "B") == 0); if (isBFormat) { - userHostName = GenUserHostName(u_sess->proc_cxt.MyProcPort, userName); + char* localhost = NULL; + userHostName = GenUserHostName(u_sess->proc_cxt.MyProcPort, userName, &localhost); roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(userHostName)); + if (localhost && !roleTup) { + roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(localhost)); + pfree_ext(localhost); + } if (!roleTup) { char* matchName = MatchOtherUserHostName(userName, userHostName); if (matchName) { diff --git a/src/common/backend/utils/init/postinit.cpp b/src/common/backend/utils/init/postinit.cpp index 21879be306ca55cc769ea048bd1317d192578584..4ffde0d7358b00fb392b0d87562fa3b2d5580db5 100644 --- a/src/common/backend/utils/init/postinit.cpp +++ b/src/common/backend/utils/init/postinit.cpp @@ -2187,8 +2187,19 @@ void PostgresInitializer::InitSession() Assert(dummyStandbyMode || CurrentMemoryContext == t_thrd.mem_cxt.cur_transaction_mem_cxt); if (IsUnderPostmaster) { - CheckAuthentication(); - InitUser(); + u_sess->proc_cxt.check_auth = true; + PG_TRY(); + { + CheckAuthentication(); + InitUser(); + u_sess->proc_cxt.check_auth = false; + } + PG_CATCH(); + { + u_sess->proc_cxt.check_auth = false; + PG_RE_THROW(); + } + PG_END_TRY(); } else { CheckAtLeastOneRoles(); SetSuperUserStandalone(); diff --git a/src/gausskernel/process/threadpool/knl_session.cpp b/src/gausskernel/process/threadpool/knl_session.cpp index 6db5125b2515a4805ff66eac072a123feabe2a07..e3c98a5585eb4d286d745131aa9bb0666d68fff1 100755 --- a/src/gausskernel/process/threadpool/knl_session.cpp +++ b/src/gausskernel/process/threadpool/knl_session.cpp @@ -612,6 +612,7 @@ static void knl_u_proc_init(knl_u_proc_context* proc_cxt) proc_cxt->gsqlRemainCopyNum = 0; proc_cxt->sessionBackupState = SESSION_BACKUP_NONE; proc_cxt->registerExclusiveHandlerdone = false; + proc_cxt->check_auth = false; } static void knl_u_time_init(knl_u_time_context* time_cxt) diff --git a/src/include/knl/knl_session.h b/src/include/knl/knl_session.h index ed5dfad4930bda9c90bb7d3f81a0d0320f73ed6d..de57f0fd49a89446523fb1f1c51b5baf4902688e 100644 --- a/src/include/knl/knl_session.h +++ b/src/include/knl/knl_session.h @@ -1230,6 +1230,7 @@ typedef struct knl_u_proc_context { char* LabelFile; char* TblspcMapFile; bool registerAbortBackupHandlerdone; /* unterminated backups handler flag */ + bool check_auth; } knl_u_proc_context; /* maximum possible number of fields in a date string */ diff --git a/src/test/regress/input/user_host_test.source b/src/test/regress/input/user_host_test.source index e966eef47dddc31a89b3608974ee1402e4c936ab..481bffd4e2ad1fd9ab458ea82dc8cbea2c2e0d97 100644 --- a/src/test/regress/input/user_host_test.source +++ b/src/test/regress/input/user_host_test.source @@ -56,15 +56,12 @@ revoke insert on test2 from 'test_user_host'@'127.0.%'; \! echo 'b_compatibility_user_host_auth = on' >> @abs_srcdir@/tmp_check/datanode1/postgresql.conf \! sed -i 's#host.*all.*all.*127.0.0.1/32.*#host all all all sha256#g' @abs_srcdir@/tmp_check/datanode1/pg_hba.conf \! @abs_bindir@/gs_ctl restart -D @abs_srcdir@/tmp_check/datanode1 > /dev/null -\! sleep 5 +\! sleep 2 \! @abs_bindir@/gsql -p @portstring@ -h 127.0.0.1 -d regression -r -U test_user_host -W 'test123@' \! @abs_bindir@/gsql -p @portstring@ -h 127.0.0.1 -d user_host_db -r -U test_user_host -W 'test123@' -c "select current_user"; \! @abs_bindir@/gsql -p @portstring@ -d user_host_db -r -c "drop user if exists 'test_user_host'@'127.0.0.1'"; -\! @abs_bindir@/gs_ctl restart -D @abs_srcdir@/tmp_check/datanode1 > /dev/null -\! sleep 5 \! @abs_bindir@/gsql -p @portstring@ -h 127.0.0.1 -d user_host_db -r -U test_user_host -W 'test123@' -c "select current_user"; \! @abs_bindir@/gsql -p @portstring@ -d user_host_db -r -c "drop user 'test_user_host'@'127.0.0.%'"; -\! @abs_bindir@/gs_ctl restart -D @abs_srcdir@/tmp_check/datanode1 > /dev/null -\! sleep 5 \! @abs_bindir@/gsql -p @portstring@ -h 127.0.0.1 -d user_host_db -r -U test_user_host -W 'test123@' -c "select current_user"; \! @abs_bindir@/gsql -p @portstring@ -h 127.0.0.1 -d user_host_db -r -U test_user_host -W 'test123@' -c "select * from test2"; +\! @abs_bindir@/gsql -p @portstring@ -h 127.0.0.1 -d user_host_db -r -U test_user_host2 -W 'test123@' -c "select current_user"; diff --git a/src/test/regress/output/user_host_test.source b/src/test/regress/output/user_host_test.source index fe89b8201cc2eaf554c209f243fd48f6c06f164c..15241eefe89a21761a25fb7071ce4f18b42641e2 100644 --- a/src/test/regress/output/user_host_test.source +++ b/src/test/regress/output/user_host_test.source @@ -111,7 +111,7 @@ revoke insert on test2 from 'test_user_host'@'127.0.%'; --?.* --?.* --?.* -\! sleep 5 +\! sleep 2 --?.* gsql: FATAL: Invalid username/password,login denied. --?.* @@ -122,8 +122,6 @@ gsql: FATAL: Invalid username/password,login denied. --?.* DROP ROLE ---?.* -\! sleep 5 --?.* current_user -------------------------- @@ -132,8 +130,6 @@ DROP ROLE --?.* DROP ROLE ---?.* -\! sleep 5 --?.* current_user ------------------------ @@ -146,3 +142,9 @@ DROP ROLE 1 (1 row) +--?.* + current_user +--------------------------- + test_user_host2@localhost +(1 row) +