Coverage Report

Created: 2026-10-16 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/tcop/backend_startup.c
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * backend_startup.c
4
 *    Backend startup code
5
 *
6
 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7
 * Portions Copyright (c) 1994, Regents of the University of California
8
 *
9
 *
10
 * IDENTIFICATION
11
 *    src/backend/tcop/backend_startup.c
12
 *
13
 *-------------------------------------------------------------------------
14
 */
15
16
#include "postgres.h"
17
18
#include <unistd.h>
19
20
#include "access/xlog.h"
21
#include "access/xlogrecovery.h"
22
#include "common/ip.h"
23
#include "common/string.h"
24
#include "libpq/libpq.h"
25
#include "libpq/libpq-be.h"
26
#include "libpq/pqformat.h"
27
#include "libpq/pqsignal.h"
28
#include "miscadmin.h"
29
#include "postmaster/postmaster.h"
30
#include "replication/walsender.h"
31
#include "storage/fd.h"
32
#include "storage/ipc.h"
33
#include "storage/procsignal.h"
34
#include "storage/proc.h"
35
#include "tcop/backend_startup.h"
36
#include "tcop/tcopprot.h"
37
#include "utils/builtins.h"
38
#include "utils/guc_hooks.h"
39
#include "utils/injection_point.h"
40
#include "utils/memutils.h"
41
#include "utils/ps_status.h"
42
#include "utils/timeout.h"
43
#include "utils/varlena.h"
44
45
/* GUCs */
46
bool    Trace_connection_negotiation = false;
47
uint32    log_connections = 0;
48
char     *log_connections_string = NULL;
49
50
/* Other globals */
51
52
/*
53
 * ConnectionTiming stores timestamps of various points in connection
54
 * establishment and setup.
55
 * ready_for_use is initialized to a special value here so we can check if
56
 * we've already set it before doing so in PostgresMain().
57
 */
58
ConnectionTiming conn_timing = {.ready_for_use = TIMESTAMP_MINUS_INFINITY};
59
60
static void BackendInitialize(ClientSocket *client_sock, CAC_state cac);
61
static int  ProcessSSLStartup(Port *port);
62
static int  ProcessStartupPacket(Port *port);
63
static void ProcessCancelRequestPacket(Port *port, void *pkt, int pktlen);
64
static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options);
65
static void process_startup_packet_die(SIGNAL_ARGS);
66
static void StartupPacketTimeoutHandler(void);
67
static bool validate_log_connections_options(List *elemlist, uint32 *flags);
68
69
/*
70
 * Entry point for a new backend process.
71
 *
72
 * Initialize the connection, read the startup packet, authenticate the
73
 * client, and start the main processing loop.
74
 */
75
void
76
BackendMain(const void *startup_data, size_t startup_data_len)
77
0
{
78
0
  const BackendStartupData *bsdata = startup_data;
79
80
0
  Assert(startup_data_len == sizeof(BackendStartupData));
81
0
  Assert(MyClientSocket != NULL);
82
83
#ifdef EXEC_BACKEND
84
85
  /*
86
   * Need to reinitialize the SSL library in the backend, since the context
87
   * structures contain function pointers and cannot be passed through the
88
   * parameter file.
89
   *
90
   * If for some reason reload fails (maybe the user installed broken key
91
   * files), soldier on without SSL; that's better than all connections
92
   * becoming impossible.
93
   *
94
   * XXX should we do this in all child processes?  For the moment it's
95
   * enough to do it in backend children.
96
   */
97
#ifdef USE_SSL
98
  if (EnableSSL)
99
  {
100
    if (secure_initialize(false) == 0)
101
      LoadedSSL = true;
102
    else
103
      ereport(LOG,
104
          (errmsg("SSL configuration could not be loaded in child process")));
105
  }
106
#endif
107
#endif
108
109
  /* Perform additional initialization and collect startup packet */
110
0
  BackendInitialize(MyClientSocket, bsdata->canAcceptConnections);
111
112
  /*
113
   * Create a per-backend PGPROC struct in shared memory.  We must do this
114
   * before we can use LWLocks or access any shared memory.
115
   */
116
0
  InitProcess();
117
118
  /*
119
   * Make sure we aren't in PostmasterContext anymore.  (We can't delete it
120
   * just yet, though, because InitPostgres will need the HBA data.)
121
   */
122
0
  MemoryContextSwitchTo(TopMemoryContext);
123
124
0
  PostgresMain(MyProcPort->database_name, MyProcPort->user_name);
125
0
}
126
127
128
/*
129
 * BackendInitialize -- initialize an interactive (postmaster-child)
130
 *        backend process, and collect the client's startup packet.
131
 *
132
 * returns: nothing.  Will not return at all if there's any failure.
133
 *
134
 * Note: this code does not depend on having any access to shared memory.
135
 * Indeed, our approach to SIGTERM/timeout handling *requires* that
136
 * shared memory not have been touched yet; see comments within.
137
 * In the EXEC_BACKEND case, we are physically attached to shared memory
138
 * but have not yet set up most of our local pointers to shmem structures.
139
 */
