PostgreSQL Source Code  git master
fe-gssapi-common.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * fe-gssapi-common.c
4  * The front-end (client) GSSAPI common code
5  *
6  * Portions Copyright (c) 1996-2019, 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  */
24 static void
25 pg_GSS_error_int(PQExpBuffer str, const char *mprefix,
26  OM_uint32 stat, int type)
27 {
28  OM_uint32 lmin_s;
29  gss_buffer_desc lmsg;
30  OM_uint32 msg_ctx = 0;
31 
32  do
33  {
34  gss_display_status(&lmin_s, stat, type,
35  GSS_C_NO_OID, &msg_ctx, &lmsg);
36  appendPQExpBuffer(str, "%s: %s\n", mprefix, (char *) lmsg.value);
37  gss_release_buffer(&lmin_s, &lmsg);
38  } while (msg_ctx);
39 }
40 
41 /*
42  * GSSAPI errors contain two parts; put both into conn->errorMessage.
43  */
44 void
45 pg_GSS_error(const char *mprefix, PGconn *conn,
46  OM_uint32 maj_stat, OM_uint32 min_stat)
47 {
49 
50  /* Fetch major error codes */
51  pg_GSS_error_int(&conn->errorMessage, mprefix, maj_stat, GSS_C_GSS_CODE);
52 
53  /* Add the minor codes as well */
54  pg_GSS_error_int(&conn->errorMessage, mprefix, min_stat, GSS_C_MECH_CODE);
55 }
56 
57 /*
58  * Check if we can acquire credentials at all (and yield them if so).
59  */
60 bool
61 pg_GSS_have_cred_cache(gss_cred_id_t *cred_out)
62 {
63  OM_uint32 major,
64  minor;
65  gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
66 
67  major = gss_acquire_cred(&minor, GSS_C_NO_NAME, 0, GSS_C_NO_OID_SET,
68  GSS_C_INITIATE, &cred, NULL, NULL);
69  if (major != GSS_S_COMPLETE)
70  {
71  *cred_out = NULL;
72  return false;
73  }
74  *cred_out = cred;
75  return true;
76 }
77 
78 /*
79  * Try to load service name for a connection
80  */
81 int
83 {
84  OM_uint32 maj_stat,
85  min_stat;
86  int maxlen;
87  gss_buffer_desc temp_gbuf;
88  char *host;
89 
90  if (conn->gtarg_nam != NULL)
91  /* Already taken care of - move along */
92  return STATUS_OK;
93 
94  host = PQhost(conn);
95  if (!(host && host[0] != '\0'))
96  {
98  libpq_gettext("host name must be specified\n"));
99  return STATUS_ERROR;
100  }
101 
102  /*
103  * Import service principal name so the proper ticket can be acquired by
104  * the GSSAPI system.
105  */
106  maxlen = NI_MAXHOST + strlen(conn->krbsrvname) + 2;
107  temp_gbuf.value = (char *) malloc(maxlen);
108  if (!temp_gbuf.value)
109  {
111  libpq_gettext("out of memory\n"));
112  return STATUS_ERROR;
113  }
114  snprintf(temp_gbuf.value, maxlen, "%s@%s",
115  conn->krbsrvname, host);
116  temp_gbuf.length = strlen(temp_gbuf.value);
117 
118  maj_stat = gss_import_name(&min_stat, &temp_gbuf,
119  GSS_C_NT_HOSTBASED_SERVICE, &conn->gtarg_nam);
120  free(temp_gbuf.value);
121 
122  if (maj_stat != GSS_S_COMPLETE)
123  {
124  pg_GSS_error(libpq_gettext("GSSAPI name import error"),
125  conn,
126  maj_stat, min_stat);
127  return STATUS_ERROR;
128  }
129  return STATUS_OK;
130 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
#define STATUS_ERROR
Definition: c.h:1090
#define malloc(a)
Definition: header.h:50
#define NI_MAXHOST
Definition: getaddrinfo.h:88
PGconn * conn
Definition: streamutil.c:56
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
static void pg_GSS_error_int(PQExpBuffer str, const char *mprefix, OM_uint32 stat, int type)
#define STATUS_OK
Definition: c.h:1089
#define stat(a, b)
Definition: win32_port.h:255
PQExpBufferData errorMessage
Definition: libpq-int.h:511
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:6479
#define free(a)
Definition: header.h:65
int pg_GSS_load_servicename(PGconn *conn)
void pg_GSS_error(const char *mprefix, PGconn *conn, OM_uint32 maj_stat, OM_uint32 min_stat)
bool pg_GSS_have_cred_cache(gss_cred_id_t *cred_out)
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:148
#define snprintf
Definition: port.h:192
#define libpq_gettext(x)
Definition: libpq-int.h:790