1/*-------------------------------------------------------------------------
4 * Common code for GSSAPI authentication and encryption
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * src/backend/libpq/be-gssapi-common.c
12 *-------------------------------------------------------------------------
20 * Fetch all errors of a specific type and append to "s" (buffer of size len).
21 * If we obtain more than one string, separate them with spaces.
22 * Call once for GSS_CODE and once for MECH_CODE.
34 if (gss_display_status(&lmin_s,
stat,
type, GSS_C_NO_OID,
35 &msg_ctx, &gmsg) != GSS_S_COMPLETE)
44 memcpy(s +
i, gmsg.value,
Min(
len -
i, gmsg.length));
46 gss_release_buffer(&lmin_s, &gmsg);
50 /* add nul termination */
61 * Report the GSSAPI error described by maj_stat/min_stat.
63 * errmsg should be an already-translated primary error message.
64 * The GSSAPI info is appended as errdetail.
66 * The error is always reported with elevel COMMERROR; we daren't try to
67 * send it to the client, as that'd likely lead to infinite recursion
68 * when elog.c tries to write to the client.
70 * To avoid memory allocation, total error size is capped (at 128 bytes for
71 * each of major and minor). No known mechanisms will produce error messages
76 OM_uint32 maj_stat, OM_uint32 min_stat)
81 /* Fetch major status message */
84 /* Fetch mechanism minor status message */
88 * errmsg_internal, since translation of the first part must be done
89 * before calling this function anyway.
97 * Store the credentials passed in into the memory cache for later usage.
99 * This allows credentials to be delegated to us for us to use to connect
100 * to other systems with, using, e.g. postgres_fdw or dblink.
102 #define GSS_MEMORY_CACHE "MEMORY:"
109 gss_cred_usage_t
usage;
110 gss_key_value_element_desc cc;
111 gss_key_value_set_desc ccset;
116 ccset.elements = &cc;
118 /* Make the delegated credential only available to current process */
119 major = gss_store_cred_into(&minor,
121 GSS_C_INITIATE,
/* credential only used for
122 * starting libpq connection */
123 GSS_C_NULL_OID,
/* store all */
124 true,
/* overwrite */
125 true,
/* make default */
130 if (major != GSS_S_COMPLETE)
135 /* Credential stored, so we can release our credential handle. */
136 major = gss_release_cred(&minor, &cred);
137 if (major != GSS_S_COMPLETE)
143 * Set KRB5CCNAME for this backend, so that later calls to
144 * gss_acquire_cred will find the delegated credentials we stored.
void pg_store_delegated_credential(gss_cred_id_t cred)
static void pg_GSS_error_int(char *s, size_t len, OM_uint32 stat, int type)
void pg_GSS_error(const char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)
int errmsg_internal(const char *fmt,...)
int errdetail_internal(const char *fmt,...)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
static void usage(const char *progname)