diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 45dcd65afaf..a533786f082 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -1193,6 +1193,7 @@ pg_GSS_checkauth(Port *port) min_stat, lmin_s; gss_buffer_desc gbuf; + char *princ; /* * Get the name of the user that authenticated, and compare it to the pg @@ -1206,18 +1207,27 @@ pg_GSS_checkauth(Port *port) return STATUS_ERROR; } + /* + * gbuf.value might not be null-terminated, so turn it into a regular + * null-terminated string. + */ + princ = palloc(gbuf.length + 1); + memcpy(princ, gbuf.value, gbuf.length); + princ[gbuf.length] = '\0'; + gss_release_buffer(&lmin_s, &gbuf); + /* * Copy the original name of the authenticated principal into our backend * memory for display later. */ - port->gss->princ = MemoryContextStrdup(TopMemoryContext, gbuf.value); + port->gss->princ = MemoryContextStrdup(TopMemoryContext, princ); /* * Split the username at the realm separator */ - if (strchr(gbuf.value, '@')) + if (strchr(princ, '@')) { - char *cp = strchr(gbuf.value, '@'); + char *cp = strchr(princ, '@'); /* * If we are not going to include the realm in the username that is @@ -1244,7 +1254,7 @@ pg_GSS_checkauth(Port *port) elog(DEBUG2, "GSSAPI realm (%s) and configured realm (%s) don't match", cp, port->hba->krb_realm); - gss_release_buffer(&lmin_s, &gbuf); + pfree(princ); return STATUS_ERROR; } } @@ -1253,15 +1263,14 @@ pg_GSS_checkauth(Port *port) { elog(DEBUG2, "GSSAPI did not return realm but realm matching was requested"); - - gss_release_buffer(&lmin_s, &gbuf); + pfree(princ); return STATUS_ERROR; } - ret = check_usermap(port->hba->usermap, port->user_name, gbuf.value, + ret = check_usermap(port->hba->usermap, port->user_name, princ, pg_krb_caseins_users); - gss_release_buffer(&lmin_s, &gbuf); + pfree(princ); return ret; } diff --git a/src/backend/libpq/be-gssapi-common.c b/src/backend/libpq/be-gssapi-common.c index be5d051c202..3e2531c5f5e 100644 --- a/src/backend/libpq/be-gssapi-common.c +++ b/src/backend/libpq/be-gssapi-common.c @@ -29,8 +29,6 @@ pg_GSS_error_int(char *s, size_t len, OM_uint32 stat, int type) OM_uint32 lmin_s, msg_ctx = 0; - s[0] = '\0'; /* just in case gss_display_status fails */ - do { if (gss_display_status(&lmin_s, stat, type, GSS_C_NO_OID, @@ -43,16 +41,19 @@ pg_GSS_error_int(char *s, size_t len, OM_uint32 stat, int type) i++; } if (i < len) - strlcpy(s + i, gmsg.value, len - i); + memcpy(s + i, gmsg.value, Min(len - i, gmsg.length)); i += gmsg.length; gss_release_buffer(&lmin_s, &gmsg); } while (msg_ctx); - if (i >= len) + /* add nul termination */ + if (i < len) + s[i] = '\0'; + else { elog(COMMERROR, "incomplete GSS error report"); - s[len - 1] = '\0'; /* ensure string is nul-terminated */ + s[len - 1] = '\0'; } } diff --git a/src/interfaces/libpq/fe-gssapi-common.c b/src/interfaces/libpq/fe-gssapi-common.c index 6538a421c70..f87e7b2e31b 100644 --- a/src/interfaces/libpq/fe-gssapi-common.c +++ b/src/interfaces/libpq/fe-gssapi-common.c @@ -34,7 +34,8 @@ pg_GSS_error_int(PQExpBuffer str, OM_uint32 stat, int type) if (gss_display_status(&lmin_s, stat, type, GSS_C_NO_OID, &msg_ctx, &lmsg) != GSS_S_COMPLETE) break; - appendPQExpBuffer(str, " %s", (char *) lmsg.value); + appendPQExpBufferChar(str, ' '); + appendBinaryPQExpBuffer(str, lmsg.value, lmsg.length); gss_release_buffer(&lmin_s, &lmsg); } while (msg_ctx); }