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_getauthname (PQExpBuffer errorMessage)
 
void * pg_fe_scram_init (PGconn *conn, const char *password, const char *sasl_mechanism)
 
bool pg_fe_scram_channel_bound (void *opaq)
 
void pg_fe_scram_free (void *opaq)
 
void pg_fe_scram_exchange (void *opaq, char *input, int inputlen, char **output, int *outputlen, bool *done, bool *success)
 
char * pg_fe_scram_build_secret (const char *password)
 

Function Documentation

◆ pg_fe_getauthname()

char* pg_fe_getauthname ( PQExpBuffer  errorMessage)

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

References libpq_gettext, name, pglock_thread, pgunlock_thread, pqGetpwuid(), printfPQExpBuffer(), strerror_r, and username.

Referenced by connectOptions2(), and conninfo_add_defaults().

1074 {
1075  char *result = NULL;
1076  const char *name = NULL;
1077 
1078 #ifdef WIN32
1079  /* Microsoft recommends buffer size of UNLEN+1, where UNLEN = 256 */
1080  char username[256 + 1];
1081  DWORD namesize = sizeof(username);
1082 #else
1083  uid_t user_id = geteuid();
1084  char pwdbuf[BUFSIZ];
1085  struct passwd pwdstr;
1086  struct passwd *pw = NULL;
1087  int pwerr;
1088 #endif
1089 
1090  /*
1091  * Some users are using configure --enable-thread-safety-force, so we
1092  * might as well do the locking within our library to protect
1093  * pqGetpwuid(). In fact, application developers can use getpwuid() in
1094  * their application if they use the locking call we provide, or install
1095  * their own locking function using PQregisterThreadLock().
1096  */
1097  pglock_thread();
1098 
1099 #ifdef WIN32
1100  if (GetUserName(username, &namesize))
1101  name = username;
1102  else if (errorMessage)
1103  printfPQExpBuffer(errorMessage,
1104  libpq_gettext("user name lookup failure: error code %lu\n"),
1105  GetLastError());
1106 #else
1107  pwerr = pqGetpwuid(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
1108  if (pw != NULL)
1109  name = pw->pw_name;
1110  else if (errorMessage)
1111  {
1112  if (pwerr != 0)
1113  printfPQExpBuffer(errorMessage,
1114  libpq_gettext("could not look up local user ID %d: %s\n"),
1115  (int) user_id,
1116  strerror_r(pwerr, pwdbuf, sizeof(pwdbuf)));
1117  else
1118  printfPQExpBuffer(errorMessage,
1119  libpq_gettext("local user with ID %d does not exist\n"),
1120  (int) user_id);
1121  }
1122 #endif
1123 
1124  if (name)
1125  {
1126  result = strdup(name);
1127  if (result == NULL && errorMessage)
1128  printfPQExpBuffer(errorMessage,
1129  libpq_gettext("out of memory\n"));
1130  }
1131 
1132  pgunlock_thread();
1133 
1134  return result;
1135 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
#define pglock_thread()
Definition: libpq-int.h:583
static char * username
Definition: initdb.c:133
#define strerror_r
Definition: port.h:209
int uid_t
Definition: win32_port.h:230
const char * name
Definition: encode.c:521
int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, size_t buflen, struct passwd **result)
Definition: thread.c:68
#define pgunlock_thread()
Definition: libpq-int.h:584
#define libpq_gettext(x)
Definition: libpq-int.h:792

◆ pg_fe_scram_build_secret()

char* pg_fe_scram_build_secret ( const char *  password)

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

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

Referenced by PQencryptPasswordConn().

828 {
829  char *prep_password;
830  pg_saslprep_rc rc;
831  char saltbuf[SCRAM_DEFAULT_SALT_LEN];
832  char *result;
833 
834  /*
835  * Normalize the password with SASLprep. If that doesn't work, because
836  * the password isn't valid UTF-8 or contains prohibited characters, just
837  * proceed with the original password. (See comments at top of file.)
838  */
839  rc = pg_saslprep(password, &prep_password);
840  if (rc == SASLPREP_OOM)
841  return NULL;
842  if (rc == SASLPREP_SUCCESS)
843  password = (const char *) prep_password;
844 
845  /* Generate a random salt */
847  {
848  if (prep_password)
849  free(prep_password);
850  return NULL;
851  }
852 
853  result = scram_build_secret(saltbuf, SCRAM_DEFAULT_SALT_LEN,
855 
856  if (prep_password)
857  free(prep_password);
858 
859  return result;
860 }
static char password[100]
Definition: streamutil.c:53
char * scram_build_secret(const char *salt, int saltlen, int iterations, const char *password)
Definition: scram-common.c:192
pg_saslprep_rc pg_saslprep(const char *input, char **output)
Definition: saslprep.c:1071
pg_saslprep_rc
Definition: saslprep.h:20
#define SCRAM_DEFAULT_SALT_LEN
Definition: scram-common.h:40
#define free(a)
Definition: header.h:65
bool pg_strong_random(void *buf, size_t len)
#define SCRAM_DEFAULT_ITERATIONS
Definition: scram-common.h:46

◆ pg_fe_scram_channel_bound()

bool pg_fe_scram_channel_bound ( void *  opaq)

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

References FE_SCRAM_FINISHED, fe_scram_state::sasl_mechanism, SCRAM_SHA_256_PLUS_NAME, and fe_scram_state::state.

Referenced by check_expected_areq().

132 {
133  fe_scram_state *state = (fe_scram_state *) opaq;
134 
135  /* no SCRAM exchange done */
136  if (state == NULL)
137  return false;
138 
139  /* SCRAM exchange not completed */
140  if (state->state != FE_SCRAM_FINISHED)
141  return false;
142 
143  /* channel binding mechanism not used */
144  if (strcmp(state->sasl_mechanism, SCRAM_SHA_256_PLUS_NAME) != 0)
145  return false;
146 
147  /* all clear! */
148  return true;
149 }
#define SCRAM_SHA_256_PLUS_NAME
Definition: scram-common.h:20
Definition: regguts.h:298
char * sasl_mechanism
Definition: fe-auth-scram.c:42
fe_scram_state_enum state
Definition: fe-auth-scram.c:37

◆ pg_fe_scram_exchange()

void pg_fe_scram_exchange ( void *  opaq,
char *  input,
int  inputlen,
char **  output,
int *  outputlen,
bool done,
bool success 
)

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

References build_client_final_message(), build_client_first_message(), fe_scram_state::conn, conn, error(), pg_conn::errorMessage, FE_SCRAM_FINISHED, FE_SCRAM_INIT, FE_SCRAM_NONCE_SENT, FE_SCRAM_PROOF_SENT, libpq_gettext, printfPQExpBuffer(), read_server_final_message(), read_server_first_message(), fe_scram_state::state, and verify_server_signature().

Referenced by pg_SASL_continue(), and pg_SASL_init().

194 {
195  fe_scram_state *state = (fe_scram_state *) opaq;
196  PGconn *conn = state->conn;
197 
198  *done = false;
199  *success = false;
200  *output = NULL;
201  *outputlen = 0;
202 
203  /*
204  * Check that the input length agrees with the string length of the input.
205  * We can ignore inputlen after this.
206  */
207  if (state->state != FE_SCRAM_INIT)
208  {
209  if (inputlen == 0)
210  {
212  libpq_gettext("malformed SCRAM message (empty message)\n"));
213  goto error;
214  }
215  if (inputlen != strlen(input))
216  {
218  libpq_gettext("malformed SCRAM message (length mismatch)\n"));
219  goto error;
220  }
221  }
222 
223  switch (state->state)
224  {
225  case FE_SCRAM_INIT:
226  /* Begin the SCRAM handshake, by sending client nonce */
228  if (*output == NULL)
229  goto error;
230 
231  *outputlen = strlen(*output);
232  *done = false;
233  state->state = FE_SCRAM_NONCE_SENT;
234  break;
235 
236  case FE_SCRAM_NONCE_SENT:
237  /* Receive salt and server nonce, send response. */
238  if (!read_server_first_message(state, input))
239  goto error;
240 
242  if (*output == NULL)
243  goto error;
244 
245  *outputlen = strlen(*output);
246  *done = false;
247  state->state = FE_SCRAM_PROOF_SENT;
248  break;
249 
250  case FE_SCRAM_PROOF_SENT:
251  /* Receive server signature */
252  if (!read_server_final_message(state, input))
253  goto error;
254 
255  /*
256  * Verify server signature, to make sure we're talking to the
257  * genuine server.
258  */
259  if (verify_server_signature(state))
260  *success = true;
261  else
262  {
263  *success = false;
265  libpq_gettext("incorrect server signature\n"));
266  }
267  *done = true;
268  state->state = FE_SCRAM_FINISHED;
269  break;
270 
271  default:
272  /* shouldn't happen */
274  libpq_gettext("invalid SCRAM exchange state\n"));
275  goto error;
276  }
277  return;
278 
279 error:
280  *done = true;
281  *success = false;
282 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
static void error(void)
Definition: sql-dyntest.c:147
static void output(uint64 loop_count)
static char * build_client_final_message(fe_scram_state *state)
PGconn * conn
Definition: streamutil.c:54
static bool read_server_final_message(fe_scram_state *state, char *input)
PQExpBufferData errorMessage
Definition: libpq-int.h:511
Definition: regguts.h:298
static bool read_server_first_message(fe_scram_state *state, char *input)
static char * build_client_first_message(fe_scram_state *state)
static bool verify_server_signature(fe_scram_state *state)
static bool success
Definition: initdb.c:163
#define libpq_gettext(x)
Definition: libpq-int.h:792
fe_scram_state_enum state
Definition: fe-auth-scram.c:37

