YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/postgres/src/interfaces/libpq/fe-connect.c
Line
Count
Source (jump to first uncovered line)
1
/*-------------------------------------------------------------------------
2
 *
3
 * fe-connect.c
4
 *    functions related to setting up a connection to the backend
5
 *
6
 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
7
 * Portions Copyright (c) 1994, Regents of the University of California
8
 *
9
 *
10
 * IDENTIFICATION
11
 *    src/interfaces/libpq/fe-connect.c
12
 *
13
 *-------------------------------------------------------------------------
14
 */
15
16
#include "postgres_fe.h"
17
18
#include <sys/stat.h>
19
#include <fcntl.h>
20
#include <ctype.h>
21
#include <time.h>
22
#include <unistd.h>
23
24
#include "libpq-fe.h"
25
#include "libpq-int.h"
26
#include "fe-auth.h"
27
#include "pg_config_paths.h"
28
29
#ifdef WIN32
30
#include "win32.h"
31
#ifdef _WIN32_IE
32
#undef _WIN32_IE
33
#endif
34
#define _WIN32_IE 0x0500
35
#ifdef near
36
#undef near
37
#endif
38
#define near
39
#include <shlobj.h>
40
#ifdef _MSC_VER         /* mstcpip.h is missing on mingw */
41
#include <mstcpip.h>
42
#endif
43
#else
44
#include <sys/socket.h>
45
#include <netdb.h>
46
#include <netinet/in.h>
47
#ifdef HAVE_NETINET_TCP_H
48
#include <netinet/tcp.h>
49
#endif
50
#endif
51
52
#ifdef ENABLE_THREAD_SAFETY
53
#ifdef WIN32
54
#include "pthread-win32.h"
55
#else
56
#include <pthread.h>
57
#endif
58
#endif
59
60
#ifdef USE_LDAP
61
#ifdef WIN32
62
#include <winldap.h>
63
#else
64
/* OpenLDAP deprecates RFC 1823, but we want standard conformance */
65
#define LDAP_DEPRECATED 1
66
#include <ldap.h>
67
typedef struct timeval LDAP_TIMEVAL;
68
#endif
69
static int ldapServiceLookup(const char *purl, PQconninfoOption *options,
70
          PQExpBuffer errorMessage);
71
#endif
72
73
#include "common/ip.h"
74
#include "common/scram-common.h"
75
#include "mb/pg_wchar.h"
76
#include "port/pg_bswap.h"
77
78
79
#ifndef WIN32
80
#define PGPASSFILE ".pgpass"
81
#else
82
#define PGPASSFILE "pgpass.conf"
83
#endif
84
85
/*
86
 * Pre-9.0 servers will return this SQLSTATE if asked to set
87
 * application_name in a startup packet.  We hard-wire the value rather
88
 * than looking into errcodes.h since it reflects historical behavior
89
 * rather than that of the current code.
90
 */
91
3
#define ERRCODE_APPNAME_UNKNOWN "42704"
92
93
/* This is part of the protocol so just define it */
94
0
#define ERRCODE_INVALID_PASSWORD "28P01"
95
/* This too */
96
0
#define ERRCODE_CANNOT_CONNECT_NOW "57P03"
97
98
/*
99
 * Cope with the various platform-specific ways to spell TCP keepalive socket
100
 * options.  This doesn't cover Windows, which as usual does its own thing.
101
 */
102
#if defined(TCP_KEEPIDLE)
103
/* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
104
#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE
105
#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE"
106
#elif defined(TCP_KEEPALIVE_THRESHOLD)
107
/* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris >= 11 */
108
#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD
109
#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD"
110
#elif defined(TCP_KEEPALIVE) && defined(__darwin__)
111
/* TCP_KEEPALIVE is the name of this option on macOS */
112
/* Caution: Solaris has this symbol but it means something different */
113
0
#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE
114
0
#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE"
115
#endif
116
117
/*
118
 * fall back options if they are not specified by arguments or defined
119
 * by environment variables
120
 */
121
#define DefaultTty    ""
122
#define DefaultOption ""
123
#define DefaultAuthtype     ""
124
#define DefaultTargetSessionAttrs "any"
125
#ifdef USE_SSL
126
0
#define DefaultSSLMode "prefer"
127
#else
128
#define DefaultSSLMode  "disable"
129
#endif
130
131
/* ----------
132
 * Definition of the conninfo parameters and their fallback resources.
133
 *
134
 * If Environment-Var and Compiled-in are specified as NULL, no
135
 * fallback is available. If after all no value can be determined
136
 * for an option, an error is returned.
137
 *
138
 * The value for the username is treated specially in conninfo_add_defaults.
139
 * If the value is not obtained any other way, the username is determined
140
 * by pg_fe_getauthname().
141
 *
142
 * The Label and Disp-Char entries are provided for applications that
143
 * want to use PQconndefaults() to create a generic database connection
144
 * dialog. Disp-Char is defined as follows:
145
 *    ""    Normal input field
146
 *    "*"   Password field - hide value
147
 *    "D"   Debug option - don't show by default
148
 *
149
 * PQconninfoOptions[] is a constant static array that we use to initialize
150
 * a dynamically allocated working copy.  All the "val" fields in
151
 * PQconninfoOptions[] *must* be NULL.  In a working copy, non-null "val"
152
 * fields point to malloc'd strings that should be freed when the working
153
 * array is freed (see PQconninfoFree).
154
 *
155
 * The first part of each struct is identical to the one in libpq-fe.h,
156
 * which is required since we memcpy() data between the two!
157
 * ----------
158
 */
159
typedef struct _internalPQconninfoOption
160
{
161
  char     *keyword;    /* The keyword of the option      */
162
  char     *envvar;     /* Fallback environment variable name */
163
  char     *compiled;   /* Fallback compiled in default value */
164
  char     *val;      /* Option's current value, or NULL     */
165
  char     *label;      /* Label for field in connect dialog  */
166
  char     *dispchar;   /* Indicates how to display this field in a
167
                 * connect dialog. Values are: "" Display
168
                 * entered value as is "*" Password field -
169
                 * hide value "D"  Debug option - don't show
170
                 * by default */
171
  int     dispsize;   /* Field size in characters for dialog  */
172
  /* ---
173
   * Anything above this comment must be synchronized with
174
   * PQconninfoOption in libpq-fe.h, since we memcpy() data
175
   * between them!
176
   * ---
177
   */
178
  off_t   connofs;    /* Offset into PGconn struct, -1 if not there */
179
} internalPQconninfoOption;
180
181
static const internalPQconninfoOption PQconninfoOptions[] = {
182
  /*
183
   * "authtype" is no longer used, so mark it "don't show".  We keep it in
184
   * the array so as not to reject conninfo strings from old apps that might
185
   * still try to set it.
186
   */
187
  {"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
188
  "Database-Authtype", "D", 20, -1},
189
190
  {"service", "PGSERVICE", NULL, NULL,
191
  "Database-Service", "", 20, -1},
192
193
  {"user", "PGUSER", NULL, NULL,
194
    "Database-User", "", 20,
195
  offsetof(struct pg_conn, pguser)},
196
197
  {"password", "PGPASSWORD", NULL, NULL,
198
    "Database-Password", "*", 20,
199
  offsetof(struct pg_conn, pgpass)},
200
201
  {"passfile", "PGPASSFILE", NULL, NULL,
202
    "Database-Password-File", "", 64,
203
  offsetof(struct pg_conn, pgpassfile)},
204
205
  {"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL,
206
    "Connect-timeout", "", 10,  /* strlen(INT32_MAX) == 10 */
207
  offsetof(struct pg_conn, connect_timeout)},
208
209
  {"dbname", "PGDATABASE", NULL, NULL,
210
    "Database-Name", "", 20,
211
  offsetof(struct pg_conn, dbName)},
212
213
  {"host", "PGHOST", NULL, NULL,
214
    "Database-Host", "", 40,
215
  offsetof(struct pg_conn, pghost)},
216
217
  {"hostaddr", "PGHOSTADDR", NULL, NULL,
218
    "Database-Host-IP-Address", "", 45,
219
  offsetof(struct pg_conn, pghostaddr)},
220
221
  /* Use YugaByte default port */
222
  {"port", "PGPORT", DEF_YBPORT_STR, NULL,
223
    "Database-Port", "", 6,
224
  offsetof(struct pg_conn, pgport)},
225
226
  {"client_encoding", "PGCLIENTENCODING", NULL, NULL,
227
    "Client-Encoding", "", 10,
228
  offsetof(struct pg_conn, client_encoding_initial)},
229
230
  /*
231
   * "tty" is no longer used either, but keep it present for backwards
232
   * compatibility.
233
   */
234
  {"tty", "PGTTY", DefaultTty, NULL,
235
    "Backend-Debug-TTY", "D", 40,
236
  offsetof(struct pg_conn, pgtty)},
237
238
  {"options", "PGOPTIONS", DefaultOption, NULL,
239
    "Backend-Debug-Options", "D", 40,
240
  offsetof(struct pg_conn, pgoptions)},
241
242
  {"application_name", "PGAPPNAME", NULL, NULL,
243
    "Application-Name", "", 64,
244
  offsetof(struct pg_conn, appname)},
245
246
  {"fallback_application_name", NULL, NULL, NULL,
247
    "Fallback-Application-Name", "", 64,
248
  offsetof(struct pg_conn, fbappname)},
249
250
  {"keepalives", NULL, NULL, NULL,
251
    "TCP-Keepalives", "", 1,  /* should be just '0' or '1' */
252
  offsetof(struct pg_conn, keepalives)},
253
254
  {"keepalives_idle", NULL, NULL, NULL,
255
    "TCP-Keepalives-Idle", "", 10,  /* strlen(INT32_MAX) == 10 */
256
  offsetof(struct pg_conn, keepalives_idle)},
257
258
  {"keepalives_interval", NULL, NULL, NULL,
259
    "TCP-Keepalives-Interval", "", 10,  /* strlen(INT32_MAX) == 10 */
260
  offsetof(struct pg_conn, keepalives_interval)},
261
262
  {"keepalives_count", NULL, NULL, NULL,
263
    "TCP-Keepalives-Count", "", 10, /* strlen(INT32_MAX) == 10 */
264
  offsetof(struct pg_conn, keepalives_count)},
265
266
  /*
267
   * ssl options are allowed even without client SSL support because the
268
   * client can still handle SSL modes "disable" and "allow". Other
269
   * parameters have no effect on non-SSL connections, so there is no reason
270
   * to exclude them since none of them are mandatory.
271
   */
272
  {"sslmode", "PGSSLMODE", DefaultSSLMode, NULL,
273
    "SSL-Mode", "", 12,   /* sizeof("verify-full") == 12 */
274
  offsetof(struct pg_conn, sslmode)},
275
276
  {"sslcompression", "PGSSLCOMPRESSION", "0", NULL,
277
    "SSL-Compression", "", 1,
278
  offsetof(struct pg_conn, sslcompression)},
279
280
  {"sslcert", "PGSSLCERT", NULL, NULL,
281
    "SSL-Client-Cert", "", 64,
282
  offsetof(struct pg_conn, sslcert)},
283
284
  {"sslkey", "PGSSLKEY", NULL, NULL,
285
    "SSL-Client-Key", "", 64,
286
  offsetof(struct pg_conn, sslkey)},
287
288
  {"sslrootcert", "PGSSLROOTCERT", NULL, NULL,
289
    "SSL-Root-Certificate", "", 64,
290
  offsetof(struct pg_conn, sslrootcert)},
291
292
  {"sslcrl", "PGSSLCRL", NULL, NULL,
293
    "SSL-Revocation-List", "", 64,
294
  offsetof(struct pg_conn, sslcrl)},
295
296
  {"requirepeer", "PGREQUIREPEER", NULL, NULL,
297
    "Require-Peer", "", 10,
298
  offsetof(struct pg_conn, requirepeer)},
299
300
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
301
  /* Kerberos and GSSAPI authentication support specifying the service name */
302
  {"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
303
    "Kerberos-service-name", "", 20,
304
  offsetof(struct pg_conn, krbsrvname)},
305
#endif
306
307
#if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
308
309
  /*
310
   * GSSAPI and SSPI both enabled, give a way to override which is used by
311
   * default
312
   */
313
  {"gsslib", "PGGSSLIB", NULL, NULL,
314
    "GSS-library", "", 7, /* sizeof("gssapi") = 7 */
315
  offsetof(struct pg_conn, gsslib)},
316
#endif
317
318
  {"replication", NULL, NULL, NULL,
319
    "Replication", "D", 5,
320
  offsetof(struct pg_conn, replication)},
321
322
  {"target_session_attrs", "PGTARGETSESSIONATTRS",
323
    DefaultTargetSessionAttrs, NULL,
324
    "Target-Session-Attrs", "", 11, /* sizeof("read-write") = 11 */
325
  offsetof(struct pg_conn, target_session_attrs)},
326
327
  /* Terminating entry --- MUST BE LAST */
328
  {NULL, NULL, NULL, NULL,
329
  NULL, NULL, 0}
330
};
331
332
static const PQEnvironmentOption EnvironmentOptions[] =
333
{
334
  /* common user-interface settings */
335
  {
336
    "PGDATESTYLE", "datestyle"
337
  },
338
  {
339
    "PGTZ", "timezone"
340
  },
341
  /* internal performance-related settings */
342
  {
343
    "PGGEQO", "geqo"
344
  },
345
  {
346
    NULL, NULL
347
  }
348
};
349
350
/* The connection URI must start with either of the following designators: */
351
static const char uri_designator[] = "postgresql://";
352
static const char short_uri_designator[] = "postgres://";
353
354
static bool connectOptions1(PGconn *conn, const char *conninfo);
355
static bool connectOptions2(PGconn *conn);
356
static int  connectDBStart(PGconn *conn);
357
static int  connectDBComplete(PGconn *conn);
358
static PGPing internal_ping(PGconn *conn);
359
static PGconn *makeEmptyPGconn(void);
360
static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions);
361
static void freePGconn(PGconn *conn);
362
static void closePGconn(PGconn *conn);
363
static void release_conn_addrinfo(PGconn *conn);
364
static void sendTerminateConn(PGconn *conn);
365
static PQconninfoOption *conninfo_init(PQExpBuffer errorMessage);
366
static PQconninfoOption *parse_connection_string(const char *conninfo,
367
            PQExpBuffer errorMessage, bool use_defaults);
368
static int  uri_prefix_length(const char *connstr);
369
static bool recognized_connection_string(const char *connstr);
370
static PQconninfoOption *conninfo_parse(const char *conninfo,
371
         PQExpBuffer errorMessage, bool use_defaults);
372
static PQconninfoOption *conninfo_array_parse(const char *const *keywords,
373
           const char *const *values, PQExpBuffer errorMessage,
374
           bool use_defaults, int expand_dbname);
375
static bool conninfo_add_defaults(PQconninfoOption *options,
376
            PQExpBuffer errorMessage);
377
static PQconninfoOption *conninfo_uri_parse(const char *uri,
378
           PQExpBuffer errorMessage, bool use_defaults);
379
static bool conninfo_uri_parse_options(PQconninfoOption *options,
380
               const char *uri, PQExpBuffer errorMessage);
381
static bool conninfo_uri_parse_params(char *params,
382
              PQconninfoOption *connOptions,
383
              PQExpBuffer errorMessage);
384
static char *conninfo_uri_decode(const char *str, PQExpBuffer errorMessage);
385
static bool get_hexdigit(char digit, int *value);
386
static const char *conninfo_getval(PQconninfoOption *connOptions,
387
        const char *keyword);
388
static PQconninfoOption *conninfo_storeval(PQconninfoOption *connOptions,
389
          const char *keyword, const char *value,
390
          PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode);
391
static PQconninfoOption *conninfo_find(PQconninfoOption *connOptions,
392
        const char *keyword);
393
static void defaultNoticeReceiver(void *arg, const PGresult *res);
394
static void defaultNoticeProcessor(void *arg, const char *message);
395
static int parseServiceInfo(PQconninfoOption *options,
396
         PQExpBuffer errorMessage);
397
static int parseServiceFile(const char *serviceFile,
398
         const char *service,
399
         PQconninfoOption *options,
400
         PQExpBuffer errorMessage,
401
         bool *group_found);
402
static char *pwdfMatchesString(char *buf, const char *token);
403
static char *passwordFromFile(const char *hostname, const char *port, const char *dbname,
404
         const char *username, const char *pgpassfile);
405
static void pgpassfileWarning(PGconn *conn);
406
static void default_threadlock(int acquire);
407
408
409
/* global variable because fe-auth.c needs to access it */
410
pgthreadlock_t pg_g_threadlock = default_threadlock;
411
412
413
/*
414
 *    pqDropConnection
415
 *
416
 * Close any physical connection to the server, and reset associated
417
 * state inside the connection object.  We don't release state that
418
 * would be needed to reconnect, though, nor local state that might still
419
 * be useful later.
420
 *
421
 * We can always flush the output buffer, since there's no longer any hope
422
 * of sending that data.  However, unprocessed input data might still be
423
 * valuable, so the caller must tell us whether to flush that or not.
424
 */
425
void
426
pqDropConnection(PGconn *conn, bool flushInput)
427
630
{
428
  /* Drop any SSL state */
429
630
  pqsecure_close(conn);
430
431
  /* Close the socket itself */
432
630
  if (conn->sock != PGINVALID_SOCKET)
433
314
    closesocket(conn->sock);
434
630
  conn->sock = PGINVALID_SOCKET;
435
436
  /* Optionally discard any unread data */
437
630
  if (flushInput)
438
630
    conn->inStart = conn->inCursor = conn->inEnd = 0;
439
440
  /* Always discard any unsent data */
441
630
  conn->outCount = 0;
442
443
  /* Free authentication state */
444
#ifdef ENABLE_GSS
445
  {
446
    OM_uint32 min_s;
447
448
    if (conn->gctx)
449
      gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
450
    if (conn->gtarg_nam)
451
      gss_release_name(&min_s, &conn->gtarg_nam);
452
  }
453
#endif
454
#ifdef ENABLE_SSPI
455
  if (conn->sspitarget)
456
  {
457
    free(conn->sspitarget);
458
    conn->sspitarget = NULL;
459
  }
460
  if (conn->sspicred)
461
  {
462
    FreeCredentialsHandle(conn->sspicred);
463
    free(conn->sspicred);
464
    conn->sspicred = NULL;
465
  }
466
  if (conn->sspictx)
467
  {
468
    DeleteSecurityContext(conn->sspictx);
469
    free(conn->sspictx);
470
    conn->sspictx = NULL;
471
  }
472
  conn->usesspi = 0;
473
#endif
474
630
  if (conn->sasl_state)
475
0
  {
476
    /*
477
     * XXX: if support for more authentication mechanisms is added, this
478
     * needs to call the right 'free' function.
479
     */
480
0
    pg_fe_scram_free(conn->sasl_state);
481
0
    conn->sasl_state = NULL;
482
0
  }
483
630
}
484
485
486
/*
487
 *    pqDropServerData
488
 *
489
 * Clear all connection state data that was received from (or deduced about)
490
 * the server.  This is essential to do between connection attempts to
491
 * different servers, else we may incorrectly hold over some data from the
492
 * old server.
493
 *
494
 * It would be better to merge this into pqDropConnection, perhaps, but
495
 * right now we cannot because that function is called immediately on
496
 * detection of connection loss (cf. pqReadData, for instance).  This data
497
 * should be kept until we are actually starting a new connection.
498
 */
499
static void
500
pqDropServerData(PGconn *conn)
501
630
{
502
630
  PGnotify   *notify;
503
630
  pgParameterStatus *pstatus;
504
505
  /* Forget pending notifies */
506
630
  notify = conn->notifyHead;
507
630
  while (notify != NULL)
508
0
  {
509
0
    PGnotify   *prev = notify;
510
511
0
    notify = notify->next;
512
0
    free(prev);
513
0
  }
514
630
  conn->notifyHead = conn->notifyTail = NULL;
515
516
  /* Reset ParameterStatus data, as well as variables deduced from it */
517
630
  pstatus = conn->pstatus;
518
4.05k
  while (pstatus != NULL)
519
3.42k
  {
520
3.42k
    pgParameterStatus *prev = pstatus;
521
522
3.42k
    pstatus = pstatus->next;
523
3.42k
    free(prev);
524
3.42k
  }
525
630
  conn->pstatus = NULL;
526
630
  conn->client_encoding = PG_SQL_ASCII;
527
630
  conn->std_strings = false;
528
630
  conn->sversion = 0;
529
530
  /* Drop large-object lookup data */
531
630
  if (conn->lobjfuncs)
532
0
    free(conn->lobjfuncs);
533
630
  conn->lobjfuncs = NULL;
534
535
  /* Reset assorted other per-connection state */
536
630
  conn->last_sqlstate[0] = '\0';
537
630
  conn->auth_req_received = false;
538
630
  conn->password_needed = false;
539
630
  conn->be_pid = 0;
540
630
  conn->be_key = 0;
541
630
}
542
543
544
/*
545
 *    Connecting to a Database
546
 *
547
 * There are now six different ways a user of this API can connect to the
548
 * database.  Two are not recommended for use in new code, because of their
549
 * lack of extensibility with respect to the passing of options to the
550
 * backend.  These are PQsetdb and PQsetdbLogin (the former now being a macro
551
 * to the latter).
552
 *
553
 * If it is desired to connect in a synchronous (blocking) manner, use the
554
 * function PQconnectdb or PQconnectdbParams. The former accepts a string of
555
 * option = value pairs (or a URI) which must be parsed; the latter takes two
556
 * NULL terminated arrays instead.
557
 *
558
 * To connect in an asynchronous (non-blocking) manner, use the functions
559
 * PQconnectStart or PQconnectStartParams (which differ in the same way as
560
 * PQconnectdb and PQconnectdbParams) and PQconnectPoll.
561
 *
562
 * Internally, the static functions connectDBStart, connectDBComplete
563
 * are part of the connection procedure.
564
 */
565
566
/*
567
 *    PQconnectdbParams
568
 *
569
 * establishes a connection to a postgres backend through the postmaster
570
 * using connection information in two arrays.
571
 *
572
 * The keywords array is defined as
573
 *
574
 *     const char *params[] = {"option1", "option2", NULL}
575
 *
576
 * The values array is defined as
577
 *
578
 *     const char *values[] = {"value1", "value2", NULL}
579
 *
580
 * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
581
 * if a memory allocation failed.
582
 * If the status field of the connection returned is CONNECTION_BAD,
583
 * then some fields may be null'ed out instead of having valid values.
584
 *
585
 * You should call PQfinish (if conn is not NULL) regardless of whether this
586
 * call succeeded.
587
 */
588
PGconn *
589
PQconnectdbParams(const char *const *keywords,
590
          const char *const *values,
591
          int expand_dbname)
592
56
{
593
56
  PGconn     *conn = PQconnectStartParams(keywords, values, expand_dbname);
594
595
56
  if (conn && conn->status != CONNECTION_BAD)
596
56
    (void) connectDBComplete(conn);
597
598
56
  return conn;
599
600
56
}
601
602
/*
603
 *    PQpingParams
604
 *
605
 * check server status, accepting parameters identical to PQconnectdbParams
606
 */
607
PGPing
608
PQpingParams(const char *const *keywords,
609
       const char *const *values,
610
       int expand_dbname)
611
0
{
612
0
  PGconn     *conn = PQconnectStartParams(keywords, values, expand_dbname);
613
0
  PGPing    ret;
614
615
0
  ret = internal_ping(conn);
616
0
  PQfinish(conn);
617
618
0
  return ret;
619
0
}
620
621
/*
622
 *    PQconnectdb
623
 *
624
 * establishes a connection to a postgres backend through the postmaster
625
 * using connection information in a string.
626
 *
627
 * The conninfo string is either a whitespace-separated list of
628
 *
629
 *     option = value
630
 *
631
 * definitions or a URI (refer to the documentation for details.) Value
632
 * might be a single value containing no whitespaces or a single quoted
633
 * string. If a single quote should appear anywhere in the value, it must be
634
 * escaped with a backslash like \'
635
 *
636
 * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
637
 * if a memory allocation failed.
638
 * If the status field of the connection returned is CONNECTION_BAD,
639
 * then some fields may be null'ed out instead of having valid values.
640
 *
641
 * You should call PQfinish (if conn is not NULL) regardless of whether this
642
 * call succeeded.
643
 */
644
PGconn *
645
PQconnectdb(const char *conninfo)
646
260
{
647
260
  PGconn     *conn = PQconnectStart(conninfo);
648
649
260
  if (conn && conn->status != CONNECTION_BAD)
650
260
    (void) connectDBComplete(conn);
651
652
260
  return conn;
653
260
}
654
655
/*
656
 *    PQping
657
 *
658
 * check server status, accepting parameters identical to PQconnectdb
659
 */
660
PGPing
661
PQping(const char *conninfo)
662
0
{
663
0
  PGconn     *conn = PQconnectStart(conninfo);
664
0
  PGPing    ret;
665
666
0
  ret = internal_ping(conn);
667
0
  PQfinish(conn);
668
669
0
  return ret;
670
0
}
671
672
/*
673
 *    PQconnectStartParams
674
 *
675
 * Begins the establishment of a connection to a postgres backend through the
676
 * postmaster using connection information in a struct.
677
 *
678
 * See comment for PQconnectdbParams for the definition of the string format.
679
 *
680
 * Returns a PGconn*.  If NULL is returned, a malloc error has occurred, and
681
 * you should not attempt to proceed with this connection.  If the status
682
 * field of the connection returned is CONNECTION_BAD, an error has
683
 * occurred. In this case you should call PQfinish on the result, (perhaps
684
 * inspecting the error message first).  Other fields of the structure may not
685
 * be valid if that occurs.  If the status field is not CONNECTION_BAD, then
686
 * this stage has succeeded - call PQconnectPoll, using select(2) to see when
687
 * this is necessary.
688
 *
689
 * See PQconnectPoll for more info.
690
 */
691
PGconn *
692
PQconnectStartParams(const char *const *keywords,
693
           const char *const *values,
694
           int expand_dbname)
695
56
{
696
56
  PGconn     *conn;
697
56
  PQconninfoOption *connOptions;
698
699
  /*
700
   * Allocate memory for the conn structure
701
   */
702
56
  conn = makeEmptyPGconn();
703
56
  if (conn == NULL)
704
0
    return NULL;
705
706
  /*
707
   * Parse the conninfo arrays
708
   */
709
56
  connOptions = conninfo_array_parse(keywords, values,
710
56
                     &conn->errorMessage,
711
56
                     true, expand_dbname);
712
56
  if (connOptions == NULL)
713
0
  {
714
0
    conn->status = CONNECTION_BAD;
715
    /* errorMessage is already set */
716
0
    return conn;
717
0
  }
718
719
  /*
720
   * Move option values into conn structure
721
   */
722
56
  if (!fillPGconn(conn, connOptions))
723
0
  {
724
0
    PQconninfoFree(connOptions);
725
0
    return conn;
726
0
  }
727
728
  /*
729
   * Free the option info - all is in conn now
730
   */
731
56
  PQconninfoFree(connOptions);
732
733
  /*
734
   * Compute derived options
735
   */
736
56
  if (!connectOptions2(conn))
737
0
    return conn;
738
739
  /*
740
   * Connect to the database
741
   */
742
56
  if (!connectDBStart(conn))
743
0
  {
744
    /* Just in case we failed to set it in connectDBStart */
745
0
    conn->status = CONNECTION_BAD;
746
0
  }
747
748
56
  return conn;
749
56
}
750
751
/*
752
 *    PQconnectStart
753
 *
754
 * Begins the establishment of a connection to a postgres backend through the
755
 * postmaster using connection information in a string.
756
 *
757
 * See comment for PQconnectdb for the definition of the string format.
758
 *
759
 * Returns a PGconn*.  If NULL is returned, a malloc error has occurred, and
760
 * you should not attempt to proceed with this connection.  If the status
761
 * field of the connection returned is CONNECTION_BAD, an error has
762
 * occurred. In this case you should call PQfinish on the result, (perhaps
763
 * inspecting the error message first).  Other fields of the structure may not
764
 * be valid if that occurs.  If the status field is not CONNECTION_BAD, then
765
 * this stage has succeeded - call PQconnectPoll, using select(2) to see when
766
 * this is necessary.
767
 *
768
 * See PQconnectPoll for more info.
769
 */
770
PGconn *
771
PQconnectStart(const char *conninfo)
772
260
{
773
260
  PGconn     *conn;
774
775
  /*
776
   * Allocate memory for the conn structure
777
   */
778
260
  conn = makeEmptyPGconn();
779
260
  if (conn == NULL)
780
0
    return NULL;
781
782
  /*
783
   * Parse the conninfo string
784
   */
785
260
  if (!connectOptions1(conn, conninfo))
786
0
    return conn;
787
788
  /*
789
   * Compute derived options
790
   */
791
260
  if (!connectOptions2(conn))
792
0
    return conn;
793
794
  /*
795
   * Connect to the database
796
   */
797
260
  if (!connectDBStart(conn))
798
0
  {
799
    /* Just in case we failed to set it in connectDBStart */
800
0
    conn->status = CONNECTION_BAD;
801
0
  }
802
803
260
  return conn;
804
260
}
805
806
/*
807
 * Move option values into conn structure
808
 *
809
 * Don't put anything cute here --- intelligence should be in
810
 * connectOptions2 ...
811
 *
812
 * Returns true on success. On failure, returns false and sets error message.
813
 */
814
static bool
815
fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
816
316
{
817
316
  const internalPQconninfoOption *option;
818
819
9.16k
  for (option = PQconninfoOptions; option->keyword; option++)
820
8.84k
  {
821
8.84k
    if (option->connofs >= 0)
822
8.21k
    {
823
8.21k
      const char *tmp = conninfo_getval(connOptions, option->keyword);
824
825
8.21k
      if (tmp)
826
3.21k
      {
827
3.21k
        char    **connmember = (char **) ((char *) conn + option->connofs);
828
829
3.21k
        if (*connmember)
830
0
          free(*connmember);
831
3.21k
        *connmember = strdup(tmp);
832
3.21k
        if (*connmember == NULL)
833
0
        {
834
0
          printfPQExpBuffer(&conn->errorMessage,
835
0
                    libpq_gettext("out of memory\n"));
836
0
          return false;
837
0
        }
838
3.21k
      }
839
8.21k
    }
840
8.84k
  }
841
842
316
  return true;
843
316
}
844
845
/*
846
 *    connectOptions1
847
 *
848
 * Internal subroutine to set up connection parameters given an already-
849
 * created PGconn and a conninfo string.  Derived settings should be
850
 * processed by calling connectOptions2 next.  (We split them because
851
 * PQsetdbLogin overrides defaults in between.)
852
 *
853
 * Returns true if OK, false if trouble (in which case errorMessage is set
854
 * and so is conn->status).
855
 */