140
static void
141
BackendInitialize(ClientSocket *client_sock, CAC_state cac)
142
0
{
143
0
  int     status;
144
0
  int     ret;
145
0
  Port     *port;
146
0
  char    remote_host[NI_MAXHOST];
147
0
  char    remote_port[NI_MAXSERV];
148
0
  StringInfoData ps_data;
149
0
  MemoryContext oldcontext;
150
151
  /* Tell fd.c about the long-lived FD associated with the client_sock */
152
0
  ReserveExternalFD();
153
154
  /*
155
   * PreAuthDelay is a debugging aid for investigating problems in the
156
   * authentication cycle: it can be set in postgresql.conf to allow time to
157
   * attach to the newly-forked backend with a debugger.  (See also
158
   * PostAuthDelay, which we allow clients to pass through PGOPTIONS, but it
159
   * is not honored until after authentication.)
160
   */
161
0
  if (PreAuthDelay > 0)
162
0
    pg_usleep(PreAuthDelay * 1000000L);
163
164
  /* This flag will remain set until InitPostgres finishes authentication */
165
0
  ClientAuthInProgress = true; /* limit visibility of log messages */
166
167
  /*
168
   * Initialize libpq and enable reporting of ereport errors to the client.
169
   * Must do this now because authentication uses libpq to send messages.
170
   *
171
   * The Port structure and all data structures attached to it are allocated
172
   * in TopMemoryContext, so that they survive into PostgresMain execution.
173
   * We need not worry about leaking this storage on failure, since we
174
   * aren't in the postmaster process anymore.
175
   */
176
0
  oldcontext = MemoryContextSwitchTo(TopMemoryContext);
177
0
  port = MyProcPort = pq_init(client_sock);
178
0
  MemoryContextSwitchTo(oldcontext);
179
180
0
  whereToSendOutput = DestRemote; /* now safe to ereport to client */
181
182
  /* set these to empty in case they are needed before we set them up */
183
0
  port->remote_host = "";
184
0
  port->remote_port = "";
185
186
  /*
187
   * We arrange to do _exit(1) if we receive SIGTERM or timeout while trying
188
   * to collect the startup packet; while SIGQUIT results in _exit(2).
189
   * Otherwise the postmaster cannot shutdown the database FAST or IMMED
190
   * cleanly if a buggy client fails to send the packet promptly.
191
   *
192
   * Exiting with _exit(1) is only possible because we have not yet touched
193
   * shared memory; therefore no outside-the-process state needs to get
194
   * cleaned up.
195
   */
196
0
  pqsignal(SIGTERM, process_startup_packet_die);
197
  /* SIGQUIT handler was already set up by InitPostmasterChild */
198
0
  InitializeTimeouts();   /* establishes SIGALRM handler */
199
0
  sigprocmask(SIG_SETMASK, &StartupBlockSig, NULL);
200
201
  /*
202
   * Get the remote host name and port for logging and status display.
203
   */
204
0
  remote_host[0] = '\0';
205
0
  remote_port[0] = '\0';
206
0
  if ((ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
207
0
                  remote_host, sizeof(remote_host),
208
0
                  remote_port, sizeof(remote_port),
209
0
                  (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV)) != 0)
210
0
    ereport(WARNING,
211
0
        (errmsg_internal("pg_getnameinfo_all() failed: %s",
212
0
                 gai_strerror(ret))));
213
214
  /*
215
   * Save remote_host and remote_port in port structure (after this, they
216
   * will appear in log_line_prefix data for log messages).
217
   */
218
0
  port->remote_host = MemoryContextStrdup(TopMemoryContext, remote_host);
219
0
  port->remote_port = MemoryContextStrdup(TopMemoryContext, remote_port);
220
221
  /* And now we can log that the connection was received, if enabled */
222
0
  if (log_connections & LOG_CONNECTION_RECEIPT)
223
0
  {
224
0
    if (remote_port[0])
225
0
      ereport(LOG,
226
0
          (errmsg("connection received: host=%s port=%s",
227
0
              remote_host,
228
0
              remote_port)));
229
0
    else
230
0
      ereport(LOG,
231
0
          (errmsg("connection received: host=%s",
232
0
              remote_host)));
233
0
  }
234
235
  /* For testing client error handling */
236
#ifdef USE_INJECTION_POINTS
237
  INJECTION_POINT("backend-initialize", NULL);
238
  if (IS_INJECTION_POINT_ATTACHED("backend-initialize-v2-error"))
239
  {
240
    /*
241
     * This simulates an early error from a pre-v14 server, which used the
242
     * version 2 protocol for any errors that occurred before processing
243
     * the startup packet.
244
     */
245
    FrontendProtocol = PG_PROTOCOL(2, 0);
246
    elog(FATAL, "protocol version 2 error triggered");
247
  }
248
#endif
249
250
  /*
251
   * If we did a reverse lookup to name, we might as well save the results
252
   * rather than possibly repeating the lookup during authentication.
253
   *
254
   * Note that we don't want to specify NI_NAMEREQD above, because then we'd
255
   * get nothing useful for a client without an rDNS entry.  Therefore, we
256
   * must check whether we got a numeric IPv4 or IPv6 address, and not save
257
   * it into remote_hostname if so.  (This test is conservative and might
258
   * sometimes classify a hostname as numeric, but an error in that
259
   * direction is safe; it only results in a possible extra lookup.)
260
   */
261
0
  if (log_hostname &&
262
0
    ret == 0 &&
263
0
    strspn(remote_host, "0123456789.") < strlen(remote_host) &&
264
0
    strspn(remote_host, "0123456789ABCDEFabcdef:") < strlen(remote_host))
265
0
  {
266
0
    port->remote_hostname = MemoryContextStrdup(TopMemoryContext, remote_host);
267
0
  }
268
269
  /*
270
   * Ready to begin client interaction.  We will give up and _exit(1) after
271
   * a time delay, so that a broken client can't hog a connection
272
   * indefinitely.  PreAuthDelay and any DNS interactions above don't count
273
   * against the time limit.
274
   *
275
   * Note: AuthenticationTimeout is applied here while waiting for the
276
   * startup packet, and then again in InitPostgres for the duration of any
277
   * authentication operations.  So a hostile client could tie up the
278
   * process for nearly twice AuthenticationTimeout before we kick him off.
279
   *
280
   * Note: because PostgresMain will call InitializeTimeouts again, the
281
   * registration of STARTUP_PACKET_TIMEOUT will be lost.  This is okay
282
   * since we never use it again after this function.
283
   */
284
0
  RegisterTimeout(STARTUP_PACKET_TIMEOUT, StartupPacketTimeoutHandler);
285
0
  enable_timeout_after(STARTUP_PACKET_TIMEOUT, AuthenticationTimeout * 1000);
286
287
  /* Handle direct SSL handshake */
288
0
  status = ProcessSSLStartup(port);
289
290
  /*
291
   * Receive the startup packet (which might turn out to be a cancel request
292
   * packet).
293
   */
294
0
  if (status == STATUS_OK)
295
0
    status = ProcessStartupPacket(port);
296
297
  /*
298
   * If we're going to reject the connection due to database state, say so
299
   * now instead of wasting cycles on an authentication exchange. (This also
300
   * allows a pg_ping utility to be written.)
301
   */
302
0
  if (status == STATUS_OK)
303
0
  {
304
0
    switch (cac)
305
0
    {
306
0
      case CAC_STARTUP:
307
0
        ereport(FATAL,
308
0
            (errcode(ERRCODE_CANNOT_CONNECT_NOW),
309
0
             errmsg("the database system is starting up")));
310
0
        break;
311
0
      case CAC_NOTHOTSTANDBY:
312
0
        if (!EnableHotStandby)
313
0
          ereport(FATAL,
314
0
              (errcode(ERRCODE_CANNOT_CONNECT_NOW),
315
0
               errmsg("the database system is not accepting connections"),
316
0
               errdetail("Hot standby mode is disabled.")));
317
0
        else if (reachedConsistency)
318
0
          ereport(FATAL,
319
0
              (errcode(ERRCODE_CANNOT_CONNECT_NOW),
320
0
               errmsg("the database system is not yet accepting connections"),
321
0
               errdetail("Recovery snapshot is not yet ready for hot standby."),
322
0
               errhint("To enable hot standby, close write transactions with more than %d subtransactions on the primary server.",
323
0
                   PGPROC_MAX_CACHED_SUBXIDS)));
324
0
        else
325
0
          ereport(FATAL,
326
0
              (errcode(ERRCODE_CANNOT_CONNECT_NOW),
327
0
               errmsg("the database system is not yet accepting connections"),
328
0
               errdetail("Consistent recovery state has not been yet reached.")));
329
0
        break;
330
0
      case CAC_SHUTDOWN:
331
0
        ereport(FATAL,
332
0
            (errcode(ERRCODE_CANNOT_CONNECT_NOW),
333
0
             errmsg("the database system is shutting down")));
334
0
        break;
335
0
      case CAC_RECOVERY:
336
0
        ereport(FATAL,
337
0
            (errcode(ERRCODE_CANNOT_CONNECT_NOW),
338
0
             errmsg("the database system is in recovery mode")));
339
0
        break;
340
0
      case CAC_TOOMANY:
341
0
        ereport(FATAL,
342
0
            (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
343
0
             errmsg("sorry, too many clients already")));
344
0
        break;
345
0
      case CAC_OK:
346
0
        break;
347
0
    }
348
0
  }
349
350
  /*
351
   * Disable the timeout, and prevent SIGTERM again.
352
   */
353
0
  disable_timeout(STARTUP_PACKET_TIMEOUT, false);
354
0
  sigprocmask(SIG_SETMASK, &BlockSig, NULL);
355
356
  /*
357
   * As a safety check that nothing in startup has yet performed
358
   * shared-memory modifications that would need to be undone if we had
359
   * exited through SIGTERM or timeout above, check that no on_shmem_exit
360
   * handlers have been registered yet.  (This isn't terribly bulletproof,
361
   * since someone might misuse an on_proc_exit handler for shmem cleanup,
362
   * but it's a cheap and helpful check.  We cannot disallow on_proc_exit
363
   * handlers unfortunately, since pq_init() already registered one.)
364
   */
365
0
  check_on_shmem_exit_lists_are_empty();
366
367
  /*
368
   * Stop here if it was bad or a cancel packet.  ProcessStartupPacket
369
   * already did any appropriate error reporting.
370
   */
371
0
  if (status != STATUS_OK)
372
0
    proc_exit(0);
373
374
  /*
375
   * Now that we have the user and database name, we can set the process
376
   * title for ps.  It's good to do this as early as possible in startup.
377
   */
378
0
  initStringInfo(&ps_data);
379
0
  if (am_walsender)
380
0
    appendStringInfo(&ps_data, "%s ", GetBackendTypeDesc(B_WAL_SENDER));
381
0
  appendStringInfo(&ps_data, "%s ", port->user_name);
382
0
  if (port->database_name[0] != '\0')
383
0
    appendStringInfo(&ps_data, "%s ", port->database_name);
384
0
  appendStringInfoString(&ps_data, port->remote_host);
385
0
  if (port->remote_port[0] != '\0')
386
0
    appendStringInfo(&ps_data, "(%s)", port->remote_port);
387
388
0
  init_ps_display(ps_data.data);
389
0
  pfree(ps_data.data);
390
391
0
  set_ps_display("initializing");
392
0
}
393
394
/*
395
 * Check for a direct SSL connection.
396
 *
397
 * This happens before the startup packet so we are careful not to actually
398
 * read any bytes from the stream if it's not a direct SSL connection.
399
 */