◆ pg_fe_scram_free()

void pg_fe_scram_free ( void *  opaq)

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

References fe_scram_state::client_final_message_without_proof, fe_scram_state::client_first_message_bare, fe_scram_state::client_nonce, free, fe_scram_state::nonce, fe_scram_state::password, fe_scram_state::salt, fe_scram_state::sasl_mechanism, fe_scram_state::server_final_message, and fe_scram_state::server_first_message.

Referenced by pqDropConnection().

156 {
157  fe_scram_state *state = (fe_scram_state *) opaq;
158 
159  if (state->password)
160  free(state->password);
161  if (state->sasl_mechanism)
162  free(state->sasl_mechanism);
163 
164  /* client messages */
165  if (state->client_nonce)
166  free(state->client_nonce);
167  if (state->client_first_message_bare)
171 
172  /* first message from server */
173  if (state->server_first_message)
174  free(state->server_first_message);
175  if (state->salt)
176  free(state->salt);
177  if (state->nonce)
178  free(state->nonce);
179 
180  /* final message from server */
181  if (state->server_final_message)
182  free(state->server_final_message);
183 
184  free(state);
185 }
char * client_nonce
Definition: fe-auth-scram.c:46
char * server_first_message
Definition: fe-auth-scram.c:51
char * client_final_message_without_proof
Definition: fe-auth-scram.c:48
#define free(a)
Definition: header.h:65
Definition: regguts.h:298
char * client_first_message_bare
Definition: fe-auth-scram.c:47
char * sasl_mechanism
Definition: fe-auth-scram.c:42
char * server_final_message
Definition: fe-auth-scram.c:58

