PostgreSQL Source Code  git master
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, int payloadlen, PGconn *conn)
 
char * pg_fe_getusername (uid_t user_id, PQExpBuffer errorMessage)
 
char * pg_fe_getauthname (PQExpBuffer errorMessage)
 
char * pg_fe_scram_build_secret (const char *password, const char **errstr)
 

Variables

const pg_fe_sasl_mech pg_scram_mech
 

Function Documentation

◆ pg_fe_getauthname()

char* pg_fe_getauthname ( PQExpBuffer  errorMessage)

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

1129 {
1130 #ifdef WIN32
1131  return pg_fe_getusername(0, errorMessage);
1132 #else
1133  return pg_fe_getusername(geteuid(), errorMessage);
1134 #endif
1135 }
char * pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage)
Definition: fe-auth.c:1072

References pg_fe_getusername().

Referenced by connectOptions2(), and conninfo_add_defaults().

◆ pg_fe_getusername()

char* pg_fe_getusername ( uid_t  user_id,
PQExpBuffer  errorMessage 
)

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

1073 {
1074  char *result = NULL;
1075  const char *name = NULL;
1076 
1077 #ifdef WIN32
1078  /* Microsoft recommends buffer size of UNLEN+1, where UNLEN = 256 */
1079  char username[256 + 1];
1080  DWORD namesize = sizeof(username);
1081 #else
1082  char pwdbuf[BUFSIZ];
1083 #endif
1084 
1085  /*
1086  * Some users are using configure --enable-thread-safety-force, so we
1087  * might as well do the locking within our library to protect getpwuid().
1088  * In fact, application developers can use getpwuid() in their application
1089  * if they use the locking call we provide, or install their own locking
1090  * function using PQregisterThreadLock().
1091  */
1092  pglock_thread();
1093 
1094 #ifdef WIN32
1095  if (GetUserName(username, &namesize))
1096  name = username;
1097  else if (errorMessage)
1098  libpq_append_error(errorMessage,
1099  "user name lookup failure: error code %lu",
1100  GetLastError());
1101 #else
1102  if (pg_get_user_name(user_id, pwdbuf, sizeof(pwdbuf)))
1103  name = pwdbuf;
1104  else if (errorMessage)
1105  appendPQExpBuffer(errorMessage, "%s\n", pwdbuf);
1106 #endif
1107 
1108  if (name)
1109  {
1110  result = strdup(name);
1111  if (result == NULL && errorMessage)
1112  libpq_append_error(errorMessage, "out of memory");
1113  }
1114 
1115  pgunlock_thread();
1116 
1117  return result;
1118 }
const char * name
Definition: encode.c:561
void libpq_append_error(PQExpBuffer errorMessage, const char *fmt,...)
Definition: fe-misc.c:1283
#define pglock_thread()
Definition: libpq-int.h:659
#define pgunlock_thread()
Definition: libpq-int.h:660
const char * username
Definition: pgbench.c:305
bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen)
Definition: thread.c:35
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265

References appendPQExpBuffer(), libpq_append_error(), name, pg_get_user_name(), pglock_thread, pgunlock_thread, and username.

Referenced by pg_fe_getauthname(), and PQconnectPoll().

◆ pg_fe_scram_build_secret()

char* pg_fe_scram_build_secret ( const char *  password,
const char **  errstr 
)

Definition at line 885 of file fe-auth-scram.c.

886 {
887  char *prep_password;
888  pg_saslprep_rc rc;
889  char saltbuf[SCRAM_DEFAULT_SALT_LEN];
890  char *result;
891 
892  /*
893  * Normalize the password with SASLprep. If that doesn't work, because
894  * the password isn't valid UTF-8 or contains prohibited characters, just
895  * proceed with the original password. (See comments at the top of
896  * auth-scram.c.)
897  */
898  rc = pg_saslprep(password, &prep_password);
899  if (rc == SASLPREP_OOM)
900  {
901  *errstr = libpq_gettext("out of memory");
902  return NULL;
903  }
904  if (rc == SASLPREP_SUCCESS)
905  password = (const char *) prep_password;
906 
907  /* Generate a random salt */
909  {
910  *errstr = libpq_gettext("could not generate random salt");
911  free(prep_password);
912  return NULL;
913  }
914 
915  result = scram_build_secret(saltbuf, SCRAM_DEFAULT_SALT_LEN,
917  errstr);
918 
919  free(prep_password);
920 
921  return result;
922 }
#define free(a)
Definition: header.h:65
#define libpq_gettext(x)
Definition: libpq-int.h:882
bool pg_strong_random(void *buf, size_t len)
pg_saslprep_rc pg_saslprep(const char *input, char **output)
Definition: saslprep.c:1044
pg_saslprep_rc
Definition: saslprep.h:21
@ SASLPREP_OOM
Definition: saslprep.h:23
@ SASLPREP_SUCCESS
Definition: saslprep.h:22
char * scram_build_secret(const char *salt, int saltlen, int iterations, const char *password, const char **errstr)
Definition: scram-common.c:195
#define SCRAM_DEFAULT_ITERATIONS
Definition: scram-common.h:47
#define SCRAM_DEFAULT_SALT_LEN
Definition: scram-common.h:41
static char * password
Definition: streamutil.c:53

