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 1168 of file fe-auth.c.

1169 {
1170 #ifdef WIN32
1171  return pg_fe_getusername(0, errorMessage);
1172 #else
1173  return pg_fe_getusername(geteuid(), errorMessage);
1174 #endif
1175 }
char * pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage)
Definition: fe-auth.c:1111

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 1111 of file fe-auth.c.

1112 {
1113  char *result = NULL;
1114  const char *name = NULL;
1115 
1116 #ifdef WIN32
1117  /* Microsoft recommends buffer size of UNLEN+1, where UNLEN = 256 */
1118  char username[256 + 1];
1119  DWORD namesize = sizeof(username);
1120 #else
1121  char pwdbuf[BUFSIZ];
1122 #endif
1123 
1124  /*
1125  * Some users are using configure --enable-thread-safety-force, so we
1126  * might as well do the locking within our library to protect getpwuid().
1127  * In fact, application developers can use getpwuid() in their application
1128  * if they use the locking call we provide, or install their own locking
1129  * function using PQregisterThreadLock().
1130  */
1131  pglock_thread();
1132 
1133 #ifdef WIN32
1134  if (GetUserName(username, &namesize))
1135  name = username;
1136  else if (errorMessage)
1137  appendPQExpBuffer(errorMessage,
1138  libpq_gettext("user name lookup failure: error code %lu\n"),
1139  GetLastError());
1140 #else
1141  if (pg_get_user_name(user_id, pwdbuf, sizeof(pwdbuf)))
1142  name = pwdbuf;
1143  else if (errorMessage)
1144  appendPQExpBuffer(errorMessage, "%s\n", pwdbuf);
1145 #endif
1146 
1147  if (name)
1148  {
1149  result = strdup(name);
1150  if (result == NULL && errorMessage)
1151  appendPQExpBufferStr(errorMessage,
1152  libpq_gettext("out of memory\n"));
1153  }
1154 
1155  pgunlock_thread();
1156 
1157  return result;
1158 }
const char * name
Definition: encode.c:561
#define libpq_gettext(x)
Definition: libpq-int.h:878
#define pglock_thread()
Definition: libpq-int.h:656
#define pgunlock_thread()
Definition: libpq-int.h:657
const char * username
Definition: pgbench.c:309
bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen)
Definition: thread.c:85
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369

References appendPQExpBuffer(), appendPQExpBufferStr(), libpq_gettext, 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 919 of file fe-auth-scram.c.

920 {
921  char *prep_password;
922  pg_saslprep_rc rc;
923  char saltbuf[SCRAM_DEFAULT_SALT_LEN];
924  char *result;
925 
926  /*
927  * Normalize the password with SASLprep. If that doesn't work, because
928  * the password isn't valid UTF-8 or contains prohibited characters, just
929  * proceed with the original password. (See comments at top of file.)
930  */
931  rc = pg_saslprep(password, &prep_password);
932  if (rc == SASLPREP_OOM)
933  {
934  *errstr = _("out of memory");
935  return NULL;
936  }
937  if (rc == SASLPREP_SUCCESS)
938  password = (const char *) prep_password;
939 
940  /* Generate a random salt */
942  {
943  *errstr = _("failed to generate random salt");
944  if (prep_password)
945  free(prep_password);
946  return NULL;
947  }
948 
949  result = scram_build_secret(saltbuf, SCRAM_DEFAULT_SALT_LEN,
951  errstr);
952 
953  if (prep_password)
954  free(prep_password);
955 
956  return result;
957 }
#define _(x)
Definition: elog.c:89
#define free(a)
Definition: header.h:65
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, 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 895 of file fe-auth.c.

