Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * fe-gssapi-common.c
4 : : * The front-end (client) GSSAPI common code
5 : : *
6 : : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : * IDENTIFICATION
10 : : * src/interfaces/libpq/fe-gssapi-common.c
11 : : *-------------------------------------------------------------------------
12 : : */
13 : :
14 : : #include "postgres_fe.h"
15 : :
16 : : #include "fe-gssapi-common.h"
17 : :
18 : : #include "libpq-int.h"
19 : : #include "pqexpbuffer.h"
20 : :
21 : : /*
22 : : * Fetch all errors of a specific type and append to "str".
23 : : * Each error string is preceded by a space.
24 : : */
25 : : static void
2138 tgl@sss.pgh.pa.us 26 :UBC 0 : pg_GSS_error_int(PQExpBuffer str, OM_uint32 stat, int type)
27 : : {
28 : : OM_uint32 lmin_s;
29 : : gss_buffer_desc lmsg;
2773 sfrost@snowman.net 30 : 0 : OM_uint32 msg_ctx = 0;
31 : :
32 : : do
33 : : {
2138 tgl@sss.pgh.pa.us 34 [ # # ]: 0 : if (gss_display_status(&lmin_s, stat, type, GSS_C_NO_OID,
35 : : &msg_ctx, &lmsg) != GSS_S_COMPLETE)
36 : 0 : break;
1961 37 : 0 : appendPQExpBufferChar(str, ' ');
38 : 0 : appendBinaryPQExpBuffer(str, lmsg.value, lmsg.length);
2773 sfrost@snowman.net 39 : 0 : gss_release_buffer(&lmin_s, &lmsg);
40 [ # # ]: 0 : } while (msg_ctx);
41 : 0 : }
42 : :
43 : : /*
44 : : * GSSAPI errors contain two parts; put both into conn->errorMessage.
45 : : */
46 : : void
47 : 0 : pg_GSS_error(const char *mprefix, PGconn *conn,
48 : : OM_uint32 maj_stat, OM_uint32 min_stat)
49 : : {
2138 tgl@sss.pgh.pa.us 50 : 0 : appendPQExpBuffer(&conn->errorMessage, "%s:", mprefix);
51 : 0 : pg_GSS_error_int(&conn->errorMessage, maj_stat, GSS_C_GSS_CODE);
52 : 0 : appendPQExpBufferChar(&conn->errorMessage, ':');
53 : 0 : pg_GSS_error_int(&conn->errorMessage, min_stat, GSS_C_MECH_CODE);
54 : 0 : appendPQExpBufferChar(&conn->errorMessage, '\n');
2773 sfrost@snowman.net 55 : 0 : }
56 : :
57 : : /*
58 : : * Attempt to acquire credentials, and return the token if successful.
59 : : * Return GSS_C_NO_CREDENTIAL if not.
60 : : */
61 : : gss_cred_id_t
6 tgl@sss.pgh.pa.us 62 :CBC 173 : pg_GSS_get_cred_cache(void)
63 : : {
64 : : OM_uint32 major,
65 : : minor;
2773 sfrost@snowman.net 66 : 173 : gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
67 : :
68 : 173 : major = gss_acquire_cred(&minor, GSS_C_NO_NAME, 0, GSS_C_NO_OID_SET,
69 : : GSS_C_INITIATE, &cred, NULL, NULL);
70 [ + - ]: 173 : if (major != GSS_S_COMPLETE)
6 tgl@sss.pgh.pa.us 71 : 173 : return GSS_C_NO_CREDENTIAL;
6 tgl@sss.pgh.pa.us 72 :UBC 0 : return cred;
73 : : }
74 : :
75 : : /*
76 : : * Try to load service name for a connection
77 : : */
78 : : int
2773 sfrost@snowman.net 79 : 0 : pg_GSS_load_servicename(PGconn *conn)
80 : : {
81 : : OM_uint32 maj_stat,
82 : : min_stat;
83 : : int maxlen;
84 : : gss_buffer_desc temp_gbuf;
85 : : char *host;
86 : :
87 [ # # ]: 0 : if (conn->gtarg_nam != NULL)
88 : : /* Already taken care of - move along */
89 : 0 : return STATUS_OK;
90 : :
91 : 0 : host = PQhost(conn);
92 [ # # # # ]: 0 : if (!(host && host[0] != '\0'))
93 : : {
1451 peter@eisentraut.org 94 : 0 : libpq_append_conn_error(conn, "host name must be specified");
2773 sfrost@snowman.net 95 : 0 : return STATUS_ERROR;
96 : : }
97 : :
98 : : /*
99 : : * Import service principal name so the proper ticket can be acquired by
100 : : * the GSSAPI system.
101 : : */
2138 tgl@sss.pgh.pa.us 102 : 0 : maxlen = strlen(conn->krbsrvname) + strlen(host) + 2;
2773 sfrost@snowman.net 103 : 0 : temp_gbuf.value = (char *) malloc(maxlen);
104 [ # # ]: 0 : if (!temp_gbuf.value)
105 : : {
1451 peter@eisentraut.org 106 : 0 : libpq_append_conn_error(conn, "out of memory");
2773 sfrost@snowman.net 107 : 0 : return STATUS_ERROR;
108 : : }
109 : 0 : snprintf(temp_gbuf.value, maxlen, "%s@%s",
110 : : conn->krbsrvname, host);
111 : 0 : temp_gbuf.length = strlen(temp_gbuf.value);
112 : :
113 : 0 : maj_stat = gss_import_name(&min_stat, &temp_gbuf,
114 : : GSS_C_NT_HOSTBASED_SERVICE, &conn->gtarg_nam);
115 : 0 : free(temp_gbuf.value);
116 : :
117 [ # # ]: 0 : if (maj_stat != GSS_S_COMPLETE)
118 : : {
119 : 0 : pg_GSS_error(libpq_gettext("GSSAPI name import error"),
120 : : conn,
121 : : maj_stat, min_stat);
122 : 0 : return STATUS_ERROR;
123 : : }
124 : 0 : return STATUS_OK;
125 : : }
|