◆ pg_fe_scram_init()

void* pg_fe_scram_init ( PGconn conn,
const char *  password,
const char *  sasl_mechanism 
)

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

References Assert, fe_scram_state::conn, conn, FE_SCRAM_INIT, free, malloc, fe_scram_state::password, pg_saslprep(), fe_scram_state::sasl_mechanism, SASLPREP_OOM, SASLPREP_SUCCESS, and fe_scram_state::state.

Referenced by pg_SASL_init().

78 {
80  char *prep_password;
81  pg_saslprep_rc rc;
82 
83  Assert(sasl_mechanism != NULL);
84 
85  state = (fe_scram_state *) malloc(sizeof(fe_scram_state));
86  if (!state)
87  return NULL;
88  memset(state, 0, sizeof(fe_scram_state));
89  state->conn = conn;
90  state->state = FE_SCRAM_INIT;
91  state->sasl_mechanism = strdup(sasl_mechanism);
92 
93  if (!state->sasl_mechanism)
94  {
95  free(state);
96  return NULL;
97  }
98 
99  /* Normalize the password with SASLprep, if possible */
100  rc = pg_saslprep(password, &prep_password);
101  if (rc == SASLPREP_OOM)
102  {
103  free(state->sasl_mechanism);
104  free(state);
105  return NULL;
106  }
107  if (rc != SASLPREP_SUCCESS)
108  {
109  prep_password = strdup(password);
110  if (!prep_password)
111  {
112  free(state->sasl_mechanism);
113  free(state);
114  return NULL;
115  }
116  }
117  state->password = prep_password;
118 
119  return state;
120 }
static char password[100]
Definition: streamutil.c:53
pg_saslprep_rc pg_saslprep(const char *input, char **output)
Definition: saslprep.c:1071
#define malloc(a)
Definition: header.h:50
pg_saslprep_rc
Definition: saslprep.h:20
PGconn * conn
Definition: streamutil.c:54
#define free(a)
Definition: header.h:65
#define Assert(condition)
Definition: c.h:739
Definition: regguts.h:298
char * sasl_mechanism
Definition: fe-auth-scram.c:42
fe_scram_state_enum state
Definition: fe-auth-scram.c:37

