LCOV - differential code coverage report
Current view: top level - src/interfaces/libpq - fe-gssapi-common.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB
Current: Differential Code Coverage HEAD vs 15 Lines: 84.1 % 44 37 2 2 2 1 1 2 34 2 1 3
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 4 4 1 3
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           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-2023, 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
      26 CBC           2 : pg_GSS_error_int(PQExpBuffer str, OM_uint32 stat, int type)
      27                 : {
      28                 :     OM_uint32   lmin_s;
      29                 :     gss_buffer_desc lmsg;
      30               2 :     OM_uint32   msg_ctx = 0;
      31                 : 
      32                 :     do
      33                 :     {
      34               2 :         if (gss_display_status(&lmin_s, stat, type, GSS_C_NO_OID,
      35                 :                                &msg_ctx, &lmsg) != GSS_S_COMPLETE)
      36 UBC           0 :             break;
      37 CBC           2 :         appendPQExpBufferChar(str, ' ');
      38               2 :         appendBinaryPQExpBuffer(str, lmsg.value, lmsg.length);
      39               2 :         gss_release_buffer(&lmin_s, &lmsg);
      40               2 :     } while (msg_ctx);
      41               2 : }
      42                 : 
      43                 : /*
      44                 :  * GSSAPI errors contain two parts; put both into conn->errorMessage.
      45                 :  */
      46                 : void
      47               1 : pg_GSS_error(const char *mprefix, PGconn *conn,
      48                 :              OM_uint32 maj_stat, OM_uint32 min_stat)
      49                 : {
      50               1 :     appendPQExpBuffer(&conn->errorMessage, "%s:", mprefix);
      51               1 :     pg_GSS_error_int(&conn->errorMessage, maj_stat, GSS_C_GSS_CODE);
      52               1 :     appendPQExpBufferChar(&conn->errorMessage, ':');
      53               1 :     pg_GSS_error_int(&conn->errorMessage, min_stat, GSS_C_MECH_CODE);
      54               1 :     appendPQExpBufferChar(&conn->errorMessage, '\n');
      55               1 : }
      56                 : 
      57                 : /*
      58                 :  * Check if we can acquire credentials at all (and yield them if so).
      59                 :  */
      60                 : bool
      61             193 : pg_GSS_have_cred_cache(gss_cred_id_t *cred_out)
      62                 : {
      63                 :     OM_uint32   major,
      64                 :                 minor;
      65             193 :     gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
      66                 : 
      67             193 :     major = gss_acquire_cred(&minor, GSS_C_NO_NAME, 0, GSS_C_NO_OID_SET,
      68                 :                              GSS_C_INITIATE, &cred, NULL, NULL);
      69             193 :     if (major != GSS_S_COMPLETE)
      70                 :     {
      71             175 :         *cred_out = NULL;
      72             175 :         return false;
      73                 :     }
      74              18 :     *cred_out = cred;
      75              18 :     return true;
      76                 : }
      77                 : 
      78                 : /*
      79                 :  * Try to load service name for a connection
      80                 :  */
      81                 : int
      82              42 : pg_GSS_load_servicename(PGconn *conn)
      83                 : {
      84                 :     OM_uint32   maj_stat,
      85                 :                 min_stat;
      86                 :     int         maxlen;
      87                 :     gss_buffer_desc temp_gbuf;
      88                 :     char       *host;
      89                 : 
      90              42 :     if (conn->gtarg_nam != NULL)
      91                 :         /* Already taken care of - move along */
      92              18 :         return STATUS_OK;
      93                 : 
      94              24 :     host = PQhost(conn);
      95              24 :     if (!(host && host[0] != '\0'))
      96                 :     {
      97 UNC           0 :         libpq_append_conn_error(conn, "host name must be specified");
      98 UIC           0 :         return STATUS_ERROR;
      99                 :     }
     100                 : 
     101                 :     /*
     102                 :      * Import service principal name so the proper ticket can be acquired by
     103                 :      * the GSSAPI system.
     104 ECB             :      */
     105 CBC          24 :     maxlen = strlen(conn->krbsrvname) + strlen(host) + 2;
     106              24 :     temp_gbuf.value = (char *) malloc(maxlen);
     107 GIC          24 :     if (!temp_gbuf.value)
     108 EUB             :     {
     109 UNC           0 :         libpq_append_conn_error(conn, "out of memory");
     110 LBC           0 :         return STATUS_ERROR;
     111                 :     }
     112 CBC          24 :     snprintf(temp_gbuf.value, maxlen, "%s@%s",
     113                 :              conn->krbsrvname, host);
     114              24 :     temp_gbuf.length = strlen(temp_gbuf.value);
     115                 : 
     116              24 :     maj_stat = gss_import_name(&min_stat, &temp_gbuf,
     117                 :                                GSS_C_NT_HOSTBASED_SERVICE, &conn->gtarg_nam);
     118              24 :     free(temp_gbuf.value);
     119                 : 
     120 GBC          24 :     if (maj_stat != GSS_S_COMPLETE)
     121                 :     {
     122 UIC           0 :         pg_GSS_error(libpq_gettext("GSSAPI name import error"),
     123 EUB             :                      conn,
     124                 :                      maj_stat, min_stat);
     125 LBC           0 :         return STATUS_ERROR;
     126                 :     }
     127 GIC          24 :     return STATUS_OK;
     128                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a