896 {
897  int oldmsglen;
898 
899  if (!check_expected_areq(areq, conn))
900  return STATUS_ERROR;
901 
902  switch (areq)
903  {
904  case AUTH_REQ_OK:
905  break;
906 
907  case AUTH_REQ_KRB4:
909  libpq_gettext("Kerberos 4 authentication not supported\n"));
910  return STATUS_ERROR;
911 
912  case AUTH_REQ_KRB5:
914  libpq_gettext("Kerberos 5 authentication not supported\n"));
915  return STATUS_ERROR;
916 
917 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
918  case AUTH_REQ_GSS:
919 #if !defined(ENABLE_SSPI)
920  /* no native SSPI, so use GSSAPI library for it */
921  case AUTH_REQ_SSPI:
922 #endif
923  {
924  int r;
925 
926  pglock_thread();
927 
928  /*
929  * If we have both GSS and SSPI support compiled in, use SSPI
930  * support by default. This is overridable by a connection
931  * string parameter. Note that when using SSPI we still leave
932  * the negotiate parameter off, since we want SSPI to use the
933  * GSSAPI kerberos protocol. For actual SSPI negotiate
934  * protocol, we use AUTH_REQ_SSPI.
935  */
936 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
937  if (conn->gsslib && (pg_strcasecmp(conn->gsslib, "gssapi") == 0))
938  r = pg_GSS_startup(conn, payloadlen);
939  else
940  r = pg_SSPI_startup(conn, 0, payloadlen);
941 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
942  r = pg_GSS_startup(conn, payloadlen);
943 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
944  r = pg_SSPI_startup(conn, 0, payloadlen);
945 #endif
946  if (r != STATUS_OK)
947  {
948  /* Error message already filled in. */
949  pgunlock_thread();
950  return STATUS_ERROR;
951  }
952  pgunlock_thread();
953  }
954  break;
955 
956  case AUTH_REQ_GSS_CONT:
957  {
958  int r;
959 
960  pglock_thread();
961 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
962  if (conn->usesspi)
963  r = pg_SSPI_continue(conn, payloadlen);
964  else
965  r = pg_GSS_continue(conn, payloadlen);
966 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
967  r = pg_GSS_continue(conn, payloadlen);
968 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
969  r = pg_SSPI_continue(conn, payloadlen);
970 #endif
971  if (r != STATUS_OK)
972  {
973  /* Error message already filled in. */
974  pgunlock_thread();
975  return STATUS_ERROR;
976  }
977  pgunlock_thread();
978  }
979  break;
980 #else /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
981  /* No GSSAPI *or* SSPI support */
982  case AUTH_REQ_GSS:
983  case AUTH_REQ_GSS_CONT:
985  libpq_gettext("GSSAPI authentication not supported\n"));
986  return STATUS_ERROR;
987 #endif /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
988 
989 #ifdef ENABLE_SSPI
990  case AUTH_REQ_SSPI:
991 
992  /*
993  * SSPI has its own startup message so libpq can decide which
994  * method to use. Indicate to pg_SSPI_startup that we want SSPI
995  * negotiation instead of Kerberos.
996  */
997  pglock_thread();
998  if (pg_SSPI_startup(conn, 1, payloadlen) != STATUS_OK)
999  {
1000  /* Error message already filled in. */
1001  pgunlock_thread();
1002  return STATUS_ERROR;
1003  }
1004  pgunlock_thread();
1005  break;
1006 #else
1007 
1008  /*
1009  * No SSPI support. However, if we have GSSAPI but not SSPI
1010  * support, AUTH_REQ_SSPI will have been handled in the codepath
1011  * for AUTH_REQ_GSS above, so don't duplicate the case label in
1012  * that case.
1013  */
1014 #if !defined(ENABLE_GSS)
1015  case AUTH_REQ_SSPI:
1017  libpq_gettext("SSPI authentication not supported\n"));
1018  return STATUS_ERROR;
1019 #endif /* !define(ENABLE_GSS) */
1020 #endif /* ENABLE_SSPI */
1021 
1022 
1023  case AUTH_REQ_CRYPT:
1025  libpq_gettext("Crypt authentication not supported\n"));
1026  return STATUS_ERROR;
1027 
1028  case AUTH_REQ_MD5:
1029  case AUTH_REQ_PASSWORD:
1030  {
1031  char *password;
1032 
1033  conn->password_needed = true;
1035  if (password == NULL)
1036  password = conn->pgpass;
1037  if (password == NULL || password[0] == '\0')
1038  {
1041  return STATUS_ERROR;
1042  }
1044  {
1046  "fe_sendauth: error sending password authentication\n");
1047  return STATUS_ERROR;
1048  }
1049  break;
1050  }
1051 
1052  case AUTH_REQ_SASL:
1053 
1054  /*
1055  * The request contains the name (as assigned by IANA) of the
1056  * authentication mechanism.
1057  */
1058  if (pg_SASL_init(conn, payloadlen) != STATUS_OK)
1059  {
1060  /* pg_SASL_init already set the error message */
1061  return STATUS_ERROR;
1062  }
1063  break;
1064 
1065  case AUTH_REQ_SASL_CONT:
1066  case AUTH_REQ_SASL_FIN:
1067  if (conn->sasl_state == NULL)
1068  {
1070  "fe_sendauth: invalid authentication request from server: AUTH_REQ_SASL_CONT without AUTH_REQ_SASL\n");
1071  return STATUS_ERROR;
1072  }
1073  oldmsglen = conn->errorMessage.len;
1074  if (pg_SASL_continue(conn, payloadlen,
1075  (areq == AUTH_REQ_SASL_FIN)) != STATUS_OK)
1076  {
1077  /* Use this message if pg_SASL_continue didn't supply one */
1078  if (conn->errorMessage.len == oldmsglen)
1080  "fe_sendauth: error in SASL authentication\n");
1081  return STATUS_ERROR;
1082  }
1083  break;
1084 
1085  case AUTH_REQ_SCM_CREDS:
1087  return STATUS_ERROR;
1088  break;
1089 
1090  default:
1092  libpq_gettext("authentication method %u not supported\n"), areq);
1093  return STATUS_ERROR;
1094  }
1095 
1096  return STATUS_OK;
1097 }
#define STATUS_OK
Definition: c.h:1167
#define STATUS_ERROR
Definition: c.h:1168
static bool check_expected_areq(AuthRequest areq, PGconn *conn)
Definition: fe-auth.c:845
static int pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
Definition: fe-auth.c:633
static int pg_SASL_init(PGconn *conn, int payloadlen)
Definition: fe-auth.c:417
static int pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
Definition: fe-auth.c:771
static int pg_local_sendauth(PGconn *conn)
Definition: fe-auth.c:719
#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:160
#define AUTH_REQ_SASL_CONT
Definition: pqcomm.h:162
#define AUTH_REQ_GSS
Definition: pqcomm.h:158
#define AUTH_REQ_MD5
Definition: pqcomm.h:156
#define AUTH_REQ_KRB5
Definition: pqcomm.h:153
#define AUTH_REQ_OK
Definition: pqcomm.h:151
#define AUTH_REQ_KRB4
Definition: pqcomm.h:152
#define AUTH_REQ_PASSWORD
Definition: pqcomm.h:154
#define AUTH_REQ_GSS_CONT
Definition: pqcomm.h:159
#define AUTH_REQ_CRYPT
Definition: pqcomm.h:155
#define AUTH_REQ_SASL
Definition: pqcomm.h:161
#define AUTH_REQ_SCM_CREDS
Definition: pqcomm.h:157
#define AUTH_REQ_SASL_FIN
Definition: pqcomm.h:163
PGconn * conn
Definition: streamutil.c:54
char * password
Definition: libpq-int.h:338
char * pgpass
Definition: libpq-int.h:369
PQExpBufferData errorMessage
Definition: libpq-int.h:585
char * gsslib
Definition: libpq-int.h:391
void * sasl_state
Definition: libpq-int.h:514
int whichhost
Definition: libpq-int.h:426
pg_conn_host * connhost
Definition: libpq-int.h:427
bool password_needed
Definition: libpq-int.h:451

References appendPQExpBuffer(), 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_gettext, 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().