856
static bool
857
connectOptions1(PGconn *conn, const char *conninfo)
858
260
{
859
260
  PQconninfoOption *connOptions;
860
861
  /*
862
   * Parse the conninfo string
863
   */
864
260
  connOptions = parse_connection_string(conninfo, &conn->errorMessage, true);
865
260
  if (connOptions == NULL)
866
0
  {
867
0
    conn->status = CONNECTION_BAD;
868
    /* errorMessage is already set */
869
0
    return false;
870
0
  }
871
872
  /*
873
   * Move option values into conn structure
874
   */
875
260
  if (!fillPGconn(conn, connOptions))
876
0
  {
877
0
    conn->status = CONNECTION_BAD;
878
0
    PQconninfoFree(connOptions);
879
0
    return false;
880
0
  }
881
882
  /*
883
   * Free the option info - all is in conn now
884
   */
885
260
  PQconninfoFree(connOptions);
886
887
260
  return true;
888
260
}
889
890
/*
891
 * Count the number of elements in a simple comma-separated list.
892
 */
893
static int
894
count_comma_separated_elems(const char *input)
895
316
{
896
316
  int     n;
897
898
316
  n = 1;
899
7.81k
  for (; *input != '\0'; input++)
900
7.50k
  {
901
7.50k
    if (*input == ',')
902
0
      n++;
903
7.50k
  }
904
905
316
  return n;
906
316
}
907
908
/*
909
 * Parse a simple comma-separated list.
910
 *
911
 * On each call, returns a malloc'd copy of the next element, and sets *more
912
 * to indicate whether there are any more elements in the list after this,
913
 * and updates *startptr to point to the next element, if any.
914
 *
915
 * On out of memory, returns NULL.
916
 */
917
static char *
918
parse_comma_separated_list(char **startptr, bool *more)
919
632
{
920
632
  char     *p;
921
632
  char     *s = *startptr;
922
632
  char     *e;
923
632
  int     len;
924
925
  /*
926
   * Search for the end of the current element; a comma or end-of-string
927
   * acts as a terminator.
928
   */
929
632
  e = s;
930
9.71k
  while (*e != '\0' && *e != ',')
931
9.08k
    ++e;
932
632
  *more = (*e == ',');
933
934
632
  len = e - s;
935
632
  p = (char *) malloc(sizeof(char) * (len + 1));
936
632
  if (p)
937
632
  {
938
632
    memcpy(p, s, len);
939
632
    p[len] = '\0';
940
632
  }
941
632
  *startptr = e + 1;
942
943
632
  return p;
944
632
}
945
946
/*
947
 *    connectOptions2
948
 *
949
 * Compute derived connection options after absorbing all user-supplied info.
950
 *
951
 * Returns true if OK, false if trouble (in which case errorMessage is set
952
 * and so is conn->status).
953
 */
954
static bool
955
connectOptions2(PGconn *conn)
956
316
{
957
316
  int     i;
958
959
  /*
960
   * Allocate memory for details about each host to which we might possibly
961
   * try to connect.  For that, count the number of elements in the hostaddr
962
   * or host options.  If neither is given, assume one host.
963
   */
964
316
  conn->whichhost = 0;
965
316
  if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
966
0
    conn->nconnhost = count_comma_separated_elems(conn->pghostaddr);
967
316
  else if (conn->pghost && conn->pghost[0] != '\0')
968
316
    conn->nconnhost = count_comma_separated_elems(conn->pghost);
969
0
  else
970
0
    conn->nconnhost = 1;
971
316
  conn->connhost = (pg_conn_host *)
972
316
    calloc(conn->nconnhost, sizeof(pg_conn_host));
973
316
  if (conn->connhost == NULL)
974
0
    goto oom_error;
975
976
  /*
977
   * We now have one pg_conn_host structure per possible host.  Fill in the
978
   * host and hostaddr fields for each, by splitting the parameter strings.
979
   */
980
316
  if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
981
0
  {
982
0
    char     *s = conn->pghostaddr;
983
0
    bool    more = true;
984
985
0
    for (i = 0; i < conn->nconnhost && more; i++)
986
0
    {
987
0
      conn->connhost[i].hostaddr = parse_comma_separated_list(&s, &more);
988
0
      if (conn->connhost[i].hostaddr == NULL)
989
0
        goto oom_error;
990
0
    }
991
992
    /*
993
     * If hostaddr was given, the array was allocated according to the
994
     * number of elements in the hostaddr list, so it really should be the
995
     * right size.
996
     */
997
0
    Assert(!more);
998
0
    Assert(i == conn->nconnhost);
999
0
  }
1000
1001
316
  if (conn->pghost != NULL && conn->pghost[0] != '\0')
1002
316
  {
1003
316
    char     *s = conn->pghost;
1004
316
    bool    more = true;
1005
1006
632
    for (i = 0; i < conn->nconnhost && more; i++)
1007
316
    {
1008
316
      conn->connhost[i].host = parse_comma_separated_list(&s, &more);
1009
316
      if (conn->connhost[i].host == NULL)
1010
0
        goto oom_error;
1011
316
    }
1012
1013
    /* Check for wrong number of host items. */
1014
316
    if (more || i != conn->nconnhost)
1015
0
    {
1016
0
      conn->status = CONNECTION_BAD;
1017
0
      printfPQExpBuffer(&conn->errorMessage,
1018
0
                libpq_gettext("could not match %d host names to %d hostaddr values\n"),
1019
0
                count_comma_separated_elems(conn->pghost), conn->nconnhost);
1020
0
      return false;
1021
0
    }
1022
316
  }
1023
1024
  /*
1025
   * Now, for each host slot, identify the type of address spec, and fill in
1026
   * the default address if nothing was given.
1027
   */
1028
632
  for (i = 0; i < conn->nconnhost; i++)
1029
316
  {
1030
316
    pg_conn_host *ch = &conn->connhost[i];
1031
1032
316
    if (ch->hostaddr != NULL && ch->hostaddr[0] != '\0')
1033
0
      ch->type = CHT_HOST_ADDRESS;
1034
316
    else if (ch->host != NULL && ch->host[0] != '\0')
1035
316
    {
1036
316
      ch->type = CHT_HOST_NAME;
1037
316
#ifdef HAVE_UNIX_SOCKETS
1038
316
      if (is_absolute_path(ch->host))
1039
235
        ch->type = CHT_UNIX_SOCKET;
1040
316
#endif
1041
316
    }
1042
0
    else
1043
0
    {
1044
0
      if (ch->host)
1045
0
        free(ch->host);
1046
1047
/* YugaByte use localhost instead of local socket */
1048
0
#pragma push_macro("HAVE_UNIX_SOCKETS")
1049
0
#undef HAVE_UNIX_SOCKETS
1050
1051
#ifdef HAVE_UNIX_SOCKETS
1052
      ch->host = strdup(DEFAULT_PGSOCKET_DIR);
1053
      ch->type = CHT_UNIX_SOCKET;
1054
#else
1055
0
      ch->host = strdup(DefaultHost);
1056
0
      ch->type = CHT_HOST_NAME;
1057
0
#endif
1058
1059
0
#pragma pop_macro("HAVE_UNIX_SOCKETS")
1060
/* YugaByte end */
1061
1062
0
      if (ch->host == NULL)
1063
0
        goto oom_error;
1064
0
    }
1065
316
  }
1066
1067
  /*
1068
   * Next, work out the port number corresponding to each host name.
1069
   *
1070
   * Note: unlike the above for host names, this could leave the port fields
1071
   * as null or empty strings.  We will substitute DEF_PGPORT whenever we
1072
   * read such a port field.
1073
   */
1074
316
  if (conn->pgport != NULL && conn->pgport[0] != '\0')
1075
316
  {
1076
316
    char     *s = conn->pgport;
1077
316
    bool    more = true;
1078
1079
632
    for (i = 0; i < conn->nconnhost && more; i++)
1080
316
    {
1081
316
      conn->connhost[i].port = parse_comma_separated_list(&s, &more);
1082
316
      if (conn->connhost[i].port == NULL)
1083
0
        goto oom_error;
1084
316
    }
1085
1086
    /*
1087
     * If exactly one port was given, use it for every host.  Otherwise,
1088
     * there must be exactly as many ports as there were hosts.
1089
     */
1090
316
    if (i == 1 && !more)
1091
316
    {
1092
316
      for (i = 1; i < conn->nconnhost; i++)
1093
0
      {
1094
0
        conn->connhost[i].port = strdup(conn->connhost[0].port);
1095
0
        if (conn->connhost[i].port == NULL)
1096
0
          goto oom_error;
1097
0
      }
1098
316
    }
1099
0
    else if (more || i != conn->nconnhost)
1100
0
    {
1101
0
      conn->status = CONNECTION_BAD;
1102
0
      printfPQExpBuffer(&conn->errorMessage,
1103
0
                libpq_gettext("could not match %d port numbers to %d hosts\n"),
1104
0
                count_comma_separated_elems(conn->pgport), conn->nconnhost);
1105
0
      return false;
1106
0
    }
1107
316
  }
1108
1109
  /*
1110
   * If user name was not given, fetch it.  (Most likely, the fetch will
1111
   * fail, since the only way we get here is if pg_fe_getauthname() failed
1112
   * during conninfo_add_defaults().  But now we want an error message.)
1113
   */
1114
316
  if (conn->pguser == NULL || conn->pguser[0] == '\0')
1115
0
  {
1116
0
    if (conn->pguser)
1117
0
      free(conn->pguser);
1118
    /* YugaByte default username to "postgres" */
1119
0
    conn->pguser = strdup("postgres");
1120
0
    if (!conn->pguser)
1121
0
    {
1122
0
      conn->status = CONNECTION_BAD;
1123
0
      return false;
1124
0
    }
1125
316
  }
1126
1127
  /*
1128
   * If database name was not given, default it to equal user name
1129
   */
1130
316
  if (conn->dbName == NULL || conn->dbName[0] == '\0')
1131
0
  {
1132
0
    if (conn->dbName)
1133
0
      free(conn->dbName);
1134
0
    conn->dbName = strdup("yugabyte");
1135
0
    if (!conn->dbName)
1136
0
      goto oom_error;
1137
316
  }
1138
1139
  /*
1140
   * If password was not given, try to look it up in password file.  Note
1141
   * that the result might be different for each host/port pair.
1142
   */
1143
316
  if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
1144
81
  {
1145
    /* If password file wasn't specified, use ~/PGPASSFILE */
1146
81
    if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
1147
78
    {
1148
78
      char    homedir[MAXPGPATH];
1149
1150
78
      if (pqGetHomeDirectory(homedir, sizeof(homedir)))
1151
78
      {
1152
78
        if (conn->pgpassfile)
1153
0
          free(conn->pgpassfile);
1154
78
        conn->pgpassfile = malloc(MAXPGPATH);
1155
78
        if (!conn->pgpassfile)
1156
0
          goto oom_error;
1157
78
        snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s",
1158
78
             homedir, PGPASSFILE);
1159
78
      }
1160
78
    }
1161
1162
81
    if (conn->pgpassfile != NULL && conn->pgpassfile[0] != '\0')
1163
81
    {
1164
162
      for (i = 0; i < conn->nconnhost; i++)
1165
81
      {
1166
        /*
1167
         * Try to get a password for this host from file.  We use host
1168
         * for the hostname search key if given, else hostaddr (at
1169
         * least one of them is guaranteed nonempty by now).
1170
         */
1171
81
        const char *pwhost = conn->connhost[i].host;
1172
1173
81
        if (pwhost == NULL || pwhost[0] == '\0')
1174
0
          pwhost = conn->connhost[i].hostaddr;
1175
1176
81
        conn->connhost[i].password =
1177
81
          passwordFromFile(pwhost,
1178
81
                   conn->connhost[i].port,
1179
81
                   conn->dbName,
1180
81
                   conn->pguser,
1181
81
                   conn->pgpassfile);
1182
81
      }
1183
81
    }
1184
81
  }
1185
1186
  /*
1187
   * validate sslmode option
1188
   */
1189
316
  if (conn->sslmode)
1190
316
  {
1191
316
    if (strcmp(conn->sslmode, "disable") != 0
1192
316
      && strcmp(conn->sslmode, "allow") != 0
1193
316
      && strcmp(conn->sslmode, "prefer") != 0
1194
0
      && strcmp(conn->sslmode, "require") != 0
1195
0
      && strcmp(conn->sslmode, "verify-ca") != 0
1196
0
      && strcmp(conn->sslmode, "verify-full") != 0)
1197
0
    {
1198
0
      conn->status = CONNECTION_BAD;
1199
0
      printfPQExpBuffer(&conn->errorMessage,
1200
0
                libpq_gettext("invalid sslmode value: \"%s\"\n"),
1201
0
                conn->sslmode);
1202
0
      return false;
1203
0
    }
1204
1205
#ifndef USE_SSL
1206
    switch (conn->sslmode[0])
1207
    {
1208
      case 'a':     /* "allow" */
1209
      case 'p':     /* "prefer" */
1210
1211
        /*
1212
         * warn user that an SSL connection will never be negotiated
1213
         * since SSL was not compiled in?
1214
         */
1215
        break;
1216
1217
      case 'r':     /* "require" */
1218
      case 'v':     /* "verify-ca" or "verify-full" */
1219
        conn->status = CONNECTION_BAD;
1220
        printfPQExpBuffer(&conn->errorMessage,
1221
                  libpq_gettext("sslmode value \"%s\" invalid when SSL support is not compiled in\n"),
1222
                  conn->sslmode);
1223
        return false;
1224
    }
1225
#endif
1226
0
  }
1227
0
  else
1228
0
  {
1229
0
    conn->sslmode = strdup(DefaultSSLMode);
1230
0
    if (!conn->sslmode)
1231
0
      goto oom_error;
1232
316
  }
1233
1234
  /*
1235
   * Resolve special "auto" client_encoding from the locale
1236
   */
1237
316
  if (conn->client_encoding_initial &&
1238
15
    strcmp(conn->client_encoding_initial, "auto") == 0)
1239
0
  {
1240
0
    free(conn->client_encoding_initial);
1241
0
    conn->client_encoding_initial = strdup(pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true)));
1242
0
    if (!conn->client_encoding_initial)
1243
0
      goto oom_error;
1244
316
  }
1245
1246
  /*
1247
   * Validate target_session_attrs option.
1248
   */
1249
316
  if (conn->target_session_attrs)
1250
316
  {
1251
316
    if (strcmp(conn->target_session_attrs, "any") != 0
1252
0
      && strcmp(conn->target_session_attrs, "read-write") != 0)
1253
0
    {
1254
0
      conn->status = CONNECTION_BAD;
1255
0
      printfPQExpBuffer(&conn->errorMessage,
1256
0
                libpq_gettext("invalid target_session_attrs value: \"%s\"\n"),
1257
0
                conn->target_session_attrs);
1258
0
      return false;
1259
0
    }
1260
316
  }
1261
1262
  /*
1263
   * Only if we get this far is it appropriate to try to connect. (We need a
1264
   * state flag, rather than just the boolean result of this function, in
1265
   * case someone tries to PQreset() the PGconn.)
1266
   */
1267
316
  conn->options_valid = true;
1268
1269
316
  return true;
1270
1271
0
oom_error:
1272
0
  conn->status = CONNECTION_BAD;
1273
0
  printfPQExpBuffer(&conn->errorMessage,
1274
0
            libpq_gettext("out of memory\n"));
1275
0
  return false;
1276
316
}
1277
1278
/*
1279
 *    PQconndefaults
1280
 *
1281
 * Construct a default connection options array, which identifies all the
1282
 * available options and shows any default values that are available from the
1283
 * environment etc.  On error (eg out of memory), NULL is returned.
1284
 *
1285
 * Using this function, an application may determine all possible options
1286
 * and their current default values.
1287
 *
1288
 * NOTE: as of PostgreSQL 7.0, the returned array is dynamically allocated
1289
 * and should be freed when no longer needed via PQconninfoFree().  (In prior
1290
 * versions, the returned array was static, but that's not thread-safe.)
1291
 * Pre-7.0 applications that use this function will see a small memory leak
1292
 * until they are updated to call PQconninfoFree.
1293
 */
1294
PQconninfoOption *
1295
PQconndefaults(void)
1296
1
{
1297
1
  PQExpBufferData errorBuf;
1298
1
  PQconninfoOption *connOptions;
1299
1300
  /* We don't actually report any errors here, but callees want a buffer */
1301
1
  initPQExpBuffer(&errorBuf);
1302
1
  if (PQExpBufferDataBroken(errorBuf))
1303
0
    return NULL;     /* out of memory already :-( */
1304
1305
1
  connOptions = conninfo_init(&errorBuf);
1306
1
  if (connOptions != NULL)
1307
1
  {
1308
    /* pass NULL errorBuf to ignore errors */
1309
1
    if (!conninfo_add_defaults(connOptions, NULL))
1310
0
    {
1311
0
      PQconninfoFree(connOptions);
1312
0
      connOptions = NULL;
1313
0
    }
1314
1
  }
1315
1316
1
  termPQExpBuffer(&errorBuf);
1317
1
  return connOptions;
1318
1
}
1319
1320
/* ----------------
1321
 *    PQsetdbLogin
1322
 *
1323
 * establishes a connection to a postgres backend through the postmaster
1324
 * at the specified host and port.
1325
 *
1326
 * returns a PGconn* which is needed for all subsequent libpq calls
1327
 *
1328
 * if the status field of the connection returned is CONNECTION_BAD,
1329
 * then only the errorMessage is likely to be useful.
1330
 * ----------------
1331
 */
1332
PGconn *
1333
PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
1334
       const char *pgtty, const char *dbName, const char *login,
1335
       const char *pwd)
1336
0
{
1337
0
  PGconn     *conn;
1338
1339
  /*
1340
   * Allocate memory for the conn structure
1341
   */
1342
0
  conn = makeEmptyPGconn();
1343
0
  if (conn == NULL)
1344
0
    return NULL;
1345
1346
  /*
1347
   * If the dbName parameter contains what looks like a connection string,
1348
   * parse it into conn struct using connectOptions1.
1349
   */
1350
0
  if (dbName && recognized_connection_string(dbName))
1351
0
  {
1352
0
    if (!connectOptions1(conn, dbName))
1353
0
      return conn;
1354
0
  }
1355
0
  else
1356
0
  {
1357
    /*
1358
     * Old-style path: first, parse an empty conninfo string in order to
1359
     * set up the same defaults that PQconnectdb() would use.
1360
     */
1361
0
    if (!connectOptions1(conn, ""))
1362
0
      return conn;
1363
1364
    /* Insert dbName parameter value into struct */
1365
0
    if (dbName && dbName[0] != '\0')
1366
0
    {
1367
0
      if (conn->dbName)
1368
0
        free(conn->dbName);
1369
0
      conn->dbName = strdup(dbName);
1370
0
      if (!conn->dbName)
1371
0
        goto oom_error;
1372
0
    }
1373
0
  }
1374
1375
  /*
1376
   * Insert remaining parameters into struct, overriding defaults (as well
1377
   * as any conflicting data from dbName taken as a conninfo).
1378
   */
1379
0
  if (pghost && pghost[0] != '\0')
1380
0
  {
1381
0
    if (conn->pghost)
1382
0
      free(conn->pghost);
1383
0
    conn->pghost = strdup(pghost);
1384
0
    if (!conn->pghost)
1385
0
      goto oom_error;
1386
0
  }
1387
1388
0
  if (pgport && pgport[0] != '\0')
1389
0
  {
1390
0
    if (conn->pgport)
1391
0
      free(conn->pgport);
1392
0
    conn->pgport = strdup(pgport);
1393
0
    if (!conn->pgport)
1394
0
      goto oom_error;
1395
0
  }
1396
1397
0
  if (pgoptions && pgoptions[0] != '\0')
1398
0
  {
1399
0
    if (conn->pgoptions)
1400
0
      free(conn->pgoptions);
1401
0
    conn->pgoptions = strdup(pgoptions);
1402
0
    if (!conn->pgoptions)
1403
0
      goto oom_error;
1404
0
  }
1405
1406
0
  if (pgtty && pgtty[0] != '\0')
1407
0
  {
1408
0
    if (conn->pgtty)
1409
0
      free(conn->pgtty);
1410
0
    conn->pgtty = strdup(pgtty);
1411
0
    if (!conn->pgtty)
1412
0
      goto oom_error;
1413
0
  }
1414
1415
0
  if (login && login[0] != '\0')
1416
0
  {
1417
0
    if (conn->pguser)
1418
0
      free(conn->pguser);
1419
0
    conn->pguser = strdup(login);
1420
0
    if (!conn->pguser)
1421
0
      goto oom_error;
1422
0
  }
1423
1424
0
  if (pwd && pwd[0] != '\0')
1425
0
  {
1426
0
    if (conn->pgpass)
1427
0
      free(conn->pgpass);
1428
0
    conn->pgpass = strdup(pwd);
1429
0
    if (!conn->pgpass)
1430
0
      goto oom_error;
1431
0
  }
1432
1433
  /*
1434
   * Compute derived options
1435
   */
1436
0
  if (!connectOptions2(conn))
1437
0
    return conn;
1438
1439
  /*
1440
   * Connect to the database
1441
   */
1442
0
  if (connectDBStart(conn))
1443
0
    (void) connectDBComplete(conn);
1444
1445
0
  return conn;
1446
1447
0
oom_error:
1448
0
  conn->status = CONNECTION_BAD;
1449
0
  printfPQExpBuffer(&conn->errorMessage,
1450
0
            libpq_gettext("out of memory\n"));
1451
0
  return conn;
1452
0
}
1453
1454
1455
/* ----------
1456
 * connectNoDelay -
1457
 * Sets the TCP_NODELAY socket option.
1458
 * Returns 1 if successful, 0 if not.
1459
 * ----------
1460
 */
1461
static int
1462
connectNoDelay(PGconn *conn)
1463
81
{
1464
81
#ifdef  TCP_NODELAY
1465
81
  int     on = 1;
1466
1467
81
  if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
1468
81
           (char *) &on,
1469
81
           sizeof(on)) < 0)
1470
0
  {
1471
0
    char    sebuf[256];
1472
1473
0
    appendPQExpBuffer(&conn->errorMessage,
1474
0
              libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
1475
0
              SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1476
0
    return 0;
1477
0
  }
1478
81
#endif
1479
1480
81
  return 1;
1481
81
}
1482
1483
1484
/* ----------
1485
 * connectFailureMessage -
1486
 * create a friendly error message on connection failure.
1487
 * ----------
1488
 */
1489
static void
1490
connectFailureMessage(PGconn *conn, int errorno)
1491
0
{
1492
0
  char    sebuf[256];
1493
1494
0
#ifdef HAVE_UNIX_SOCKETS
1495
0
  if (IS_AF_UNIX(conn->raddr.addr.ss_family))
1496
0
  {
1497
0
    char    service[NI_MAXHOST];
1498
1499
0
    pg_getnameinfo_all(&conn->raddr.addr, conn->raddr.salen,
1500
0
               NULL, 0,
1501
0
               service, sizeof(service),
1502
0
               NI_NUMERICSERV);
1503
0
    appendPQExpBuffer(&conn->errorMessage,
1504
0
              libpq_gettext("could not connect to server: %s\n"
1505
0
                    "\tIs the server running locally and accepting\n"
1506
0
                    "\tconnections on Unix domain socket \"%s\"?\n"),
1507
0
              SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1508
0
              service);
1509
0
  }
1510
0
  else
1511
0
#endif              /* HAVE_UNIX_SOCKETS */
1512
0
  {
1513
0
    char    host_addr[NI_MAXHOST];
1514
0
    const char *displayed_host;
1515
0
    const char *displayed_port;
1516
0
    struct sockaddr_storage *addr = &conn->raddr.addr;
1517
1518
    /*
1519
     * Optionally display the network address with the hostname. This is
1520
     * useful to distinguish between IPv4 and IPv6 connections.
1521
     */
1522
0
    if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
1523
0
      strlcpy(host_addr, conn->connhost[conn->whichhost].hostaddr, NI_MAXHOST);
1524
0
    else if (addr->ss_family == AF_INET)
1525
0
    {
1526
0
      if (inet_net_ntop(AF_INET,
1527
0
                &((struct sockaddr_in *) addr)->sin_addr.s_addr,
1528
0
                32,
1529
0
                host_addr, sizeof(host_addr)) == NULL)
1530
0
        strcpy(host_addr, "???");
1531
0
    }
1532
0
#ifdef HAVE_IPV6
1533
0
    else if (addr->ss_family == AF_INET6)
1534
0
    {
1535
0
      if (inet_net_ntop(AF_INET6,
1536
0
                &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
1537
0
                128,
1538
0
                host_addr, sizeof(host_addr)) == NULL)
1539
0
        strcpy(host_addr, "???");
1540
0
    }
1541
0
#endif
1542
0
    else
1543
0
      strcpy(host_addr, "???");
1544
1545
    /* To which host and port were we actually connecting? */
1546
0
    if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
1547
0
      displayed_host = conn->connhost[conn->whichhost].hostaddr;
1548
0
    else
1549
0
      displayed_host = conn->connhost[conn->whichhost].host;
1550
0
    displayed_port = conn->connhost[conn->whichhost].port;
1551
0
    if (displayed_port == NULL || displayed_port[0] == '\0')
1552
      /* Use YugaByte default port */
1553
0
      displayed_port = DEF_YBPORT_STR;
1554
1555
    /*
1556
     * If the user did not supply an IP address using 'hostaddr', and
1557
     * 'host' was missing or does not match our lookup, display the
1558
     * looked-up IP address.
1559
     */
1560
0
    if (conn->connhost[conn->whichhost].type != CHT_HOST_ADDRESS &&
1561
0
      strcmp(displayed_host, host_addr) != 0)
1562
0
      appendPQExpBuffer(&conn->errorMessage,
1563
0
                libpq_gettext("could not connect to server: %s\n"
1564
0
                      "\tIs the server running on host \"%s\" (%s) and accepting\n"
1565
0
                      "\tTCP/IP connections on port %s?\n"),
1566
0
                SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1567
0
                displayed_host,
1568
0
                host_addr,
1569
0
                displayed_port);
1570
0
    else
1571
0
      appendPQExpBuffer(&conn->errorMessage,
1572
0
                libpq_gettext("could not connect to server: %s\n"
1573
0
                      "\tIs the server running on host \"%s\" and accepting\n"
1574
0
                      "\tTCP/IP connections on port %s?\n"),
1575
0
                SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
1576
0
                displayed_host,
1577
0
                displayed_port);
1578
0
  }
1579
0
}
1580
1581
/*
1582
 * Should we use keepalives?  Returns 1 if yes, 0 if no, and -1 if
1583
 * conn->keepalives is set to a value which is not parseable as an
1584
 * integer.
1585
 */
1586
static int
1587
useKeepalives(PGconn *conn)
1588
81
{
1589
81
  char     *ep;
1590
81
  int     val;
1591
1592
81
  if (conn->keepalives == NULL)
1593
81
    return 1;
1594
0
  val = strtol(conn->keepalives, &ep, 10);
1595
0
  if (*ep)
1596
0
    return -1;
1597
0
  return val != 0 ? 1 : 0;
1598
0
}
1599
1600
#ifndef WIN32
1601
/*
1602
 * Set the keepalive idle timer.
1603
 */
1604
static int
1605
setKeepalivesIdle(PGconn *conn)
1606
81
{
1607
81
  int     idle;
1608
1609
81
  if (conn->keepalives_idle == NULL)
1610
81
    return 1;
1611
1612
0
  idle = atoi(conn->keepalives_idle);
1613
0
  if (idle < 0)
1614
0
    idle = 0;
1615
1616
0
#ifdef PG_TCP_KEEPALIVE_IDLE
1617
0
  if (setsockopt(conn->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
1618
0
           (char *) &idle, sizeof(idle)) < 0)
1619
0
  {
1620
0
    char    sebuf[256];
1621
1622
0
    appendPQExpBuffer(&conn->errorMessage,
1623
0
              libpq_gettext("setsockopt(%s) failed: %s\n"),
1624
0
              PG_TCP_KEEPALIVE_IDLE_STR,
1625
0
              SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1626
0
    return 0;
1627
0
  }
1628
0
#endif
1629
1630
0
  return 1;
1631
0
}
1632
1633
/*
1634
 * Set the keepalive interval.
1635
 */
1636
static int
1637
setKeepalivesInterval(PGconn *conn)
1638
81
{
1639
81
  int     interval;
1640
1641
81
  if (conn->keepalives_interval == NULL)
1642
81
    return 1;
1643
1644
0
  interval = atoi(conn->keepalives_interval);
1645
0
  if (interval < 0)
1646
0
    interval = 0;
1647
1648
0
#ifdef TCP_KEEPINTVL
1649
0
  if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPINTVL,
1650
0
           (char *) &interval, sizeof(interval)) < 0)
1651
0
  {
1652
0
    char    sebuf[256];
1653
1654
0
    appendPQExpBuffer(&conn->errorMessage,
1655
0
              libpq_gettext("setsockopt(%s) failed: %s\n"),
1656
0
              "TCP_KEEPINTVL",
1657
0
              SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1658
0
    return 0;
1659
0
  }
1660
0
#endif
1661
1662
0
  return 1;
1663
0
}
1664
1665
/*
1666
 * Set the count of lost keepalive packets that will trigger a connection
1667
 * break.
1668
 */
1669
static int
1670
setKeepalivesCount(PGconn *conn)
1671
81
{
1672
81
  int     count;
1673
1674
81
  if (conn->keepalives_count == NULL)
1675
81
    return 1;
1676
1677
0
  count = atoi(conn->keepalives_count);
1678
0
  if (count < 0)
1679
0
    count = 0;
1680
1681
0
#ifdef TCP_KEEPCNT
1682
0
  if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPCNT,
1683
0
           (char *) &count, sizeof(count)) < 0)