400
static int
401
ProcessSSLStartup(Port *port)
402
{
403
  int     firstbyte;
404
405
  Assert(!port->ssl_in_use);
406
407
  pq_startmsgread();
408
  firstbyte = pq_peekbyte();
409
  pq_endmsgread();
410
  if (firstbyte == EOF)
411
  {
412
    /*
413
     * Like in ProcessStartupPacket, if we get no data at all, don't
414
     * clutter the log with a complaint.
415
     */
416
    return STATUS_ERROR;
417
  }
418
419
  if (firstbyte != 0x16)
420
  {
421
    /* Not an SSL handshake message */
422
    return STATUS_OK;
423
  }
424
425
  /*
426
   * First byte indicates standard SSL handshake message
427
   *
428
   * (It can't be a Postgres startup length because in network byte order
429
   * that would be a startup packet hundreds of megabytes long)
430
   */
431
432
#ifdef USE_SSL
433
  if (!LoadedSSL || port->laddr.addr.ss_family == AF_UNIX)
434
  {
435
    /* SSL not supported */
436
    goto reject;
437
  }
438
439
  if (secure_open_server(port) == -1)
440
  {
441
    /*
442
     * we assume secure_open_server() sent an appropriate TLS alert
443
     * already
444
     */
445
    goto reject;
446
  }
447
  Assert(port->ssl_in_use);
448
449
  if (!port->alpn_used)
450
  {
451
    ereport(COMMERROR,
452
        (errcode(ERRCODE_PROTOCOL_VIOLATION),
453
         errmsg("received direct SSL connection request without ALPN protocol negotiation extension")));
454
    goto reject;
455
  }
456
457
  if (Trace_connection_negotiation)
458
    ereport(LOG,
459
        (errmsg("direct SSL connection accepted")));
460
  return STATUS_OK;
461
#else
462
  /* SSL not supported by this build */
463
  goto reject;
464
#endif
465
466
reject:
467
  if (Trace_connection_negotiation)
468
    ereport(LOG,
469
        (errmsg("direct SSL connection rejected")));
470
  return STATUS_ERROR;
471
}
472
473
/*
474
 * Read a client's startup packet and do something according to it.
475
 *
476
 * Returns STATUS_OK or STATUS_ERROR, or might call ereport(FATAL) and
477
 * not return at all.
478
 *
479
 * (Note that ereport(FATAL) stuff is sent to the client, so only use it
480
 * if that's what you want.  Return STATUS_ERROR if you don't want to
481
 * send anything to the client, which would typically be appropriate
482
 * if we detect a communications failure.)
483
 *
484
 */
