Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * be-gssapi-common.c
4 : * Common code for GSSAPI authentication and encryption
5 : *
6 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : * IDENTIFICATION
10 : * src/backend/libpq/be-gssapi-common.c
11 : *
12 : *-------------------------------------------------------------------------
13 : */
14 :
15 : #include "postgres.h"
16 :
17 : #include "libpq/be-gssapi-common.h"
18 :
19 : /*
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.
23 : */
24 : static void
1467 sfrost 25 UBC 0 : pg_GSS_error_int(char *s, size_t len, OM_uint32 stat, int type)
26 : {
27 : gss_buffer_desc gmsg;
28 0 : size_t i = 0;
29 : OM_uint32 lmin_s,
30 0 : msg_ctx = 0;
31 :
32 : do
33 : {
832 tgl 34 0 : if (gss_display_status(&lmin_s, stat, type, GSS_C_NO_OID,
35 : &msg_ctx, &gmsg) != GSS_S_COMPLETE)
36 0 : break;
37 0 : if (i > 0)
38 : {
39 0 : if (i < len)
40 0 : s[i] = ' ';
41 0 : i++;
42 : }
43 0 : if (i < len)
655 44 0 : memcpy(s + i, gmsg.value, Min(len - i, gmsg.length));
1467 sfrost 45 0 : i += gmsg.length;
46 0 : gss_release_buffer(&lmin_s, &gmsg);
47 : }
832 tgl 48 0 : while (msg_ctx);
49 :
50 : /* add nul termination */
655 51 0 : if (i < len)
52 0 : s[i] = '\0';
53 : else
54 : {
832 55 0 : elog(COMMERROR, "incomplete GSS error report");
655 56 0 : s[len - 1] = '\0';
57 : }
1467 sfrost 58 0 : }
59 :
60 : /*
61 : * Report the GSSAPI error described by maj_stat/min_stat.
62 : *
63 : * errmsg should be an already-translated primary error message.
64 : * The GSSAPI info is appended as errdetail.
65 : *
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.
69 : *
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
72 : * beyond this cap.
73 : */
74 : void
832 tgl 75 0 : pg_GSS_error(const char *errmsg,
76 : OM_uint32 maj_stat, OM_uint32 min_stat)
77 : {
78 : char msg_major[128],
79 : msg_minor[128];
80 :
81 : /* Fetch major status message */
1467 sfrost 82 0 : pg_GSS_error_int(msg_major, sizeof(msg_major), maj_stat, GSS_C_GSS_CODE);
83 :
84 : /* Fetch mechanism minor status message */
85 0 : pg_GSS_error_int(msg_minor, sizeof(msg_minor), min_stat, GSS_C_MECH_CODE);
86 :
87 : /*
88 : * errmsg_internal, since translation of the first part must be done
89 : * before calling this function anyway.
90 : */
832 tgl 91 0 : ereport(COMMERROR,
92 : (errmsg_internal("%s", errmsg),
93 : errdetail_internal("%s: %s", msg_major, msg_minor)));
1467 sfrost 94 0 : }
|