1684
0
  {
1685
0
    char    sebuf[256];
1686
1687
0
    appendPQExpBuffer(&conn->errorMessage,
1688
0
              libpq_gettext("setsockopt(%s) failed: %s\n"),
1689
0
              "TCP_KEEPCNT",
1690
0
              SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1691
0
    return 0;
1692
0
  }
1693
0
#endif
1694
1695
0
  return 1;
1696
0
}
1697
#else             /* WIN32 */
1698
#ifdef SIO_KEEPALIVE_VALS
1699
/*
1700
 * Enable keepalives and set the keepalive values on Win32,
1701
 * where they are always set in one batch.
1702
 */
1703
static int
1704
setKeepalivesWin32(PGconn *conn)
1705
{
1706
  struct tcp_keepalive ka;
1707
  DWORD   retsize;
1708
  int     idle = 0;
1709
  int     interval = 0;
1710
1711
  if (conn->keepalives_idle)
1712
    idle = atoi(conn->keepalives_idle);
1713
  if (idle <= 0)
1714
    idle = 2 * 60 * 60;   /* 2 hours = default */
1715
1716
  if (conn->keepalives_interval)
1717
    interval = atoi(conn->keepalives_interval);
1718
  if (interval <= 0)
1719
    interval = 1;     /* 1 second = default */
1720
1721
  ka.onoff = 1;
1722
  ka.keepalivetime = idle * 1000;
1723
  ka.keepaliveinterval = interval * 1000;
1724
1725
  if (WSAIoctl(conn->sock,
1726
         SIO_KEEPALIVE_VALS,
1727
         (LPVOID) &ka,
1728
         sizeof(ka),
1729
         NULL,
1730
         0,
1731
         &retsize,
1732
         NULL,
1733
         NULL)
1734
    != 0)
1735
  {
1736
    appendPQExpBuffer(&conn->errorMessage,
1737
              libpq_gettext("WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n"),
1738
              WSAGetLastError());
1739
    return 0;
1740
  }
1741
  return 1;
1742
}
1743
#endif              /* SIO_KEEPALIVE_VALS */
1744
#endif              /* WIN32 */
1745
1746
/* ----------
1747
 * connectDBStart -
1748
 *    Begin the process of making a connection to the backend.
1749
 *
1750
 * Returns 1 if successful, 0 if not.
1751
 * ----------
1752
 */
1753
static int
1754
connectDBStart(PGconn *conn)
1755
316
{
1756
316
  if (!conn)
1757
0
    return 0;
1758
1759
316
  if (!conn->options_valid)
1760
0
    goto connect_errReturn;
1761
1762
  /* Ensure our buffers are empty */
1763
316
  conn->inStart = conn->inCursor = conn->inEnd = 0;
1764
316
  conn->outCount = 0;
1765
1766
  /*
1767
   * Ensure errorMessage is empty, too.  PQconnectPoll will append messages
1768
   * to it in the process of scanning for a working server.  Thus, if we
1769
   * fail to connect to multiple hosts, the final error message will include
1770
   * details about each failure.
1771
   */
1772
316
  resetPQExpBuffer(&conn->errorMessage);
1773
1774
  /*
1775
   * Set up to try to connect to the first host.  (Setting whichhost = -1 is
1776
   * a bit of a cheat, but PQconnectPoll will advance it to 0 before
1777
   * anything else looks at it.)
1778
   */
1779
316
  conn->whichhost = -1;
1780
316
  conn->try_next_addr = false;
1781
316
  conn->try_next_host = true;
1782
316
  conn->status = CONNECTION_NEEDED;
1783
1784
  /*
1785
   * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
1786
   * so that it can easily be re-executed if needed again during the
1787
   * asynchronous startup process.  However, we must run it once here,
1788
   * because callers expect a success return from this routine to mean that
1789
   * we are in PGRES_POLLING_WRITING connection state.
1790
   */
1791
316
  if (PQconnectPoll(conn) == PGRES_POLLING_WRITING)
1792
316
    return 1;
1793
1794
0
connect_errReturn:
1795
1796
  /*
1797
   * If we managed to open a socket, close it immediately rather than
1798
   * waiting till PQfinish.  (The application cannot have gotten the socket
1799
   * from PQsocket yet, so this doesn't risk breaking anything.)
1800
   */
1801
0
  pqDropConnection(conn, true);
1802
0
  conn->status = CONNECTION_BAD;
1803
0
  return 0;
1804
316
}
1805
1806
1807
/*
1808
 *    connectDBComplete
1809
 *
1810
 * Block and complete a connection.
1811
 *
1812
 * Returns 1 on success, 0 on failure.
1813
 */
1814
static int
1815
connectDBComplete(PGconn *conn)
1816
316
{
1817
316
  PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
1818
316
  time_t    finish_time = ((time_t) -1);
1819
316
  int     timeout = 0;
1820
316
  int     last_whichhost = -2;  /* certainly different from whichhost */
1821
316
  struct addrinfo *last_addr_cur = NULL;
1822
1823
316
  if (conn == NULL || conn->status == CONNECTION_BAD)
1824
0
    return 0;
1825
1826
  /*
1827
   * Set up a time limit, if connect_timeout isn't zero.
1828
   */
1829
316
  if (conn->connect_timeout != NULL)
1830
0
  {
1831
0
    timeout = atoi(conn->connect_timeout);
1832
0
    if (timeout > 0)
1833
0
    {
1834
      /*
1835
       * Rounding could cause connection to fail unexpectedly quickly;
1836
       * to prevent possibly waiting hardly-at-all, insist on at least
1837
       * two seconds.
1838
       */
1839
0
      if (timeout < 2)
1840
0
        timeout = 2;
1841
0
    }
1842
0
  }
1843
1844
316
  for (;;)
1845
1.42k
  {
1846
1.42k
    int     ret = 0;
1847
1848
    /*
1849
     * (Re)start the connect_timeout timer if it's active and we are
1850
     * considering a different host than we were last time through.  If
1851
     * we've already succeeded, though, needn't recalculate.
1852
     */
1853
1.42k
    if (flag != PGRES_POLLING_OK &&
1854
1.11k
      timeout > 0 &&
1855
0
      (conn->whichhost != last_whichhost ||
1856
0
       conn->addr_cur != last_addr_cur))
1857
0
    {
1858
0
      finish_time = time(NULL) + timeout;
1859
0
      last_whichhost = conn->whichhost;
1860
0
      last_addr_cur = conn->addr_cur;
1861
0
    }
1862
1863
    /*
1864
     * Wait, if necessary.  Note that the initial state (just after
1865
     * PQconnectStart) is to wait for the socket to select for writing.
1866
     */
1867
1.42k
    switch (flag)
1868
1.42k
    {
1869
313
      case PGRES_POLLING_OK:
1870
1871
        /*
1872
         * Reset stored error messages since we now have a working
1873
         * connection
1874
         */
1875
313
        resetPQExpBuffer(&conn->errorMessage);
1876
313
        return 1;   /* success! */
1877
1878
632
      case PGRES_POLLING_READING:
1879
632
        ret = pqWaitTimed(1, 0, conn, finish_time);
1880
632
        if (ret == -1)
1881
0
        {
1882
          /* hard failure, eg select() problem, aborts everything */
1883
0
          conn->status = CONNECTION_BAD;
1884
0
          return 0;
1885
0
        }
1886
632
        break;
1887
1888
478
      case PGRES_POLLING_WRITING:
1889
478
        ret = pqWaitTimed(0, 1, conn, finish_time);
1890
478
        if (ret == -1)
1891
0
        {
1892
          /* hard failure, eg select() problem, aborts everything */
1893
0
          conn->status = CONNECTION_BAD;
1894
0
          return 0;
1895
0
        }
1896
478
        break;
1897
1898
3
      default:
1899
        /* Just in case we failed to set it in PQconnectPoll */
1900
3
        conn->status = CONNECTION_BAD;
1901
3
        return 0;
1902
1.11k
    }
1903
1904
1.11k
    if (ret == 1)      /* connect_timeout elapsed */
1905
0
    {
1906
      /*
1907
       * Give up on current server/address, try the next one.
1908
       */
1909
0
      conn->try_next_addr = true;
1910
0
      conn->status = CONNECTION_NEEDED;
1911
0
    }
1912
1913
    /*
1914
     * Now try to advance the state machine.
1915
     */
1916
1.11k
    flag = PQconnectPoll(conn);
1917
1.11k
  }
1918
316
}
1919
1920
/*
1921
 * This subroutine saves conn->errorMessage, which will be restored back by
1922
 * restoreErrorMessage subroutine.  Returns false on OOM failure.
1923
 */
1924
static bool
1925
saveErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
1926
0
{
1927
0
  initPQExpBuffer(savedMessage);
1928
0
  appendPQExpBufferStr(savedMessage,
1929
0
             conn->errorMessage.data);
1930
0
  if (PQExpBufferBroken(savedMessage))
1931
0
  {
1932
0
    printfPQExpBuffer(&conn->errorMessage,
1933
0
              libpq_gettext("out of memory\n"));
1934
0
    return false;
1935
0
  }
1936
  /* Clear whatever is in errorMessage now */
1937
0
  resetPQExpBuffer(&conn->errorMessage);
1938
0
  return true;
1939
0
}
1940
1941
/*
1942
 * Restores saved error messages back to conn->errorMessage, prepending them
1943
 * to whatever is in conn->errorMessage already.  (This does the right thing
1944
 * if anything's been added to conn->errorMessage since saveErrorMessage.)
1945
 */
1946
static void
1947
restoreErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
1948
0
{
1949
0
  appendPQExpBufferStr(savedMessage, conn->errorMessage.data);
1950
0
  resetPQExpBuffer(&conn->errorMessage);
1951
0
  appendPQExpBufferStr(&conn->errorMessage, savedMessage->data);
1952
  /* If any step above hit OOM, just report that */
1953
0
  if (PQExpBufferBroken(savedMessage) ||
1954
0
    PQExpBufferBroken(&conn->errorMessage))
1955
0
    printfPQExpBuffer(&conn->errorMessage,
1956
0
              libpq_gettext("out of memory\n"));
1957
0
  termPQExpBuffer(savedMessage);
1958
0
}
1959
1960
/* ----------------
1961
 *    PQconnectPoll
1962
 *
1963
 * Poll an asynchronous connection.
1964
 *
1965
 * Returns a PostgresPollingStatusType.
1966
 * Before calling this function, use select(2) to determine when data
1967
 * has arrived..
1968
 *
1969
 * You must call PQfinish whether or not this fails.
1970
 *
1971
 * This function and PQconnectStart are intended to allow connections to be
1972
 * made without blocking the execution of your program on remote I/O. However,
1973
 * there are a number of caveats:
1974
 *
1975
 *   o  If you call PQtrace, ensure that the stream object into which you trace
1976
 *    will not block.
1977
 *   o  If you do not supply an IP address for the remote host (i.e. you
1978
 *    supply a host name instead) then PQconnectStart will block on
1979
 *    gethostbyname.  You will be fine if using Unix sockets (i.e. by
1980
 *    supplying neither a host name nor a host address).
1981
 *   o  If your backend wants to use Kerberos authentication then you must
1982
 *    supply both a host name and a host address, otherwise this function
1983
 *    may block on gethostname.
1984
 *
1985
 * ----------------
1986
 */