485
static int
486
ProcessStartupPacket(Port *port)
487
0
{
488
0
  int32   len;
489
0
  char     *buf = NULL;
490
0
  ProtocolVersion proto;
491
0
  MemoryContext oldcontext;
492
0
  bool    gss_done;
493
0
  bool    ssl_done;
494
495
  /*
496
   * Set ssl_done and/or gss_done when negotiation of an encrypted layer
497
   * (currently, TLS or GSSAPI) is completed.  A successful negotiation of
498
   * either encryption layer sets both flags, but a rejected negotiation
499
   * sets only the flag for that layer, since the client may wish to try the
500
   * other one.  We should make no assumption here about the order in which
501
   * the client may make requests.
502
   */
503
0
  gss_done = false;
504
0
  ssl_done = false;
505
506
0
retry:
507
0
  pq_startmsgread();
508
509
  /*
510
   * Grab the first byte of the length word separately, so that we can tell
511
   * whether we have no data at all or an incomplete packet.  (This might
512
   * sound inefficient, but it's not really, because of buffering in
513
   * pqcomm.c.)
514
   */
515
0
  if (pq_getbytes(&len, 1) == EOF)
516
0
  {
517
    /*
518
     * If we get no data at all, don't clutter the log with a complaint;
519
     * such cases often occur for legitimate reasons.  An example is that
520
     * we might be here after responding to NEGOTIATE_SSL_CODE, and if the
521
     * client didn't like our response, it'll probably just drop the
522
     * connection.  Service-monitoring software also often just opens and
523
     * closes a connection without sending anything.  (So do port
524
     * scanners, which may be less benign, but it's not really our job to
525
     * notice those.)
526
     */
527
0
    goto fail;
528
0
  }
529
530
0
  if (pq_getbytes(((char *) &len) + 1, 3) == EOF)
531
0
  {
532
    /* Got a partial length word, so bleat about that */
533
0
    if (!ssl_done && !gss_done)
534
0
      ereport(COMMERROR,
535
0
          (errcode(ERRCODE_PROTOCOL_VIOLATION),
536
0
           errmsg("incomplete startup packet")));
537
0
    goto fail;
538
0
  }
539
540
0
  len = pg_ntoh32(len);
541
0
  len -= 4;
542
543
0
  if (len < (int32) sizeof(ProtocolVersion) ||
544
0
    len > MAX_STARTUP_PACKET_LENGTH)
545
0
  {
546
0
    ereport(COMMERROR,
547
0
        (errcode(ERRCODE_PROTOCOL_VIOLATION),
548
0
         errmsg("invalid length of startup packet")));
549
0
    goto fail;
550
0
  }
551
552
  /*
553
   * Allocate space to hold the startup packet, plus one extra byte that's
554
   * initialized to be zero.  This ensures we will have null termination of
555
   * all strings inside the packet.
556
   */
557
0
  buf = palloc(len + 1);
558
0
  buf[len] = '\0';
559
560
0
  if (pq_getbytes(buf, len) == EOF)
561
0
  {
562
0
    ereport(COMMERROR,
563
0
        (errcode(ERRCODE_PROTOCOL_VIOLATION),
564
0
         errmsg("incomplete startup packet")));
565
0
    goto fail;
566
0
  }
567
0
  pq_endmsgread();
568
569
  /*
570
   * The first field is either a protocol version number or a special
571
   * request code.
572
   */
573
0
  port->proto = proto = pg_ntoh32(*((ProtocolVersion *) buf));
574
575
0
  if (proto == CANCEL_REQUEST_CODE)
576
0
  {
577
0
    ProcessCancelRequestPacket(port, buf, len);
578
    /* Not really an error, but we don't want to proceed further */
579
0
    goto fail;
580
0
  }
581
582
0
  if (proto == NEGOTIATE_SSL_CODE && !ssl_done)
583
0
  {
584
0
    char    SSLok;
585
586
#ifdef USE_SSL
587
588
    /*
589
     * No SSL when disabled or on Unix sockets.
590
     *
591
     * Also no SSL negotiation if we already have a direct SSL connection
592
     */
593
    if (!LoadedSSL || port->laddr.addr.ss_family == AF_UNIX || port->ssl_in_use)
594
      SSLok = 'N';
595
    else
596
      SSLok = 'S';    /* Support for SSL */
597
#else
598
0
    SSLok = 'N';      /* No support for SSL */
599
0
#endif
600
601
0
    if (Trace_connection_negotiation)
602
0
    {
603
0
      if (SSLok == 'S')
604
0
        ereport(LOG,
605
0
            (errmsg("SSLRequest accepted")));
606
0
      else
607
0
        ereport(LOG,
608
0
            (errmsg("SSLRequest rejected")));
609
0
    }
610
611
0
    while (secure_write(port, &SSLok, 1) != 1)
612
0
    {
613
0
      if (errno == EINTR)
614
0
        continue;   /* if interrupted, just retry */
615
0
      ereport(COMMERROR,
616
0
          (errcode_for_socket_access(),
617
0
           errmsg("failed to send SSL negotiation response: %m")));
618
0
      goto fail;     /* close the connection */
619
0
    }
620
621
#ifdef USE_SSL
622
    if (SSLok == 'S' && secure_open_server(port) == -1)
623
      goto fail;
624
#endif
625
626
0
    pfree(buf);
627
0
    buf = NULL;
628
629
    /*
630
     * At this point we should have no data already buffered.  If we do,
631
     * it was received before we performed the SSL handshake, so it wasn't
632
     * encrypted and indeed may have been injected by a man-in-the-middle.
633
     * We report this case to the client.
634
     */
635
0
    if (pq_buffer_remaining_data() > 0)
636
0
      ereport(FATAL,
637
0
          (errcode(ERRCODE_PROTOCOL_VIOLATION),
638
0
           errmsg("received unencrypted data after SSL request"),
639
0
           errdetail("This could be either a client-software bug or evidence of an attempted man-in-the-middle attack.")));
640
641
    /*
642
     * regular startup packet, cancel, etc packet should follow, but not
643
     * another SSL negotiation request, and a GSS request should only
644
     * follow if SSL was rejected (client may negotiate in either order)
645
     */
646
0
    ssl_done = true;
647
0
    if (SSLok == 'S')
648
0
    {
649
      /*
650
       * We are done with SSL and negotiated correctly, so consider the
651
       * same for GSS.
652
       */
653
0
      gss_done = true;
654
0
    }
655
0
    goto retry;
656
0
  }
657
0
  else if (proto == NEGOTIATE_GSS_CODE && !gss_done)
658
0
  {
659
0
    char    GSSok = 'N';
660
661
#ifdef ENABLE_GSS
662
663
    /*
664
     * No GSSAPI encryption when on Unix socket.
665
     *
666
     * Also no GSS negotiation if we already have a direct SSL connection.
667
     */
668
    if (port->laddr.addr.ss_family != AF_UNIX && !port->ssl_in_use)
669
      GSSok = 'G';
670
#endif
671
672
0
    if (Trace_connection_negotiation)
673
0
    {
674
0
      if (GSSok == 'G')
675
0
        ereport(LOG,
676
0
            (errmsg("GSSENCRequest accepted")));
677
0
      else
678
0
        ereport(LOG,
679
0
            (errmsg("GSSENCRequest rejected")));
680
0
    }
681
682
0
    while (secure_write(port, &GSSok, 1) != 1)
683
0
    {
684
0
      if (errno == EINTR)
685
0
        continue;
686
0
      ereport(COMMERROR,
687
0
          (errcode_for_socket_access(),
688
0
           errmsg("failed to send GSSAPI negotiation response: %m")));
689
0
      goto fail;     /* close the connection */
690
0
    }
691
692
#ifdef ENABLE_GSS
693
    if (GSSok == 'G' && secure_open_gssapi(port) == -1)
694
      goto fail;
695
#endif
696
697
0
    pfree(buf);
698
0
    buf = NULL;
699
700
    /*
701
     * At this point we should have no data already buffered.  If we do,
702
     * it was received before we performed the GSS handshake, so it wasn't
703
     * encrypted and indeed may have been injected by a man-in-the-middle.
704
     * We report this case to the client.
705
     */
706
0
    if (pq_buffer_remaining_data() > 0)
707
0
      ereport(FATAL,
708
0
          (errcode(ERRCODE_PROTOCOL_VIOLATION),
709
0
           errmsg("received unencrypted data after GSSAPI encryption request"),
710
0
           errdetail("This could be either a client-software bug or evidence of an attempted man-in-the-middle attack.")));
711
712
    /*
713
     * regular startup packet, cancel, etc packet should follow, but not
714
     * another GSS negotiation request, and an SSL request should only
715
     * follow if GSS was rejected (client may negotiate in either order)
716
     */
717
0
    gss_done = true;
718
0
    if (GSSok == 'G')
719
0
    {
720
      /*
721
       * We are done with GSS and negotiated correctly, so consider the
722
       * same for SSL.
723
       */
724
0
      ssl_done = true;
725
0
    }
726
0
    goto retry;
727
0
  }
728
729
  /* Could add additional special packet types here */
730
731
  /*
732
   * Set FrontendProtocol now so that ereport() knows what format to send if
733
   * we fail during startup. We use the protocol version requested by the
734
   * client unless it's higher than the latest version we support. It's
735
   * possible that error message fields might look different in newer
736
   * protocol versions, but that's something those new clients should be
737
   * able to deal with.
738
   */
739
0
  FrontendProtocol = Min(proto, PG_PROTOCOL_LATEST);
740
741
  /* Check that the major protocol version is in range. */
742
0
  if (PG_PROTOCOL_MAJOR(proto) < PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST) ||
743
0
    PG_PROTOCOL_MAJOR(proto) > PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST))
