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