1987
PostgresPollingStatusType
1988
PQconnectPoll(PGconn *conn)
1989
1.42k
{
1990
1.42k
  bool    reset_connection_state_machine = false;
1991
1.42k
  bool    need_new_connection = false;
1992
1.42k
  PGresult   *res;
1993
1.42k
  char    sebuf[256];
1994
1.42k
  int     optval;
1995
1.42k
  PQExpBufferData savedMessage;
1996
1997
1.42k
  if (conn == NULL)
1998
0
    return PGRES_POLLING_FAILED;
1999
2000
  /* Get the new data */
2001
1.42k
  switch (conn->status)
2002
1.42k
  {
2003
      /*
2004
       * We really shouldn't have been polled in these two cases, but we
2005
       * can handle it.
2006
       */
2007
0
    case CONNECTION_BAD:
2008
0
      return PGRES_POLLING_FAILED;
2009
0
    case CONNECTION_OK:
2010
0
      return PGRES_POLLING_OK;
2011
2012
      /* These are reading states */
2013
551
    case CONNECTION_AWAITING_RESPONSE:
2014
551
    case CONNECTION_AUTH_OK:
2015
551
      {
2016
        /* Load waiting data */
2017
551
        int     n = pqReadData(conn);
2018
2019
551
        if (n < 0)
2020
0
          goto error_return;
2021
551
        if (n == 0)
2022
0
          return PGRES_POLLING_READING;
2023
2024
551
        break;
2025
551
      }
2026
2027
      /* These are writing states, so we just proceed. */
2028
81
    case CONNECTION_STARTED:
2029
478
    case CONNECTION_MADE:
2030
478
      break;
2031
2032
      /* We allow pqSetenvPoll to decide whether to proceed. */
2033
0
    case CONNECTION_SETENV:
2034
0
      break;
2035
2036
      /* Special cases: proceed without waiting. */
2037
81
    case CONNECTION_SSL_STARTUP:
2038
397
    case CONNECTION_NEEDED:
2039
397
    case CONNECTION_CHECK_WRITABLE:
2040
397
    case CONNECTION_CONSUME:
2041
397
      break;
2042
2043
0
    default:
2044
0
      appendPQExpBufferStr(&conn->errorMessage,
2045
0
                 libpq_gettext(
2046
0
                         "invalid connection state, "
2047
0
                         "probably indicative of memory corruption\n"
2048
0
                         ));
2049
0
      goto error_return;
2050
2.21k
  }
2051
2052
2053
2.21k
keep_going:           /* We will come back to here until there is
2054
                 * nothing left to do. */
2055
2056
  /* Time to advance to next address, or next host if no more addresses? */
2057
2.21k
  if (conn->try_next_addr)
2058
0
  {
2059
0
    if (conn->addr_cur && conn->addr_cur->ai_next)
2060
0
    {
2061
0
      conn->addr_cur = conn->addr_cur->ai_next;
2062
0
      reset_connection_state_machine = true;
2063
0
    }
2064
0
    else
2065
0
      conn->try_next_host = true;
2066
0
    conn->try_next_addr = false;
2067
0
  }
2068
2069
  /* Time to advance to next connhost[] entry? */
2070
2.21k
  if (conn->try_next_host)
2071
316
  {
2072
316
    pg_conn_host *ch;
2073
316
    struct addrinfo hint;
2074
316
    int     thisport;
2075
316
    int     ret;
2076
316
    char    portstr[MAXPGPATH];
2077
2078
316
    if (conn->whichhost + 1 >= conn->nconnhost)
2079
0
    {
2080
      /*
2081
       * Oops, no more hosts.  An appropriate error message is already
2082
       * set up, so just set the right status.
2083
       */
2084
0
      goto error_return;
2085
0
    }
2086
316
    conn->whichhost++;
2087
2088
    /* Drop any address info for previous host */
2089
316
    release_conn_addrinfo(conn);
2090
2091
    /*
2092
     * Look up info for the new host.  On failure, log the problem in
2093
     * conn->errorMessage, then loop around to try the next host.  (Note
2094
     * we don't clear try_next_host until we've succeeded.)
2095
     */
2096
316
    ch = &conn->connhost[conn->whichhost];
2097
2098
    /* Initialize hint structure */
2099
316
    MemSet(&hint, 0, sizeof(hint));
2100
316
    hint.ai_socktype = SOCK_STREAM;
2101
316
    conn->addrlist_family = hint.ai_family = AF_UNSPEC;
2102
2103
    /* Figure out the port number we're going to use. */
2104
316
    if (ch->port == NULL || ch->port[0] == '\0')
2105
      /* Use YugaByte default port */
2106
0
      thisport = DEF_YBPORT;
2107
316
    else
2108
316
    {
2109
316
      thisport = atoi(ch->port);
2110
316
      if (thisport < 1 || thisport > 65535)
2111
0
      {
2112
0
        appendPQExpBuffer(&conn->errorMessage,
2113
0
                  libpq_gettext("invalid port number: \"%s\"\n"),
2114
0
                  ch->port);
2115
0
        goto keep_going;
2116
0
      }
2117
316
    }
2118
316
    snprintf(portstr, sizeof(portstr), "%d", thisport);
2119
2120
    /* Use pg_getaddrinfo_all() to resolve the address */
2121
316
    switch (ch->type)
2122
316
    {
2123
81
      case CHT_HOST_NAME:
2124
81
        ret = pg_getaddrinfo_all(ch->host, portstr, &hint,
2125
81
                     &conn->addrlist);
2126
81
        if (ret || !conn->addrlist)
2127
0
        {
2128
0
          appendPQExpBuffer(&conn->errorMessage,
2129
0
                    libpq_gettext("could not translate host name \"%s\" to address: %s\n"),
2130
0
                    ch->host, gai_strerror(ret));
2131
0
          goto keep_going;
2132
0
        }
2133
81
        break;
2134
2135
0
      case CHT_HOST_ADDRESS:
2136
0
        hint.ai_flags = AI_NUMERICHOST;
2137
0
        ret = pg_getaddrinfo_all(ch->hostaddr, portstr, &hint,
2138
0
                     &conn->addrlist);
2139
0
        if (ret || !conn->addrlist)
2140
0
        {
2141
0
          appendPQExpBuffer(&conn->errorMessage,
2142
0
                    libpq_gettext("could not parse network address \"%s\": %s\n"),
2143
0
                    ch->hostaddr, gai_strerror(ret));
2144
0
          goto keep_going;
2145
0
        }
2146
0
        break;
2147
2148
235
      case CHT_UNIX_SOCKET:
2149
235
#ifdef HAVE_UNIX_SOCKETS
2150
235
        conn->addrlist_family = hint.ai_family = AF_UNIX;
2151
235
        UNIXSOCK_PATH(portstr, thisport, ch->host);
2152
235
        if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
2153
0
        {
2154
0
          appendPQExpBuffer(&conn->errorMessage,
2155
0
                    libpq_gettext("Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n"),
2156
0
                    portstr,
2157
0
                    (int) (UNIXSOCK_PATH_BUFLEN - 1));
2158
0
          goto keep_going;
2159
0
        }
2160
2161
        /*
2162
         * NULL hostname tells pg_getaddrinfo_all to parse the service
2163
         * name as a Unix-domain socket path.
2164
         */
2165
235
        ret = pg_getaddrinfo_all(NULL, portstr, &hint,
2166
235
                     &conn->addrlist);
2167
235
        if (ret || !conn->addrlist)
2168
0
        {
2169
0
          appendPQExpBuffer(&conn->errorMessage,
2170
0
                    libpq_gettext("could not translate Unix-domain socket path \"%s\" to address: %s\n"),
2171
0
                    portstr, gai_strerror(ret));
2172
0
          goto keep_going;
2173
0
        }
2174
#else
2175
        Assert(false);
2176
#endif
2177
235
        break;
2178
316
    }
2179
2180
    /* OK, scan this addrlist for a working server address */
2181
316
    conn->addr_cur = conn->addrlist;
2182
316
    reset_connection_state_machine = true;
2183
316
    conn->try_next_host = false;
2184
316
  }
2185
2186
  /* Reset connection state machine? */
2187
2.21k
  if (reset_connection_state_machine)
2188
316
  {
2189
    /*
2190
     * (Re) initialize our connection control variables for a set of
2191
     * connection attempts to a single server address.  These variables
2192
     * must persist across individual connection attempts, but we must
2193
     * reset them when we start to consider a new server.
2194
     */
2195
316
    conn->pversion = PG_PROTOCOL(3, 0);
2196
316
    conn->send_appname = true;
2197
316
#ifdef USE_SSL
2198
    /* initialize these values based on SSL mode */
2199
316
    conn->allow_ssl_try = (conn->sslmode[0] != 'd');  /* "disable" */
2200
316
    conn->wait_ssl_try = (conn->sslmode[0] == 'a'); /* "allow" */
2201
316
#endif
2202
2203
316
    reset_connection_state_machine = false;
2204
316
    need_new_connection = true;
2205
316
  }
2206
2207
  /* Force a new connection (perhaps to the same server as before)? */
2208
2.21k
  if (need_new_connection)
2209
316
  {
2210
    /* Drop any existing connection */
2211
316
    pqDropConnection(conn, true);
2212
2213
    /* Reset all state obtained from old server */
2214
316
    pqDropServerData(conn);
2215
2216
    /* Drop any PGresult we might have, too */
2217
316
    conn->asyncStatus = PGASYNC_IDLE;
2218
316
    conn->xactStatus = PQTRANS_IDLE;
2219
316
    pqClearAsyncResult(conn);
2220
2221
    /* Reset conn->status to put the state machine in the right state */
2222
316
    conn->status = CONNECTION_NEEDED;
2223
2224
316
    need_new_connection = false;
2225
316
  }
2226
2227
  /* Now try to advance the state machine for this connection */
2228
2.21k
  switch (conn->status)
2229
2.21k
  {
2230
316
    case CONNECTION_NEEDED:
2231
316
      {
2232
        /*
2233
         * Try to initiate a connection to one of the addresses
2234
         * returned by pg_getaddrinfo_all().  conn->addr_cur is the
2235
         * next one to try.
2236
         *
2237
         * The extra level of braces here is historical.  It's not
2238
         * worth reindenting this whole switch case to remove 'em.
2239
         */
2240
316
        {
2241
316
          struct addrinfo *addr_cur = conn->addr_cur;
2242
2243
          /*
2244
           * Advance to next possible host, if we've tried all of
2245
           * the addresses for the current host.
2246
           */
2247
316
          if (addr_cur == NULL)
2248
0
          {
2249
0
            conn->try_next_host = true;
2250
0
            goto keep_going;
2251
0
          }
2252
2253
          /* Remember current address for possible error msg */
2254
316
          memcpy(&conn->raddr.addr, addr_cur->ai_addr,
2255
316
               addr_cur->ai_addrlen);
2256
316
          conn->raddr.salen = addr_cur->ai_addrlen;
2257
2258
316
          conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
2259
316
          if (conn->sock == PGINVALID_SOCKET)
2260
0
          {
2261
            /*
2262
             * Silently ignore socket() failure if we have more
2263
             * addresses to try; this reduces useless chatter in
2264
             * cases where the address list includes both IPv4 and
2265
             * IPv6 but kernel only accepts one family.
2266
             */
2267
0
            if (addr_cur->ai_next != NULL ||
2268
0
              conn->whichhost + 1 < conn->nconnhost)
2269
0
            {
2270
0
              conn->try_next_addr = true;
2271
0
              goto keep_going;
2272
0
            }
2273
0
            appendPQExpBuffer(&conn->errorMessage,
2274
0
                      libpq_gettext("could not create socket: %s\n"),
2275
0
                      SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2276
0
            goto error_return;
2277
0
          }
2278
2279
          /*
2280
           * Select socket options: no delay of outgoing data for
2281
           * TCP sockets, nonblock mode, close-on-exec.  Try the
2282
           * next address if any of this fails.
2283
           */
2284
316
          if (!IS_AF_UNIX(addr_cur->ai_family))
2285
81
          {
2286
81
            if (!connectNoDelay(conn))
2287
0
            {
2288
              /* error message already created */
2289
0
              conn->try_next_addr = true;
2290
0
              goto keep_going;
2291
0
            }
2292
316
          }
2293
316
          if (!pg_set_noblock(conn->sock))
2294
0
          {
2295
0
            appendPQExpBuffer(&conn->errorMessage,
2296
0
                      libpq_gettext("could not set socket to nonblocking mode: %s\n"),
2297
0
                      SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2298
0
            conn->try_next_addr = true;
2299
0
            goto keep_going;
2300
0
          }
2301
2302
316
#ifdef F_SETFD
2303
316
          if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
2304
0
          {
2305
0
            appendPQExpBuffer(&conn->errorMessage,
2306
0
                      libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
2307
0
                      SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2308
0
            conn->try_next_addr = true;
2309
0
            goto keep_going;
2310
0
          }
2311
316
#endif              /* F_SETFD */
2312
2313
316
          if (!IS_AF_UNIX(addr_cur->ai_family))
2314
81
          {
2315
81
#ifndef WIN32
2316
81
            int     on = 1;
2317
81
#endif
2318
81
            int     usekeepalives = useKeepalives(conn);
2319
81
            int     err = 0;
2320
2321
81
            if (usekeepalives < 0)
2322
0
            {
2323
0
              appendPQExpBufferStr(&conn->errorMessage,
2324
0
                         libpq_gettext("keepalives parameter must be an integer\n"));
2325
0
              err = 1;
2326
0
            }
2327
81
            else if (usekeepalives == 0)
2328
0
            {
2329
              /* Do nothing */
2330
0
            }
2331
81
#ifndef WIN32
2332
81
            else if (setsockopt(conn->sock,
2333
81
                      SOL_SOCKET, SO_KEEPALIVE,
2334
81
                      (char *) &on, sizeof(on)) < 0)
2335
0
            {
2336
0
              appendPQExpBuffer(&conn->errorMessage,
2337
0
                        libpq_gettext("setsockopt(%s) failed: %s\n"),
2338
0
                        "SO_KEEPALIVE",
2339
0
                        SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2340
0
              err = 1;
2341
0
            }
2342
81
            else if (!setKeepalivesIdle(conn)
2343
81
                 || !setKeepalivesInterval(conn)
2344
81
                 || !setKeepalivesCount(conn))
2345
0
              err = 1;
2346
#else             /* WIN32 */
2347
#ifdef SIO_KEEPALIVE_VALS
2348
            else if (!setKeepalivesWin32(conn))
2349
              err = 1;
2350
#endif              /* SIO_KEEPALIVE_VALS */
2351
#endif              /* WIN32 */
2352
2353
81
            if (err)
2354
0
            {
2355
0
              conn->try_next_addr = true;
2356
0
              goto keep_going;
2357
0
            }
2358
316
          }
2359
2360
          /*----------
2361
           * We have three methods of blocking SIGPIPE during
2362
           * send() calls to this socket:
2363
           *
2364
           *  - setsockopt(sock, SO_NOSIGPIPE)
2365
           *  - send(sock, ..., MSG_NOSIGNAL)
2366
           *  - setting the signal mask to SIG_IGN during send()
2367
           *
2368
           * The third method requires three syscalls per send,
2369
           * so we prefer either of the first two, but they are
2370
           * less portable.  The state is tracked in the following
2371
           * members of PGconn:
2372
           *
2373
           * conn->sigpipe_so   - we have set up SO_NOSIGPIPE
2374
           * conn->sigpipe_flag - we're specifying MSG_NOSIGNAL
2375
           *
2376
           * If we can use SO_NOSIGPIPE, then set sigpipe_so here
2377
           * and we're done.  Otherwise, set sigpipe_flag so that
2378
           * we will try MSG_NOSIGNAL on sends.  If we get an error
2379
           * with MSG_NOSIGNAL, we'll clear that flag and revert to
2380
           * signal masking.
2381
           *----------
2382
           */
2383
316
          conn->sigpipe_so = false;
2384
316
#ifdef MSG_NOSIGNAL
2385
316
          conn->sigpipe_flag = true;
2386
#else
2387
          conn->sigpipe_flag = false;
2388
#endif              /* MSG_NOSIGNAL */
2389
2390
316
#ifdef SO_NOSIGPIPE
2391
316
          optval = 1;
2392
316
          if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
2393
316
                   (char *) &optval, sizeof(optval)) == 0)
2394
316
          {
2395
316
            conn->sigpipe_so = true;
2396
316
            conn->sigpipe_flag = false;
2397
316
          }
2398
316
#endif              /* SO_NOSIGPIPE */
2399
2400
          /*
2401
           * Start/make connection.  This should not block, since we
2402
           * are in nonblock mode.  If it does, well, too bad.
2403
           */
2404
316
          if (connect(conn->sock, addr_cur->ai_addr,
2405
316
                addr_cur->ai_addrlen) < 0)
2406
81
          {
2407
81
            if (SOCK_ERRNO == EINPROGRESS ||
2408
#ifdef WIN32
2409
              SOCK_ERRNO == EWOULDBLOCK ||
2410
#endif
2411
0
              SOCK_ERRNO == EINTR)
2412
81
            {
2413
              /*
2414
               * This is fine - we're in non-blocking mode, and
2415
               * the connection is in progress.  Tell caller to
2416
               * wait for write-ready on socket.
2417
               */
2418
81
              conn->status = CONNECTION_STARTED;
2419
81
              return PGRES_POLLING_WRITING;
2420
81
            }
2421
            /* otherwise, trouble */
2422
235
          }
2423
235
          else
2424
235
          {
2425
            /*
2426
             * Hm, we're connected already --- seems the "nonblock
2427
             * connection" wasn't.  Advance the state machine and
2428
             * go do the next stuff.
2429
             */
2430
235
            conn->status = CONNECTION_STARTED;
2431
235
            goto keep_going;
2432
235
          }
2433
2434
          /*
2435
           * This connection failed.  Add the error report to
2436
           * conn->errorMessage, then try the next address if any.
2437
           */
2438
0
          connectFailureMessage(conn, SOCK_ERRNO);
2439
0
          conn->try_next_addr = true;
2440
0
          goto keep_going;
2441
0
        }
2442
0
      }
2443
2444
316
    case CONNECTION_STARTED:
2445
316
      {
2446
316
        ACCEPT_TYPE_ARG3 optlen = sizeof(optval);
2447
2448
        /*
2449
         * Write ready, since we've made it here, so the connection
2450
         * has been made ... or has failed.
2451
         */
2452
2453
        /*
2454
         * Now check (using getsockopt) that there is not an error
2455
         * state waiting for us on the socket.
2456
         */
2457
2458
316
        if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
2459
316
                 (char *) &optval, &optlen) == -1)
2460
0
        {
2461
0
          appendPQExpBuffer(&conn->errorMessage,
2462
0
                    libpq_gettext("could not get socket error status: %s\n"),
2463
0
                    SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2464
0
          goto error_return;
2465
0
        }
2466
316
        else if (optval != 0)
2467
0
        {
2468
          /*
2469
           * When using a nonblocking connect, we will typically see
2470
           * connect failures at this point, so provide a friendly
2471
           * error message.
2472
           */
2473
0
          connectFailureMessage(conn, optval);
2474
2475
          /*
2476
           * Try the next address if any, just as in the case where
2477
           * connect() returned failure immediately.
2478
           */
2479
0
          conn->try_next_addr = true;
2480
0
          goto keep_going;
2481
0
        }
2482
2483
        /* Fill in the client address */
2484
316
        conn->laddr.salen = sizeof(conn->laddr.addr);
2485
316
        if (getsockname(conn->sock,
2486
316
                (struct sockaddr *) &conn->laddr.addr,
2487
316
                &conn->laddr.salen) < 0)
2488
0
        {
2489
0
          appendPQExpBuffer(&conn->errorMessage,
2490
0
                    libpq_gettext("could not get client address from socket: %s\n"),
2491
0
                    SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2492
0
          goto error_return;
2493
0
        }
2494
2495
        /*
2496
         * Make sure we can write before advancing to next step.
2497
         */
2498
316
        conn->status = CONNECTION_MADE;
2499
316
        return PGRES_POLLING_WRITING;
2500
316
      }
2501
2502
397
    case CONNECTION_MADE:
2503
397
      {
2504
397
        char     *startpacket;
2505
397
        int     packetlen;
2506
2507
397
#ifdef HAVE_UNIX_SOCKETS
2508
2509
        /*
2510
         * Implement requirepeer check, if requested and it's a
2511
         * Unix-domain socket.
2512
         */
2513
397
        if (conn->requirepeer && conn->requirepeer[0] &&
2514
0
          IS_AF_UNIX(conn->raddr.addr.ss_family))
2515
0
        {
2516
0
          char    pwdbuf[BUFSIZ];
2517
0
          struct passwd pass_buf;
2518
0
          struct passwd *pass;
2519
0
          int     passerr;
2520
0
          uid_t   uid;
2521
0
          gid_t   gid;
2522
2523
0
          errno = 0;
2524
0
          if (getpeereid(conn->sock, &uid, &gid) != 0)
2525
0
          {
2526
            /*
2527
             * Provide special error message if getpeereid is a
2528
             * stub
2529
             */
2530
0
            if (errno == ENOSYS)
2531
0
              appendPQExpBufferStr(&conn->errorMessage,
2532
0
                         libpq_gettext("requirepeer parameter is not supported on this platform\n"));
2533
0
            else
2534
0
              appendPQExpBuffer(&conn->errorMessage,
2535
0
                        libpq_gettext("could not get peer credentials: %s\n"),
2536
0
                        pqStrerror(errno, sebuf, sizeof(sebuf)));
2537
0
            goto error_return;
2538
0
          }
2539
2540
0
          passerr = pqGetpwuid(uid, &pass_buf, pwdbuf, sizeof(pwdbuf), &pass);
2541
0
          if (pass == NULL)
2542
0
          {
2543
0
            if (passerr != 0)
2544
0
              appendPQExpBuffer(&conn->errorMessage,
2545
0
                        libpq_gettext("could not look up local user ID %d: %s\n"),
2546
0
                        (int) uid,
2547
0
                        pqStrerror(passerr, sebuf, sizeof(sebuf)));
2548
0
            else
2549
0
              appendPQExpBuffer(&conn->errorMessage,
2550
0
                        libpq_gettext("local user with ID %d does not exist\n"),
2551
0
                        (int) uid);
2552
0
            goto error_return;
2553
0
          }
2554
2555
0
          if (strcmp(pass->pw_name, conn->requirepeer) != 0)
2556
0
          {
2557
0
            appendPQExpBuffer(&conn->errorMessage,
2558
0
                      libpq_gettext("requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n"),
2559
0
                      conn->requirepeer, pass->pw_name);
2560
0
            goto error_return;
2561
0
          }
2562
397
        }
2563
397
#endif              /* HAVE_UNIX_SOCKETS */
2564
2565
397
#ifdef USE_SSL
2566
2567
        /*
2568
         * If SSL is enabled and we haven't already got it running,
2569
         * request it instead of sending the startup message.
2570
         */
2571
397
        if (IS_AF_UNIX(conn->raddr.addr.ss_family))
2572
235
        {
2573
          /* Don't bother requesting SSL over a Unix socket */
2574
235
          conn->allow_ssl_try = false;
2575
235
        }
2576
397
        if (conn->allow_ssl_try && !conn->wait_ssl_try &&
2577
81
          !conn->ssl_in_use)
2578
81
        {
2579
81
          ProtocolVersion pv;
2580
2581
          /*
2582
           * Send the SSL request packet.
2583
           *
2584
           * Theoretically, this could block, but it really
2585
           * shouldn't since we only got here if the socket is
2586
           * write-ready.
2587
           */
2588
81
          pv = pg_hton32(NEGOTIATE_SSL_CODE);
2589
81
          if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
2590
0
          {
2591
0
            appendPQExpBuffer(&conn->errorMessage,
2592
0
                      libpq_gettext("could not send SSL negotiation packet: %s\n"),
2593
0
                      SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2594
0
            goto error_return;
2595
0
          }
2596
          /* Ok, wait for response */
2597
81
          conn->status = CONNECTION_SSL_STARTUP;
2598
81
          return PGRES_POLLING_READING;
2599
81
        }
2600
316
#endif              /* USE_SSL */
2601
2602
        /*
2603
         * Build the startup packet.
2604
         */
2605
316
        if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2606
316
          startpacket = pqBuildStartupPacket3(conn, &packetlen,
2607
316
                            EnvironmentOptions);
2608
0
        else
2609
0
          startpacket = pqBuildStartupPacket2(conn, &packetlen,
2610
0
                            EnvironmentOptions);
2611
316
        if (!startpacket)
2612
0
        {
2613
          /*
2614
           * will not appendbuffer here, since it's likely to also
2615
           * run out of memory
2616
           */
2617
0
          printfPQExpBuffer(&conn->errorMessage,
2618
0
                    libpq_gettext("out of memory\n"));
2619
0
          goto error_return;
2620
0
        }
2621
2622
        /*
2623
         * Send the startup packet.
2624
         *
2625
         * Theoretically, this could block, but it really shouldn't
2626
         * since we only got here if the socket is write-ready.
2627
         */
2628
316
        if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
2629
0
        {
2630
0
          appendPQExpBuffer(&conn->errorMessage,
2631
0
                    libpq_gettext("could not send startup packet: %s\n"),
2632
0
                    SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
2633
0
          free(startpacket);
2634
0
          goto error_return;
2635
0
        }
2636
2637
316
        free(startpacket);
2638
2639
316
        conn->status = CONNECTION_AWAITING_RESPONSE;
2640
316
        return PGRES_POLLING_READING;
2641
316
      }
2642
2643
      /*
2644
       * Handle SSL negotiation: wait for postmaster messages and
2645
       * respond as necessary.
2646
       */
2647
81
    case CONNECTION_SSL_STARTUP:
2648
81
      {
2649
81
#ifdef USE_SSL
2650
81
        PostgresPollingStatusType pollres;
2651
2652
        /*
2653
         * On first time through, get the postmaster's response to our
2654
         * SSL negotiation packet.
2655
         */
2656
81
        if (!conn->ssl_in_use)
2657
81
        {
2658
          /*
2659
           * We use pqReadData here since it has the logic to
2660
           * distinguish no-data-yet from connection closure. Since
2661
           * conn->ssl isn't set, a plain recv() will occur.
2662
           */
2663
81
          char    SSLok;
2664
81
          int     rdresult;
2665
2666
81
          rdresult = pqReadData(conn);
2667
81
          if (rdresult < 0)
2668
0
          {
2669
            /* errorMessage is already filled in */
2670
0
            goto error_return;
2671
0
          }
2672
81
          if (rdresult == 0)
2673
0
          {
2674
            /* caller failed to wait for data */
2675
0
            return PGRES_POLLING_READING;
2676
0
          }
2677
81
          if (pqGetc(&SSLok, conn) < 0)
2678
0
          {
2679
            /* should not happen really */
2680
0
            return PGRES_POLLING_READING;
2681
0
          }
2682
81
          if (SSLok == 'S')
2683
0
          {
2684
            /* mark byte consumed */
2685
0
            conn->inStart = conn->inCursor;
2686
            /* Set up global SSL state if required */
2687
0
            if (pqsecure_initialize(conn) != 0)
2688
0
              goto error_return;
2689
81
          }
2690
81
          else if (SSLok == 'N')
2691
81
          {
2692
            /* mark byte consumed */
2693
81
            conn->inStart = conn->inCursor;
2694
            /* OK to do without SSL? */
2695
81
            if (conn->sslmode[0] == 'r' || /* "require" */
2696
81
              conn->sslmode[0] == 'v')  /* "verify-ca" or
2697
                             * "verify-full" */
2698
0
            {
2699
              /* Require SSL, but server does not want it */
2700
0
              appendPQExpBufferStr(&conn->errorMessage,
2701
0
                         libpq_gettext("server does not support SSL, but SSL was required\n"));
2702
0
              goto error_return;
2703
0
            }
2704
            /* Otherwise, proceed with normal startup */
2705
81
            conn->allow_ssl_try = false;
2706
81
            conn->status = CONNECTION_MADE;
2707
81
            return PGRES_POLLING_WRITING;
2708
81
          }
2709
0
          else if (SSLok == 'E')
2710
0
          {
2711
            /*
2712
             * Server failure of some sort, such as failure to
2713
             * fork a backend process.  We need to process and
2714
             * report the error message, which might be formatted
2715
             * according to either protocol 2 or protocol 3.
2716
             * Rather than duplicate the code for that, we flip
2717
             * into AWAITING_RESPONSE state and let the code there
2718
             * deal with it.  Note we have *not* consumed the "E"
2719
             * byte here.
2720
             */
2721
0
            conn->status = CONNECTION_AWAITING_RESPONSE;
2722
0
            goto keep_going;
2723
0
          }
2724
0
          else
2725
0
          {
2726
0
            appendPQExpBuffer(&conn->errorMessage,
2727
0
                      libpq_gettext("received invalid response to SSL negotiation: %c\n"),
2728
0
                      SSLok);
2729
0
            goto error_return;
2730
0
          }
2731
0
        }
2732
2733
        /*
2734
         * Begin or continue the SSL negotiation process.
2735
         */
2736
0
        pollres = pqsecure_open_client(conn);
2737
0
        if (pollres == PGRES_POLLING_OK)
2738
0
        {
2739
          /*
2740
           * At this point we should have no data already buffered.
2741
           * If we do, it was received before we performed the SSL
2742
           * handshake, so it wasn't encrypted and indeed may have
2743
           * been injected by a man-in-the-middle.
2744
           */
2745
0
          if (conn->inCursor != conn->inEnd)
2746
0
          {
2747
0
            appendPQExpBufferStr(&conn->errorMessage,
2748
0
                       libpq_gettext("received unencrypted data after SSL response\n"));
2749
0
            goto error_return;
2750
0
          }
2751
2752
          /* SSL handshake done, ready to send startup packet */
2753
0
          conn->status = CONNECTION_MADE;
2754
0
          return PGRES_POLLING_WRITING;
2755
0
        }
2756
0
        if (pollres == PGRES_POLLING_FAILED)
2757
0
        {
2758
          /*
2759
           * Failed ... if sslmode is "prefer" then do a non-SSL
2760
           * retry
2761
           */
2762
0
          if (conn->sslmode[0] == 'p' /* "prefer" */
2763
0
            && conn->allow_ssl_try  /* redundant? */
2764
0
            && !conn->wait_ssl_try) /* redundant? */
2765
0
          {
2766
            /* only retry once */
2767
0
            conn->allow_ssl_try = false;
2768
0
            need_new_connection = true;
2769
0
            goto keep_going;
2770
0
          }
2771
          /* Else it's a hard failure */
2772
0
          goto error_return;
2773
0
        }
2774
        /* Else, return POLLING_READING or POLLING_WRITING status */
2775
0
        return pollres;
2776
#else             /* !USE_SSL */
2777
        /* can't get here */
2778
        goto error_return;
2779
#endif              /* USE_SSL */
2780
0
      }
2781
2782
      /*
2783
       * Handle authentication exchange: wait for postmaster messages
2784
       * and respond as necessary.
2785
       */
2786
786
    case CONNECTION_AWAITING_RESPONSE:
2787
786
      {
2788
786
        char    beresp;
2789
786
        int     msgLength;
2790
786
        int     avail;
2791
786
        AuthRequest areq;
2792
786
        int     res;
2793
2794
        /*
2795
         * Scan the message from current point (note that if we find
2796
         * the message is incomplete, we will return without advancing
2797
         * inStart, and resume here next time).
2798
         */
2799
786
        conn->inCursor = conn->inStart;
2800
2801
        /* Read type byte */
2802
786
        if (pqGetc(&beresp, conn))
2803
235
        {
2804
          /* We'll come back when there is more data */
2805
235
          return PGRES_POLLING_READING;
2806
235
        }
2807
2808
        /*
2809
         * Validate message type: we expect only an authentication
2810
         * request or an error here.  Anything else probably means
2811
         * it's not Postgres on the other end at all.
2812
         */
2813
551
        if (!(beresp == 'R' || beresp == 'E'))
2814
0
        {
2815
0
          appendPQExpBuffer(&conn->errorMessage,
2816
0
                    libpq_gettext(
2817
0
                          "expected authentication request from "
2818
0
                          "server, but received %c\n"),
2819
0
                    beresp);
2820
0
          goto error_return;
2821
0
        }
2822
2823
551
        if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2824
551
        {
2825
          /* Read message length word */
2826
551
          if (pqGetInt(&msgLength, 4, conn))
2827
0
          {
2828
            /* We'll come back when there is more data */
2829
0
            return PGRES_POLLING_READING;
2830
0
          }
2831
0
        }
2832
0
        else
2833
0
        {
2834
          /* Set phony message length to disable checks below */
2835
0
          msgLength = 8;
2836
0
        }
2837
2838
        /*
2839
         * Try to validate message length before using it.
2840
         * Authentication requests can't be very large, although GSS
2841
         * auth requests may not be that small.  Errors can be a
2842
         * little larger, but not huge.  If we see a large apparent
2843
         * length in an error, it means we're really talking to a
2844
         * pre-3.0-protocol server; cope.
2845
         */
2846
551
        if (beresp == 'R' && (msgLength < 8 || msgLength > 2000))
2847
0
        {
2848
0
          appendPQExpBuffer(&conn->errorMessage,
2849
0
                    libpq_gettext(
2850
0
                          "expected authentication request from "
2851
0
                          "server, but received %c\n"),
2852
0
                    beresp);
2853
0
          goto error_return;
2854
0
        }
2855
2856
551
        if (beresp == 'E' && (msgLength < 8 || msgLength > 30000))
2857
0
        {
2858
          /* Handle error from a pre-3.0 server */
2859
0
          conn->inCursor = conn->inStart + 1; /* reread data */
2860
0
          if (pqGets_append(&conn->errorMessage, conn))
2861
0
          {
2862
            /* We'll come back when there is more data */
2863
0
            return PGRES_POLLING_READING;
2864
0
          }
2865
          /* OK, we read the message; mark data consumed */
2866
0
          conn->inStart = conn->inCursor;
2867
2868
          /*
2869
           * The postmaster typically won't end its message with a
2870
           * newline, so add one to conform to libpq conventions.
2871
           */
2872
0
          appendPQExpBufferChar(&conn->errorMessage, '\n');
2873
2874
          /*
2875
           * If we tried to open the connection in 3.0 protocol,
2876
           * fall back to 2.0 protocol.
2877
           */
2878
0
          if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2879
0
          {
2880
0
            conn->pversion = PG_PROTOCOL(2, 0);
2881
0
            need_new_connection = true;
2882
0
            goto keep_going;
2883
0
          }
2884
2885
0
          goto error_return;
2886
0
        }
2887
2888
        /*
2889
         * Can't process if message body isn't all here yet.
2890
         *
2891
         * (In protocol 2.0 case, we are assuming messages carry at
2892
         * least 4 bytes of data.)
2893
         */
2894
551
        msgLength -= 4;
2895
551
        avail = conn->inEnd - conn->inCursor;
2896
551
        if (avail < msgLength)
2897
0
        {
2898
          /*
2899
           * Before returning, try to enlarge the input buffer if
2900
           * needed to hold the whole message; see notes in
2901
           * pqParseInput3.
2902
           */
2903
0
          if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
2904
0
                       conn))
2905
0
            goto error_return;
2906
          /* We'll come back when there is more data */
2907
0
          return PGRES_POLLING_READING;
2908
0
        }
2909
2910
        /* Handle errors. */
2911
551
        if (beresp == 'E')
2912
0
        {
2913
0
          if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
2914
0
          {
2915
0
            if (pqGetErrorNotice3(conn, true))
2916
0
            {
2917
              /* We'll come back when there is more data */
2918
0
              return PGRES_POLLING_READING;
2919
0
            }
2920
0
          }
2921
0
          else
2922
0
          {
2923
0
            if (pqGets_append(&conn->errorMessage, conn))
2924
0
            {
2925
              /* We'll come back when there is more data */
2926
0
              return PGRES_POLLING_READING;
2927
0
            }
2928
0
          }
2929
          /* OK, we read the message; mark data consumed */
2930
0
          conn->inStart = conn->inCursor;
2931
2932
          /* Check to see if we should mention pgpassfile */
2933
0
          pgpassfileWarning(conn);
2934
2935
0
#ifdef USE_SSL
2936
2937
          /*
2938
           * if sslmode is "allow" and we haven't tried an SSL
2939
           * connection already, then retry with an SSL connection
2940
           */
2941
0
          if (conn->sslmode[0] == 'a' /* "allow" */
2942
0
            && !conn->ssl_in_use
2943
0
            && conn->allow_ssl_try
2944
0
            && conn->wait_ssl_try)
2945
0
          {
2946
            /* only retry once */
2947
0
            conn->wait_ssl_try = false;
2948
0
            need_new_connection = true;
2949
0
            goto keep_going;
2950
0
          }
2951
2952
          /*
2953
           * if sslmode is "prefer" and we're in an SSL connection,
2954
           * then do a non-SSL retry
2955
           */
2956
0
          if (conn->sslmode[0] == 'p' /* "prefer" */
2957
0
            && conn->ssl_in_use
2958
0
            && conn->allow_ssl_try  /* redundant? */
2959
0
            && !conn->wait_ssl_try) /* redundant? */
2960
0
          {
2961
            /* only retry once */
2962
0
            conn->allow_ssl_try = false;
2963
0
            need_new_connection = true;
2964
0
            goto keep_going;
2965
0
          }
2966
0
#endif
2967
2968
0
          goto error_return;
2969
0
        }
2970
2971
        /* It is an authentication request. */
2972
551
        conn->auth_req_received = true;
2973
2974
        /* Get the type of request. */
2975
551
        if (pqGetInt((int *) &areq, 4, conn))
2976
0
        {
2977
          /* We'll come back when there are more data */
2978
0
          return PGRES_POLLING_READING;
2979
0
        }
2980
551
        msgLength -= 4;
2981
2982
        /*
2983
         * Ensure the password salt is in the input buffer, if it's an
2984
         * MD5 request.  All the other authentication methods that
2985
         * contain extra data in the authentication request are only
2986
         * supported in protocol version 3, in which case we already
2987
         * read the whole message above.
2988
         */
2989
551
        if (areq == AUTH_REQ_MD5 && PG_PROTOCOL_MAJOR(conn->pversion) < 3)
2990
0
        {
2991
0
          msgLength += 4;
2992
2993
0
          avail = conn->inEnd - conn->inCursor;
2994
0
          if (avail < 4)
2995
0
          {
2996
            /*
2997
             * Before returning, try to enlarge the input buffer
2998
             * if needed to hold the whole message; see notes in
2999
             * pqParseInput3.
3000
             */
3001
0
            if (pqCheckInBufferSpace(conn->inCursor + (size_t) 4,
3002
0
                         conn))
3003
0
              goto error_return;
3004
            /* We'll come back when there is more data */
3005
0
            return PGRES_POLLING_READING;
3006
0
          }
3007
0
        }
3008
3009
        /*
3010
         * Process the rest of the authentication request message, and
3011
         * respond to it if necessary.
3012
         *
3013
         * Note that conn->pghost must be non-NULL if we are going to
3014
         * avoid the Kerberos code doing a hostname look-up.
3015
         */
3016
551
        res = pg_fe_sendauth(areq, msgLength, conn);
3017
551
        conn->errorMessage.len = strlen(conn->errorMessage.data);
3018
3019
        /* OK, we have processed the message; mark data consumed */
3020
551
        conn->inStart = conn->inCursor;
3021
3022
551
        if (res != STATUS_OK)
3023
0
          goto error_return;
3024
3025
        /*
3026
         * Just make sure that any data sent by pg_fe_sendauth is
3027
         * flushed out.  Although this theoretically could block, it
3028
         * really shouldn't since we don't send large auth responses.
3029
         */
3030
551
        if (pqFlush(conn))
3031
0
          goto error_return;
3032
3033
551
        if (areq == AUTH_REQ_OK)
3034
316
        {
3035
          /* We are done with authentication exchange */
3036
316
          conn->status = CONNECTION_AUTH_OK;
3037
3038
          /*
3039
           * Set asyncStatus so that PQgetResult will think that
3040
           * what comes back next is the result of a query.  See
3041
           * below.
3042
           */
3043
316
          conn->asyncStatus = PGASYNC_BUSY;
3044
316
        }
3045
3046
        /* Look to see if we have more data yet. */
3047
551
        goto keep_going;
3048
551
      }
3049
3050
316
    case CONNECTION_AUTH_OK:
3051
316
      {
3052
        /*
3053
         * Now we expect to hear from the backend. A ReadyForQuery
3054
         * message indicates that startup is successful, but we might
3055
         * also get an Error message indicating failure. (Notice
3056
         * messages indicating nonfatal warnings are also allowed by
3057
         * the protocol, as are ParameterStatus and BackendKeyData
3058
         * messages.) Easiest way to handle this is to let
3059
         * PQgetResult() read the messages. We just have to fake it
3060
         * out about the state of the connection, by setting
3061
         * asyncStatus = PGASYNC_BUSY (done above).
3062
         */
3063
3064
316
        if (PQisBusy(conn))
3065
0
          return PGRES_POLLING_READING;
3066
3067
316
        res = PQgetResult(conn);
3068
3069
        /*
3070
         * NULL return indicating we have gone to IDLE state is
3071
         * expected
3072
         */
3073
316
        if (res)
3074
3
        {
3075
3
          if (res->resultStatus != PGRES_FATAL_ERROR)
3076
0
            appendPQExpBufferStr(&conn->errorMessage,
3077
0
                       libpq_gettext("unexpected message from server during startup\n"));
3078
3
          else if (conn->send_appname &&
3079
3
               (conn->appname || conn->fbappname))
3080
3
          {
3081
            /*
3082
             * If we tried to send application_name, check to see
3083
             * if the error is about that --- pre-9.0 servers will
3084
             * reject it at this stage of the process.  If so,
3085
             * close the connection and retry without sending
3086
             * application_name.  We could possibly get a false
3087
             * SQLSTATE match here and retry uselessly, but there
3088
             * seems no great harm in that; we'll just get the
3089
             * same error again if it's unrelated.
3090
             */
3091
3
            const char *sqlstate;
3092
3093
3
            sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
3094
3
            if (sqlstate &&
3095
3
              strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0)
3096
0
            {
3097
0
              PQclear(res);
3098
0
              conn->send_appname = false;
3099
0
              need_new_connection = true;
3100
0
              goto keep_going;
3101
0
            }
3102
3
          }
3103
3104
          /*
3105
           * if the resultStatus is FATAL, then conn->errorMessage
3106
           * already has a copy of the error; needn't copy it back.
3107
           * But add a newline if it's not there already, since
3108
           * postmaster error messages may not have one.
3109
           */
3110
3
          if (conn->errorMessage.len <= 0 ||
3111
3
            conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
3112
0
            appendPQExpBufferChar(&conn->errorMessage, '\n');
3113
3
          PQclear(res);
3114
3
          goto error_return;
3115
3
        }
3116
3117
        /* Fire up post-connection housekeeping if needed */
3118
313
        if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
3119
0
        {
3120
0
          conn->status = CONNECTION_SETENV;
3121
0
          conn->setenv_state = SETENV_STATE_CLIENT_ENCODING_SEND;
3122
0
          conn->next_eo = EnvironmentOptions;
3123
0
          return PGRES_POLLING_WRITING;
3124
0
        }
3125
3126
        /*
3127
         * If a read-write connection is required, see if we have one.
3128
         *
3129
         * Servers before 7.4 lack the transaction_read_only GUC, but
3130
         * by the same token they don't have any read-only mode, so we
3131
         * may just skip the test in that case.
3132
         */
3133
313
        if (conn->sversion >= 70400 &&
3134
313
          conn->target_session_attrs != NULL &&
3135
313
          strcmp(conn->target_session_attrs, "read-write") == 0)
3136
0
        {
3137
          /*
3138
           * Save existing error messages across the PQsendQuery
3139
           * attempt.  This is necessary because PQsendQuery is
3140
           * going to reset conn->errorMessage, so we would lose
3141
           * error messages related to previous hosts we have tried
3142
           * and failed to connect to.
3143
           */
3144
0
          if (!saveErrorMessage(conn, &savedMessage))
3145
0
            goto error_return;
3146
3147
0
          conn->status = CONNECTION_OK;
3148
0
          if (!PQsendQuery(conn,
3149
0
                   "SHOW transaction_read_only"))
3150
0
          {
3151
0
            restoreErrorMessage(conn, &savedMessage);
3152
0
            goto error_return;
3153
0
          }
3154
0
          conn->status = CONNECTION_CHECK_WRITABLE;
3155
0
          restoreErrorMessage(conn, &savedMessage);
3156
0
          return PGRES_POLLING_READING;
3157
0
        }
3158
3159
        /* We can release the address list now. */
3160
313
        release_conn_addrinfo(conn);
3161
3162
        /* We are open for business! */
3163
313
        conn->status = CONNECTION_OK;
3164
313
        return PGRES_POLLING_OK;
3165
313
      }
3166
3167
0
    case CONNECTION_SETENV:
3168
3169
      /*
3170
       * Do post-connection housekeeping (only needed in protocol 2.0).
3171
       *
3172
       * We pretend that the connection is OK for the duration of these
3173
       * queries.
3174
       */
3175
0
      conn->status = CONNECTION_OK;
3176
3177
0
      switch (pqSetenvPoll(conn))
3178
0
      {
3179
0
        case PGRES_POLLING_OK:  /* Success */
3180
0
          break;
3181
3182
0
        case PGRES_POLLING_READING: /* Still going */
3183
0
          conn->status = CONNECTION_SETENV;
3184
0
          return PGRES_POLLING_READING;
3185
3186
0
        case PGRES_POLLING_WRITING: /* Still going */
3187
0
          conn->status = CONNECTION_SETENV;
3188
0
          return PGRES_POLLING_WRITING;
3189
3190
0
        default:
3191
0
          goto error_return;
3192
0
      }
3193
3194
      /*
3195
       * If a read-write connection is required, see if we have one.
3196
       * (This should match the stanza in the CONNECTION_AUTH_OK case
3197
       * above.)
3198
       *
3199
       * Servers before 7.4 lack the transaction_read_only GUC, but by
3200
       * the same token they don't have any read-only mode, so we may
3201
       * just skip the test in that case.
3202
       */
3203
0
      if (conn->sversion >= 70400 &&
3204
0
        conn->target_session_attrs != NULL &&
3205
0
        strcmp(conn->target_session_attrs, "read-write") == 0)
3206
0
      {
3207
0
        if (!saveErrorMessage(conn, &savedMessage))
3208
0
          goto error_return;
3209
3210
0
        conn->status = CONNECTION_OK;
3211
0
        if (!PQsendQuery(conn,
3212
0
                 "SHOW transaction_read_only"))
3213
0
        {
3214
0
          restoreErrorMessage(conn, &savedMessage);
3215
0
          goto error_return;
3216
0
        }
3217
0
        conn->status = CONNECTION_CHECK_WRITABLE;
3218
0
        restoreErrorMessage(conn, &savedMessage);
3219
0
        return PGRES_POLLING_READING;
3220
0
      }
3221
3222
      /* We can release the address list now. */
3223
0
      release_conn_addrinfo(conn);
3224
3225
      /* We are open for business! */
3226
0
      conn->status = CONNECTION_OK;
3227
0
      return PGRES_POLLING_OK;
3228
3229
0
    case CONNECTION_CONSUME:
3230
0
      {
3231
0
        conn->status = CONNECTION_OK;
3232
0
        if (!PQconsumeInput(conn))
3233
0
          goto error_return;
3234
3235
0
        if (PQisBusy(conn))
3236
0
        {
3237
0
          conn->status = CONNECTION_CONSUME;
3238
0
          return PGRES_POLLING_READING;
3239
0
        }
3240
3241
        /*
3242
         * Call PQgetResult() again to consume NULL result.
3243
         */
3244
0
        res = PQgetResult(conn);
3245
0
        if (res != NULL)
3246
0
        {
3247
0
          PQclear(res);
3248
0
          conn->status = CONNECTION_CONSUME;
3249
0
          goto keep_going;
3250
0
        }
3251
3252
        /* We can release the address list now. */
3253
0
        release_conn_addrinfo(conn);
3254
3255
        /* We are open for business! */
3256
0
        conn->status = CONNECTION_OK;
3257
0
        return PGRES_POLLING_OK;
3258
0
      }
3259
0
    case CONNECTION_CHECK_WRITABLE:
3260
0
      {
3261
0
        const char *displayed_host;
3262
0
        const char *displayed_port;
3263
3264
0
        if (!saveErrorMessage(conn, &savedMessage))
3265
0
          goto error_return;
3266
3267
0
        conn->status = CONNECTION_OK;
3268
0
        if (!PQconsumeInput(conn))
3269
0
        {
3270
0
          restoreErrorMessage(conn, &savedMessage);
3271
0
          goto error_return;
3272
0
        }
3273
3274
0
        if (PQisBusy(conn))
3275
0
        {
3276
0
          conn->status = CONNECTION_CHECK_WRITABLE;
3277
0
          restoreErrorMessage(conn, &savedMessage);
3278
0
          return PGRES_POLLING_READING;
3279
0
        }
3280
3281
0
        res = PQgetResult(conn);
3282
0
        if (res && (PQresultStatus(res) == PGRES_TUPLES_OK) &&
3283
0
          PQntuples(res) == 1)
3284
0
        {
3285
0
          char     *val;
3286
3287
0
          val = PQgetvalue(res, 0, 0);
3288
0
          if (strncmp(val, "on", 2) == 0)
3289
0
          {
3290
            /* Not writable; fail this connection. */
3291
0
            const char *displayed_host;
3292
0
            const char *displayed_port;
3293
3294
0
            PQclear(res);
3295
0
            restoreErrorMessage(conn, &savedMessage);
3296
3297
            /* Append error report to conn->errorMessage. */
3298
0
            if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
3299
0
              displayed_host = conn->connhost[conn->whichhost].hostaddr;
3300
0
            else
3301
0
              displayed_host = conn->connhost[conn->whichhost].host;
3302
0
            displayed_port = conn->connhost[conn->whichhost].port;
3303
0
            if (displayed_port == NULL || displayed_port[0] == '\0')
3304
              /* Use YugaByte default port */
3305
0
              displayed_port = DEF_YBPORT_STR;
3306
3307
0
            appendPQExpBuffer(&conn->errorMessage,
3308
0
                      libpq_gettext("could not make a writable "
3309
0
                            "connection to server "
3310
0
                            "\"%s:%s\"\n"),
3311
0
                      displayed_host, displayed_port);
3312
3313
            /* Close connection politely. */
3314
0
            conn->status = CONNECTION_OK;
3315
0
            sendTerminateConn(conn);
3316
3317
            /*
3318
             * Try next host if any, but we don't want to consider
3319
             * additional addresses for this host.
3320
             */
3321
0
            conn->try_next_host = true;
3322
0
            goto keep_going;
3323
0
          }
3324
3325
          /* Session is read-write, so we're good. */
3326
0
          PQclear(res);
3327
0
          termPQExpBuffer(&savedMessage);
3328
3329
          /*
3330
           * Finish reading any remaining messages before being
3331
           * considered as ready.
3332
           */
3333
0
          conn->status = CONNECTION_CONSUME;
3334
0
          goto keep_going;
3335
0
        }
3336
3337
        /*
3338
         * Something went wrong with "SHOW transaction_read_only". We
3339
         * should try next addresses.
3340
         */
3341
0
        if (res)
3342
0
          PQclear(res);
3343
0
        restoreErrorMessage(conn, &savedMessage);
3344
3345
        /* Append error report to conn->errorMessage. */
3346
0
        if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
3347
0
          displayed_host = conn->connhost[conn->whichhost].hostaddr;
3348
0
        else
3349
0
          displayed_host = conn->connhost[conn->whichhost].host;
3350
0
        displayed_port = conn->connhost[conn->whichhost].port;
3351
0
        if (displayed_port == NULL || displayed_port[0] == '\0')
3352
          /* Use YugaByte default port */
3353
0
          displayed_port = DEF_YBPORT_STR;
3354
0
        appendPQExpBuffer(&conn->errorMessage,
3355
0
                  libpq_gettext("test \"SHOW transaction_read_only\" failed "
3356
0
                        "on server \"%s:%s\"\n"),
3357
0
                  displayed_host, displayed_port);
3358
3359
        /* Close connection politely. */
3360
0
        conn->status = CONNECTION_OK;
3361
0
        sendTerminateConn(conn);
3362
3363
        /* Try next address */
3364
0
        conn->try_next_addr = true;
3365
0
        goto keep_going;
3366
0
      }
3367
3368
0
    default:
3369
0
      appendPQExpBuffer(&conn->errorMessage,
3370
0
                libpq_gettext("invalid connection state %d, "
3371
0
                      "probably indicative of memory corruption\n"),
3372
0
                conn->status);
3373
0
      goto error_return;
3374
3
  }
3375
3376
  /* Unreachable */
3377
3378
3
error_return:
3379
3380
  /*
3381
   * We used to close the socket at this point, but that makes it awkward
3382
   * for those above us if they wish to remove this socket from their own
3383
   * records (an fd_set for example).  We'll just have this socket closed
3384
   * when PQfinish is called (which is compulsory even after an error, since
3385
   * the connection structure must be freed).
3386
   */
3387
3
  conn->status = CONNECTION_BAD;
3388
3
  return PGRES_POLLING_FAILED;
3389
2.21k
}
3390
3391
3392
/*
3393
 * internal_ping
3394
 *    Determine if a server is running and if we can connect to it.
3395
 *
3396
 * The argument is a connection that's been started, but not completed.
3397
 */
3398
static PGPing
3399
internal_ping(PGconn *conn)
3400
0
{
3401
  /* Say "no attempt" if we never got to PQconnectPoll */
3402
0
  if (!conn || !conn->options_valid)
3403
0
    return PQPING_NO_ATTEMPT;
3404
3405
  /* Attempt to complete the connection */
3406
0
  if (conn->status != CONNECTION_BAD)
3407
0
    (void) connectDBComplete(conn);
3408
3409
  /* Definitely OK if we succeeded */
3410
0
  if (conn->status != CONNECTION_BAD)
3411
0
    return PQPING_OK;
3412
3413
  /*
3414
   * Here begins the interesting part of "ping": determine the cause of the
3415
   * failure in sufficient detail to decide what to return.  We do not want
3416
   * to report that the server is not up just because we didn't have a valid
3417
   * password, for example.  In fact, any sort of authentication request
3418
   * implies the server is up.  (We need this check since the libpq side of
3419
   * things might have pulled the plug on the connection before getting an
3420
   * error as such from the postmaster.)
3421
   */
3422
0
  if (conn->auth_req_received)
3423
0
    return PQPING_OK;
3424
3425
  /*
3426
   * If we failed to get any ERROR response from the postmaster, report
3427
   * PQPING_NO_RESPONSE.  This result could be somewhat misleading for a
3428
   * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
3429
   * out of support.  Another corner case where the server could return a
3430
   * failure without a SQLSTATE is fork failure, but NO_RESPONSE isn't
3431
   * totally unreasonable for that anyway.  We expect that every other
3432
   * failure case in a modern server will produce a report with a SQLSTATE.
3433
   *
3434
   * NOTE: whenever we get around to making libpq generate SQLSTATEs for
3435
   * client-side errors, we should either not store those into
3436
   * last_sqlstate, or add an extra flag so we can tell client-side errors
3437
   * apart from server-side ones.
3438
   */
3439
0
  if (strlen(conn->last_sqlstate) != 5)
3440
0
    return PQPING_NO_RESPONSE;
3441
3442
  /*
3443
   * Report PQPING_REJECT if server says it's not accepting connections. (We
3444
   * distinguish this case mainly for the convenience of pg_ctl.)
3445
   */
3446
0
  if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
3447
0
    return PQPING_REJECT;
3448
3449
  /*
3450
   * Any other SQLSTATE can be taken to indicate that the server is up.
3451
   * Presumably it didn't like our username, password, or database name; or
3452
   * perhaps it had some transient failure, but that should not be taken as
3453
   * meaning "it's down".
3454
   */
3455
0
  return PQPING_OK;
3456
0
}
3457
3458
3459
/*
3460
 * makeEmptyPGconn
3461
 *   - create a PGconn data structure with (as yet) no interesting data
3462
 */
3463
static PGconn *
3464
makeEmptyPGconn(void)
3465
316
{
3466
316
  PGconn     *conn;
3467
3468
#ifdef WIN32
3469
3470
  /*
3471
   * Make sure socket support is up and running.
3472
   */
3473
  WSADATA   wsaData;
3474
3475
  if (WSAStartup(MAKEWORD(1, 1), &wsaData))
3476
    return NULL;
3477
  WSASetLastError(0);
3478
#endif
3479
3480
316
  conn = (PGconn *) malloc(sizeof(PGconn));
3481
316
  if (conn == NULL)
3482
0
  {
3483
#ifdef WIN32
3484
    WSACleanup();
3485
#endif
3486
0
    return conn;
3487
0
  }
3488
3489
  /* Zero all pointers and booleans */
3490
316
  MemSet(conn, 0, sizeof(PGconn));
3491
3492
  /* install default notice hooks */
3493
316
  conn->noticeHooks.noticeRec = defaultNoticeReceiver;
3494
316
  conn->noticeHooks.noticeProc = defaultNoticeProcessor;
3495
3496
316
  conn->status = CONNECTION_BAD;
3497
316
  conn->asyncStatus = PGASYNC_IDLE;
3498
316
  conn->xactStatus = PQTRANS_IDLE;
3499
316
  conn->options_valid = false;
3500
316
  conn->nonblocking = false;
3501
316
  conn->setenv_state = SETENV_STATE_IDLE;
3502
316
  conn->client_encoding = PG_SQL_ASCII;
3503
316
  conn->std_strings = false;  /* unless server says differently */
3504
316
  conn->verbosity = PQERRORS_DEFAULT;
3505
316
  conn->show_context = PQSHOW_CONTEXT_ERRORS;
3506
316
  conn->sock = PGINVALID_SOCKET;
3507
3508
  /*
3509
   * We try to send at least 8K at a time, which is the usual size of pipe
3510
   * buffers on Unix systems.  That way, when we are sending a large amount
3511
   * of data, we avoid incurring extra kernel context swaps for partial
3512
   * bufferloads.  The output buffer is initially made 16K in size, and we
3513
   * try to dump it after accumulating 8K.
3514
   *
3515
   * With the same goal of minimizing context swaps, the input buffer will
3516
   * be enlarged anytime it has less than 8K free, so we initially allocate
3517
   * twice that.
3518
   */
3519
316
  conn->inBufSize = 16 * 1024;
3520
316
  conn->inBuffer = (char *) malloc(conn->inBufSize);
3521
316
  conn->outBufSize = 16 * 1024;
3522
316
  conn->outBuffer = (char *) malloc(conn->outBufSize);
3523
316
  conn->rowBufLen = 32;
3524
316
  conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
3525
316
  initPQExpBuffer(&conn->errorMessage);
3526
316
  initPQExpBuffer(&conn->workBuffer);
3527
3528
316
  if (conn->inBuffer == NULL ||
3529
316
    conn->outBuffer == NULL ||
3530
316
    conn->rowBuf == NULL ||
3531
316
    PQExpBufferBroken(&conn->errorMessage) ||
3532
316
    PQExpBufferBroken(&conn->workBuffer))
3533
0
  {
3534
    /* out of memory already :-( */
3535
0
    freePGconn(conn);
3536
0
    conn = NULL;
3537
0
  }
3538
3539
316
  return conn;
3540
316
}
3541
3542
/*
3543
 * freePGconn
3544
 *   - free an idle (closed) PGconn data structure
3545
 *
3546
 * NOTE: this should not overlap any functionality with closePGconn().
3547
 * Clearing/resetting of transient state belongs there; what we do here is
3548
 * release data that is to be held for the life of the PGconn structure.
3549
 * If a value ought to be cleared/freed during PQreset(), do it there not here.
3550
 */
3551
static void
3552
freePGconn(PGconn *conn)
3553
314
{
3554
314
  int     i;
3555
3556
  /* let any event procs clean up their state data */
3557
314
  for (i = 0; i < conn->nEvents; i++)
3558
0
  {
3559
0
    PGEventConnDestroy evt;
3560
3561
0
    evt.conn = conn;
3562
0
    (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
3563
0
                  conn->events[i].passThrough);
3564
0
    free(conn->events[i].name);
3565
0
  }
3566
3567
  /* clean up pg_conn_host structures */
3568
314
  if (conn->connhost != NULL)
3569
314
  {
3570
628
    for (i = 0; i < conn->nconnhost; ++i)
3571
314
    {
3572
314
      if (conn->connhost[i].host != NULL)
3573
314
        free(conn->connhost[i].host);
3574
314
      if (conn->connhost[i].hostaddr != NULL)
3575
0
        free(conn->connhost[i].hostaddr);
3576
314
      if (conn->connhost[i].port != NULL)
3577
314
        free(conn->connhost[i].port);
3578
314
      if (conn->connhost[i].password != NULL)
3579
0
        free(conn->connhost[i].password);
3580
314
    }
3581
314
    free(conn->connhost);
3582
314
  }
3583
3584
314
  if (conn->client_encoding_initial)
3585
13
    free(conn->client_encoding_initial);
3586
314
  if (conn->events)
3587
0
    free(conn->events);
3588
314
  if (conn->pghost)
3589
314
    free(conn->pghost);
3590
314
  if (conn->pghostaddr)
3591
0
    free(conn->pghostaddr);
3592
314
  if (conn->pgport)
3593
314
    free(conn->pgport);
3594
314
  if (conn->pgtty)
3595
314
    free(conn->pgtty);
3596
314
  if (conn->connect_timeout)
3597
0
    free(conn->connect_timeout);
3598
314
  if (conn->pgoptions)
3599
314
    free(conn->pgoptions);
3600
314
  if (conn->appname)
3601
65
    free(conn->appname);
3602
314
  if (conn->fbappname)
3603
54
    free(conn->fbappname);
3604
314
  if (conn->dbName)
3605
314
    free(conn->dbName);
3606
314
  if (conn->replication)
3607
0
    free(conn->replication);
3608
314
  if (conn->pguser)
3609
314
    free(conn->pguser);
3610
314
  if (conn->pgpass)
3611
235
    free(conn->pgpass);
3612
314
  if (conn->pgpassfile)
3613
79
    free(conn->pgpassfile);
3614
314
  if (conn->keepalives)
3615
0
    free(conn->keepalives);
3616
314
  if (conn->keepalives_idle)
3617
0
    free(conn->keepalives_idle);
3618
314
  if (conn->keepalives_interval)
3619
0
    free(conn->keepalives_interval);
3620
314
  if (conn->keepalives_count)
3621
0
    free(conn->keepalives_count);
3622
314
  if (conn->sslmode)
3623
314
    free(conn->sslmode);
3624
314
  if (conn->sslcert)
3625
0
    free(conn->sslcert);
3626
314
  if (conn->sslkey)
3627
0
    free(conn->sslkey);
3628
314
  if (conn->sslrootcert)
3629
0
    free(conn->sslrootcert);
3630
314
  if (conn->sslcrl)
3631
0
    free(conn->sslcrl);
3632
314
  if (conn->sslcompression)
3633
314
    free(conn->sslcompression);
3634
314
  if (conn->requirepeer)
3635
0
    free(conn->requirepeer);
3636
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
3637
  if (conn->krbsrvname)
3638
    free(conn->krbsrvname);
3639
#endif
3640
#if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
3641
  if (conn->gsslib)
3642
    free(conn->gsslib);
3643
#endif
3644
  /* Note that conn->Pfdebug is not ours to close or free */
3645
314
  if (conn->last_query)
3646
311
    free(conn->last_query);
3647
314
  if (conn->inBuffer)
3648
314
    free(conn->inBuffer);
3649
314
  if (conn->outBuffer)
3650
314
    free(conn->outBuffer);
3651
314
  if (conn->rowBuf)
3652
314
    free(conn->rowBuf);
3653
314
  if (conn->target_session_attrs)
3654
314
    free(conn->target_session_attrs);
3655
314
  termPQExpBuffer(&conn->errorMessage);
3656
314
  termPQExpBuffer(&conn->workBuffer);
3657
3658
314
  free(conn);
3659
3660
#ifdef WIN32
3661
  WSACleanup();
3662
#endif
3663
314
}
3664
3665
/*
3666
 * release_conn_addrinfo
3667
 *   - Free any addrinfo list in the PGconn.
3668
 */
3669
static void
3670
release_conn_addrinfo(PGconn *conn)
3671
943
{
3672
943
  if (conn->addrlist)
3673
316
  {
3674
316
    pg_freeaddrinfo_all(conn->addrlist_family, conn->addrlist);
3675
316
    conn->addrlist = NULL;
3676
316
    conn->addr_cur = NULL;  /* for safety */
3677
316
  }
3678
943
}
3679
3680
/*
3681
 * sendTerminateConn
3682
 *   - Send a terminate message to backend.
3683
 */
3684
static void
3685
sendTerminateConn(PGconn *conn)
3686
314
{
3687
  /*
3688
   * Note that the protocol doesn't allow us to send Terminate messages
3689
   * during the startup phase.
3690
   */
3691
314
  if (conn->sock != PGINVALID_SOCKET && conn->status == CONNECTION_OK)
3692
311
  {
3693
    /*
3694
     * Try to send "close connection" message to backend. Ignore any
3695
     * error.
3696
     */
3697
311
    pqPutMsgStart('X', false, conn);
3698
311
    pqPutMsgEnd(conn);
3699
311
    (void) pqFlush(conn);
3700
311
  }
3701
314
}
3702
3703
/*
3704
 * closePGconn
3705
 *   - properly close a connection to the backend
3706
 *
3707
 * This should reset or release all transient state, but NOT the connection
3708
 * parameters.  On exit, the PGconn should be in condition to start a fresh
3709
 * connection with the same parameters (see PQreset()).
3710
 */
3711
static void
3712
closePGconn(PGconn *conn)
3713
314
{
3714
  /*
3715
   * If possible, send Terminate message to close the connection politely.
3716
   */
3717
314
  sendTerminateConn(conn);
3718
3719
  /*
3720
   * Must reset the blocking status so a possible reconnect will work.
3721
   *
3722
   * Don't call PQsetnonblocking() because it will fail if it's unable to
3723
   * flush the connection.
3724
   */
3725
314
  conn->nonblocking = false;
3726
3727
  /*
3728
   * Close the connection, reset all transient state, flush I/O buffers.
3729
   */
3730
314
  pqDropConnection(conn, true);
3731
314
  conn->status = CONNECTION_BAD;  /* Well, not really _bad_ - just absent */
3732
314
  conn->asyncStatus = PGASYNC_IDLE;
3733
314
  conn->xactStatus = PQTRANS_IDLE;
3734
314
  pqClearAsyncResult(conn); /* deallocate result */
3735
314
  resetPQExpBuffer(&conn->errorMessage);
3736
314
  release_conn_addrinfo(conn);
3737
3738
  /* Reset all state obtained from server, too */
3739
314
  pqDropServerData(conn);
3740
314
}
3741
3742
/*
3743
 * PQfinish: properly close a connection to the backend. Also frees
3744
 * the PGconn data structure so it shouldn't be re-used after this.
3745
 */
3746
void
3747
PQfinish(PGconn *conn)
3748
315
{
3749
315
  if (conn)
3750
314
  {
3751
314
    closePGconn(conn);
3752
314
    freePGconn(conn);
3753
314
  }
3754
315
}
3755
3756
/*
3757
 * PQreset: resets the connection to the backend by closing the
3758
 * existing connection and creating a new one.
3759
 */
3760
void
3761
PQreset(PGconn *conn)
3762
0
{
3763
0
  if (conn)
3764
0
  {
3765
0
    closePGconn(conn);
3766
3767
0
    if (connectDBStart(conn) && connectDBComplete(conn))
3768
0
    {
3769
      /*
3770
       * Notify event procs of successful reset.  We treat an event proc
3771
       * failure as disabling the connection ... good idea?
3772
       */
3773
0
      int     i;
3774
3775
0
      for (i = 0; i < conn->nEvents; i++)
3776
0
      {
3777
0
        PGEventConnReset evt;
3778
3779
0
        evt.conn = conn;
3780
0
        if (!conn->events[i].proc(PGEVT_CONNRESET, &evt,
3781
0
                      conn->events[i].passThrough))
3782
0
        {
3783
0
          conn->status = CONNECTION_BAD;
3784
0
          printfPQExpBuffer(&conn->errorMessage,
3785
0
                    libpq_gettext("PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n"),
3786
0
                    conn->events[i].name);
3787
0
          break;
3788
0
        }
3789
0
      }
3790
0
    }
3791
0
  }
3792
0
}
3793
3794
3795
/*
3796
 * PQresetStart:
3797
 * resets the connection to the backend
3798
 * closes the existing connection and makes a new one
3799
 * Returns 1 on success, 0 on failure.
3800
 */
3801
int
3802
PQresetStart(PGconn *conn)
3803
0
{
3804
0
  if (conn)
3805
0
  {
3806
0
    closePGconn(conn);
3807
3808
0
    return connectDBStart(conn);
3809
0
  }
3810
3811
0
  return 0;
3812
0
}
3813
3814
3815
/*
3816
 * PQresetPoll:
3817
 * resets the connection to the backend
3818
 * closes the existing connection and makes a new one
3819
 */
3820
PostgresPollingStatusType
3821
PQresetPoll(PGconn *conn)
3822
0
{
3823
0
  if (conn)
3824
0
  {
3825
0
    PostgresPollingStatusType status = PQconnectPoll(conn);
3826
3827
0
    if (status == PGRES_POLLING_OK)
3828
0
    {
3829
      /*
3830
       * Notify event procs of successful reset.  We treat an event proc
3831
       * failure as disabling the connection ... good idea?
3832
       */
3833
0
      int     i;
3834
3835
0
      for (i = 0; i < conn->nEvents; i++)
3836
0
      {
3837
0
        PGEventConnReset evt;
3838
3839
0
        evt.conn = conn;
3840
0
        if (!conn->events[i].proc(PGEVT_CONNRESET, &evt,
3841
0
                      conn->events[i].passThrough))
3842
0
        {
3843
0
          conn->status = CONNECTION_BAD;
3844
0
          printfPQExpBuffer(&conn->errorMessage,
3845
0
                    libpq_gettext("PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n"),
3846
0
                    conn->events[i].name);
3847
0
          return PGRES_POLLING_FAILED;
3848
0
        }
3849
0
      }
3850
0
    }
3851
3852
0
    return status;
3853
0
  }
3854
3855
0
  return PGRES_POLLING_FAILED;
3856
0
}
3857
3858
/*
3859
 * PQgetCancel: get a PGcancel structure corresponding to a connection.
3860
 *
3861
 * A copy is needed to be able to cancel a running query from a different
3862
 * thread. If the same structure is used all structure members would have
3863
 * to be individually locked (if the entire structure was locked, it would
3864
 * be impossible to cancel a synchronous query because the structure would
3865
 * have to stay locked for the duration of the query).
3866
 */
3867
PGcancel *
3868
PQgetCancel(PGconn *conn)
3869
3.57k
{
3870
3.57k
  PGcancel   *cancel;
3871
3872
3.57k
  if (!conn)
3873
0
    return NULL;
3874
3875
3.57k
  if (conn->sock == PGINVALID_SOCKET)
3876
0
    return NULL;
3877
3878
3.57k
  cancel = malloc(sizeof(PGcancel));
3879
3.57k
  if (cancel == NULL)
3880
0
    return NULL;
3881
3882
3.57k
  memcpy(&cancel->raddr, &conn->raddr, sizeof(SockAddr));
3883
3.57k
  cancel->be_pid = conn->be_pid;
3884
3.57k
  cancel->be_key = conn->be_key;
3885
3886
3.57k
  return cancel;
3887
3.57k
}
3888
3889
/* PQfreeCancel: free a cancel structure */
3890
void
3891
PQfreeCancel(PGcancel *cancel)
3892
3.57k
{
3893
3.57k
  if (cancel)
3894
3.57k
    free(cancel);
3895
3.57k
}
3896
3897
3898
/*
3899
 * PQcancel and PQrequestCancel: attempt to request cancellation of the
3900
 * current operation.
3901
 *
3902
 * The return value is true if the cancel request was successfully
3903
 * dispatched, false if not (in which case an error message is available).
3904
 * Note: successful dispatch is no guarantee that there will be any effect at
3905
 * the backend.  The application must read the operation result as usual.
3906
 *
3907
 * CAUTION: we want this routine to be safely callable from a signal handler
3908
 * (for example, an application might want to call it in a SIGINT handler).
3909
 * This means we cannot use any C library routine that might be non-reentrant.
3910
 * malloc/free are often non-reentrant, and anything that might call them is
3911
 * just as dangerous.  We avoid sprintf here for that reason.  Building up
3912
 * error messages with strcpy/strcat is tedious but should be quite safe.
3913
 * We also save/restore errno in case the signal handler support doesn't.
3914
 *
3915
 * internal_cancel() is an internal helper function to make code-sharing
3916
 * between the two versions of the cancel function possible.
3917
 */
3918
static int
3919
internal_cancel(SockAddr *raddr, int be_pid, int be_key,
3920
        char *errbuf, int errbufsize)
3921
0
{
3922
0
  int     save_errno = SOCK_ERRNO;
3923
0
  pgsocket  tmpsock = PGINVALID_SOCKET;
3924
0
  char    sebuf[256];
3925
0
  int     maxlen;
3926
0
  struct
3927
0
  {
3928
0
    uint32    packetlen;
3929
0
    CancelRequestPacket cp;
3930
0
  }     crp;
3931
3932
  /*
3933
   * We need to open a temporary connection to the postmaster. Do this with
3934
   * only kernel calls.
3935
   */
3936
0
  if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
3937
0
  {
3938
0
    strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
3939
0
    goto cancel_errReturn;
3940
0
  }
3941
0
retry3:
3942
0
  if (connect(tmpsock, (struct sockaddr *) &raddr->addr,
3943
0
        raddr->salen) < 0)
3944
0
  {
3945
0
    if (SOCK_ERRNO == EINTR)
3946
      /* Interrupted system call - we'll just try again */
3947
0
      goto retry3;
3948
0
    strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize);
3949
0
    goto cancel_errReturn;
3950
0
  }
3951
3952
  /*
3953
   * We needn't set nonblocking I/O or NODELAY options here.
3954
   */
3955
3956
  /* Create and send the cancel request packet. */
3957
3958
0
  crp.packetlen = pg_hton32((uint32) sizeof(crp));
3959
0
  crp.cp.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE);
3960
0
  crp.cp.backendPID = pg_hton32(be_pid);
3961
0
  crp.cp.cancelAuthCode = pg_hton32(be_key);
3962
3963
0
retry4:
3964
0
  if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp))