744
0
    ereport(FATAL,
745
0
        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
746
0
         errmsg("unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u",
747
0
            PG_PROTOCOL_MAJOR(proto), PG_PROTOCOL_MINOR(proto),
748
0
            PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST),
749
0
            PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST),
750
0
            PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST))));
751
752
  /*
753
   * Now fetch parameters out of startup packet and save them into the Port
754
   * structure.
755
   */
756
0
  oldcontext = MemoryContextSwitchTo(TopMemoryContext);
757
758
  /* Handle protocol version 3 startup packet */
759
0
  {
760
0
    int32   offset = sizeof(ProtocolVersion);
761
0
    List     *unrecognized_protocol_options = NIL;
762
763
    /*
764
     * Scan packet body for name/option pairs.  We can assume any string
765
     * beginning within the packet body is null-terminated, thanks to
766
     * zeroing extra byte above.
767
     */
768
0
    port->guc_options = NIL;
769
770
0
    while (offset < len)
771
0
    {
772
0
      char     *nameptr = buf + offset;
773
0
      int32   valoffset;
774
0
      char     *valptr;
775
776
0
      if (*nameptr == '\0')
777
0
        break;     /* found packet terminator */
778
0
      valoffset = offset + strlen(nameptr) + 1;
779
0
      if (valoffset >= len)
780
0
        break;     /* missing value, will complain below */
781
0
      valptr = buf + valoffset;
782
783
0
      if (strcmp(nameptr, "database") == 0)
784
0
        port->database_name = pstrdup(valptr);
785
0
      else if (strcmp(nameptr, "user") == 0)
786
0
        port->user_name = pstrdup(valptr);
787
0
      else if (strcmp(nameptr, "options") == 0)
788
0
        port->cmdline_options = pstrdup(valptr);
789
0
      else if (strcmp(nameptr, "replication") == 0)
790
0
      {
791
        /*
792
         * Due to backward compatibility concerns the replication
793
         * parameter is a hybrid beast which allows the value to be
794
         * either boolean or the string 'database'. The latter
795
         * connects to a specific database which is e.g. required for
796
         * logical decoding while.
797
         */
798
0
        if (strcmp(valptr, "database") == 0)
799
0
        {
800
0
          am_walsender = true;
801
0
          am_db_walsender = true;
802
0
        }
803
0
        else if (!parse_bool(valptr, &am_walsender))
804
0
          ereport(FATAL,
805
0
              (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
806
0
               errmsg("invalid value for parameter \"%s\": \"%s\"",
807
0
                  "replication",
808
0
                  valptr),
809
0
               errhint("Valid values are: \"false\", 0, \"true\", 1, \"database\".")));
810
0
      }
811
0
      else if (strncmp(nameptr, "_pq_.", 5) == 0)
812
0
      {
813
        /*
814
         * Any option beginning with _pq_. is reserved for use as a
815
         * protocol-level option, but at present no such options are
816
         * defined.
817
         */
818
0
        unrecognized_protocol_options =
819
0
          lappend(unrecognized_protocol_options, pstrdup(nameptr));
820
0
      }
821
0
      else
822
0
      {
823
        /* Assume it's a generic GUC option */
824
0
        port->guc_options = lappend(port->guc_options,
825
0
                      pstrdup(nameptr));
826
0
        port->guc_options = lappend(port->guc_options,
827
0
                      pstrdup(valptr));
828
829
        /*
830
         * Copy application_name to port if we come across it.  This
831
         * is done so we can log the application_name in the
832
         * connection authorization message.  Note that the GUC would
833
         * be used but we haven't gone through GUC setup yet.
834
         */
835
0
        if (strcmp(nameptr, "application_name") == 0)
836
0
        {
837
0
          port->application_name = pg_clean_ascii(valptr, 0);
838
0
        }
839
0
      }
840
0
      offset = valoffset + strlen(valptr) + 1;
841
0
    }
842
843
    /*
844
     * If we didn't find a packet terminator exactly at the end of the
845
     * given packet length, complain.
846
     */
847
0
    if (offset != len - 1)
848
0
      ereport(FATAL,
849
0
          (errcode(ERRCODE_PROTOCOL_VIOLATION),
850
0
           errmsg("invalid startup packet layout: expected terminator as last byte")));
851
852
    /*
853
     * If the client requested a newer protocol version or if the client
854
     * requested any protocol options we didn't recognize, let them know
855
     * the newest minor protocol version we do support and the names of
856
     * any unrecognized options.
857
     */
858
0
    if (PG_PROTOCOL_MINOR(proto) > PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST) ||
859
0
      unrecognized_protocol_options != NIL)
