Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

fe-auth.h File Reference

#include "libpq-fe.h"
#include "libpq-int.h"
Include dependency graph for fe-auth.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int pg_fe_sendauth (AuthRequest areq, PGconn *conn)
char * pg_fe_getauthname (PQExpBuffer errorMessage)

Function Documentation

char* pg_fe_getauthname ( PQExpBuffer  errorMessage  ) 

Definition at line 979 of file fe-auth.c.

References name, pglock_thread, pgunlock_thread, pqGetpwuid(), and username.

Referenced by conninfo_add_defaults().

{
    const char *name = NULL;
    char       *authn;

#ifdef WIN32
    char        username[128];
    DWORD       namesize = sizeof(username) - 1;
#else
    char        pwdbuf[BUFSIZ];
    struct passwd pwdstr;
    struct passwd *pw = NULL;
#endif

    /*
     * Some users are using configure --enable-thread-safety-force, so we
     * might as well do the locking within our library to protect
     * pqGetpwuid(). In fact, application developers can use getpwuid() in
     * their application if they use the locking call we provide, or install
     * their own locking function using PQregisterThreadLock().
     */
    pglock_thread();

    if (!name)
    {
#ifdef WIN32
        if (GetUserName(username, &namesize))
            name = username;
#else
        if (pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pw) == 0)
            name = pw->pw_name;
#endif
    }

    authn = name ? strdup(name) : NULL;

    pgunlock_thread();

    return authn;
}

int pg_fe_sendauth ( AuthRequest  areq,
PGconn conn 
)

Definition at line 800 of file fe-auth.c.

References AUTH_REQ_CRYPT, AUTH_REQ_GSS, AUTH_REQ_GSS_CONT, AUTH_REQ_KRB4, AUTH_REQ_KRB5, AUTH_REQ_MD5, AUTH_REQ_OK, AUTH_REQ_PASSWORD, AUTH_REQ_SCM_CREDS, AUTH_REQ_SSPI, pg_conn::errorMessage, libpq_gettext, NULL, pg_conn::password_needed, pg_local_sendauth(), pg_password_sendauth(), pg_strcasecmp(), pglock_thread, pg_conn::pgpass, pgunlock_thread, PQnoPasswordSupplied, printfPQExpBuffer(), and STATUS_OK.

Referenced by PQconnectPoll().

{
    switch (areq)
    {
        case AUTH_REQ_OK:
            break;

        case AUTH_REQ_KRB4:
            printfPQExpBuffer(&conn->errorMessage,
                 libpq_gettext("Kerberos 4 authentication not supported\n"));
            return STATUS_ERROR;

        case AUTH_REQ_KRB5:
#ifdef KRB5
            pglock_thread();
            if (pg_krb5_sendauth(conn) != STATUS_OK)
            {
                /* Error message already filled in */
                pgunlock_thread();
                return STATUS_ERROR;
            }
            pgunlock_thread();
            break;
#else
            printfPQExpBuffer(&conn->errorMessage,
                 libpq_gettext("Kerberos 5 authentication not supported\n"));
            return STATUS_ERROR;
#endif

#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
        case AUTH_REQ_GSS:
#if !defined(ENABLE_SSPI)
            /* no native SSPI, so use GSSAPI library for it */
        case AUTH_REQ_SSPI:
#endif
            {
                int         r;

                pglock_thread();

                /*
                 * If we have both GSS and SSPI support compiled in, use SSPI
                 * support by default. This is overridable by a connection
                 * string parameter. Note that when using SSPI we still leave
                 * the negotiate parameter off, since we want SSPI to use the
                 * GSSAPI kerberos protocol. For actual SSPI negotiate
                 * protocol, we use AUTH_REQ_SSPI.
                 */
#if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
                if (conn->gsslib && (pg_strcasecmp(conn->gsslib, "gssapi") == 0))
                    r = pg_GSS_startup(conn);
                else
                    r = pg_SSPI_startup(conn, 0);
#elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
                r = pg_GSS_startup(conn);
#elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
                r = pg_SSPI_startup(conn, 0);
#endif
                if (r != STATUS_OK)
                {
                    /* Error message already filled in. */
                    pgunlock_thread();
                    return STATUS_ERROR;
                }
                pgunlock_thread();
            }
            break;

        case AUTH_REQ_GSS_CONT:
            {
                int         r;

                pglock_thread();
#if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
                if (conn->usesspi)
                    r = pg_SSPI_continue(conn);
                else
                    r = pg_GSS_continue(conn);
#elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
                r = pg_GSS_continue(conn);
#elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
                r = pg_SSPI_continue(conn);
#endif
                if (r != STATUS_OK)
                {
                    /* Error message already filled in. */
                    pgunlock_thread();
                    return STATUS_ERROR;
                }
                pgunlock_thread();
            }
            break;
#else                           /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
            /* No GSSAPI *or* SSPI support */
        case AUTH_REQ_GSS:
        case AUTH_REQ_GSS_CONT:
            printfPQExpBuffer(&conn->errorMessage,
                     libpq_gettext("GSSAPI authentication not supported\n"));
            return STATUS_ERROR;
#endif   /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */

#ifdef ENABLE_SSPI
        case AUTH_REQ_SSPI:

            /*
             * SSPI has it's own startup message so libpq can decide which
             * method to use. Indicate to pg_SSPI_startup that we want SSPI
             * negotiation instead of Kerberos.
             */
            pglock_thread();
            if (pg_SSPI_startup(conn, 1) != STATUS_OK)
            {
                /* Error message already filled in. */
                pgunlock_thread();
                return STATUS_ERROR;
            }
            pgunlock_thread();
            break;
#else

            /*
             * No SSPI support. However, if we have GSSAPI but not SSPI
             * support, AUTH_REQ_SSPI will have been handled in the codepath
             * for AUTH_REQ_GSSAPI above, so don't duplicate the case label in
             * that case.
             */
#if !defined(ENABLE_GSS)
        case AUTH_REQ_SSPI:
            printfPQExpBuffer(&conn->errorMessage,
                       libpq_gettext("SSPI authentication not supported\n"));
            return STATUS_ERROR;
#endif   /* !define(ENABLE_GSSAPI) */
#endif   /* ENABLE_SSPI */


        case AUTH_REQ_CRYPT:
            printfPQExpBuffer(&conn->errorMessage,
                      libpq_gettext("Crypt authentication not supported\n"));
            return STATUS_ERROR;

        case AUTH_REQ_MD5:
        case AUTH_REQ_PASSWORD:
            conn->password_needed = true;
            if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
            {
                printfPQExpBuffer(&conn->errorMessage,
                                  PQnoPasswordSupplied);
                return STATUS_ERROR;
            }
            if (pg_password_sendauth(conn, conn->pgpass, areq) != STATUS_OK)
            {
                printfPQExpBuffer(&conn->errorMessage,
                     "fe_sendauth: error sending password authentication\n");
                return STATUS_ERROR;
            }
            break;

        case AUTH_REQ_SCM_CREDS:
            if (pg_local_sendauth(conn) != STATUS_OK)
                return STATUS_ERROR;
            break;

        default:
            printfPQExpBuffer(&conn->errorMessage,
            libpq_gettext("authentication method %u not supported\n"), areq);
            return STATUS_ERROR;
    }

    return STATUS_OK;
}