3965
0
  {
3966
0
    if (SOCK_ERRNO == EINTR)
3967
      /* Interrupted system call - we'll just try again */
3968
0
      goto retry4;
3969
0
    strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize);
3970
0
    goto cancel_errReturn;
3971
0
  }
3972
3973
  /*
3974
   * Wait for the postmaster to close the connection, which indicates that
3975
   * it's processed the request.  Without this delay, we might issue another
3976
   * command only to find that our cancel zaps that command instead of the
3977
   * one we thought we were canceling.  Note we don't actually expect this
3978
   * read to obtain any data, we are just waiting for EOF to be signaled.
3979
   */
3980
0
retry5:
3981
0
  if (recv(tmpsock, (char *) &crp, 1, 0) < 0)
3982
0
  {
3983
0
    if (SOCK_ERRNO == EINTR)
3984
      /* Interrupted system call - we'll just try again */
3985
0
      goto retry5;
3986
    /* we ignore other error conditions */
3987
0
  }
3988
3989
  /* All done */
3990
0
  closesocket(tmpsock);
3991
0
  SOCK_ERRNO_SET(save_errno);
3992
0
  return true;
3993
3994
0
cancel_errReturn:
3995
3996
  /*
3997
   * Make sure we don't overflow the error buffer. Leave space for the \n at
3998
   * the end, and for the terminating zero.
3999
   */
4000
0
  maxlen = errbufsize - strlen(errbuf) - 2;
4001
0
  if (maxlen >= 0)
4002
0
  {
4003
0
    strncat(errbuf, SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)),
4004
0
        maxlen);
4005
0
    strcat(errbuf, "\n");
4006
0
  }
4007
0
  if (tmpsock != PGINVALID_SOCKET)
4008
0
    closesocket(tmpsock);
4009
0
  SOCK_ERRNO_SET(save_errno);
4010
0
  return false;
4011
0
}
4012
4013
/*
4014
 * PQcancel: request query cancel
4015
 *
4016
 * Returns true if able to send the cancel request, false if not.
4017
 *
4018
 * On failure, an error message is stored in *errbuf, which must be of size
4019
 * errbufsize (recommended size is 256 bytes).  *errbuf is not changed on
4020
 * success return.
4021
 */
4022
int
4023
PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
4024
0
{
4025
0
  if (!cancel)
4026
0
  {
4027
0
    strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize);
4028
0
    return false;
4029
0
  }
4030
4031
0
  return internal_cancel(&cancel->raddr, cancel->be_pid, cancel->be_key,
4032
0
               errbuf, errbufsize);
4033
0
}
4034
4035
/*
4036
 * PQrequestCancel: old, not thread-safe function for requesting query cancel
4037
 *
4038
 * Returns true if able to send the cancel request, false if not.
4039
 *
4040
 * On failure, the error message is saved in conn->errorMessage; this means
4041
 * that this can't be used when there might be other active operations on
4042
 * the connection object.
4043
 *
4044
 * NOTE: error messages will be cut off at the current size of the
4045
 * error message buffer, since we dare not try to expand conn->errorMessage!
4046
 */
4047
int
4048
PQrequestCancel(PGconn *conn)
4049
0
{
4050
0
  int     r;
4051
4052
  /* Check we have an open connection */
4053
0
  if (!conn)
4054
0
    return false;
4055
4056
0
  if (conn->sock == PGINVALID_SOCKET)
4057
0
  {
4058
0
    strlcpy(conn->errorMessage.data,
4059
0
        "PQrequestCancel() -- connection is not open\n",
4060
0
        conn->errorMessage.maxlen);
4061
0
    conn->errorMessage.len = strlen(conn->errorMessage.data);
4062
4063
0
    return false;
4064
0
  }
4065
4066
0
  r = internal_cancel(&conn->raddr, conn->be_pid, conn->be_key,
4067
0
            conn->errorMessage.data, conn->errorMessage.maxlen);
4068
4069
0
  if (!r)
4070
0
    conn->errorMessage.len = strlen(conn->errorMessage.data);
4071
4072
0
  return r;
4073
0
}
4074
4075
4076
/*
4077
 * pqPacketSend() -- convenience routine to send a message to server.
4078
 *
4079
 * pack_type: the single-byte message type code.  (Pass zero for startup
4080
 * packets, which have no message type code.)
4081
 *
4082
 * buf, buf_len: contents of message.  The given length includes only what
4083
 * is in buf; the message type and message length fields are added here.
4084
 *
4085
 * RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
4086
 * SIDE_EFFECTS: may block.
4087
 *
4088
 * Note: all messages sent with this routine have a length word, whether
4089
 * it's protocol 2.0 or 3.0.
4090
 */
4091
int
4092
pqPacketSend(PGconn *conn, char pack_type,
4093
       const void *buf, size_t buf_len)