860
0
      SendNegotiateProtocolVersion(unrecognized_protocol_options);
861
862
0
    list_free_deep(unrecognized_protocol_options);
863
0
  }
864
865
  /* Check a user name was given. */
866
0
  if (port->user_name == NULL || port->user_name[0] == '\0')
867
0
    ereport(FATAL,
868
0
        (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
869
0
         errmsg("no PostgreSQL user name specified in startup packet")));
870
871
  /* The database defaults to the user name. */
872
0
  if (port->database_name == NULL || port->database_name[0] == '\0')
873
0
    port->database_name = pstrdup(port->user_name);
874
875
  /*
876
   * Truncate given database and user names to length of a Postgres name.
877
   * This avoids lookup failures when overlength names are given.
878
   */
879
0
  if (strlen(port->database_name) >= NAMEDATALEN)
880
0
    port->database_name[NAMEDATALEN - 1] = '\0';
881
0
  if (strlen(port->user_name) >= NAMEDATALEN)
882
0
    port->user_name[NAMEDATALEN - 1] = '\0';
883
884
0
  Assert(MyBackendType == B_BACKEND || MyBackendType == B_DEAD_END_BACKEND);
885
0
  if (am_walsender)
886
0
    MyBackendType = B_WAL_SENDER;
887
888
  /*
889
   * Normal walsender backends, e.g. for streaming replication, are not
890
   * connected to a particular database. But walsenders used for logical
891
   * replication need to connect to a specific database. We allow streaming
892
   * replication commands to be issued even if connected to a database as it
893
   * can make sense to first make a basebackup and then stream changes
894
   * starting from that.
895
   */
