PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
backend_startup.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * backend_startup.c
4 * Backend startup code
5 *
6 * Portions Copyright (c) 1996-2025, 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"
31#include "storage/fd.h"
32#include "storage/ipc.h"
33#include "storage/procsignal.h"
34#include "storage/proc.h"
36#include "tcop/tcopprot.h"
37#include "utils/builtins.h"
38#include "utils/guc_hooks.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 */
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 */
59
60static void BackendInitialize(ClientSocket *client_sock, CAC_state cac);
61static int ProcessSSLStartup(Port *port);
62static int ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done);
63static void ProcessCancelRequestPacket(Port *port, void *pkt, int pktlen);
64static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options);
66static void StartupPacketTimeoutHandler(void);
67static 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 */
75void
76BackendMain(const void *startup_data, size_t startup_data_len)
77{
78 const BackendStartupData *bsdata = startup_data;
79
80 Assert(startup_data_len == sizeof(BackendStartupData));
81 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 */
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 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 */
123
125}
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 */
140static void
142{
143 int status;
144 int ret;
145 Port *port;
146 char remote_host[NI_MAXHOST];
147 char remote_port[NI_MAXSERV];
148 StringInfoData ps_data;
149 MemoryContext oldcontext;
150
151 /* Tell fd.c about the long-lived FD associated with the client_sock */
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 if (PreAuthDelay > 0)
162 pg_usleep(PreAuthDelay * 1000000L);
163
164 /* This flag will remain set until InitPostgres finishes authentication */
165 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 */
177 port = MyProcPort = pq_init(client_sock);
178 MemoryContextSwitchTo(oldcontext);
179
180 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 port->remote_host = "";
184 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 */
197 /* SIGQUIT handler was already set up by InitPostmasterChild */
198 InitializeTimeouts(); /* establishes SIGALRM handler */
199 sigprocmask(SIG_SETMASK, &StartupBlockSig, NULL);
200
201 /*
202 * Get the remote host name and port for logging and status display.
203 */
204 remote_host[0] = '\0';
205 remote_port[0] = '\0';
206 if ((ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
207 remote_host, sizeof(remote_host),
208 remote_port, sizeof(remote_port),
209 (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV)) != 0)
211 (errmsg_internal("pg_getnameinfo_all() failed: %s",
212 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 port->remote_host = MemoryContextStrdup(TopMemoryContext, remote_host);
219 port->remote_port = MemoryContextStrdup(TopMemoryContext, remote_port);
220
221 /* And now we can log that the connection was received, if enabled */
223 {
224 if (remote_port[0])
225 ereport(LOG,
226 (errmsg("connection received: host=%s port=%s",
227 remote_host,
228 remote_port)));
229 else
230 ereport(LOG,
231 (errmsg("connection received: host=%s",
232 remote_host)));
233 }
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 */
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 if (log_hostname &&
262 ret == 0 &&
263 strspn(remote_host, "0123456789.") < strlen(remote_host) &&
264 strspn(remote_host, "0123456789ABCDEFabcdef:") < strlen(remote_host))
265 {
266 port->remote_hostname = MemoryContextStrdup(TopMemoryContext, remote_host);
267 }
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 */
286
287 /* Handle direct SSL handshake */
288 status = ProcessSSLStartup(port);
289
290 /*
291 * Receive the startup packet (which might turn out to be a cancel request
292 * packet).
293 */
294 if (status == STATUS_OK)
295 status = ProcessStartupPacket(port, false, false);
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 if (status == STATUS_OK)
303 {
304 switch (cac)
305 {
306 case CAC_STARTUP:
309 errmsg("the database system is starting up")));
310 break;
312 if (!EnableHotStandby)
315 errmsg("the database system is not accepting connections"),
316 errdetail("Hot standby mode is disabled.")));
317 else if (reachedConsistency)
320 errmsg("the database system is not yet accepting connections"),
321 errdetail("Recovery snapshot is not yet ready for hot standby."),
322 errhint("To enable hot standby, close write transactions with more than %d subtransactions on the primary server.",
324 else
327 errmsg("the database system is not yet accepting connections"),
328 errdetail("Consistent recovery state has not been yet reached.")));
329 break;
330 case CAC_SHUTDOWN:
333 errmsg("the database system is shutting down")));
334 break;
335 case CAC_RECOVERY:
338 errmsg("the database system is in recovery mode")));
339 break;
340 case CAC_TOOMANY:
342 (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
343 errmsg("sorry, too many clients already")));
344 break;
345 case CAC_OK:
346 break;
347 }
348 }
349
350 /*
351 * Disable the timeout, and prevent SIGTERM again.
352 */
354 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 */
366
367 /*
368 * Stop here if it was bad or a cancel packet. ProcessStartupPacket
369 * already did any appropriate error reporting.
370 */
371 if (status != STATUS_OK)
372 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 initStringInfo(&ps_data);
379 if (am_walsender)
381 appendStringInfo(&ps_data, "%s ", port->user_name);
382 if (port->database_name[0] != '\0')
383 appendStringInfo(&ps_data, "%s ", port->database_name);
384 appendStringInfoString(&ps_data, port->remote_host);
385 if (port->remote_port[0] != '\0')
386 appendStringInfo(&ps_data, "(%s)", port->remote_port);
387
388 init_ps_display(ps_data.data);
389 pfree(ps_data.data);
390
391 set_ps_display("initializing");
392}
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 */
400static int
402{
403 int firstbyte;
404
405 Assert(!port->ssl_in_use);
406
408 firstbyte = pq_peekbyte();
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 {
452 (errcode(ERRCODE_PROTOCOL_VIOLATION),
453 errmsg("received direct SSL connection request without ALPN protocol negotiation extension")));
454 goto reject;
455 }
456
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
466reject:
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 * Set ssl_done and/or gss_done when negotiation of an encrypted layer
485 * (currently, TLS or GSSAPI) is completed. A successful negotiation of either
486 * encryption layer sets both flags, but a rejected negotiation sets only the
487 * flag for that layer, since the client may wish to try the other one. We
488 * should make no assumption here about the order in which the client may make
489 * requests.
490 */
491static int
492ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
493{
494 int32 len;
495 char *buf = NULL;
496 ProtocolVersion proto;
497 MemoryContext oldcontext;
498
500
501 /*
502 * Grab the first byte of the length word separately, so that we can tell
503 * whether we have no data at all or an incomplete packet. (This might
504 * sound inefficient, but it's not really, because of buffering in
505 * pqcomm.c.)
506 */
507 if (pq_getbytes(&len, 1) == EOF)
508 {
509 /*
510 * If we get no data at all, don't clutter the log with a complaint;
511 * such cases often occur for legitimate reasons. An example is that
512 * we might be here after responding to NEGOTIATE_SSL_CODE, and if the
513 * client didn't like our response, it'll probably just drop the
514 * connection. Service-monitoring software also often just opens and
515 * closes a connection without sending anything. (So do port
516 * scanners, which may be less benign, but it's not really our job to
517 * notice those.)
518 */
519 goto fail;
520 }
521
522 if (pq_getbytes(((char *) &len) + 1, 3) == EOF)
523 {
524 /* Got a partial length word, so bleat about that */
525 if (!ssl_done && !gss_done)
527 (errcode(ERRCODE_PROTOCOL_VIOLATION),
528 errmsg("incomplete startup packet")));
529 goto fail;
530 }
531
532 len = pg_ntoh32(len);
533 len -= 4;
534
535 if (len < (int32) sizeof(ProtocolVersion) ||
537 {
539 (errcode(ERRCODE_PROTOCOL_VIOLATION),
540 errmsg("invalid length of startup packet")));
541 goto fail;
542 }
543
544 /*
545 * Allocate space to hold the startup packet, plus one extra byte that's
546 * initialized to be zero. This ensures we will have null termination of
547 * all strings inside the packet.
548 */
549 buf = palloc(len + 1);
550 buf[len] = '\0';
551
552 if (pq_getbytes(buf, len) == EOF)
553 {
555 (errcode(ERRCODE_PROTOCOL_VIOLATION),
556 errmsg("incomplete startup packet")));
557 goto fail;
558 }
560
561 /*
562 * The first field is either a protocol version number or a special
563 * request code.
564 */
565 port->proto = proto = pg_ntoh32(*((ProtocolVersion *) buf));
566
567 if (proto == CANCEL_REQUEST_CODE)
568 {
570 /* Not really an error, but we don't want to proceed further */
571 goto fail;
572 }
573
574 if (proto == NEGOTIATE_SSL_CODE && !ssl_done)
575 {
576 char SSLok;
577
578#ifdef USE_SSL
579
580 /*
581 * No SSL when disabled or on Unix sockets.
582 *
583 * Also no SSL negotiation if we already have a direct SSL connection
584 */
585 if (!LoadedSSL || port->laddr.addr.ss_family == AF_UNIX || port->ssl_in_use)
586 SSLok = 'N';
587 else
588 SSLok = 'S'; /* Support for SSL */
589#else
590 SSLok = 'N'; /* No support for SSL */
591#endif
592
594 {
595 if (SSLok == 'S')
596 ereport(LOG,
597 (errmsg("SSLRequest accepted")));
598 else
599 ereport(LOG,
600 (errmsg("SSLRequest rejected")));
601 }
602
603 while (secure_write(port, &SSLok, 1) != 1)
604 {
605 if (errno == EINTR)
606 continue; /* if interrupted, just retry */
609 errmsg("failed to send SSL negotiation response: %m")));
610 goto fail; /* close the connection */
611 }
612
613#ifdef USE_SSL
614 if (SSLok == 'S' && secure_open_server(port) == -1)
615 goto fail;
616#endif
617
618 pfree(buf);
619
620 /*
621 * At this point we should have no data already buffered. If we do,
622 * it was received before we performed the SSL handshake, so it wasn't
623 * encrypted and indeed may have been injected by a man-in-the-middle.
624 * We report this case to the client.
625 */
626 if (pq_buffer_remaining_data() > 0)
628 (errcode(ERRCODE_PROTOCOL_VIOLATION),
629 errmsg("received unencrypted data after SSL request"),
630 errdetail("This could be either a client-software bug or evidence of an attempted man-in-the-middle attack.")));
631
632 /*
633 * regular startup packet, cancel, etc packet should follow, but not
634 * another SSL negotiation request, and a GSS request should only
635 * follow if SSL was rejected (client may negotiate in either order)
636 */
637 return ProcessStartupPacket(port, true, SSLok == 'S');
638 }
639 else if (proto == NEGOTIATE_GSS_CODE && !gss_done)
640 {
641 char GSSok = 'N';
642
643#ifdef ENABLE_GSS
644 /* No GSSAPI encryption when on Unix socket */
645 if (port->laddr.addr.ss_family != AF_UNIX)
646 GSSok = 'G';
647#endif
648
650 {
651 if (GSSok == 'G')
652 ereport(LOG,
653 (errmsg("GSSENCRequest accepted")));
654 else
655 ereport(LOG,
656 (errmsg("GSSENCRequest rejected")));
657 }
658
659 while (secure_write(port, &GSSok, 1) != 1)
660 {
661 if (errno == EINTR)
662 continue;
665 errmsg("failed to send GSSAPI negotiation response: %m")));
666 goto fail; /* close the connection */
667 }
668
669#ifdef ENABLE_GSS
670 if (GSSok == 'G' && secure_open_gssapi(port) == -1)
671 goto fail;
672#endif
673
674 pfree(buf);
675
676 /*
677 * At this point we should have no data already buffered. If we do,
678 * it was received before we performed the GSS handshake, so it wasn't
679 * encrypted and indeed may have been injected by a man-in-the-middle.
680 * We report this case to the client.
681 */
682 if (pq_buffer_remaining_data() > 0)
684 (errcode(ERRCODE_PROTOCOL_VIOLATION),
685 errmsg("received unencrypted data after GSSAPI encryption request"),
686 errdetail("This could be either a client-software bug or evidence of an attempted man-in-the-middle attack.")));
687
688 /*
689 * regular startup packet, cancel, etc packet should follow, but not
690 * another GSS negotiation request, and an SSL request should only
691 * follow if GSS was rejected (client may negotiate in either order)
692 */
693 return ProcessStartupPacket(port, GSSok == 'G', true);
694 }
695
696 /* Could add additional special packet types here */
697
698 /*
699 * Set FrontendProtocol now so that ereport() knows what format to send if
700 * we fail during startup. We use the protocol version requested by the
701 * client unless it's higher than the latest version we support. It's
702 * possible that error message fields might look different in newer
703 * protocol versions, but that's something those new clients should be
704 * able to deal with.
705 */
707
708 /* Check that the major protocol version is in range. */
712 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
713 errmsg("unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u",
718
719 /*
720 * Now fetch parameters out of startup packet and save them into the Port
721 * structure.
722 */
724
725 /* Handle protocol version 3 startup packet */
726 {
727 int32 offset = sizeof(ProtocolVersion);
728 List *unrecognized_protocol_options = NIL;
729
730 /*
731 * Scan packet body for name/option pairs. We can assume any string
732 * beginning within the packet body is null-terminated, thanks to
733 * zeroing extra byte above.
734 */
735 port->guc_options = NIL;
736
737 while (offset < len)
738 {
739 char *nameptr = buf + offset;
740 int32 valoffset;
741 char *valptr;
742
743 if (*nameptr == '\0')
744 break; /* found packet terminator */
745 valoffset = offset + strlen(nameptr) + 1;
746 if (valoffset >= len)
747 break; /* missing value, will complain below */
748 valptr = buf + valoffset;
749
750 if (strcmp(nameptr, "database") == 0)
751 port->database_name = pstrdup(valptr);
752 else if (strcmp(nameptr, "user") == 0)
753 port->user_name = pstrdup(valptr);
754 else if (strcmp(nameptr, "options") == 0)
755 port->cmdline_options = pstrdup(valptr);
756 else if (strcmp(nameptr, "replication") == 0)
757 {
758 /*
759 * Due to backward compatibility concerns the replication
760 * parameter is a hybrid beast which allows the value to be
761 * either boolean or the string 'database'. The latter
762 * connects to a specific database which is e.g. required for
763 * logical decoding while.
764 */
765 if (strcmp(valptr, "database") == 0)
766 {
767 am_walsender = true;
768 am_db_walsender = true;
769 }
770 else if (!parse_bool(valptr, &am_walsender))
772 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
773 errmsg("invalid value for parameter \"%s\": \"%s\"",
774 "replication",
775 valptr),
776 errhint("Valid values are: \"false\", 0, \"true\", 1, \"database\".")));
777 }
778 else if (strncmp(nameptr, "_pq_.", 5) == 0)
779 {
780 /*
781 * Any option beginning with _pq_. is reserved for use as a
782 * protocol-level option, but at present no such options are
783 * defined.
784 */
785 unrecognized_protocol_options =
786 lappend(unrecognized_protocol_options, pstrdup(nameptr));
787 }
788 else
789 {
790 /* Assume it's a generic GUC option */
791 port->guc_options = lappend(port->guc_options,
792 pstrdup(nameptr));
793 port->guc_options = lappend(port->guc_options,
794 pstrdup(valptr));
795
796 /*
797 * Copy application_name to port if we come across it. This
798 * is done so we can log the application_name in the
799 * connection authorization message. Note that the GUC would
800 * be used but we haven't gone through GUC setup yet.
801 */
802 if (strcmp(nameptr, "application_name") == 0)
803 {
804 port->application_name = pg_clean_ascii(valptr, 0);
805 }
806 }
807 offset = valoffset + strlen(valptr) + 1;
808 }
809
810 /*
811 * If we didn't find a packet terminator exactly at the end of the
812 * given packet length, complain.
813 */
814 if (offset != len - 1)
816 (errcode(ERRCODE_PROTOCOL_VIOLATION),
817 errmsg("invalid startup packet layout: expected terminator as last byte")));
818
819 /*
820 * If the client requested a newer protocol version or if the client
821 * requested any protocol options we didn't recognize, let them know
822 * the newest minor protocol version we do support and the names of
823 * any unrecognized options.
824 */
826 unrecognized_protocol_options != NIL)
827 SendNegotiateProtocolVersion(unrecognized_protocol_options);
828 }
829
830 /* Check a user name was given. */
831 if (port->user_name == NULL || port->user_name[0] == '\0')
833 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
834 errmsg("no PostgreSQL user name specified in startup packet")));
835
836 /* The database defaults to the user name. */
837 if (port->database_name == NULL || port->database_name[0] == '\0')
838 port->database_name = pstrdup(port->user_name);
839
840 /*
841 * Truncate given database and user names to length of a Postgres name.
842 * This avoids lookup failures when overlength names are given.
843 */
844 if (strlen(port->database_name) >= NAMEDATALEN)
845 port->database_name[NAMEDATALEN - 1] = '\0';
846 if (strlen(port->user_name) >= NAMEDATALEN)
847 port->user_name[NAMEDATALEN - 1] = '\0';
848
849 if (am_walsender)
851 else
853
854 /*
855 * Normal walsender backends, e.g. for streaming replication, are not
856 * connected to a particular database. But walsenders used for logical
857 * replication need to connect to a specific database. We allow streaming
858 * replication commands to be issued even if connected to a database as it
859 * can make sense to first make a basebackup and then stream changes
860 * starting from that.
861 */
863 port->database_name[0] = '\0';
864
865 /*
866 * Done filling the Port structure
867 */
868 MemoryContextSwitchTo(oldcontext);
869
870 pfree(buf);
871
872 return STATUS_OK;
873
874fail:
875 /* be tidy, just to avoid Valgrind complaints */
876 if (buf)
877 pfree(buf);
878
879 return STATUS_ERROR;
880}
881
882/*
883 * The client has sent a cancel request packet, not a normal
884 * start-a-new-connection packet. Perform the necessary processing. Nothing
885 * is sent back to the client.
886 */
887static void
888ProcessCancelRequestPacket(Port *port, void *pkt, int pktlen)
889{
891 int len;
892
893 if (pktlen < offsetof(CancelRequestPacket, cancelAuthCode))
894 {
896 (errcode(ERRCODE_PROTOCOL_VIOLATION),
897 errmsg("invalid length of cancel request packet")));
898 return;
899 }
900 len = pktlen - offsetof(CancelRequestPacket, cancelAuthCode);
901 if (len == 0 || len > 256)
902 {
904 (errcode(ERRCODE_PROTOCOL_VIOLATION),
905 errmsg("invalid length of cancel key in cancel request packet")));
906 return;
907 }
908
909 canc = (CancelRequestPacket *) pkt;
911}
912
913/*
914 * Send a NegotiateProtocolVersion to the client. This lets the client know
915 * that they have either requested a newer minor protocol version than we are
916 * able to speak, or at least one protocol option that we don't understand, or
917 * possibly both. FrontendProtocol has already been set to the version
918 * requested by the client or the highest version we know how to speak,
919 * whichever is older. If the highest version that we know how to speak is too
920 * old for the client, it can abandon the connection.
921 *
922 * We also include in the response a list of protocol options we didn't
923 * understand. This allows clients to include optional parameters that might
924 * be present either in newer protocol versions or third-party protocol
925 * extensions without fear of having to reconnect if those options are not
926 * understood, while at the same time making certain that the client is aware
927 * of which options were actually accepted.
928 */
929static void
930SendNegotiateProtocolVersion(List *unrecognized_protocol_options)
931{
933 ListCell *lc;
934
937 pq_sendint32(&buf, list_length(unrecognized_protocol_options));
938 foreach(lc, unrecognized_protocol_options)
939 pq_sendstring(&buf, lfirst(lc));
941
942 /* no need to flush, some other message will follow */
943}
944
945
946/*
947 * SIGTERM while processing startup packet.
948 *
949 * Running proc_exit() from a signal handler would be quite unsafe.
950 * However, since we have not yet touched shared memory, we can just
951 * pull the plug and exit without running any atexit handlers.
952 *
953 * One might be tempted to try to send a message, or log one, indicating
954 * why we are disconnecting. However, that would be quite unsafe in itself.
955 * Also, it seems undesirable to provide clues about the database's state
956 * to a client that has not yet completed authentication, or even sent us
957 * a startup packet.
958 */
959static void
961{
962 _exit(1);
963}
964
965/*
966 * Timeout while processing startup packet.
967 * As for process_startup_packet_die(), we exit via _exit(1).
968 */
969static void
971{
972 _exit(1);
973}
974
975/*
976 * Helper for the log_connections GUC check hook.
977 *
978 * `elemlist` is a listified version of the string input passed to the
979 * log_connections GUC check hook, check_log_connections().
980 * check_log_connections() is responsible for cleaning up `elemlist`.
981 *
982 * validate_log_connections_options() returns false if an error was
983 * encountered and the GUC input could not be validated and true otherwise.
984 *
985 * `flags` returns the flags that should be stored in the log_connections GUC
986 * by its assign hook.
987 */
988static bool
990{
991 ListCell *l;
992 char *item;
993
994 /*
995 * For backwards compatibility, we accept these tokens by themselves.
996 *
997 * Prior to PostgreSQL 18, log_connections was a boolean GUC that accepted
998 * any unambiguous substring of 'true', 'false', 'yes', 'no', 'on', and
999 * 'off'. Since log_connections became a list of strings in 18, we only
1000 * accept complete option strings.
1001 */
1002 static const struct config_enum_entry compat_options[] = {
1003 {"off", 0},
1004 {"false", 0},
1005 {"no", 0},
1006 {"0", 0},
1007 {"on", LOG_CONNECTION_ON},
1008 {"true", LOG_CONNECTION_ON},
1009 {"yes", LOG_CONNECTION_ON},
1010 {"1", LOG_CONNECTION_ON},
1011 };
1012
1013 *flags = 0;
1014
1015 /* If an empty string was passed, we're done */
1016 if (list_length(elemlist) == 0)
1017 return true;
1018
1019 /*
1020 * Now check for the backwards compatibility options. They must always be
1021 * specified on their own, so we error out if the first option is a
1022 * backwards compatibility option and other options are also specified.
1023 */
1024 item = linitial(elemlist);
1025
1026 for (size_t i = 0; i < lengthof(compat_options); i++)
1027 {
1028 struct config_enum_entry option = compat_options[i];
1029
1030 if (pg_strcasecmp(item, option.name) != 0)
1031 continue;
1032
1033 if (list_length(elemlist) > 1)
1034 {
1035 GUC_check_errdetail("Cannot specify log_connections option \"%s\" in a list with other options.",
1036 item);
1037 return false;
1038 }
1039
1040 *flags = option.val;
1041 return true;
1042 }
1043
1044 /* Now check the aspect options. The empty string was already handled */
1045 foreach(l, elemlist)
1046 {
1047 static const struct config_enum_entry options[] = {
1048 {"receipt", LOG_CONNECTION_RECEIPT},
1049 {"authentication", LOG_CONNECTION_AUTHENTICATION},
1050 {"authorization", LOG_CONNECTION_AUTHORIZATION},
1051 {"setup_durations", LOG_CONNECTION_SETUP_DURATIONS},
1052 {"all", LOG_CONNECTION_ALL},
1053 };
1054
1055 item = lfirst(l);
1056 for (size_t i = 0; i < lengthof(options); i++)
1057 {
1059
1060 if (pg_strcasecmp(item, option.name) == 0)
1061 {
1062 *flags |= option.val;
1063 goto next;
1064 }
1065 }
1066
1067 GUC_check_errdetail("Invalid option \"%s\".", item);
1068 return false;
1069
1070next: ;
1071 }
1072
1073 return true;
1074}
1075
1076
1077/*
1078 * GUC check hook for log_connections
1079 */
1080bool
1082{
1083 uint32 flags;
1084 char *rawstring;
1085 List *elemlist;
1086 bool success;
1087
1088 /* Need a modifiable copy of string */
1089 rawstring = pstrdup(*newval);
1090
1091 if (!SplitIdentifierString(rawstring, ',', &elemlist))
1092 {
1093 GUC_check_errdetail("Invalid list syntax in parameter \"%s\".", "log_connections");
1094 pfree(rawstring);
1095 list_free(elemlist);
1096 return false;
1097 }
1098
1099 /* Validation logic is all in the helper */
1100 success = validate_log_connections_options(elemlist, &flags);
1101
1102 /* Time for cleanup */
1103 pfree(rawstring);
1104 list_free(elemlist);
1105
1106 if (!success)
1107 return false;
1108
1109 /*
1110 * We succeeded, so allocate `extra` and save the flags there for use by
1111 * assign_log_connections().
1112 */
1113 *extra = guc_malloc(LOG, sizeof(int));
1114 if (!*extra)
1115 return false;
1116 *((int *) *extra) = flags;
1117
1118 return true;
1119}
1120
1121/*
1122 * GUC assign hook for log_connections
1123 */
1124void
1125assign_log_connections(const char *newval, void *extra)
1126{
1127 log_connections = *((int *) extra);
1128}
sigset_t StartupBlockSig
Definition: pqsignal.c:24
sigset_t BlockSig
Definition: pqsignal.c:23
bool check_log_connections(char **newval, void **extra, GucSource source)
uint32 log_connections
bool Trace_connection_negotiation
ConnectionTiming conn_timing
static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options)
static void process_startup_packet_die(SIGNAL_ARGS)
static void StartupPacketTimeoutHandler(void)
static void BackendInitialize(ClientSocket *client_sock, CAC_state cac)
static int ProcessSSLStartup(Port *port)
char * log_connections_string
static void ProcessCancelRequestPacket(Port *port, void *pkt, int pktlen)
void assign_log_connections(const char *newval, void *extra)
void BackendMain(const void *startup_data, size_t startup_data_len)
static int ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
static bool validate_log_connections_options(List *elemlist, uint32 *flags)
CAC_state
@ CAC_TOOMANY
@ CAC_OK
@ CAC_RECOVERY
@ CAC_NOTHOTSTANDBY
@ CAC_STARTUP
@ CAC_SHUTDOWN
@ LOG_CONNECTION_AUTHORIZATION
@ LOG_CONNECTION_ON
@ LOG_CONNECTION_SETUP_DURATIONS
@ LOG_CONNECTION_ALL
@ LOG_CONNECTION_RECEIPT
@ LOG_CONNECTION_AUTHENTICATION
ssize_t secure_open_gssapi(Port *port)
int secure_initialize(bool isServerStart)
Definition: be-secure.c:75
ssize_t secure_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:305
int secure_open_server(Port *port)
Definition: be-secure.c:112
static int32 next
Definition: blutils.c:224
bool parse_bool(const char *value, bool *result)
Definition: bool.c:31
#define Min(x, y)
Definition: c.h:1003
#define STATUS_OK
Definition: c.h:1168
#define SIGNAL_ARGS
Definition: c.h:1348
int32_t int32
Definition: c.h:534
uint32_t uint32
Definition: c.h:538
#define lengthof(array)
Definition: c.h:787
#define STATUS_ERROR
Definition: c.h:1169
#define TIMESTAMP_MINUS_INFINITY
Definition: timestamp.h:150
@ DestRemote
Definition: dest.h:89
int errcode_for_socket_access(void)
Definition: elog.c:954
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1161
int errdetail(const char *fmt,...)
Definition: elog.c:1207
int errhint(const char *fmt,...)
Definition: elog.c:1321
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define LOG
Definition: elog.h:31
#define COMMERROR
Definition: elog.h:33
#define FATAL
Definition: elog.h:41
#define WARNING
Definition: elog.h:36
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:150
void ReserveExternalFD(void)
Definition: fd.c:1220
#define ERRCODE_CANNOT_CONNECT_NOW
Definition: fe-connect.c:94
struct ClientSocket * MyClientSocket
Definition: globals.c:50
ProtocolVersion FrontendProtocol
Definition: globals.c:30
struct Port * MyProcPort
Definition: globals.c:51
void * guc_malloc(int elevel, size_t size)
Definition: guc.c:640
#define newval
#define GUC_check_errdetail
Definition: guc.h:505
GucSource
Definition: guc.h:112
Assert(PointerIsAligned(start, uint64))
static bool success
Definition: initdb.c:187
#define INJECTION_POINT(name, arg)
#define IS_INJECTION_POINT_ATTACHED(name)
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:114
void check_on_shmem_exit_lists_are_empty(void)
Definition: ipc.c:432
void proc_exit(int code)
Definition: ipc.c:104
int i
Definition: isn.c:77
List * lappend(List *list, void *datum)
Definition: list.c:339
void list_free(List *list)
Definition: list.c:1546
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1746
char * pstrdup(const char *in)
Definition: mcxt.c:1759
void pfree(void *pointer)
Definition: mcxt.c:1594
MemoryContext TopMemoryContext
Definition: mcxt.c:166
void * palloc(Size size)
Definition: mcxt.c:1365
@ B_WAL_SENDER
Definition: miscadmin.h:346
@ B_BACKEND
Definition: miscadmin.h:341
const char * GetBackendTypeDesc(BackendType backendType)
Definition: miscinit.c:263
BackendType MyBackendType
Definition: miscinit.c:64
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
#define pg_ntoh32(x)
Definition: pg_bswap.h:125
#define NAMEDATALEN
const void size_t len
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define linitial(l)
Definition: pg_list.h:178
static int port
Definition: pg_regress.c:115
static rewind_source * source
Definition: pg_rewind.c:89
static char * buf
Definition: pg_test_fsync.c:72
#define pqsignal
Definition: port.h:531
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
CommandDest whereToSendOutput
Definition: postgres.c:92
void PostgresMain(const char *dbname, const char *username)
Definition: postgres.c:4193
int PreAuthDelay
Definition: postmaster.c:240
bool log_hostname
Definition: postmaster.c:243
bool ClientAuthInProgress
Definition: postmaster.c:372
int AuthenticationTimeout
Definition: postmaster.c:241
bool EnableSSL
Definition: postmaster.c:238
PGDLLIMPORT bool LoadedSSL
Port * pq_init(ClientSocket *client_sock)
Definition: pqcomm.c:174
int pq_peekbyte(void)
Definition: pqcomm.c:982
ssize_t pq_buffer_remaining_data(void)
Definition: pqcomm.c:1127
int pq_getbytes(void *b, size_t len)
Definition: pqcomm.c:1062
void pq_endmsgread(void)
Definition: pqcomm.c:1165
void pq_startmsgread(void)
Definition: pqcomm.c:1141
#define PG_PROTOCOL_MAJOR(v)
Definition: pqcomm.h:87
#define PG_PROTOCOL_EARLIEST
Definition: pqcomm.h:96
#define CANCEL_REQUEST_CODE
Definition: pqcomm.h:137
#define MAX_STARTUP_PACKET_LENGTH
Definition: pqcomm.h:118
#define PG_PROTOCOL_LATEST
Definition: pqcomm.h:97
#define NEGOTIATE_GSS_CODE
Definition: pqcomm.h:173
#define NEGOTIATE_SSL_CODE
Definition: pqcomm.h:172
uint32 ProtocolVersion
Definition: pqcomm.h:99
#define PG_PROTOCOL(m, n)
Definition: pqcomm.h:90
#define PG_PROTOCOL_MINOR(v)
Definition: pqcomm.h:88
void pq_sendstring(StringInfo buf, const char *str)
Definition: pqformat.c:195
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:296
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:88
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:144
#define PGPROC_MAX_CACHED_SUBXIDS
Definition: proc.h:39
void SendCancelRequest(int backendPID, const uint8 *cancel_key, int cancel_key_len)
Definition: procsignal.c:729
#define PqMsg_NegotiateProtocolVersion
Definition: protocol.h:59
void init_ps_display(const char *fixed_part)
Definition: ps_status.c:285
static void set_ps_display(const char *activity)
Definition: ps_status.h:40
void pg_usleep(long microsec)
Definition: signal.c:53
const char * gai_strerror(int ecode)
void InitProcess(void)
Definition: proc.c:390
char * pg_clean_ascii(const char *str, int alloc_flags)
Definition: string.c:85
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
CAC_state canAcceptConnections
uint32 backendPID
Definition: pqcomm.h:143
uint8 cancelAuthCode[FLEXIBLE_ARRAY_MEMBER]
Definition: pqcomm.h:144
TimestampTz ready_for_use
Definition: pg_list.h:54
Definition: libpq-be.h:129
char * user_name
Definition: libpq-be.h:151
char * database_name
Definition: libpq-be.h:150
Definition: guc.h:174
int val
Definition: getopt_long.h:22
const char * name
Definition: getopt_long.h:19
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:560
void InitializeTimeouts(void)
Definition: timeout.c:470
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:685
TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler)
Definition: timeout.c:505
@ STARTUP_PACKET_TIMEOUT
Definition: timeout.h:26
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:2744
bool am_walsender
Definition: walsender.c:123
bool am_db_walsender
Definition: walsender.c:126
#define EINTR
Definition: win32_port.h:364
bool EnableHotStandby
Definition: xlog.c:122
bool reachedConsistency
Definition: xlogrecovery.c:301