4094
632
{
4095
  /* Start the message. */
4096
632
  if (pqPutMsgStart(pack_type, true, conn))
4097
0
    return STATUS_ERROR;
4098
4099
  /* Send the message body. */
4100
632
  if (pqPutnchar(buf, buf_len, conn))
4101
0
    return STATUS_ERROR;
4102
4103
  /* Finish the message. */
4104
632
  if (pqPutMsgEnd(conn))
4105
0
    return STATUS_ERROR;
4106
4107
  /* Flush to ensure backend gets it. */
4108
632
  if (pqFlush(conn))
4109
0
    return STATUS_ERROR;
4110
4111
632
  return STATUS_OK;
4112
632
}
4113
4114
#ifdef USE_LDAP
4115
4116
0
#define LDAP_URL  "ldap://"
4117
0
#define LDAP_DEF_PORT 389
4118
0
#define PGLDAP_TIMEOUT 2
4119
4120
0
#define ld_is_sp_tab(x) ((x) == ' ' || (x) == '\t')
4121
0
#define ld_is_nl_cr(x) ((x) == '\r' || (x) == '\n')
4122
4123
4124
/*
4125
 *    ldapServiceLookup
4126
 *
4127
 * Search the LDAP URL passed as first argument, treat the result as a
4128
 * string of connection options that are parsed and added to the array of
4129
 * options passed as second argument.
4130
 *
4131
 * LDAP URLs must conform to RFC 1959 without escape sequences.
4132
 *  ldap://host:port/dn?attributes?scope?filter?extensions
4133
 *
4134
 * Returns
4135
 *  0 if the lookup was successful,
4136
 *  1 if the connection to the LDAP server could be established but
4137
 *    the search was unsuccessful,
4138
 *  2 if a connection could not be established, and
4139
 *  3 if a fatal error occurred.
4140
 *
4141
 * An error message is returned in the third argument for return codes 1 and 3.
4142
 */
4143
static int
4144
ldapServiceLookup(const char *purl, PQconninfoOption *options,
4145
          PQExpBuffer errorMessage)