896
0
  if (am_walsender && !am_db_walsender)
897
0
    port->database_name[0] = '\0';
898
899
  /*
900
   * Done filling the Port structure
901
   */
902
0
  MemoryContextSwitchTo(oldcontext);
903
904
0
  pfree(buf);
905
906
0
  return STATUS_OK;
907
908
0
fail:
909
  /* be tidy, just to avoid Valgrind complaints */
910
0
  if (buf)
911
0
    pfree(buf);
912
913
0
  return STATUS_ERROR;
914
0
}
915
916
/*
917
 * The client has sent a cancel request packet, not a normal
918
 * start-a-new-connection packet.  Perform the necessary processing.  Nothing
919
 * is sent back to the client.
920
 */
921
static void
922
ProcessCancelRequestPacket(Port *port, void *pkt, int pktlen)
923
{
924
  CancelRequestPacket *canc;
925
  int     len;
926
927
  if (pktlen < offsetof(CancelRequestPacket, cancelAuthCode))
928
  {
929
    ereport(COMMERROR,
930
        (errcode(ERRCODE_PROTOCOL_VIOLATION),
931
         errmsg("invalid length of cancel request packet")));
932
    return;
933
  }
934
  len = pktlen - offsetof(CancelRequestPacket, cancelAuthCode);
935
  if (len == 0 || len > 256)
936
  {
937
    ereport(COMMERROR,
938
        (errcode(ERRCODE_PROTOCOL_VIOLATION),
939
         errmsg("invalid length of cancel key in cancel request packet")));
940
    return;
941
  }
942
943
  canc = (CancelRequestPacket *) pkt;
944
  SendCancelRequest(pg_ntoh32(canc->backendPID), canc->cancelAuthCode, len);
945
}
946
947
/*
948
 * Send a NegotiateProtocolVersion to the client.  This lets the client know
949
 * that they have either requested a newer minor protocol version than we are
950
 * able to speak, or at least one protocol option that we don't understand, or
951
 * possibly both. FrontendProtocol has already been set to the version
952
 * requested by the client or the highest version we know how to speak,
953
 * whichever is older. If the highest version that we know how to speak is too
954
 * old for the client, it can abandon the connection.
955
 *
956
 * We also include in the response a list of protocol options we didn't
957
 * understand.  This allows clients to include optional parameters that might
958
 * be present either in newer protocol versions or third-party protocol
959
 * extensions without fear of having to reconnect if those options are not
960
 * understood, while at the same time making certain that the client is aware
961
 * of which options were actually accepted.
962
 */
963
static void
964
SendNegotiateProtocolVersion(List *unrecognized_protocol_options)
965
0
{
966
0
  StringInfoData buf;
967
0
  ListCell   *lc;
968
969
0
  pq_beginmessage(&buf, PqMsg_NegotiateProtocolVersion);
970
0
  pq_sendint32(&buf, FrontendProtocol);
971
0
  pq_sendint32(&buf, list_length(unrecognized_protocol_options));
972
0
  foreach(lc, unrecognized_protocol_options)
973
0
    pq_sendstring(&buf, lfirst(lc));
974
0
  pq_endmessage(&buf);
975
976
  /* no need to flush, some other message will follow */
977
0
}
978
979
980
/*
981
 * SIGTERM while processing startup packet.
982
 *
983
 * Running proc_exit() from a signal handler would be quite unsafe.
984
 * However, since we have not yet touched shared memory, we can just
985
 * pull the plug and exit without running any atexit handlers.
986
 *
987
 * One might be tempted to try to send a message, or log one, indicating
988
 * why we are disconnecting.  However, that would be quite unsafe in itself.
989
 * Also, it seems undesirable to provide clues about the database's state
990
 * to a client that has not yet completed authentication, or even sent us
991
 * a startup packet.
992
 */
993
static void
994
process_startup_packet_die(SIGNAL_ARGS)
995
0
{
996
0
  _exit(1);
997
0
}
998
999
/*
1000
 * Timeout while processing startup packet.
1001
 * As for process_startup_packet_die(), we exit via _exit(1).
1002
 */