◆ pg_fe_sendauth()

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

Definition at line 863 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_SASL, AUTH_REQ_SASL_CONT, AUTH_REQ_SASL_FIN, AUTH_REQ_SCM_CREDS, AUTH_REQ_SSPI, check_expected_areq(), pg_conn::connhost, pg_conn::errorMessage, 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, printfPQExpBuffer(), pg_conn::sasl_state, STATUS_ERROR, STATUS_OK, and pg_conn::whichhost.

Referenced by PQconnectPoll().

864 {
865  if (!check_expected_areq(areq, conn))
866  return STATUS_ERROR;
867 
868  switch (areq)
869  {
870  case AUTH_REQ_OK:
871  break;
872 
873  case AUTH_REQ_KRB4:
875  libpq_gettext("Kerberos 4 authentication not supported\n"));
876  return STATUS_ERROR;
877 
878  case AUTH_REQ_KRB5:
880  libpq_gettext("Kerberos 5 authentication not supported\n"));
881  return STATUS_ERROR;
882 
883 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
884  case AUTH_REQ_GSS:
885 #if !defined(ENABLE_SSPI)
886  /* no native SSPI, so use GSSAPI library for it */
887  case AUTH_REQ_SSPI:
888 #endif
889  {
890  int r;
891 
892  pglock_thread();
893 
894  /*
895  * If we have both GSS and SSPI support compiled in, use SSPI
896  * support by default. This is overridable by a connection
897  * string parameter. Note that when using SSPI we still leave
898  * the negotiate parameter off, since we want SSPI to use the
899  * GSSAPI kerberos protocol. For actual SSPI negotiate
900  * protocol, we use AUTH_REQ_SSPI.
901  */
902 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
903  if (conn->gsslib && (pg_strcasecmp(conn->gsslib, "gssapi") == 0))
904  r = pg_GSS_startup(conn, payloadlen);
905  else
906  r = pg_SSPI_startup(conn, 0, payloadlen);
907 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
908  r = pg_GSS_startup(conn, payloadlen);
909 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
910  r = pg_SSPI_startup(conn, 0, payloadlen);
911 #endif
912  if (r != STATUS_OK)
913  {
914  /* Error message already filled in. */
915  pgunlock_thread();
916  return STATUS_ERROR;
917  }
918  pgunlock_thread();
919  }
920  break;
921 
922  case AUTH_REQ_GSS_CONT:
923  {
924  int r;
925 
926  pglock_thread();
927 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
928  if (conn->usesspi)
929  r = pg_SSPI_continue(conn, payloadlen);
930  else
931  r = pg_GSS_continue(conn, payloadlen);
932 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
933  r = pg_GSS_continue(conn, payloadlen);
934 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
935  r = pg_SSPI_continue(conn, payloadlen);
936 #endif
937  if (r != STATUS_OK)
938  {
939  /* Error message already filled in. */
940  pgunlock_thread();
941  return STATUS_ERROR;
942  }
943  pgunlock_thread();
944  }
945  break;
946 #else /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
947  /* No GSSAPI *or* SSPI support */
948  case AUTH_REQ_GSS:
949  case AUTH_REQ_GSS_CONT:
951  libpq_gettext("GSSAPI authentication not supported\n"));
952  return STATUS_ERROR;
953 #endif /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
954 
955 #ifdef ENABLE_SSPI
956  case AUTH_REQ_SSPI:
957 
958  /*
959  * SSPI has its own startup message so libpq can decide which
960  * method to use. Indicate to pg_SSPI_startup that we want SSPI
961  * negotiation instead of Kerberos.
962  */
963  pglock_thread();
964  if (pg_SSPI_startup(conn, 1, payloadlen) != STATUS_OK)
965  {
966  /* Error message already filled in. */
967  pgunlock_thread();
968  return STATUS_ERROR;
969  }
970  pgunlock_thread();
971  break;
972 #else
973 
974  /*
975  * No SSPI support. However, if we have GSSAPI but not SSPI
976  * support, AUTH_REQ_SSPI will have been handled in the codepath
977  * for AUTH_REQ_GSS above, so don't duplicate the case label in
978  * that case.
979  */
980 #if !defined(ENABLE_GSS)
981  case AUTH_REQ_SSPI:
983  libpq_gettext("SSPI authentication not supported\n"));
984  return STATUS_ERROR;
985 #endif /* !define(ENABLE_GSS) */
986 #endif /* ENABLE_SSPI */
987 
988 
989  case AUTH_REQ_CRYPT:
991  libpq_gettext("Crypt authentication not supported\n"));
992  return STATUS_ERROR;
993 
994  case AUTH_REQ_MD5:
995  case AUTH_REQ_PASSWORD:
996  {
997  char *password;
998 
999  conn->password_needed = true;
1000  password = conn->connhost[conn->whichhost].password;
1001  if (password == NULL)
1002  password = conn->pgpass;
1003  if (password == NULL || password[0] == '\0')
1004  {
1007  return STATUS_ERROR;
1008  }
1009  if (pg_password_sendauth(conn, password, areq) != STATUS_OK)
1010  {
1012  "fe_sendauth: error sending password authentication\n");
1013  return STATUS_ERROR;
1014  }
1015  break;
1016  }
1017 
1018  case AUTH_REQ_SASL:
1019 
1020  /*
1021  * The request contains the name (as assigned by IANA) of the
1022  * authentication mechanism.
1023  */
1024  if (pg_SASL_init(conn, payloadlen) != STATUS_OK)
1025  {
1026  /* pg_SASL_init already set the error message */
1027  return STATUS_ERROR;
1028  }
1029  break;
1030 
1031  case AUTH_REQ_SASL_CONT:
1032  case AUTH_REQ_SASL_FIN:
1033  if (conn->sasl_state == NULL)
1034  {
1036  "fe_sendauth: invalid authentication request from server: AUTH_REQ_SASL_CONT without AUTH_REQ_SASL\n");
1037  return STATUS_ERROR;
1038  }
1039  if (pg_SASL_continue(conn, payloadlen,
1040  (areq == AUTH_REQ_SASL_FIN)) != STATUS_OK)
1041  {
1042  /* Use error message, if set already */
1043  if (conn->errorMessage.len == 0)
1045  "fe_sendauth: error in SASL authentication\n");
1046  return STATUS_ERROR;
1047  }
1048  break;
1049 
1050  case AUTH_REQ_SCM_CREDS:
1051  if (pg_local_sendauth(conn) != STATUS_OK)
1052  return STATUS_ERROR;
1053  break;
1054 
1055  default:
1057  libpq_gettext("authentication method %u not supported\n"), areq);
1058  return STATUS_ERROR;
1059  }
1060 
1061  return STATUS_OK;
1062 }
static char password[100]
Definition: streamutil.c:53
#define AUTH_REQ_SSPI
Definition: pqcomm.h:174
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
static int pg_local_sendauth(PGconn *conn)
Definition: fe-auth.c:691
#define AUTH_REQ_SASL_FIN
Definition: pqcomm.h:177
bool password_needed
Definition: libpq-int.h:414
#define AUTH_REQ_OK
Definition: pqcomm.h:165
#define AUTH_REQ_GSS
Definition: pqcomm.h:172
static int pg_SASL_init(PGconn *conn, int payloadlen)
Definition: fe-auth.c:413
static int pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
Definition: fe-auth.c:743
#define STATUS_ERROR
Definition: c.h:1121
#define pglock_thread()
Definition: libpq-int.h:583
#define PQnoPasswordSupplied
Definition: libpq-fe.h:522
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define AUTH_REQ_MD5
Definition: pqcomm.h:170
static int pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
Definition: fe-auth.c:621
pg_conn_host * connhost
Definition: libpq-int.h:403
void * sasl_state
Definition: libpq-int.h:466
#define AUTH_REQ_CRYPT
Definition: pqcomm.h:169
#define STATUS_OK
Definition: c.h:1120
#define AUTH_REQ_PASSWORD
Definition: pqcomm.h:168
PQExpBufferData errorMessage
Definition: libpq-int.h:511
#define AUTH_REQ_KRB5
Definition: pqcomm.h:167
#define AUTH_REQ_SASL_CONT
Definition: pqcomm.h:176
#define AUTH_REQ_KRB4
Definition: pqcomm.h:166
char * pgpass
Definition: libpq-int.h:348
#define AUTH_REQ_SASL
Definition: pqcomm.h:175
#define AUTH_REQ_GSS_CONT
Definition: pqcomm.h:173
static bool check_expected_areq(AuthRequest areq, PGconn *conn)
Definition: fe-auth.c:813
#define pgunlock_thread()
Definition: libpq-int.h:584
int whichhost
Definition: libpq-int.h:402
#define libpq_gettext(x)
Definition: libpq-int.h:792
#define AUTH_REQ_SCM_CREDS
Definition: pqcomm.h:171
char * password
Definition: libpq-int.h:315