4146
0
{
4147
0
  int     port = LDAP_DEF_PORT,
4148
0
        scope,
4149
0
        rc,
4150
0
        size,
4151
0
        state,
4152
0
        oldstate,
4153
0
        i;
4154
0
#ifndef WIN32
4155
0
  int     msgid;
4156
0
#endif
4157
0
  bool    found_keyword;
4158
0
  char     *url,
4159
0
         *hostname,
4160
0
         *portstr,
4161
0
         *endptr,
4162
0
         *dn,
4163
0
         *scopestr,
4164
0
         *filter,
4165
0
         *result,
4166
0
         *p,
4167
0
         *p1 = NULL,
4168
0
         *optname = NULL,
4169
0
         *optval = NULL;
4170
0
  char     *attrs[2] = {NULL, NULL};
4171
0
  LDAP     *ld = NULL;
4172
0
  LDAPMessage *res,
4173
0
         *entry;
4174
0
  struct berval **values;
4175
0
  LDAP_TIMEVAL time = {PGLDAP_TIMEOUT, 0};
4176
4177
0
  if ((url = strdup(purl)) == NULL)
4178
0
  {
4179
0
    printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
4180
0
    return 3;
4181
0
  }
4182
4183
  /*
4184
   * Parse URL components, check for correctness.  Basically, url has '\0'
4185
   * placed at component boundaries and variables are pointed at each
4186
   * component.
4187
   */
4188
4189
0
  if (pg_strncasecmp(url, LDAP_URL, strlen(LDAP_URL)) != 0)
4190
0
  {
4191
0
    printfPQExpBuffer(errorMessage,
4192
0
              libpq_gettext("invalid LDAP URL \"%s\": scheme must be ldap://\n"), purl);
4193
0
    free(url);
4194
0
    return 3;
4195
0
  }
4196
4197
  /* hostname */
4198
0
  hostname = url + strlen(LDAP_URL);
4199
0
  if (*hostname == '/')   /* no hostname? */
4200
0
    hostname = DefaultHost; /* the default */
4201
4202
  /* dn, "distinguished name" */
4203
0
  p = strchr(url + strlen(LDAP_URL), '/');
4204
0
  if (p == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
4205
0
  {
4206
0
    printfPQExpBuffer(errorMessage, libpq_gettext(
4207
0
                            "invalid LDAP URL \"%s\": missing distinguished name\n"), purl);
4208
0
    free(url);
4209
0
    return 3;
4210
0
  }
4211
0
  *p = '\0';          /* terminate hostname */
4212
0
  dn = p + 1;
4213
4214
  /* attribute */
4215
0
  if ((p = strchr(dn, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
4216
0
  {
4217
0
    printfPQExpBuffer(errorMessage, libpq_gettext(
4218
0
                            "invalid LDAP URL \"%s\": must have exactly one attribute\n"), purl);
4219
0
    free(url);
4220
0
    return 3;
4221
0
  }
4222
0
  *p = '\0';
4223
0
  attrs[0] = p + 1;
4224
4225
  /* scope */
4226
0
  if ((p = strchr(attrs[0], '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
4227
0
  {
4228
0
    printfPQExpBuffer(errorMessage, libpq_gettext("invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n"), purl);
4229
0
    free(url);
4230
0
    return 3;
4231
0
  }
4232
0
  *p = '\0';
4233
0
  scopestr = p + 1;
4234
4235
  /* filter */
4236
0
  if ((p = strchr(scopestr, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
4237
0
  {
4238
0
    printfPQExpBuffer(errorMessage,
4239
0
              libpq_gettext("invalid LDAP URL \"%s\": no filter\n"), purl);
4240
0
    free(url);
4241
0
    return 3;
4242
0
  }
4243
0
  *p = '\0';
4244
0
  filter = p + 1;
4245
0
  if ((p = strchr(filter, '?')) != NULL)
4246
0
    *p = '\0';
4247
4248
  /* port number? */
4249
0
  if ((p1 = strchr(hostname, ':')) != NULL)
4250
0
  {
4251
0
    long    lport;
4252
4253
0
    *p1 = '\0';
4254
0
    portstr = p1 + 1;
4255
0
    errno = 0;
4256
0
    lport = strtol(portstr, &endptr, 10);
4257
0
    if (*portstr == '\0' || *endptr != '\0' || errno || lport < 0 || lport > 65535)
4258
0
    {
4259
0
      printfPQExpBuffer(errorMessage, libpq_gettext(
4260
0
                              "invalid LDAP URL \"%s\": invalid port number\n"), purl);
4261
0
      free(url);
4262
0
      return 3;
4263
0
    }
4264
0
    port = (int) lport;
4265
0
  }
4266
4267
  /* Allow only one attribute */
4268
0
  if (strchr(attrs[0], ',') != NULL)
4269
0
  {
4270
0
    printfPQExpBuffer(errorMessage, libpq_gettext(
4271
0
                            "invalid LDAP URL \"%s\": must have exactly one attribute\n"), purl);
4272
0
    free(url);
4273
0
    return 3;
4274
0
  }
4275
4276
  /* set scope */
4277
0
  if (pg_strcasecmp(scopestr, "base") == 0)
4278
0
    scope = LDAP_SCOPE_BASE;
4279
0
  else if (pg_strcasecmp(scopestr, "one") == 0)
4280
0
    scope = LDAP_SCOPE_ONELEVEL;
4281
0
  else if (pg_strcasecmp(scopestr, "sub") == 0)
4282
0
    scope = LDAP_SCOPE_SUBTREE;
4283
0
  else
4284
0
  {
4285
0
    printfPQExpBuffer(errorMessage, libpq_gettext("invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n"), purl);
4286
0
    free(url);
4287
0
    return 3;
4288
0
  }
4289
4290
  /* initialize LDAP structure */
4291
0
  if ((ld = ldap_init(hostname, port)) == NULL)
4292
0
  {
4293
0
    printfPQExpBuffer(errorMessage,
4294
0
              libpq_gettext("could not create LDAP structure\n"));
4295
0
    free(url);
4296
0
    return 3;
4297
0
  }
4298
4299
  /*
4300
   * Perform an explicit anonymous bind.
4301
   *
4302
   * LDAP does not require that an anonymous bind is performed explicitly,
4303
   * but we want to distinguish between the case where LDAP bind does not
4304
   * succeed within PGLDAP_TIMEOUT seconds (return 2 to continue parsing the
4305
   * service control file) and the case where querying the LDAP server fails
4306
   * (return 1 to end parsing).
4307
   *
4308
   * Unfortunately there is no way of setting a timeout that works for both
4309
   * Windows and OpenLDAP.
4310
   */
4311
#ifdef WIN32
4312
  /* the nonstandard ldap_connect function performs an anonymous bind */
4313
  if (ldap_connect(ld, &time) != LDAP_SUCCESS)
4314
  {
4315
    /* error or timeout in ldap_connect */
4316
    free(url);
4317
    ldap_unbind(ld);
4318
    return 2;
4319
  }
4320
#else             /* !WIN32 */
4321
  /* in OpenLDAP, use the LDAP_OPT_NETWORK_TIMEOUT option */
4322
0
  if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
4323
0
  {
4324
0
    free(url);
4325
0
    ldap_unbind(ld);
4326
0
    return 3;
4327
0
  }
4328
4329
  /* anonymous bind */
4330
0
  if ((msgid = ldap_simple_bind(ld, NULL, NULL)) == -1)
4331
0
  {
4332
    /* error or network timeout */
4333
0
    free(url);
4334
0
    ldap_unbind(ld);
4335
0
    return 2;
4336
0
  }
4337
4338
  /* wait some time for the connection to succeed */
4339
0
  res = NULL;
4340
0
  if ((rc = ldap_result(ld, msgid, LDAP_MSG_ALL, &time, &res)) == -1 ||
4341
0
    res == NULL)
4342
0
  {
4343
    /* error or timeout */
4344
0
    if (res != NULL)
4345
0
      ldap_msgfree(res);
4346
0
    free(url);
4347
0
    ldap_unbind(ld);
4348
0
    return 2;
4349
0
  }
4350
0
  ldap_msgfree(res);
4351
4352
  /* reset timeout */
4353
0
  time.tv_sec = -1;
4354
0
  if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
4355
0
  {
4356
0
    free(url);
4357
0
    ldap_unbind(ld);
4358
0
    return 3;
4359
0
  }
4360
0
#endif              /* WIN32 */
4361
4362
  /* search */
4363
0
  res = NULL;
4364
0
  if ((rc = ldap_search_st(ld, dn, scope, filter, attrs, 0, &time, &res))
4365
0
    != LDAP_SUCCESS)
4366
0
  {
4367
0
    if (res != NULL)
4368
0
      ldap_msgfree(res);
4369
0
    printfPQExpBuffer(errorMessage,
4370
0
              libpq_gettext("lookup on LDAP server failed: %s\n"),
4371
0
              ldap_err2string(rc));
4372
0
    ldap_unbind(ld);
4373
0
    free(url);
4374
0
    return 1;
4375
0
  }
4376
4377
  /* complain if there was not exactly one result */
4378
0
  if ((rc = ldap_count_entries(ld, res)) != 1)
4379
0
  {
4380
0
    printfPQExpBuffer(errorMessage,
4381
0
              rc ? libpq_gettext("more than one entry found on LDAP lookup\n")
4382
0
              : libpq_gettext("no entry found on LDAP lookup\n"));
4383
0
    ldap_msgfree(res);
4384
0
    ldap_unbind(ld);
4385
0
    free(url);
4386
0
    return 1;
4387
0
  }
4388
4389
  /* get entry */
4390
0
  if ((entry = ldap_first_entry(ld, res)) == NULL)
4391
0
  {
4392
    /* should never happen */
4393
0
    printfPQExpBuffer(errorMessage,
4394
0
              libpq_gettext("no entry found on LDAP lookup\n"));
4395
0
    ldap_msgfree(res);
4396
0
    ldap_unbind(ld);
4397
0
    free(url);
4398
0
    return 1;
4399
0
  }
4400
4401
  /* get values */
4402
0
  if ((values = ldap_get_values_len(ld, entry, attrs[0])) == NULL)
4403
0
  {
4404
0
    printfPQExpBuffer(errorMessage,
4405
0
              libpq_gettext("attribute has no values on LDAP lookup\n"));
4406
0
    ldap_msgfree(res);
4407
0
    ldap_unbind(ld);
4408
0
    free(url);
4409
0
    return 1;
4410
0
  }
4411
4412
0
  ldap_msgfree(res);
4413
0
  free(url);
4414
4415
0
  if (values[0] == NULL)
4416
0
  {
4417
0
    printfPQExpBuffer(errorMessage,
4418
0
              libpq_gettext("attribute has no values on LDAP lookup\n"));
4419
0
    ldap_value_free_len(values);
4420
0
    ldap_unbind(ld);
4421
0
    return 1;
4422
0
  }
4423
4424
  /* concatenate values into a single string with newline terminators */
4425
0
  size = 1;         /* for the trailing null */
4426
0
  for (i = 0; values[i] != NULL; i++)
4427
0
    size += values[i]->bv_len + 1;
4428
0
  if ((result = malloc(size)) == NULL)
4429
0
  {
4430
0
    printfPQExpBuffer(errorMessage,
4431
0
              libpq_gettext("out of memory\n"));
4432
0
    ldap_value_free_len(values);
4433
0
    ldap_unbind(ld);
4434
0
    return 3;
4435
0
  }
4436
0
  p = result;
4437
0
  for (i = 0; values[i] != NULL; i++)
4438
0
  {
4439
0
    memcpy(p, values[i]->bv_val, values[i]->bv_len);
4440
0
    p += values[i]->bv_len;
4441
0
    *(p++) = '\n';
4442
0
  }
4443
0
  *p = '\0';
4444
4445
0
  ldap_value_free_len(values);
4446
0
  ldap_unbind(ld);
4447
4448
  /* parse result string */
4449
0
  oldstate = state = 0;
4450
0
  for (p = result; *p != '\0'; ++p)
4451
0
  {
4452
0
    switch (state)
4453
0
    {
4454
0
      case 0:       /* between entries */
4455
0
        if (!ld_is_sp_tab(*p) && !ld_is_nl_cr(*p))
4456
0
        {
4457
0
          optname = p;
4458
0
          state = 1;
4459
0
        }
4460
0
        break;
4461
0
      case 1:       /* in option name */
4462
0
        if (ld_is_sp_tab(*p))
4463
0
        {
4464
0
          *p = '\0';
4465
0
          state = 2;
4466
0
        }
4467
0
        else if (ld_is_nl_cr(*p))
4468
0
        {
4469
0
          printfPQExpBuffer(errorMessage, libpq_gettext(
4470
0
                                  "missing \"=\" after \"%s\" in connection info string\n"),
4471
0
                    optname);
4472
0
          free(result);
4473
0
          return 3;
4474
0
        }
4475
0
        else if (*p == '=')
4476
0
        {
4477
0
          *p = '\0';
4478
0
          state = 3;
4479
0
        }
4480
0
        break;
4481
0
      case 2:       /* after option name */
4482
0
        if (*p == '=')
4483
0
        {
4484
0
          state = 3;
4485
0
        }
4486
0
        else if (!ld_is_sp_tab(*p))
4487
0
        {
4488
0
          printfPQExpBuffer(errorMessage, libpq_gettext(
4489
0
                                  "missing \"=\" after \"%s\" in connection info string\n"),
4490
0
                    optname);
4491
0
          free(result);
4492
0
          return 3;
4493
0
        }
4494
0
        break;
4495
0
      case 3:       /* before option value */
4496
0
        if (*p == '\'')
4497
0
        {
4498
0
          optval = p + 1;
4499
0
          p1 = p + 1;
4500
0
          state = 5;
4501
0
        }
4502
0
        else if (ld_is_nl_cr(*p))
4503
0
        {
4504
0
          optval = optname + strlen(optname); /* empty */
4505
0
          state = 0;
4506
0
        }
4507
0
        else if (!ld_is_sp_tab(*p))
4508
0
        {
4509
0
          optval = p;
4510
0
          state = 4;
4511
0
        }
4512
0
        break;
4513
0
      case 4:       /* in unquoted option value */
4514
0
        if (ld_is_sp_tab(*p) || ld_is_nl_cr(*p))
4515
0
        {
4516
0
          *p = '\0';
4517
0
          state = 0;
4518
0
        }
4519
0
        break;
4520
0
      case 5:       /* in quoted option value */
4521
0
        if (*p == '\'')
4522
0
        {
4523
0
          *p1 = '\0';
4524
0
          state = 0;
4525
0
        }
4526
0
        else if (*p == '\\')
4527
0
          state = 6;
4528
0
        else
4529
0
          *(p1++) = *p;
4530
0
        break;
4531
0
      case 6:       /* in quoted option value after escape */
4532
0
        *(p1++) = *p;
4533
0
        state = 5;
4534
0
        break;
4535
0
    }
4536
4537
0
    if (state == 0 && oldstate != 0)
4538
0
    {
4539
0
      found_keyword = false;
4540
0
      for (i = 0; options[i].keyword; i++)
4541
0
      {
4542
0
        if (strcmp(options[i].keyword, optname) == 0)
4543
0
        {
4544
0
          if (options[i].val == NULL)
4545
0
          {
4546
0
            options[i].val = strdup(optval);
4547
0
            if (!options[i].val)
4548
0
            {
4549
0
              printfPQExpBuffer(errorMessage,
4550
0
                        libpq_gettext("out of memory\n"));
4551
0
              free(result);
4552
0
              return 3;
4553
0
            }
4554
0
          }
4555
0
          found_keyword = true;
4556
0
          break;
4557
0
        }
4558
0
      }
4559
0
      if (!found_keyword)
4560
0
      {
4561
0
        printfPQExpBuffer(errorMessage,
4562
0
                  libpq_gettext("invalid connection option \"%s\"\n"),
4563
0
                  optname);
4564
0
        free(result);
4565
0
        return 1;
4566
0
      }
4567
0
      optname = NULL;
4568
0
      optval = NULL;
4569
0
    }
4570
0
    oldstate = state;
4571
0
  }
4572
4573
0
  free(result);
4574
4575
0
  if (state == 5 || state == 6)
4576
0
  {
4577
0
    printfPQExpBuffer(errorMessage, libpq_gettext(
4578
0
                            "unterminated quoted string in connection info string\n"));
4579
0
    return 3;
4580
0
  }
4581
4582
0
  return 0;
4583
0
}
4584
4585
#endif              /* USE_LDAP */
4586
4587
#define MAXBUFSIZE 256
4588
4589
/*
4590
 * parseServiceInfo: if a service name has been given, look it up and absorb
4591
 * connection options from it into *options.
4592
 *
4593
 * Returns 0 on success, nonzero on failure.  On failure, if errorMessage
4594
 * isn't null, also store an error message there.  (Note: the only reason
4595
 * this function and related ones don't dump core on errorMessage == NULL
4596
 * is the undocumented fact that printfPQExpBuffer does nothing when passed
4597
 * a null PQExpBuffer pointer.)
4598
 */
4599
static int
4600
parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
4601
317
{
4602
317
  const char *service = conninfo_getval(options, "service");
4603
317
  char    serviceFile[MAXPGPATH];
4604
317
  char     *env;
4605
317
  bool    group_found = false;
4606
317
  int     status;
4607
317
  struct stat stat_buf;
4608
4609
  /*
4610
   * We have to special-case the environment variable PGSERVICE here, since
4611
   * this is and should be called before inserting environment defaults for
4612
   * other connection options.
4613
   */
4614
317
  if (service == NULL)
4615
317
    service = getenv("PGSERVICE");
4616
4617
  /* If no service name given, nothing to do */
4618
317
  if (service == NULL)
4619
317
    return 0;
4620
4621
  /*
4622
   * Try PGSERVICEFILE if specified, else try ~/.pg_service.conf (if that
4623
   * exists).
4624
   */
4625
0
  if ((env = getenv("PGSERVICEFILE")) != NULL)
4626
0
    strlcpy(serviceFile, env, sizeof(serviceFile));
4627
0
  else
4628
0
  {
4629
0
    char    homedir[MAXPGPATH];
4630
4631
0
    if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
4632
0
      goto next_file;
4633
0
    snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
4634
0
    if (stat(serviceFile, &stat_buf) != 0)
4635
0
      goto next_file;
4636
0
  }
4637
4638
0
  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4639
0
  if (group_found || status != 0)
4640
0
    return status;
4641
4642
0
next_file:
4643
4644
  /*
4645
   * This could be used by any application so we can't use the binary
4646
   * location to find our config files.
4647
   */
4648
0
  snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
4649
0
       getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
4650
0
  if (stat(serviceFile, &stat_buf) != 0)
4651
0
    goto last_file;
4652
4653
0
  status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
4654
0
  if (status != 0)
4655
0
    return status;
4656
4657
0
last_file:
4658
0
  if (!group_found)
4659
0
  {
4660
0
    printfPQExpBuffer(errorMessage,
4661
0
              libpq_gettext("definition of service \"%s\" not found\n"), service);
4662
0
    return 3;
4663
0
  }
4664
4665
0
  return 0;
4666
0
}
4667
4668
static int
4669
parseServiceFile(const char *serviceFile,
4670
         const char *service,
4671
         PQconninfoOption *options,
4672
         PQExpBuffer errorMessage,
4673
         bool *group_found)
4674
0
{
4675
0
  int     linenr = 0,
4676
0
        i;
4677
0
  FILE     *f;
4678
0
  char    buf[MAXBUFSIZE],
4679
0
         *line;
4680
4681
0
  f = fopen(serviceFile, "r");
4682
0
  if (f == NULL)
4683
0
  {
4684
0
    printfPQExpBuffer(errorMessage, libpq_gettext("service file \"%s\" not found\n"),
4685
0
              serviceFile);
4686
0
    return 1;
4687
0
  }
4688
4689
0
  while ((line = fgets(buf, sizeof(buf), f)) != NULL)
4690
0
  {
4691
0
    linenr++;
4692
4693
0
    if (strlen(line) >= sizeof(buf) - 1)
4694
0
    {
4695
0
      fclose(f);
4696
0
      printfPQExpBuffer(errorMessage,
4697
0
                libpq_gettext("line %d too long in service file \"%s\"\n"),
4698
0
                linenr,
4699
0
                serviceFile);
4700
0
      return 2;
4701
0
    }
4702
4703
    /* ignore EOL at end of line */
4704
0
    if (strlen(line) && line[strlen(line) - 1] == '\n')
4705
0
      line[strlen(line) - 1] = 0;
4706
4707
    /* ignore leading blanks */
4708
0
    while (*line && isspace((unsigned char) line[0]))
4709
0
      line++;
4710
4711
    /* ignore comments and empty lines */
4712
0
    if (strlen(line) == 0 || line[0] == '#')
4713
0
      continue;
4714
4715
    /* Check for right groupname */
4716
0
    if (line[0] == '[')
4717
0
    {
4718
0
      if (*group_found)
4719
0
      {
4720
        /* group info already read */
4721
0
        fclose(f);
4722
0
        return 0;
4723
0
      }
4724
4725
0
      if (strncmp(line + 1, service, strlen(service)) == 0 &&
4726
0
        line[strlen(service) + 1] == ']')
4727
0
        *group_found = true;
4728
0
      else
4729
0
        *group_found = false;
4730
0
    }
4731
0
    else
4732
0
    {
4733
0
      if (*group_found)
4734
0
      {
4735
        /*
4736
         * Finally, we are in the right group and can parse the line
4737
         */
4738
0
        char     *key,
4739
0
               *val;
4740
0
        bool    found_keyword;
4741
4742
0
#ifdef USE_LDAP
4743
0
        if (strncmp(line, "ldap", 4) == 0)
4744
0
        {
4745
0
          int     rc = ldapServiceLookup(line, options, errorMessage);
4746
4747
          /* if rc = 2, go on reading for fallback */
4748
0
          switch (rc)
4749
0
          {
4750
0
            case 0:
4751
0
              fclose(f);
4752
0
              return 0;
4753
0
            case 1:
4754
0
            case 3:
4755
0
              fclose(f);
4756
0
              return 3;
4757
0
            case 2:
4758
0
              continue;
4759
0
          }
4760
0
        }
4761
0
#endif
4762
4763
0
        key = line;
4764
0
        val = strchr(line, '=');
4765
0
        if (val == NULL)
4766
0
        {
4767
0
          printfPQExpBuffer(errorMessage,
4768
0
                    libpq_gettext("syntax error in service file \"%s\", line %d\n"),
4769
0
                    serviceFile,
4770
0
                    linenr);
4771
0
          fclose(f);
4772
0
          return 3;
4773
0
        }
4774
0
        *val++ = '\0';
4775
4776
0
        if (strcmp(key, "service") == 0)
4777
0
        {
4778
0
          printfPQExpBuffer(errorMessage,
4779
0
                    libpq_gettext("nested service specifications not supported in service file \"%s\", line %d\n"),
4780
0
                    serviceFile,
4781
0
                    linenr);
4782
0
          fclose(f);
4783
0
          return 3;
4784
0
        }
4785
4786
        /*
4787
         * Set the parameter --- but don't override any previous
4788
         * explicit setting.
4789
         */
4790
0
        found_keyword = false;
4791
0
        for (i = 0; options[i].keyword; i++)
4792
0
        {
4793
0
          if (strcmp(options[i].keyword, key) == 0)
4794
0
          {
4795
0
            if (options[i].val == NULL)
4796
0
              options[i].val = strdup(val);
4797
0
            if (!options[i].val)
4798
0
            {
4799
0
              printfPQExpBuffer(errorMessage,
4800
0
                        libpq_gettext("out of memory\n"));
4801
0
              fclose(f);
4802
0
              return 3;
4803
0
            }
4804
0
            found_keyword = true;
4805
0
            break;
4806
0
          }
4807
0
        }
4808
4809
0
        if (!found_keyword)
4810
0
        {
4811
0
          printfPQExpBuffer(errorMessage,
4812
0
                    libpq_gettext("syntax error in service file \"%s\", line %d\n"),
4813
0
                    serviceFile,
4814
0
                    linenr);
4815
0
          fclose(f);
4816
0
          return 3;
4817
0
        }
4818
0
      }
4819
0
    }
4820
0
  }
4821
4822
0
  fclose(f);
4823
4824
0
  return 0;
4825
0
}
4826
4827
4828
/*
4829
 *    PQconninfoParse
4830
 *
4831
 * Parse a string like PQconnectdb() would do and return the
4832
 * resulting connection options array.  NULL is returned on failure.
4833
 * The result contains only options specified directly in the string,
4834
 * not any possible default values.
4835
 *
4836
 * If errmsg isn't NULL, *errmsg is set to NULL on success, or a malloc'd
4837
 * string on failure (use PQfreemem to free it).  In out-of-memory conditions
4838
 * both *errmsg and the result could be NULL.
4839
 *
4840
 * NOTE: the returned array is dynamically allocated and should
4841
 * be freed when no longer needed via PQconninfoFree().
4842
 */
4843
PQconninfoOption *
4844
PQconninfoParse(const char *conninfo, char **errmsg)
4845
0
{
4846
0
  PQExpBufferData errorBuf;
4847
0
  PQconninfoOption *connOptions;
4848
4849
0
  if (errmsg)
4850
0
    *errmsg = NULL;     /* default */
4851
0
  initPQExpBuffer(&errorBuf);
4852
0
  if (PQExpBufferDataBroken(errorBuf))
4853
0
    return NULL;     /* out of memory already :-( */
4854
0
  connOptions = parse_connection_string(conninfo, &errorBuf, false);
4855
0
  if (connOptions == NULL && errmsg)
4856
0
    *errmsg = errorBuf.data;
4857
0
  else
4858
0
    termPQExpBuffer(&errorBuf);
4859
0
  return connOptions;
4860
0
}
4861
4862
/*
4863
 * Build a working copy of the constant PQconninfoOptions array.
4864
 */
4865
static PQconninfoOption *
4866
conninfo_init(PQExpBuffer errorMessage)
4867
320
{
4868
320
  PQconninfoOption *options;
4869
320
  PQconninfoOption *opt_dest;
4870
320
  const internalPQconninfoOption *cur_opt;
4871
4872
  /*
4873
   * Get enough memory for all options in PQconninfoOptions, even if some
4874
   * end up being filtered out.
4875
   */
4876
320
  options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
4877
320
  if (options == NULL)
4878
0
  {
4879
0
    printfPQExpBuffer(errorMessage,
4880
0
              libpq_gettext("out of memory\n"));
4881
0
    return NULL;
4882
0
  }
4883
320
  opt_dest = options;
4884
4885
9.28k
  for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
4886
8.96k
  {
4887
    /* Only copy the public part of the struct, not the full internal */
4888
8.96k
    memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
4889
8.96k
    opt_dest++;
4890
8.96k
  }
4891
320
  MemSet(opt_dest, 0, sizeof(PQconninfoOption));
4892
4893
320
  return options;
4894
320
}
4895
4896
/*
4897
 * Connection string parser
4898
 *
4899
 * Returns a malloc'd PQconninfoOption array, if parsing is successful.
4900
 * Otherwise, NULL is returned and an error message is left in errorMessage.
4901
 *
4902
 * If use_defaults is true, default values are filled in (from a service file,
4903
 * environment variables, etc).
4904
 */
4905
static PQconninfoOption *
4906
parse_connection_string(const char *connstr, PQExpBuffer errorMessage,
4907
            bool use_defaults)
4908
260
{
4909
  /* Parse as URI if connection string matches URI prefix */
4910
260
  if (uri_prefix_length(connstr) != 0)
4911
0
    return conninfo_uri_parse(connstr, errorMessage, use_defaults);
4912
4913
  /* Parse as default otherwise */
4914
260
  return conninfo_parse(connstr, errorMessage, use_defaults);
4915
260
}
4916
4917
/*
4918
 * Checks if connection string starts with either of the valid URI prefix
4919
 * designators.
4920
 *
4921
 * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix.
4922
 *
4923
 * XXX this is duplicated in psql/common.c.
4924
 */
4925
static int
4926
uri_prefix_length(const char *connstr)
4927
298
{
4928
298
  if (strncmp(connstr, uri_designator,
4929
298
        sizeof(uri_designator) - 1) == 0)
4930
0
    return sizeof(uri_designator) - 1;
4931
4932
298
  if (strncmp(connstr, short_uri_designator,
4933
298
        sizeof(short_uri_designator) - 1) == 0)
4934
0
    return sizeof(short_uri_designator) - 1;
4935
4936
298
  return 0;
4937
298
}
4938
4939
/*
4940
 * Recognized connection string either starts with a valid URI prefix or
4941
 * contains a "=" in it.
4942
 *
4943
 * Must be consistent with parse_connection_string: anything for which this
4944
 * returns true should at least look like it's parseable by that routine.
4945
 *
4946
 * XXX this is duplicated in psql/common.c
4947
 */
4948
static bool
4949
recognized_connection_string(const char *connstr)
4950
38
{
4951
38
  return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
4952
38
}
4953
4954
/*
4955
 * Subroutine for parse_connection_string
4956
 *
4957
 * Deal with a string containing key=value pairs.
4958
 */
4959
static PQconninfoOption *
4960
conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
4961
         bool use_defaults)
4962
260
{
4963
260
  char     *pname;
4964
260
  char     *pval;
4965
260
  char     *buf;
4966
260
  char     *cp;
4967
260
  char     *cp2;
4968
260
  PQconninfoOption *options;
4969
4970
  /* Make a working copy of PQconninfoOptions */
4971
260
  options = conninfo_init(errorMessage);
4972
260
  if (options == NULL)
4973
0
    return NULL;
4974
4975
  /* Need a modifiable copy of the input string */
4976
260
  if ((buf = strdup(conninfo)) == NULL)
4977
0
  {
4978
0
    printfPQExpBuffer(errorMessage,
4979
0
              libpq_gettext("out of memory\n"));
4980
0
    PQconninfoFree(options);
4981
0
    return NULL;
4982
0
  }
4983
260
  cp = buf;
4984
4985
1.46k
  while (*cp)
4986
1.20k
  {
4987
    /* Skip blanks before the parameter name */
4988
1.20k
    if (isspace((unsigned char) *cp))
4989
0
    {
4990
0
      cp++;
4991
0
      continue;
4992
0
    }
4993
4994
    /* Get the parameter name */
4995
1.20k
    pname = cp;
4996
7.46k
    while (*cp)
4997
7.46k
    {
4998
7.46k
      if (*cp == '=')
4999
1.20k
        break;
5000
6.26k
      if (isspace((unsigned char) *cp))
5001
0
      {
5002
0
        *cp++ = '\0';
5003
0
        while (*cp)
5004
0
        {
5005
0
          if (!isspace((unsigned char) *cp))
5006
0
            break;
5007
0
          cp++;
5008
0
        }
5009
0
        break;
5010
0
      }
5011
6.26k
      cp++;
5012
6.26k
    }
5013
5014
    /* Check that there is a following '=' */
5015
1.20k
    if (*cp != '=')
5016
0
    {
5017
0
      printfPQExpBuffer(errorMessage,
5018
0
                libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
5019
0
                pname);
5020
0
      PQconninfoFree(options);
5021
0
      free(buf);
5022
0
      return NULL;
5023
0
    }
5024
1.20k
    *cp++ = '\0';
5025
5026
    /* Skip blanks after the '=' */
5027
1.20k
    while (*cp)
5028
1.20k
    {
5029
1.20k
      if (!isspace((unsigned char) *cp))
5030
1.20k
        break;
5031
0
      cp++;
5032
0
    }
5033
5034
    /* Get the parameter value */
5035
1.20k
    pval = cp;
5036
5037
1.20k
    if (*cp != '\'')
5038
965
    {
5039
965
      cp2 = pval;
5040
15.4k
      while (*cp)
5041
15.3k
      {
5042
15.3k
        if (isspace((unsigned char) *cp))
5043
940
        {
5044
940
          *cp++ = '\0';
5045
940
          break;
5046
940
        }
5047
14.4k
        if (*cp == '\\')
5048
0
        {
5049
0
          cp++;
5050
0
          if (*cp != '\0')
5051
0
            *cp2++ = *cp++;
5052
0
        }
5053
14.4k
        else
5054
14.4k
          *cp2++ = *cp++;
5055
14.4k
      }
5056
965
      *cp2 = '\0';
5057
965
    }
5058
235
    else
5059
235
    {
5060
235
      cp2 = pval;
5061
235
      cp++;
5062
235
      for (;;)
5063
2.22k
      {
5064
2.22k
        if (*cp == '\0')
5065
0
        {
5066
0
          printfPQExpBuffer(errorMessage,
5067
0
                    libpq_gettext("unterminated quoted string in connection info string\n"));
5068
0
          PQconninfoFree(options);
5069
0
          free(buf);
5070
0
          return NULL;
5071
0
        }
5072
2.22k
        if (*cp == '\\')
5073
0
        {
5074
0
          cp++;
5075
0
          if (*cp != '\0')
5076
0
            *cp2++ = *cp++;
5077
0
          continue;
5078
0
        }
5079
2.22k
        if (*cp == '\'')
5080
235
        {
5081
235
          *cp2 = '\0';
5082
235
          cp++;
5083
235
          break;
5084
235
        }
5085
1.99k
        *cp2++ = *cp++;
5086
1.99k
      }
5087
235
    }
5088
5089
    /*
5090
     * Now that we have the name and the value, store the record.
5091
     */
5092
1.20k
    if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
5093
0
    {
5094
0
      PQconninfoFree(options);
5095
0
      free(buf);
5096
0
      return NULL;
5097
0
    }
5098
1.20k
  }
5099
5100
  /* Done with the modifiable input string */
5101
260
  free(buf);
5102
5103
  /*
5104
   * Add in defaults if the caller wants that.
5105
   */
5106
260
  if (use_defaults)
5107
260
  {
5108
260
    if (!conninfo_add_defaults(options, errorMessage))
5109
0
    {
5110
0
      PQconninfoFree(options);
5111
0
      return NULL;
5112
0
    }
5113
260
  }
5114
5115
260
  return options;
5116
260
}
5117
5118
/*
5119
 * Conninfo array parser routine
5120
 *
5121
 * If successful, a malloc'd PQconninfoOption array is returned.
5122
 * If not successful, NULL is returned and an error message is
5123
 * left in errorMessage.
5124
 * Defaults are supplied (from a service file, environment variables, etc)
5125
 * for unspecified options, but only if use_defaults is true.
5126
 *
5127
 * If expand_dbname is non-zero, and the value passed for the first occurrence
5128
 * of "dbname" keyword is a connection string (as indicated by
5129
 * recognized_connection_string) then parse and process it, overriding any
5130
 * previously processed conflicting keywords. Subsequent keywords will take
5131
 * precedence, however. In-tree programs generally specify expand_dbname=true,
5132
 * so command-line arguments naming a database can use a connection string.
5133
 * Some code acquires arbitrary database names from known-literal sources like
5134
 * PQdb(), PQconninfoParse() and pg_database.datname.  When connecting to such
5135
 * a database, in-tree code first wraps the name in a connection string.
5136
 */
5137
static PQconninfoOption *
5138
conninfo_array_parse(const char *const *keywords, const char *const *values,
5139
           PQExpBuffer errorMessage, bool use_defaults,
5140
           int expand_dbname)
5141
56
{
5142
56
  PQconninfoOption *options;
5143
56
  PQconninfoOption *dbname_options = NULL;
5144
56
  PQconninfoOption *option;
5145
56
  int     i = 0;
5146
5147
  /*
5148
   * If expand_dbname is non-zero, check keyword "dbname" to see if val is
5149
   * actually a recognized connection string.
5150
   */
5151
208
  while (expand_dbname && keywords[i])
5152
190
  {
5153
190
    const char *pname = keywords[i];
5154
190
    const char *pvalue = values[i];
5155
5156
    /* first find "dbname" if any */
5157
190
    if (strcmp(pname, "dbname") == 0 && pvalue)
5158
38
    {
5159
      /*
5160
       * If value is a connection string, parse it, but do not use
5161
       * defaults here -- those get picked up later. We only want to
5162
       * override for those parameters actually passed.
5163
       */
5164
38
      if (recognized_connection_string(pvalue))
5165
0
      {
5166
0
        dbname_options = parse_connection_string(pvalue, errorMessage, false);
5167
0
        if (dbname_options == NULL)
5168
0
          return NULL;
5169
38
      }
5170
38
      break;
5171
38
    }
5172
152
    ++i;
5173
152
  }
5174
5175
  /* Make a working copy of PQconninfoOptions */
5176
56
  options = conninfo_init(errorMessage);
5177
56
  if (options == NULL)
5178
0
  {
5179
0
    PQconninfoFree(dbname_options);
5180
0
    return NULL;
5181
0
  }
5182
5183
  /* Parse the keywords/values arrays */
5184
56
  i = 0;
5185
434
  while (keywords[i])
5186
378
  {
5187
378
    const char *pname = keywords[i];
5188
378
    const char *pvalue = values[i];
5189
5190
378
    if (pvalue != NULL && pvalue[0] != '\0')
5191
187
    {
5192
      /* Search for the param record */
5193
2.05k
      for (option = options; option->keyword != NULL; option++)
5194
2.05k
      {
5195
2.05k
        if (strcmp(option->keyword, pname) == 0)
5196
187
          break;
5197
2.05k
      }
5198
5199
      /* Check for invalid connection option */
5200
187
      if (option->keyword == NULL)
5201
0
      {
5202
0
        printfPQExpBuffer(errorMessage,
5203
0
                  libpq_gettext("invalid connection option \"%s\"\n"),
5204
0
                  pname);
5205
0
        PQconninfoFree(options);
5206
0
        PQconninfoFree(dbname_options);
5207
0
        return NULL;
5208
0
      }
5209
5210
      /*
5211
       * If we are on the first dbname parameter, and we have a parsed
5212
       * connection string, copy those parameters across, overriding any
5213
       * existing previous settings.
5214
       */
5215
187
      if (strcmp(pname, "dbname") == 0 && dbname_options)
5216
0
      {
5217
0
        PQconninfoOption *str_option;
5218
5219
0
        for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
5220
0
        {
5221
0
          if (str_option->val != NULL)
5222
0
          {
5223
0
            int     k;
5224
5225
0
            for (k = 0; options[k].keyword; k++)
5226
0
            {
5227
0
              if (strcmp(options[k].keyword, str_option->keyword) == 0)
5228
0
              {
5229
0
                if (options[k].val)
5230
0
                  free(options[k].val);
5231
0
                options[k].val = strdup(str_option->val);
5232
0
                if (!options[k].val)
5233
0
                {
5234
0
                  printfPQExpBuffer(errorMessage,
5235
0
                            libpq_gettext("out of memory\n"));
5236
0
                  PQconninfoFree(options);
5237
0
                  PQconninfoFree(dbname_options);
5238
0
                  return NULL;
5239
0
                }
5240
0
                break;
5241
0
              }
5242
0
            }
5243
0
          }
5244
0
        }
5245
5246
        /*
5247
         * Forget the parsed connection string, so that any subsequent
5248
         * dbname parameters will not be expanded.
5249
         */
5250
0
        PQconninfoFree(dbname_options);
5251
0
        dbname_options = NULL;
5252
0
      }
5253
187
      else
5254
187
      {
5255
        /*
5256
         * Store the value, overriding previous settings
5257
         */
5258
187
        if (option->val)
5259
0
          free(option->val);
5260
187
        option->val = strdup(pvalue);
5261
187
        if (!option->val)
5262
0
        {
5263
0
          printfPQExpBuffer(errorMessage,
5264
0
                    libpq_gettext("out of memory\n"));
5265
0
          PQconninfoFree(options);
5266
0
          PQconninfoFree(dbname_options);
5267
0
          return NULL;
5268
0
        }
5269
378
      }
5270
187
    }
5271
378
    ++i;
5272
378
  }
5273
56
  PQconninfoFree(dbname_options);
5274
5275
  /*
5276
   * Add in defaults if the caller wants that.
5277
   */
5278
56
  if (use_defaults)
5279
56
  {
5280
56
    if (!conninfo_add_defaults(options, errorMessage))
5281
0
    {
5282
0
      PQconninfoFree(options);
5283
0
      return NULL;
5284
0
    }
5285
56
  }
5286
5287
56
  return options;
5288
56
}
5289
5290
/*
5291
 * Add the default values for any unspecified options to the connection
5292
 * options array.
5293
 *
5294
 * Defaults are obtained from a service file, environment variables, etc.
5295
 *
5296
 * Returns true if successful, otherwise false; errorMessage, if supplied,
5297
 * is filled in upon failure.  Note that failure to locate a default value
5298
 * is not an error condition here --- we just leave the option's value as
5299
 * NULL.
5300
 */
5301
static bool
5302
conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
5303
317
{
5304
317
  PQconninfoOption *option;
5305
317
  char     *tmp;
5306
5307
  /*
5308
   * If there's a service spec, use it to obtain any not-explicitly-given
5309
   * parameters.  Ignore error if no error message buffer is passed because
5310
   * there is no way to pass back the failure message.
5311
   */
5312
317
  if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
5313
0
    return false;
5314
5315
  /*
5316
   * Get the fallback resources for parameters not specified in the conninfo
5317
   * string nor the service.
5318
   */
5319
9.19k
  for (option = options; option->keyword != NULL; option++)
5320
8.87k
  {
5321
8.87k
    if (option->val != NULL)
5322
1.38k
      continue;     /* Value was in conninfo or service */
5323
5324
    /*
5325
     * Try to get the environment variable fallback
5326
     */
5327
7.48k
    if (option->envvar != NULL)
5328
5.64k
    {
5329
5.64k
      if ((tmp = getenv(option->envvar)) != NULL)
5330
310
      {
5331
310
        option->val = strdup(tmp);
5332
310
        if (!option->val)
5333
0
        {
5334
0
          if (errorMessage)
5335
0
            printfPQExpBuffer(errorMessage,
5336
0
                      libpq_gettext("out of memory\n"));
5337
0
          return false;
5338
0
        }
5339
310
        continue;
5340
310
      }
5341
5.64k
    }
5342
5343
    /*
5344
     * Interpret the deprecated PGREQUIRESSL environment variable.  Per
5345
     * tradition, translate values starting with "1" to sslmode=require,
5346
     * and ignore other values.  Given both PGREQUIRESSL=1 and PGSSLMODE,
5347
     * PGSSLMODE takes precedence; the opposite was true before v9.3.
5348
     */
5349
7.17k
    if (strcmp(option->keyword, "sslmode") == 0)
5350
314
    {
5351
314
      const char *requiresslenv = getenv("PGREQUIRESSL");
5352
5353
314
      if (requiresslenv != NULL && requiresslenv[0] == '1')
5354
0
      {
5355
0
        option->val = strdup("require");
5356
0
        if (!option->val)
5357
0
        {
5358
0
          if (errorMessage)
5359
0
            printfPQExpBuffer(errorMessage,
5360
0
                      libpq_gettext("out of memory\n"));
5361
0
          return false;
5362
0
        }
5363
0
        continue;
5364
0
      }
5365
314
    }
5366
5367
    /*
5368
     * No environment variable specified or the variable isn't set - try
5369
     * compiled-in default
5370
     */
5371
7.17k
    if (option->compiled != NULL)
5372
1.82k
    {
5373
1.82k
      option->val = strdup(option->compiled);
5374
1.82k
      if (!option->val)
5375
0
      {
5376
0
        if (errorMessage)
5377
0
          printfPQExpBuffer(errorMessage,
5378
0
                    libpq_gettext("out of memory\n"));
5379
0
        return false;
5380
0
      }
5381
1.82k
      continue;
5382
1.82k
    }
5383
5384
    /*
5385
     * Special handling for "user" option.  Note that if pg_fe_getauthname
5386
     * fails, we just leave the value as NULL; there's no need for this to
5387
     * be an error condition if the caller provides a user name.  The only
5388
     * reason we do this now at all is so that callers of PQconndefaults
5389
     * will see a correct default (barring error, of course).
5390
     */
5391
5.35k
    if (strcmp(option->keyword, "user") == 0)
5392
16
    {
5393
      /* Yugabyte default username to "yugabyte" */
5394
16
      option->val = strdup("yugabyte");
5395
16
      continue;
5396
16
    }
5397
5398
    /*
5399
     * Special handling for "dbname" option.
5400
     */
5401
5.33k
    if (strcmp(option->keyword, "dbname") == 0)
5402
1
    {
5403
      /* Yugabyte default dbname to "yugabyte" */
5404
1
      option->val = strdup("yugabyte");
5405
1
      continue;
5406
1
    }
5407
5.33k
  }
5408
5409
317
  return true;
5410
317
}
5411
5412
/*
5413
 * Subroutine for parse_connection_string
5414
 *
5415
 * Deal with a URI connection string.
5416
 */
5417
static PQconninfoOption *
5418
conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage,
5419
           bool use_defaults)
5420
0
{
5421
0
  PQconninfoOption *options;
5422
5423
  /* Make a working copy of PQconninfoOptions */
5424
0
  options = conninfo_init(errorMessage);
5425
0
  if (options == NULL)
5426
0
    return NULL;
5427
5428
0
  if (!conninfo_uri_parse_options(options, uri, errorMessage))
5429
0
  {
5430
0
    PQconninfoFree(options);
5431
0
    return NULL;
5432
0
  }
5433
5434
  /*
5435
   * Add in defaults if the caller wants that.
5436
   */
5437
0
  if (use_defaults)
5438
0
  {
5439
0
    if (!conninfo_add_defaults(options, errorMessage))
5440
0
    {
5441
0
      PQconninfoFree(options);
5442
0
      return NULL;
5443
0
    }
5444
0
  }
5445
5446
0
  return options;
5447
0
}
5448
5449
/*
5450
 * conninfo_uri_parse_options
5451
 *    Actual URI parser.
5452
 *
5453
 * If successful, returns true while the options array is filled with parsed
5454
 * options from the URI.
5455
 * If not successful, returns false and fills errorMessage accordingly.
5456
 *
5457
 * Parses the connection URI string in 'uri' according to the URI syntax (RFC
5458
 * 3986):
5459
 *
5460
 * postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
5461
 *
5462
 * where "netloc" is a hostname, an IPv4 address, or an IPv6 address surrounded
5463
 * by literal square brackets.  As an extension, we also allow multiple
5464
 * netloc[:port] specifications, separated by commas:
5465
 *
5466
 * postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...]
5467
 *
5468
 * Any of the URI parts might use percent-encoding (%xy).
5469
 */
5470
static bool
5471
conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
5472
               PQExpBuffer errorMessage)
5473
0
{
5474
0
  int     prefix_len;
5475
0
  char     *p;
5476
0
  char     *buf = NULL;
5477
0
  char     *start;
5478
0
  char    prevchar = '\0';
5479
0
  char     *user = NULL;
5480
0
  char     *host = NULL;
5481
0
  bool    retval = false;
5482
0
  PQExpBufferData hostbuf;
5483
0
  PQExpBufferData portbuf;
5484
5485
0
  initPQExpBuffer(&hostbuf);
5486
0
  initPQExpBuffer(&portbuf);
5487
0
  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
5488
0
  {
5489
0
    printfPQExpBuffer(errorMessage,
5490
0
              libpq_gettext("out of memory\n"));
5491
0
    goto cleanup;
5492
0
  }
5493
5494
  /* need a modifiable copy of the input URI */
5495
0
  buf = strdup(uri);
5496
0
  if (buf == NULL)
5497
0
  {
5498
0
    printfPQExpBuffer(errorMessage,
5499
0
              libpq_gettext("out of memory\n"));
5500
0
    goto cleanup;
5501
0
  }
5502
0
  start = buf;
5503
5504
  /* Skip the URI prefix */
5505
0
  prefix_len = uri_prefix_length(uri);
5506
0
  if (prefix_len == 0)
5507
0
  {
5508
    /* Should never happen */
5509
0
    printfPQExpBuffer(errorMessage,
5510
0
              libpq_gettext("invalid URI propagated to internal parser routine: \"%s\"\n"),
5511
0
              uri);
5512
0
    goto cleanup;
5513
0
  }
5514
0
  start += prefix_len;
5515
0
  p = start;
5516
5517
  /* Look ahead for possible user credentials designator */
5518
0
  while (*p && *p != '@' && *p != '/')
5519
0
    ++p;
5520
0
  if (*p == '@')
5521
0
  {
5522
    /*
5523
     * Found username/password designator, so URI should be of the form
5524
     * "scheme://user[:password]@[netloc]".
5525
     */
5526
0
    user = start;
5527
5528
0
    p = user;
5529
0
    while (*p != ':' && *p != '@')
5530
0
      ++p;
5531
5532
    /* Save last char and cut off at end of user name */
5533
0
    prevchar = *p;
5534
0
    *p = '\0';
5535
5536
0
    if (*user &&
5537
0
      !conninfo_storeval(options, "user", user,
5538
0
                 errorMessage, false, true))
5539
0
      goto cleanup;
5540
5541
0
    if (prevchar == ':')
5542
0
    {
5543
0
      const char *password = p + 1;
5544
5545
0
      while (*p != '@')
5546
0
        ++p;
5547
0
      *p = '\0';
5548
5549
0
      if (*password &&
5550
0
        !conninfo_storeval(options, "password", password,
5551
0
                   errorMessage, false, true))
5552
0
        goto cleanup;
5553
0
    }
5554
5555
    /* Advance past end of parsed user name or password token */
5556
0
    ++p;
5557
0
  }
5558
0
  else
5559
0
  {
5560
    /*
5561
     * No username/password designator found.  Reset to start of URI.
5562
     */
5563
0
    p = start;
5564
0
  }
5565
5566
  /*
5567
   * There may be multiple netloc[:port] pairs, each separated from the next
5568
   * by a comma.  When we initially enter this loop, "p" has been
5569
   * incremented past optional URI credential information at this point and
5570
   * now points at the "netloc" part of the URI.  On subsequent loop
5571
   * iterations, "p" has been incremented past the comma separator and now
5572
   * points at the start of the next "netloc".
5573
   */
5574
0
  for (;;)
5575
0
  {
5576
    /*
5577
     * Look for IPv6 address.
5578
     */
5579
0
    if (*p == '[')
5580
0
    {
5581
0
      host = ++p;
5582
0
      while (*p && *p != ']')
5583
0
        ++p;
5584
0
      if (!*p)
5585
0
      {
5586
0
        printfPQExpBuffer(errorMessage,
5587
0
                  libpq_gettext("end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n"),
5588
0
                  uri);
5589
0
        goto cleanup;
5590
0
      }
5591
0
      if (p == host)
5592
0
      {
5593
0
        printfPQExpBuffer(errorMessage,
5594
0
                  libpq_gettext("IPv6 host address may not be empty in URI: \"%s\"\n"),
5595
0
                  uri);
5596
0
        goto cleanup;
5597
0
      }
5598
5599
      /* Cut off the bracket and advance */
5600
0
      *(p++) = '\0';
5601
5602
      /*
5603
       * The address may be followed by a port specifier or a slash or a
5604
       * query or a separator comma.
5605
       */
5606
0
      if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
5607
0
      {
5608
0
        printfPQExpBuffer(errorMessage,
5609
0
                  libpq_gettext("unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n"),
5610
0
                  *p, (int) (p - buf + 1), uri);
5611
0
        goto cleanup;
5612
0
      }
5613
0
    }
5614
0
    else
5615
0
    {
5616
      /* not an IPv6 address: DNS-named or IPv4 netloc */
5617
0
      host = p;
5618
5619
      /*
5620
       * Look for port specifier (colon) or end of host specifier
5621
       * (slash) or query (question mark) or host separator (comma).
5622
       */
5623
0
      while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
5624
0
        ++p;
5625
0
    }
5626
5627
    /* Save the hostname terminator before we null it */
5628
0
    prevchar = *p;
5629
0
    *p = '\0';
5630
5631
0
    appendPQExpBufferStr(&hostbuf, host);
5632
5633
0
    if (prevchar == ':')
5634
0
    {
5635
0
      const char *port = ++p; /* advance past host terminator */
5636
5637
0
      while (*p && *p != '/' && *p != '?' && *p != ',')
5638
0
        ++p;
5639
5640
0
      prevchar = *p;
5641
0
      *p = '\0';
5642
5643
0
      appendPQExpBufferStr(&portbuf, port);
5644
0
    }
5645
5646
0
    if (prevchar != ',')
5647
0
      break;
5648
0
    ++p;          /* advance past comma separator */
5649
0
    appendPQExpBufferChar(&hostbuf, ',');
5650
0
    appendPQExpBufferChar(&portbuf, ',');
5651
0
  }
5652
5653
  /* Save final values for host and port. */
5654
0
  if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
5655
0
    goto cleanup;
5656
0
  if (hostbuf.data[0] &&
5657
0
    !conninfo_storeval(options, "host", hostbuf.data,
5658
0
               errorMessage, false, true))
5659
0
    goto cleanup;
5660
0
  if (portbuf.data[0] &&
5661
0
    !conninfo_storeval(options, "port", portbuf.data,
5662
0
               errorMessage, false, true))
5663
0
    goto cleanup;
5664
5665
0
  if (prevchar && prevchar != '?')
5666
0
  {
5667
0
    const char *dbname = ++p; /* advance past host terminator */
5668
5669
    /* Look for query parameters */
5670
0
    while (*p && *p != '?')
5671
0
      ++p;
5672
5673
0
    prevchar = *p;
5674
0
    *p = '\0';
5675
5676
    /*
5677
     * Avoid setting dbname to an empty string, as it forces the default
5678
     * value (username) and ignores $PGDATABASE, as opposed to not setting
5679
     * it at all.
5680
     */
5681
0
    if (*dbname &&
5682
0
      !conninfo_storeval(options, "dbname", dbname,
5683
0
                 errorMessage, false, true))
5684
0
      goto cleanup;
5685
0
  }
5686
5687
0
  if (prevchar)
5688
0
  {
5689
0
    ++p;          /* advance past terminator */
5690
5691
0
    if (!conninfo_uri_parse_params(p, options, errorMessage))
5692
0
      goto cleanup;
5693
0
  }
5694
5695
  /* everything parsed okay */
5696
0
  retval = true;
5697
5698
0
cleanup:
5699
0
  termPQExpBuffer(&hostbuf);
5700
0
  termPQExpBuffer(&portbuf);
5701
0
  if (buf)
5702
0
    free(buf);
5703
0
  return retval;
5704
0
}
5705
5706
/*
5707
 * Connection URI parameters parser routine
5708
 *
5709
 * If successful, returns true while connOptions is filled with parsed
5710
 * parameters.  Otherwise, returns false and fills errorMessage appropriately.
5711
 *
5712
 * Destructively modifies 'params' buffer.
5713
 */
5714
static bool
5715
conninfo_uri_parse_params(char *params,
5716
              PQconninfoOption *connOptions,
5717
              PQExpBuffer errorMessage)
5718
0
{
5719
0
  while (*params)
5720
0
  {
5721
0
    char     *keyword = params;
5722
0
    char     *value = NULL;
5723
0
    char     *p = params;
5724
0
    bool    malloced = false;
5725
5726
    /*
5727
     * Scan the params string for '=' and '&', marking the end of keyword
5728
     * and value respectively.
5729
     */
5730
0
    for (;;)
5731
0
    {
5732
0
      if (*p == '=')
5733
0
      {
5734
        /* Was there '=' already? */
5735
0
        if (value != NULL)
5736
0
        {
5737
0
          printfPQExpBuffer(errorMessage,
5738
0
                    libpq_gettext("extra key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5739
0
                    keyword);
5740
0
          return false;
5741
0
        }
5742
        /* Cut off keyword, advance to value */
5743
0
        *p++ = '\0';
5744
0
        value = p;
5745
0
      }
5746
0
      else if (*p == '&' || *p == '\0')
5747
0
      {
5748
        /*
5749
         * If not at the end, cut off value and advance; leave p
5750
         * pointing to start of the next parameter, if any.
5751
         */
5752
0
        if (*p != '\0')
5753
0
          *p++ = '\0';
5754
        /* Was there '=' at all? */
5755
0
        if (value == NULL)
5756
0
        {
5757
0
          printfPQExpBuffer(errorMessage,
5758
0
                    libpq_gettext("missing key/value separator \"=\" in URI query parameter: \"%s\"\n"),
5759
0
                    keyword);
5760
0
          return false;
5761
0
        }
5762
        /* Got keyword and value, go process them. */
5763
0
        break;
5764
0
      }
5765
0
      else
5766
0
        ++p;     /* Advance over all other bytes. */
5767
0
    }
5768
5769
0
    keyword = conninfo_uri_decode(keyword, errorMessage);
5770
0
    if (keyword == NULL)
5771
0
    {
5772
      /* conninfo_uri_decode already set an error message */
5773
0
      return false;
5774
0
    }
5775
0
    value = conninfo_uri_decode(value, errorMessage);
5776
0
    if (value == NULL)
5777
0
    {
5778
      /* conninfo_uri_decode already set an error message */
5779
0
      free(keyword);
5780
0
      return false;
5781
0
    }
5782
0
    malloced = true;
5783
5784
    /*
5785
     * Special keyword handling for improved JDBC compatibility.
5786
     */
5787
0
    if (strcmp(keyword, "ssl") == 0 &&
5788
0
      strcmp(value, "true") == 0)
5789
0
    {
5790
0
      free(keyword);
5791
0
      free(value);
5792
0
      malloced = false;
5793
5794
0
      keyword = "sslmode";
5795
0
      value = "require";
5796
0
    }
5797
5798
    /*
5799
     * Store the value if the corresponding option exists; ignore
5800
     * otherwise.  At this point both keyword and value are not
5801
     * URI-encoded.
5802
     */
5803
0
    if (!conninfo_storeval(connOptions, keyword, value,
5804
0
                 errorMessage, true, false))
5805
0
    {
5806
      /* Insert generic message if conninfo_storeval didn't give one. */
5807
0
      if (errorMessage->len == 0)
5808
0
        printfPQExpBuffer(errorMessage,
5809
0
                  libpq_gettext("invalid URI query parameter: \"%s\"\n"),
5810
0
                  keyword);
5811
      /* And fail. */
5812
0
      if (malloced)
5813
0
      {
5814
0
        free(keyword);
5815
0
        free(value);
5816
0
      }
5817
0
      return false;
5818
0
    }
5819
5820
0
    if (malloced)
5821
0
    {
5822
0
      free(keyword);
5823
0
      free(value);
5824
0
    }
5825
5826
    /* Proceed to next key=value pair, if any */
5827
0
    params = p;
5828
0
  }
5829
5830
0
  return true;
5831
0
}
5832
5833
/*
5834
 * Connection URI decoder routine
5835
 *
5836
 * If successful, returns the malloc'd decoded string.
5837
 * If not successful, returns NULL and fills errorMessage accordingly.
5838
 *
5839
 * The string is decoded by replacing any percent-encoded tokens with
5840
 * corresponding characters, while preserving any non-encoded characters.  A
5841
 * percent-encoded token is a character triplet: a percent sign, followed by a
5842
 * pair of hexadecimal digits (0-9A-F), where lower- and upper-case letters are
5843
 * treated identically.
5844
 */
5845
static char *
5846
conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
5847
0
{
5848
0
  char     *buf;
5849
0
  char     *p;
5850
0
  const char *q = str;
5851
5852
0
  buf = malloc(strlen(str) + 1);
5853
0
  if (buf == NULL)
5854
0
  {
5855
0
    printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
5856
0
    return NULL;
5857
0
  }
5858
0
  p = buf;
5859
5860
0
  for (;;)
5861
0
  {
5862
0
    if (*q != '%')
5863
0
    {
5864
      /* copy and check for NUL terminator */
5865
0
      if (!(*(p++) = *(q++)))
5866
0
        break;
5867
0
    }
5868
0
    else
5869
0
    {
5870
0
      int     hi;
5871
0
      int     lo;
5872
0
      int     c;
5873
5874
0
      ++q;        /* skip the percent sign itself */
5875
5876
      /*
5877
       * Possible EOL will be caught by the first call to
5878
       * get_hexdigit(), so we never dereference an invalid q pointer.
5879
       */
5880
0
      if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
5881
0
      {
5882
0
        printfPQExpBuffer(errorMessage,
5883
0
                  libpq_gettext("invalid percent-encoded token: \"%s\"\n"),
5884
0
                  str);
5885
0
        free(buf);
5886
0
        return NULL;
5887
0
      }
5888
5889
0
      c = (hi << 4) | lo;
5890
0
      if (c == 0)
5891
0
      {
5892
0
        printfPQExpBuffer(errorMessage,
5893
0
                  libpq_gettext("forbidden value %%00 in percent-encoded value: \"%s\"\n"),
5894
0
                  str);
5895
0
        free(buf);
5896
0
        return NULL;
5897
0
      }
5898
0
      *(p++) = c;
5899
0
    }
5900
0
  }
5901
5902
0
  return buf;
5903
0
}
5904
5905
/*
5906
 * Convert hexadecimal digit character to its integer value.
5907
 *
5908
 * If successful, returns true and value is filled with digit's base 16 value.
5909
 * If not successful, returns false.
5910
 *
5911
 * Lower- and upper-case letters in the range A-F are treated identically.
5912
 */
5913
static bool
5914
get_hexdigit(char digit, int *value)
5915
0
{
5916
0
  if ('0' <= digit && digit <= '9')
5917
0
    *value = digit - '0';
5918
0
  else if ('A' <= digit && digit <= 'F')
5919
0
    *value = digit - 'A' + 10;
5920
0
  else if ('a' <= digit && digit <= 'f')
5921
0
    *value = digit - 'a' + 10;
5922
0
  else
5923
0
    return false;
5924
5925
0
  return true;
5926
0
}
5927
5928
/*
5929
 * Find an option value corresponding to the keyword in the connOptions array.
5930
 *
5931
 * If successful, returns a pointer to the corresponding option's value.
5932
 * If not successful, returns NULL.
5933
 */
5934
static const char *
5935
conninfo_getval(PQconninfoOption *connOptions,
5936
        const char *keyword)
5937
8.53k
{
5938
8.53k
  PQconninfoOption *option;
5939
5940
8.53k
  option = conninfo_find(connOptions, keyword);
5941
5942
8.53k
  return option ? option->val : NULL;
5943
8.53k
}
5944
5945
/*
5946
 * Store a (new) value for an option corresponding to the keyword in
5947
 * connOptions array.
5948
 *
5949
 * If uri_decode is true, the value is URI-decoded.  The keyword is always
5950
 * assumed to be non URI-encoded.
5951
 *
5952
 * If successful, returns a pointer to the corresponding PQconninfoOption,
5953
 * which value is replaced with a strdup'd copy of the passed value string.
5954
 * The existing value for the option is free'd before replacing, if any.
5955
 *
5956
 * If not successful, returns NULL and fills errorMessage accordingly.
5957
 * However, if the reason of failure is an invalid keyword being passed and
5958
 * ignoreMissing is true, errorMessage will be left untouched.
5959
 */
5960
static PQconninfoOption *
5961
conninfo_storeval(PQconninfoOption *connOptions,
5962
          const char *keyword, const char *value,
5963
          PQExpBuffer errorMessage, bool ignoreMissing,
5964
          bool uri_decode)
5965
1.23k
{
5966
1.23k
  PQconninfoOption *option;
5967
1.23k
  char     *value_copy;
5968
5969
  /*
5970
   * For backwards compatibility, requiressl=1 gets translated to
5971
   * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
5972
   * (which is the default for sslmode).
5973
   */
5974
1.23k
  if (strcmp(keyword, "requiressl") == 0)
5975
0
  {
5976
0
    keyword = "sslmode";
5977
0
    if (value[0] == '1')
5978
0
      value = "require";
5979
0
    else
5980
0
      value = "prefer";
5981
0
  }
5982
5983
1.23k
  option = conninfo_find(connOptions, keyword);
5984
1.23k
  if (option == NULL)
5985
0
  {
5986
0
    if (!ignoreMissing)
5987
0
      printfPQExpBuffer(errorMessage,
5988
0
                libpq_gettext("invalid connection option \"%s\"\n"),
5989
0
                keyword);
5990
0
    return NULL;
5991
0
  }
5992
5993
1.23k
  if (uri_decode)
5994
0
  {
5995
0
    value_copy = conninfo_uri_decode(value, errorMessage);
5996
0
    if (value_copy == NULL)
5997
      /* conninfo_uri_decode already set an error message */
5998
0
      return NULL;
5999
1.23k
  }
6000
1.23k
  else
6001
1.23k
  {
6002
1.23k
    value_copy = strdup(value);
6003
1.23k
    if (value_copy == NULL)
6004
0
    {
6005
0
      printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
6006
0
      return NULL;
6007
0
    }
6008
1.23k
  }
6009
6010
1.23k
  if (option->val)
6011
0
    free(option->val);
6012
1.23k
  option->val = value_copy;
6013
6014
1.23k
  return option;
6015
1.23k
}
6016
6017
/*
6018
 * Find a PQconninfoOption option corresponding to the keyword in the
6019
 * connOptions array.
6020
 *
6021
 * If successful, returns a pointer to the corresponding PQconninfoOption
6022
 * structure.
6023
 * If not successful, returns NULL.
6024
 */
6025
static PQconninfoOption *
6026
conninfo_find(PQconninfoOption *connOptions, const char *keyword)
6027
9.76k
{
6028
9.76k
  PQconninfoOption *option;
6029
6030
136k
  for (option = connOptions; option->keyword != NULL; option++)
6031
136k
  {
6032
136k
    if (strcmp(option->keyword, keyword) == 0)
6033
9.76k
      return option;
6034
136k
  }
6035
6036
0
  return NULL;
6037
9.76k
}
6038
6039
6040
/*
6041
 * Return the connection options used for the connection
6042
 */
6043
PQconninfoOption *
6044
PQconninfo(PGconn *conn)
6045
3
{
6046
3
  PQExpBufferData errorBuf;
6047
3
  PQconninfoOption *connOptions;
6048
6049
3
  if (conn == NULL)
6050
0
    return NULL;
6051
6052
  /* We don't actually report any errors here, but callees want a buffer */
6053
3
  initPQExpBuffer(&errorBuf);
6054
3
  if (PQExpBufferDataBroken(errorBuf))
6055
0
    return NULL;     /* out of memory already :-( */
6056
6057
3
  connOptions = conninfo_init(&errorBuf);
6058
6059
3
  if (connOptions != NULL)
6060
3
  {
6061
3
    const internalPQconninfoOption *option;
6062
6063
87
    for (option = PQconninfoOptions; option->keyword; option++)
6064
84
    {
6065
84
      char    **connmember;
6066
6067
84
      if (option->connofs < 0)
6068
6
        continue;
6069
6070
78
      connmember = (char **) ((char *) conn + option->connofs);
6071
6072
78
      if (*connmember)
6073
36
        conninfo_storeval(connOptions, option->keyword, *connmember,
6074
36
                  &errorBuf, true, false);
6075
78
    }
6076
3
  }
6077
6078
3
  termPQExpBuffer(&errorBuf);
6079
6080
3
  return connOptions;
6081
3
}
6082
6083
6084
void
6085
PQconninfoFree(PQconninfoOption *connOptions)
6086
375
{
6087
375
  PQconninfoOption *option;
6088
6089
375
  if (connOptions == NULL)
6090
56
    return;
6091
6092
9.25k
  for (option = connOptions; option->keyword != NULL; option++)
6093
8.93k
  {
6094
8.93k
    if (option->val != NULL)
6095
3.57k
      free(option->val);
6096
8.93k
  }
6097
319
  free(connOptions);
6098
319
}
6099
6100
6101
/* =========== accessor functions for PGconn ========= */
6102
char *
6103
PQdb(const PGconn *conn)
6104
40
{
6105
40
  if (!conn)
6106
0
    return NULL;
6107
40
  return conn->dbName;
6108
40
}
6109
6110
char *
6111
PQuser(const PGconn *conn)
6112
40
{
6113
40
  if (!conn)
6114
0
    return NULL;
6115
40
  return conn->pguser;
6116
40
}
6117
6118
char *
6119
PQpass(const PGconn *conn)
6120
1
{
6121
1
  char     *password = NULL;
6122
6123
1
  if (!conn)
6124
0
    return NULL;
6125
1
  if (conn->connhost != NULL)
6126
1
    password = conn->connhost[conn->whichhost].password;
6127
1
  if (password == NULL)
6128
1
    password = conn->pgpass;
6129
  /* Historically we've returned "" not NULL for no password specified */
6130
1
  if (password == NULL)
6131
1
    password = "";
6132
1
  return password;
6133
1
}
6134
6135
char *
6136
PQhost(const PGconn *conn)
6137
40
{
6138
40
  if (!conn)
6139
0
    return NULL;
6140
6141
40
  if (conn->connhost != NULL)
6142
40
  {
6143
40
    if (conn->connhost[conn->whichhost].host != NULL &&
6144
40
      conn->connhost[conn->whichhost].host[0] != '\0')
6145
40
      return conn->connhost[conn->whichhost].host;
6146
0
    else if (conn->connhost[conn->whichhost].hostaddr != NULL &&
6147
0
         conn->connhost[conn->whichhost].hostaddr[0] != '\0')
6148
0
      return conn->connhost[conn->whichhost].hostaddr;
6149
0
  }
6150
6151
0
  return "";
6152
0
}
6153
6154
char *
6155
PQport(const PGconn *conn)
6156
40
{
6157
40
  if (!conn)
6158
0
    return NULL;
6159
6160
40
  if (conn->connhost != NULL)
6161
40
    return conn->connhost[conn->whichhost].port;
6162
6163
0
  return "";
6164
0
}
6165
6166
char *
6167
PQtty(const PGconn *conn)
6168
0
{
6169
0
  if (!conn)
6170
0
    return NULL;
6171
0
  return conn->pgtty;
6172
0
}
6173
6174
char *
6175
PQoptions(const PGconn *conn)
6176
0
{
6177
0
  if (!conn)
6178
0
    return NULL;
6179
0
  return conn->pgoptions;
6180
0
}
6181
6182
ConnStatusType
6183
PQstatus(const PGconn *conn)
6184
1.32k
{
6185
1.32k
  if (!conn)
6186
0
    return CONNECTION_BAD;
6187
1.32k
  return conn->status;
6188
1.32k
}
6189
6190
PGTransactionStatusType
6191
PQtransactionStatus(const PGconn *conn)
6192
3.75k
{
6193
3.75k
  if (!conn || conn->status != CONNECTION_OK)
6194
0
    return PQTRANS_UNKNOWN;
6195
3.75k
  if (conn->asyncStatus != PGASYNC_IDLE)
6196
0
    return PQTRANS_ACTIVE;
6197
3.75k
  return conn->xactStatus;
6198
3.75k
}
6199
6200
const char *
6201
PQparameterStatus(const PGconn *conn, const char *paramName)
6202
7.16k
{
6203
7.16k
  const pgParameterStatus *pstatus;
6204
6205
7.16k
  if (!conn || !paramName)
6206
0
    return NULL;
6207
18.4k
  for (pstatus = conn->pstatus; pstatus != NULL; pstatus = pstatus->next)
6208
18.4k
  {
6209
18.4k
    if (strcmp(pstatus->name, paramName) == 0)
6210
7.16k
      return pstatus->value;
6211
18.4k
  }
6212
0
  return NULL;
6213
7.16k
}
6214
6215
int
6216
PQprotocolVersion(const PGconn *conn)
6217
0
{
6218
0
  if (!conn)
6219
0
    return 0;
6220
0
  if (conn->status == CONNECTION_BAD)
6221
0
    return 0;
6222
0
  return PG_PROTOCOL_MAJOR(conn->pversion);
6223
0
}
6224
6225
int
6226
PQserverVersion(const PGconn *conn)
6227
68
{
6228
68
  if (!conn)
6229
0
    return 0;
6230
68
  if (conn->status == CONNECTION_BAD)
6231
0
    return 0;
6232
68
  return conn->sversion;
6233
68
}
6234
6235
char *
6236
PQerrorMessage(const PGconn *conn)
6237
462
{
6238
462
  if (!conn)
6239
0
    return libpq_gettext("connection pointer is NULL\n");
6240
6241
462
  return conn->errorMessage.data;
6242
462
}
6243
6244
/*
6245
 * In Windows, socket values are unsigned, and an invalid socket value
6246
 * (INVALID_SOCKET) is ~0, which equals -1 in comparisons (with no compiler
6247
 * warning). Ideally we would return an unsigned value for PQsocket() on
6248
 * Windows, but that would cause the function's return value to differ from
6249
 * Unix, so we just return -1 for invalid sockets.
6250
 * http://msdn.microsoft.com/en-us/library/windows/desktop/cc507522%28v=vs.85%29.aspx
6251
 * http://stackoverflow.com/questions/10817252/why-is-invalid-socket-defined-as-0-in-winsock2-h-c
6252
 */
6253
int
6254
PQsocket(const PGconn *conn)
6255
7.85k
{
6256
7.85k
  if (!conn)
6257
0
    return -1;
6258
7.85k
  return (conn->sock != PGINVALID_SOCKET) ? conn->sock : -1;
6259
7.85k
}
6260
6261
int
6262
PQbackendPID(const PGconn *conn)
6263
0
{
6264
0
  if (!conn || conn->status != CONNECTION_OK)
6265
0
    return 0;
6266
0
  return conn->be_pid;
6267
0
}
6268
6269
int
6270
PQconnectionNeedsPassword(const PGconn *conn)
6271
1
{
6272
1
  char     *password;
6273
6274
1
  if (!conn)
6275
0
    return false;
6276
1
  password = PQpass(conn);
6277
1
  if (conn->password_needed &&
6278
0
    (password == NULL || password[0] == '\0'))
6279
0
    return true;
6280
1
  else
6281
1
    return false;
6282
1
}
6283
6284
int
6285
PQconnectionUsedPassword(const PGconn *conn)
6286
0
{
6287
0
  if (!conn)
6288
0
    return false;
6289
0
  if (conn->password_needed)
6290
0
    return true;
6291
0
  else
6292
0
    return false;
6293
0
}
6294
6295
int
6296
PQclientEncoding(const PGconn *conn)
6297
3.30k
{
6298
3.30k
  if (!conn || conn->status != CONNECTION_OK)
6299
0
    return -1;
6300
3.30k
  return conn->client_encoding;
6301
3.30k
}
6302
6303
int
6304
PQsetClientEncoding(PGconn *conn, const char *encoding)
6305
0
{
6306
0
  char    qbuf[128];
6307
0
  static const char query[] = "set client_encoding to '%s'";
6308
0
  PGresult   *res;
6309
0
  int     status;
6310
6311
0
  if (!conn || conn->status != CONNECTION_OK)
6312
0
    return -1;
6313
6314
0
  if (!encoding)
6315
0
    return -1;
6316
6317
  /* Resolve special "auto" value from the locale */
6318
0
  if (strcmp(encoding, "auto") == 0)
6319
0
    encoding = pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true));
6320
6321
  /* check query buffer overflow */
6322
0
  if (sizeof(qbuf) < (sizeof(query) + strlen(encoding)))
6323
0
    return -1;
6324
6325
  /* ok, now send a query */
6326
0
  sprintf(qbuf, query, encoding);
6327
0
  res = PQexec(conn, qbuf);
6328
6329
0
  if (res == NULL)
6330
0
    return -1;
6331
0
  if (res->resultStatus != PGRES_COMMAND_OK)
6332
0
    status = -1;
6333
0
  else
6334
0
  {
6335
    /*
6336
     * In protocol 2 we have to assume the setting will stick, and adjust
6337
     * our state immediately.  In protocol 3 and up we can rely on the
6338
     * backend to report the parameter value, and we'll change state at
6339
     * that time.
6340
     */
6341
0
    if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
6342
0
      pqSaveParameterStatus(conn, "client_encoding", encoding);
6343
0
    status = 0;       /* everything is ok */
6344
0
  }
6345
0
  PQclear(res);
6346
0
  return status;
6347
0
}
6348
6349
PGVerbosity
6350
PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
6351
44
{
6352
44
  PGVerbosity old;
6353
6354
44
  if (!conn)
6355
0
    return PQERRORS_DEFAULT;
6356
44
  old = conn->verbosity;
6357
44
  conn->verbosity = verbosity;
6358
44
  return old;
6359
44
}
6360
6361
PGContextVisibility
6362
PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
6363
40
{
6364
40
  PGContextVisibility old;
6365
6366
40
  if (!conn)
6367
0
    return PQSHOW_CONTEXT_ERRORS;
6368
40
  old = conn->show_context;
6369
40
  conn->show_context = show_context;
6370
40
  return old;
6371
40
}
6372
6373
void
6374
PQtrace(PGconn *conn, FILE *debug_port)
6375
0
{
6376
0
  if (conn == NULL)
6377
0
    return;
6378
0
  PQuntrace(conn);
6379
0
  conn->Pfdebug = debug_port;
6380
0
}
6381
6382
void
6383
PQuntrace(PGconn *conn)
6384
0
{
6385
0
  if (conn == NULL)
6386
0
    return;
6387
0
  if (conn->Pfdebug)
6388
0
  {
6389
0
    fflush(conn->Pfdebug);
6390
0
    conn->Pfdebug = NULL;
6391
0
  }
6392
0
}
6393
6394
PQnoticeReceiver
6395
PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
6396
0
{
6397
0
  PQnoticeReceiver old;
6398
6399
0
  if (conn == NULL)
6400
0
    return NULL;
6401
6402
0
  old = conn->noticeHooks.noticeRec;
6403
0
  if (proc)
6404
0
  {
6405
0
    conn->noticeHooks.noticeRec = proc;
6406
0
    conn->noticeHooks.noticeRecArg = arg;
6407
0
  }
6408
0
  return old;
6409
0
}
6410
6411
PQnoticeProcessor
6412
PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
6413
40
{
6414
40
  PQnoticeProcessor old;
6415
6416
40
  if (conn == NULL)
6417
0
    return NULL;
6418
6419
40
  old = conn->noticeHooks.noticeProc;
6420
40
  if (proc)
6421
40
  {
6422
40
    conn->noticeHooks.noticeProc = proc;
6423
40
    conn->noticeHooks.noticeProcArg = arg;
6424
40
  }
6425
40
  return old;
6426
40
}
6427
6428
/*
6429
 * The default notice message receiver just gets the standard notice text
6430
 * and sends it to the notice processor.  This two-level setup exists
6431
 * mostly for backwards compatibility; perhaps we should deprecate use of
6432
 * PQsetNoticeProcessor?
6433
 */
6434
static void
6435
defaultNoticeReceiver(void *arg, const PGresult *res)
6436
73
{
6437
73
  (void) arg;         /* not used */
6438
73
  if (res->noticeHooks.noticeProc != NULL)
6439
73
    res->noticeHooks.noticeProc(res->noticeHooks.noticeProcArg,
6440
73
                  PQresultErrorMessage(res));
6441
73
}
6442
6443
/*
6444
 * The default notice message processor just prints the
6445
 * message on stderr.  Applications can override this if they
6446
 * want the messages to go elsewhere (a window, for example).
6447
 * Note that simply discarding notices is probably a bad idea.
6448
 */
6449
static void
6450
defaultNoticeProcessor(void *arg, const char *message)
6451
0
{
6452
0
  (void) arg;         /* not used */
6453
  /* Note: we expect the supplied string to end with a newline already. */
6454
0
  fprintf(stderr, "%s", message);
6455
0
}
6456
6457
/*
6458
 * returns a pointer to the next token or NULL if the current
6459
 * token doesn't match
6460
 */
6461
static char *
6462
pwdfMatchesString(char *buf, const char *token)
6463
0
{
6464
0
  char     *tbuf;
6465
0
  const char *ttok;
6466
0
  bool    bslash = false;
6467
6468
0
  if (buf == NULL || token == NULL)
6469
0
    return NULL;
6470
0
  tbuf = buf;
6471
0
  ttok = token;
6472
0
  if (tbuf[0] == '*' && tbuf[1] == ':')
6473
0
    return tbuf + 2;
6474
0
  while (*tbuf != 0)
6475
0
  {
6476
0
    if (*tbuf == '\\' && !bslash)
6477
0
    {
6478
0
      tbuf++;
6479
0
      bslash = true;
6480
0
    }
6481
0
    if (*tbuf == ':' && *ttok == 0 && !bslash)
6482
0
      return tbuf + 1;
6483
0
    bslash = false;
6484
0
    if (*ttok == 0)
6485
0
      return NULL;
6486
0
    if (*tbuf == *ttok)
6487
0
    {
6488
0
      tbuf++;
6489
0
      ttok++;
6490
0
    }
6491
0
    else
6492
0
      return NULL;
6493
0
  }
6494
0
  return NULL;
6495
0
}
6496
6497
/* Get a password from the password file. Return value is malloc'd. */
6498
static char *
6499
passwordFromFile(const char *hostname, const char *port, const char *dbname,
6500
         const char *username, const char *pgpassfile)
6501
81
{
6502
81
  FILE     *fp;
6503
81
  struct stat stat_buf;
6504
6505
81
#define LINELEN NAMEDATALEN*5
6506
81
  char    buf[LINELEN];
6507
6508
81
  if (dbname == NULL || dbname[0] == '\0')
6509
0
    return NULL;
6510
6511
81
  if (username == NULL || username[0] == '\0')
6512
0
    return NULL;
6513
6514
  /* 'localhost' matches pghost of '' or the default socket directory */
6515
81
  if (hostname == NULL || hostname[0] == '\0')
6516
0
    hostname = DefaultHost;
6517
81
  else if (is_absolute_path(hostname))
6518
6519
    /*
6520
     * We should probably use canonicalize_path(), but then we have to
6521
     * bring path.c into libpq, and it doesn't seem worth it.
6522
     */
6523
0
    if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
6524
0
      hostname = DefaultHost;
6525
6526
81
  if (port == NULL || port[0] == '\0')
6527
    /* Use YugaByte default port */
6528
0
    port = DEF_YBPORT_STR;
6529
6530
  /* If password file cannot be opened, ignore it. */
6531
81
  if (stat(pgpassfile, &stat_buf) != 0)
6532
81
    return NULL;
6533
6534
0
#ifndef WIN32
6535
0
  if (!S_ISREG(stat_buf.st_mode))
6536
0
  {
6537
0
    fprintf(stderr,
6538
0
        libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
6539
0
        pgpassfile);
6540
0
    return NULL;
6541
0
  }
6542
6543
  /* If password file is insecure, alert the user and ignore it. */
6544
0
  if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
6545
0
  {
6546
0
    fprintf(stderr,
6547
0
        libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
6548
0
        pgpassfile);
6549
0
    return NULL;
6550
0
  }
6551
#else
6552
6553
  /*
6554
   * On Win32, the directory is protected, so we don't have to check the
6555
   * file.
6556
   */
6557
#endif
6558
6559
0
  fp = fopen(pgpassfile, "r");
6560
0
  if (fp == NULL)
6561
0
    return NULL;
6562
6563
0
  while (!feof(fp) && !ferror(fp))
6564
0
  {
6565
0
    char     *t = buf,
6566
0
           *ret,
6567
0
           *p1,
6568
0
           *p2;
6569
0
    int     len;
6570
6571
0
    if (fgets(buf, sizeof(buf), fp) == NULL)
6572
0
      break;
6573
6574
0
    len = strlen(buf);
6575
6576
    /* Remove trailing newline */
6577
0
    if (len > 0 && buf[len - 1] == '\n')
6578
0
    {
6579
0
      buf[--len] = '\0';
6580
      /* Handle DOS-style line endings, too, even when not on Windows */
6581
0
      if (len > 0 && buf[len - 1] == '\r')
6582
0
        buf[--len] = '\0';
6583
0
    }
6584
6585
0
    if (len == 0)
6586
0
      continue;
6587
6588
0
    if ((t = pwdfMatchesString(t, hostname)) == NULL ||
6589
0
      (t = pwdfMatchesString(t, port)) == NULL ||
6590
0
      (t = pwdfMatchesString(t, dbname)) == NULL ||
6591
0
      (t = pwdfMatchesString(t, username)) == NULL)
6592
0
      continue;
6593
6594
    /* Found a match. */
6595
0
    ret = strdup(t);
6596
0
    fclose(fp);
6597
6598
0
    if (!ret)
6599
0
    {
6600
      /* Out of memory. XXX: an error message would be nice. */
6601
0
      return NULL;
6602
0
    }
6603
6604
    /* De-escape password. */
6605
0
    for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
6606
0
    {
6607
0
      if (*p1 == '\\' && p1[1] != '\0')
6608
0
        ++p1;
6609
0
      *p2 = *p1;
6610
0
    }
6611
0
    *p2 = '\0';
6612
6613
0
    return ret;
6614
0
  }
6615
6616
0
  fclose(fp);
6617
0
  return NULL;
6618
6619
0
#undef LINELEN
6620
0
}
6621
6622
6623
/*
6624
 *  If the connection failed due to bad password, we should mention
6625
 *  if we got the password from the pgpassfile.
6626
 */
6627
static void
6628
pgpassfileWarning(PGconn *conn)
6629
0
{
6630
  /* If it was 'invalid authorization', add pgpassfile mention */
6631
  /* only works with >= 9.0 servers */
6632
0
  if (conn->password_needed &&
6633
0
    conn->connhost[conn->whichhost].password != NULL &&
6634
0
    conn->result)
6635
0
  {
6636
0
    const char *sqlstate = PQresultErrorField(conn->result,
6637
0
                          PG_DIAG_SQLSTATE);
6638
6639
0
    if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
6640
0
      appendPQExpBuffer(&conn->errorMessage,
6641
0
                libpq_gettext("password retrieved from file \"%s\"\n"),
6642
0
                conn->pgpassfile);
6643
0
  }
6644
0
}
6645
6646
6647
/*
6648
 * Obtain user's home directory, return in given buffer
6649
 *
6650
 * On Unix, this actually returns the user's home directory.  On Windows
6651
 * it returns the PostgreSQL-specific application data folder.
6652
 *
6653
 * This is essentially the same as get_home_path(), but we don't use that
6654
 * because we don't want to pull path.c into libpq (it pollutes application
6655
 * namespace).
6656
 *
6657
 * Returns true on success, false on failure to obtain the directory name.
6658
 *
6659
 * CAUTION: although in most situations failure is unexpected, there are users
6660
 * who like to run applications in a home-directory-less environment.  On
6661
 * failure, you almost certainly DO NOT want to report an error.  Just act as
6662
 * though whatever file you were hoping to find in the home directory isn't
6663
 * there (which it isn't).
6664
 */
6665
bool
6666
pqGetHomeDirectory(char *buf, int bufsize)
6667
78
{
6668
78
#ifndef WIN32
6669
78
  char    pwdbuf[BUFSIZ];
6670
78
  struct passwd pwdstr;
6671
78
  struct passwd *pwd = NULL;
6672
78
  const char* home = NULL;
6673
6674
78
  (void) pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd);
6675
78
  home = (pwd == NULL ? getenv("HOME") : pwd->pw_dir);
6676
78
  if (home == NULL)
6677
0
    return false;
6678
78
  strlcpy(buf, home, bufsize);
6679
78
  return true;
6680
#else
6681
  char    tmppath[MAX_PATH];
6682
6683
  ZeroMemory(tmppath, sizeof(tmppath));
6684
  if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
6685
    return false;
6686
  snprintf(buf, bufsize, "%s/postgresql", tmppath);
6687
  return true;
6688
#endif
6689
78
}
6690
6691
/*
6692
 * To keep the API consistent, the locking stubs are always provided, even
6693
 * if they are not required.
6694
 */
6695
6696
static void
6697
default_threadlock(int acquire)
6698
0
{
6699
0
#ifdef ENABLE_THREAD_SAFETY
6700
0
#ifndef WIN32
6701
0
  static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
6702
#else
6703
  static pthread_mutex_t singlethread_lock = NULL;
6704
  static long mutex_initlock = 0;
6705
6706
  if (singlethread_lock == NULL)
6707
  {
6708
    while (InterlockedExchange(&mutex_initlock, 1) == 1)
6709
       /* loop, another thread own the lock */ ;
6710
    if (singlethread_lock == NULL)
6711
    {
6712
      if (pthread_mutex_init(&singlethread_lock, NULL))
6713
        PGTHREAD_ERROR("failed to initialize mutex");
6714
    }
6715
    InterlockedExchange(&mutex_initlock, 0);
6716
  }
6717
#endif
6718
0
  if (acquire)
6719
0
  {
6720
0
    if (pthread_mutex_lock(&singlethread_lock))
6721
0
      PGTHREAD_ERROR("failed to lock mutex");
6722
0
  }
6723
0
  else
6724
0
  {
6725
0
    if (pthread_mutex_unlock(&singlethread_lock))
6726
0
      PGTHREAD_ERROR("failed to unlock mutex");
6727
0
  }
6728
0
#endif
6729
0
}
6730
6731
pgthreadlock_t
6732
PQregisterThreadLock(pgthreadlock_t newhandler)
6733
0
{
6734
0
  pgthreadlock_t prev = pg_g_threadlock;
6735
6736
0
  if (newhandler)
6737
0
    pg_g_threadlock = newhandler;
6738
0
  else
6739
0
    pg_g_threadlock = default_threadlock;
6740
6741
0
  return prev;
6742
0
}