1003
static void
1004
StartupPacketTimeoutHandler(void)
1005
0
{
1006
0
  _exit(1);
1007
0
}
1008
1009
/*
1010
 * Helper for the log_connections GUC check hook.
1011
 *
1012
 * `elemlist` is a listified version of the string input passed to the
1013
 * log_connections GUC check hook, check_log_connections().
1014
 * check_log_connections() is responsible for cleaning up `elemlist`.
1015
 *
1016
 * validate_log_connections_options() returns false if an error was
1017
 * encountered and the GUC input could not be validated and true otherwise.
1018
 *
1019
 * `flags` returns the flags that should be stored in the log_connections GUC
1020
 * by its assign hook.
1021
 */
1022
static bool
1023
validate_log_connections_options(List *elemlist, uint32 *flags)
1024
2
{
1025
2
  ListCell   *l;
1026
2
  char     *item;
1027
1028
  /*
1029
   * For backwards compatibility, we accept these tokens by themselves.
1030
   *
1031
   * Prior to PostgreSQL 18, log_connections was a boolean GUC that accepted
1032
   * any unambiguous substring of 'true', 'false', 'yes', 'no', 'on', and
1033
   * 'off'. Since log_connections became a list of strings in 18, we only
1034
   * accept complete option strings.
1035
   */
1036
2
  static const struct config_enum_entry compat_options[] = {
1037
2
    {"off", 0},
1038
2
    {"false", 0},
1039
2
    {"no", 0},
1040
2
    {"0", 0},
1041
2
    {"on", LOG_CONNECTION_ON},
1042
2
    {"true", LOG_CONNECTION_ON},
1043
2
    {"yes", LOG_CONNECTION_ON},
1044
2
    {"1", LOG_CONNECTION_ON},
1045
2
  };
1046
1047
2
  *flags = 0;
1048
1049
  /* If an empty string was passed, we're done */
1050
2
  if (list_length(elemlist) == 0)
1051
2
    return true;
1052
1053
  /*
1054
   * Now check for the backwards compatibility options. They must always be
1055
   * specified on their own, so we error out if the first option is a
1056
   * backwards compatibility option and other options are also specified.
1057
   */
1058
0
  item = linitial(elemlist);
1059
1060
0
  for (size_t i = 0; i < lengthof(compat_options); i++)
1061
0
  {
1062
0
    struct config_enum_entry option = compat_options[i];
1063
1064
0
    if (pg_strcasecmp(item, option.name) != 0)
1065
0
      continue;
1066
1067
0
    if (list_length(elemlist) > 1)
1068
0
    {
1069
0
      GUC_check_errdetail("Cannot specify log_connections option \"%s\" in a list with other options.",
1070
0
                item);
1071
0
      return false;
1072
0
    }
1073
1074
0
    *flags = option.val;
1075
0
    return true;
1076
0
  }
1077
1078
  /* Now check the aspect options. The empty string was already handled */
1079
0
  foreach(l, elemlist)
1080
0
  {
1081
0
    static const struct config_enum_entry options[] = {
1082
0
      {"receipt", LOG_CONNECTION_RECEIPT},
1083
0
      {"authentication", LOG_CONNECTION_AUTHENTICATION},
1084
0
      {"authorization", LOG_CONNECTION_AUTHORIZATION},
1085
0
      {"setup_durations", LOG_CONNECTION_SETUP_DURATIONS},
1086
0
      {"all", LOG_CONNECTION_ALL},
1087
0
    };
1088
1089
0
    item = lfirst(l);
1090
0
    for (size_t i = 0; i < lengthof(options); i++)
1091
0
    {
1092
0
      struct config_enum_entry option = options[i];
1093
1094
0
      if (pg_strcasecmp(item, option.name) == 0)
1095
0
      {
1096
0
        *flags |= option.val;
1097
0
        goto next;
1098
0
      }
1099
0
    }
1100
1101
0
    GUC_check_errdetail("Invalid option \"%s\".", item);
1102
0
    return false;
1103
1104
0
next: ;
1105
0
  }
1106
1107
0
  return true;
1108
0
}
1109
1110
1111
/*
1112
 * GUC check hook for log_connections
1113
 */
1114
bool
1115
check_log_connections(char **newval, void **extra, GucSource source)
1116
2
{
1117
2
  uint32    flags;
1118
2
  char     *rawstring;
1119
2
  List     *elemlist;
1120
2
  bool    success;
1121
1122
  /* Need a modifiable copy of string */
1123
2
  rawstring = pstrdup(*newval);
1124
1125
2
  if (!SplitIdentifierString(rawstring, ',', &elemlist))
1126
0
  {
1127
0
    GUC_check_errdetail("Invalid list syntax in parameter \"%s\".", "log_connections");
1128
0
    pfree(rawstring);
1129
0
    list_free(elemlist);
1130
0
    return false;
1131
0
  }
1132
1133
  /* Validation logic is all in the helper */
1134
2
  success = validate_log_connections_options(elemlist, &flags);
1135
1136
  /* Time for cleanup */
1137
2
  pfree(rawstring);
1138
2
  list_free(elemlist);
1139
1140
2
  if (!success)
1141
0
    return false;
1142
1143
  /*
1144
   * We succeeded, so allocate `extra` and save the flags there for use by
1145
   * assign_log_connections().
1146
   */
1147
2
  *extra = guc_malloc(LOG, sizeof(int));
1148
2
  if (!*extra)
1149
0
    return false;
1150
2
  *((int *) *extra) = flags;
1151
1152
2
  return true;
1153
2
}
1154
1155
/*
1156
 * GUC assign hook for log_connections
1157
 */
1158
void
1159
assign_log_connections(const char *newval, void *extra)
1160
2
{
1161
2
  log_connections = *((int *) extra);
1162
2
}