References free, libpq_gettext, password, pg_saslprep(), pg_strong_random(), SASLPREP_OOM, SASLPREP_SUCCESS, scram_build_secret(), SCRAM_DEFAULT_ITERATIONS, and SCRAM_DEFAULT_SALT_LEN.

Referenced by PQencryptPasswordConn().

◆ pg_fe_sendauth()

int pg_fe_sendauth ( AuthRequest  areq,
int  payloadlen,
PGconn conn 
)

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

863 {
864  int oldmsglen;
865 
866  if (!check_expected_areq(areq, conn))
867  return STATUS_ERROR;
868 
869  switch (areq)
870  {
871  case AUTH_REQ_OK:
872  break;
873 
874  case AUTH_REQ_KRB4:
875  libpq_append_conn_error(conn, "Kerberos 4 authentication not supported");
876  return STATUS_ERROR;
877 
878  case AUTH_REQ_KRB5:
879  libpq_append_conn_error(conn, "Kerberos 5 authentication not supported");
880  return STATUS_ERROR;
881 
882 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
883  case AUTH_REQ_GSS:
884 #if !defined(ENABLE_SSPI)
885  /* no native SSPI, so use GSSAPI library for it */
886  case AUTH_REQ_SSPI:
887 #endif
888  {
889  int r;
890 
891  pglock_thread();
892 
893  /*
894  * If we have both GSS and SSPI support compiled in, use SSPI
895  * support by default. This is overridable by a connection
896  * string parameter. Note that when using SSPI we still leave
897  * the negotiate parameter off, since we want SSPI to use the
898  * GSSAPI kerberos protocol. For actual SSPI negotiate
899  * protocol, we use AUTH_REQ_SSPI.
900  */
901 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
902  if (conn->gsslib && (pg_strcasecmp(conn->gsslib, "gssapi") == 0))
903  r = pg_GSS_startup(conn, payloadlen);
904  else
905  r = pg_SSPI_startup(conn, 0, payloadlen);
906 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
907  r = pg_GSS_startup(conn, payloadlen);
908 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
909  r = pg_SSPI_startup(conn, 0, payloadlen);
910 #endif
911  if (r != STATUS_OK)
912  {
913  /* Error message already filled in. */
914  pgunlock_thread();
915  return STATUS_ERROR;
916  }
917  pgunlock_thread();
918  }
919  break;
920 
921  case AUTH_REQ_GSS_CONT:
922  {
923  int r;
924 
925  pglock_thread();
926 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
927  if (conn->usesspi)
928  r = pg_SSPI_continue(conn, payloadlen);
929  else
930  r = pg_GSS_continue(conn, payloadlen);
931 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
932  r = pg_GSS_continue(conn, payloadlen);
933 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
934  r = pg_SSPI_continue(conn, payloadlen);
935 #endif
936  if (r != STATUS_OK)
937  {
938  /* Error message already filled in. */
939  pgunlock_thread();
940  return STATUS_ERROR;
941  }
942  pgunlock_thread();
943  }
944  break;
945 #else /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
946  /* No GSSAPI *or* SSPI support */
947  case AUTH_REQ_GSS:
948  case AUTH_REQ_GSS_CONT:
949  libpq_append_conn_error(conn, "GSSAPI authentication not supported");
950  return STATUS_ERROR;
951 #endif /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
952 
953 #ifdef ENABLE_SSPI
954  case AUTH_REQ_SSPI:
955 
956  /*
957  * SSPI has its own startup message so libpq can decide which
958  * method to use. Indicate to pg_SSPI_startup that we want SSPI
959  * negotiation instead of Kerberos.
960  */
961  pglock_thread();
962  if (pg_SSPI_startup(conn, 1, payloadlen) != STATUS_OK)
963  {
964  /* Error message already filled in. */
965  pgunlock_thread();
966  return STATUS_ERROR;
967  }
968  pgunlock_thread();
969  break;
970 #else
971 
972  /*
973  * No SSPI support. However, if we have GSSAPI but not SSPI
974  * support, AUTH_REQ_SSPI will have been handled in the codepath
975  * for AUTH_REQ_GSS above, so don't duplicate the case label in
976  * that case.
977  */
978 #if !defined(ENABLE_GSS)
979  case AUTH_REQ_SSPI:
980  libpq_append_conn_error(conn, "SSPI authentication not supported");
981  return STATUS_ERROR;
982 #endif /* !define(ENABLE_GSS) */
983 #endif /* ENABLE_SSPI */
984 
985 
986  case AUTH_REQ_CRYPT:
987  libpq_append_conn_error(conn, "Crypt authentication not supported");
988  return STATUS_ERROR;
989 
990  case AUTH_REQ_MD5:
991  case AUTH_REQ_PASSWORD:
992  {
993  char *password;
994 
995  conn->password_needed = true;
997  if (password == NULL)
998  password = conn->pgpass;
999  if (password == NULL || password[0] == '\0')
1000  {
1003  return STATUS_ERROR;
1004  }
1006  {
1008  "fe_sendauth: error sending password authentication\n");
1009  return STATUS_ERROR;
1010  }
1011  break;
1012  }
1013 
1014  case AUTH_REQ_SASL:
1015 
1016  /*
1017  * The request contains the name (as assigned by IANA) of the
1018  * authentication mechanism.
1019  */
1020  if (pg_SASL_init(conn, payloadlen) != STATUS_OK)
1021  {
1022  /* pg_SASL_init already set the error message */
1023  return STATUS_ERROR;
1024  }
1025  break;
1026 
1027  case AUTH_REQ_SASL_CONT:
1028  case AUTH_REQ_SASL_FIN:
1029  if (conn->sasl_state == NULL)
1030  {
1032  "fe_sendauth: invalid authentication request from server: AUTH_REQ_SASL_CONT without AUTH_REQ_SASL\n");
1033  return STATUS_ERROR;
1034  }
1035  oldmsglen = conn->errorMessage.len;
1036  if (pg_SASL_continue(conn, payloadlen,
1037  (areq == AUTH_REQ_SASL_FIN)) != STATUS_OK)
1038  {
1039  /* Use this message if pg_SASL_continue didn't supply one */
1040  if (conn->errorMessage.len == oldmsglen)
1042  "fe_sendauth: error in SASL authentication\n");
1043  return STATUS_ERROR;
1044  }
1045  break;
1046 
1047  case AUTH_REQ_SCM_CREDS:
1049  return STATUS_ERROR;
1050  break;
1051 
1052  default:
1053  libpq_append_conn_error(conn, "authentication method %u not supported", areq);
1054  return STATUS_ERROR;
1055  }
1056 
1057  return STATUS_OK;
1058 }
#define STATUS_OK
Definition: c.h:1108
#define STATUS_ERROR
Definition: c.h:1109
static bool check_expected_areq(AuthRequest areq, PGconn *conn)
Definition: fe-auth.c:814
static int pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
Definition: fe-auth.c:612
static int pg_SASL_init(PGconn *conn, int payloadlen)
Definition: fe-auth.c:406
static int pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
Definition: fe-auth.c:746
static int pg_local_sendauth(PGconn *conn)
Definition: fe-auth.c:695
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1312
#define PQnoPasswordSupplied
Definition: libpq-fe.h:561
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define AUTH_REQ_SSPI
Definition: pqcomm.h:122
#define AUTH_REQ_SASL_CONT
Definition: pqcomm.h:124
#define AUTH_REQ_GSS
Definition: pqcomm.h:120
#define AUTH_REQ_MD5
Definition: pqcomm.h:118
#define AUTH_REQ_KRB5
Definition: pqcomm.h:115
#define AUTH_REQ_OK
Definition: pqcomm.h:113
#define AUTH_REQ_KRB4
Definition: pqcomm.h:114
#define AUTH_REQ_PASSWORD
Definition: pqcomm.h:116
#define AUTH_REQ_GSS_CONT
Definition: pqcomm.h:121
#define AUTH_REQ_CRYPT
Definition: pqcomm.h:117
#define AUTH_REQ_SASL
Definition: pqcomm.h:123
#define AUTH_REQ_SCM_CREDS
Definition: pqcomm.h:119
#define AUTH_REQ_SASL_FIN
Definition: pqcomm.h:125
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
PGconn * conn
Definition: streamutil.c:54
char * password
Definition: libpq-int.h:341
char * pgpass
Definition: libpq-int.h:372
PQExpBufferData errorMessage
Definition: libpq-int.h:588
char * gsslib
Definition: libpq-int.h:394
void * sasl_state
Definition: libpq-int.h:517
int whichhost
Definition: libpq-int.h:429
pg_conn_host * connhost
Definition: libpq-int.h:430
bool password_needed
Definition: libpq-int.h:454

References appendPQExpBufferStr(), 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_SASL, AUTH_REQ_SASL_CONT, AUTH_REQ_SASL_FIN, AUTH_REQ_SCM_CREDS, AUTH_REQ_SSPI, check_expected_areq(), conn, pg_conn::connhost, pg_conn::errorMessage, pg_conn::gsslib, PQExpBufferData::len, libpq_append_conn_error(), password, pg_conn_host::password, pg_conn::password_needed, pg_local_sendauth(), pg_password_sendauth(), pg_SASL_continue(), pg_SASL_init(), pg_strcasecmp(), pglock_thread, pg_conn::pgpass, pgunlock_thread, PQnoPasswordSupplied, pg_conn::sasl_state, STATUS_ERROR, STATUS_OK, and pg_conn::whichhost.

Referenced by PQconnectPoll().

Variable Documentation

◆ pg_scram_mech

const pg_fe_sasl_mech pg_scram_mech
extern

Definition at line 33 of file fe-auth-scram.c.

Referenced by pg_SASL_init().