2222 * if it did much with shared memory then it would be prone to crashing
2323 * along with the backends.
2424 *
25+ * When a request message is received, we now fork() immediately.
26+ * The child process performs authentication of the request, and
27+ * then becomes a backend if successful. This allows the auth code
28+ * to be written in a simple single-threaded style (as opposed to the
29+ * crufty "poor man's multitasking" code that used to be needed).
30+ * More importantly, it ensures that blockages in non-multithreaded
31+ * libraries like SSL or PAM cannot cause denial of service to other
32+ * clients.
33+ *
2534 *
2635 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
2736 * Portions Copyright (c) 1994, Regents of the University of California
2837 *
2938 *
3039 * IDENTIFICATION
31- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.224 2001/06/20 18:07:55 petere Exp $
40+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.225 2001/06/21 16:43:24 tgl Exp $
3241 *
3342 * NOTES
3443 *
102111#ifdef HAVE_SIGPROCMASK
103112sigset_t UnBlockSig ,
104113BlockSig ;
105-
106114#else
107115int UnBlockSig ,
108116BlockSig ;
109-
110117#endif
111118
112119/*
113- * Info for garbage collection. Whenever a process dies, the Postmaster
114- * cleans up after it.Currently, NO information is required for cleanup,
115- * but I left this structure around in case that changed.
120+ * List of active backends (or child processes anyway; we don't actually
121+ * know whether a given child has become a backend or is still in the
122+ * authorization phase). This is used mainly to keep track of how many
123+ * children we have and send them appropriate signals when necessary.
116124 */
117125typedef struct bkend
118126{
119127pid_t pid ;/* process id of backend */
120128long cancel_key ;/* cancel key for cancels for this backend */
121129}Backend ;
122130
123- /* list of active backends. For garbage collection only now. */
124131static Dllist * BackendList ;
125132
126133/* The socket number we are listening for connections on */
@@ -155,12 +162,10 @@ static intServerSock_INET = INVALID_SOCK;/* stream socket server */
155162
156163#ifdef HAVE_UNIX_SOCKETS
157164static int ServerSock_UNIX = INVALID_SOCK ;/* stream socket server */
158-
159165#endif
160166
161167#ifdef USE_SSL
162168static SSL_CTX * SSL_context = NULL ;/* Global SSL context */
163-
164169#endif
165170
166171/*
@@ -178,12 +183,14 @@ static char ExtraOptions[MAXPGPATH];
178183static bool Reinit = true;
179184static int SendStop = false;
180185
186+ /* still more option variables */
181187bool NetServer = false;/* listen on TCP/IP */
182188bool EnableSSL = false;
183189bool SilentMode = false;/* silent mode (-S) */
184190
185191int CheckPointTimeout = 300 ;
186192
193+ /* Startup/shutdown state */
187194static pid_t StartupPID = 0 ,
188195ShutdownPID = 0 ,
189196CheckPointPID = 0 ;
@@ -230,7 +237,7 @@ static void ExitPostmaster(int status);
230237static void usage (const char * );
231238static int ServerLoop (void );
232239static int BackendStartup (Port * port );
233- static int ProcessStartupPacket (Port * port );
240+ static int ProcessStartupPacket (Port * port , bool SSLdone );
234241static void processCancelRequest (Port * port ,void * pkt );
235242static int initMasks (fd_set * rmask ,fd_set * wmask );
236243static char * canAcceptConnections (void );
@@ -579,6 +586,20 @@ PostmasterMain(int argc, char *argv[])
579586fprintf (stderr ,"-----------------------------------------\n" );
580587}
581588
589+ /*
590+ * Initialize SSL library, if specified.
591+ */
592+ #ifdef USE_SSL
593+ if (EnableSSL && !NetServer )
594+ {
595+ postmaster_error ("For SSL, TCP/IP connections must be enabled." );
596+ fprintf (stderr ,gettext ("Try '%s --help' for more information.\n" ),progname );
597+ ExitPostmaster (1 );
598+ }
599+ if (EnableSSL )
600+ InitSSL ();
601+ #endif
602+
582603/*
583604 * Fork away from controlling terminal, if -S specified.
584605 *
@@ -609,17 +630,6 @@ PostmasterMain(int argc, char *argv[])
609630/*
610631 * Establish input sockets.
611632 */
612- #ifdef USE_SSL
613- if (EnableSSL && !NetServer )
614- {
615- postmaster_error ("For SSL, TCP/IP connections must be enabled." );
616- fprintf (stderr ,gettext ("Try '%s --help' for more information.\n" ),progname );
617- ExitPostmaster (1 );
618- }
619- if (EnableSSL )
620- InitSSL ();
621- #endif
622-
623633if (NetServer )
624634{
625635status = StreamServerPort (AF_INET ,VirtualHost ,
@@ -653,8 +663,7 @@ PostmasterMain(int argc, char *argv[])
653663reset_shared (PostPortNumber );
654664
655665/*
656- * Initialize the list of active backends.This list is only used for
657- * garbage collecting the backend processes.
666+ * Initialize the list of active backends.
658667 */
659668BackendList = DLNewList ();
660669
@@ -811,7 +820,6 @@ ServerLoop(void)
811820
812821if (CheckPointTimeout + checkpointed > now )
813822{
814-
815823/*
816824 * Not time for checkpoint yet, so set a timeout for
817825 * select
@@ -883,7 +891,8 @@ ServerLoop(void)
883891}
884892
885893/*
886- * new connection pending on our well-known port's socket?
894+ * New connection pending on our well-known port's socket?
895+ * If so, fork a child process to deal with it.
887896 */
888897
889898#ifdef HAVE_UNIX_SOCKETS
@@ -892,9 +901,15 @@ ServerLoop(void)
892901{
893902port = ConnCreate (ServerSock_UNIX );
894903if (port )
904+ {
895905BackendStartup (port );
896- StreamClose (port -> sock );
897- ConnFree (port );
906+ /*
907+ * We no longer need the open socket or port structure
908+ * in this process
909+ */
910+ StreamClose (port -> sock );
911+ ConnFree (port );
912+ }
898913}
899914#endif
900915
@@ -903,9 +918,15 @@ ServerLoop(void)
903918{
904919port = ConnCreate (ServerSock_INET );
905920if (port )
921+ {
906922BackendStartup (port );
907- StreamClose (port -> sock );
908- ConnFree (port );
923+ /*
924+ * We no longer need the open socket or port structure
925+ * in this process
926+ */
927+ StreamClose (port -> sock );
928+ ConnFree (port );
929+ }
909930}
910931}
911932}
@@ -952,7 +973,7 @@ initMasks(fd_set *rmask, fd_set *wmask)
952973 * not return at all.
953974 */
954975static int
955- ProcessStartupPacket (Port * port )
976+ ProcessStartupPacket (Port * port , bool SSLdone )
956977{
957978StartupPacket * packet ;
958979char * rejectMsg ;
@@ -983,7 +1004,7 @@ ProcessStartupPacket(Port *port)
9831004return 127 ;/* XXX */
9841005}
9851006
986- if (port -> proto == NEGOTIATE_SSL_CODE )
1007+ if (port -> proto == NEGOTIATE_SSL_CODE && ! SSLdone )
9871008{
9881009char SSLok ;
9891010
@@ -1016,10 +1037,9 @@ ProcessStartupPacket(Port *port)
10161037}
10171038}
10181039#endif
1019- /* regular startup packet should follow... */
1020- /* FIXME: by continuing to send SSL negotiation packets, a
1021- client could run us out of stack space */
1022- return ProcessStartupPacket (port );
1040+ /* regular startup packet, cancel, etc packet should follow... */
1041+ /* but not another SSL negotiation request */
1042+ return ProcessStartupPacket (port , true);
10231043}
10241044
10251045/* Could add additional special packet types here */
@@ -1211,11 +1231,8 @@ ConnFree(Port *conn)
12111231 * ClosePostmasterPorts -- close all the postmaster's open sockets
12121232 *
12131233 * This is called during child process startup to release file descriptors
1214- * that are not needed by that child process.
1215- *
1216- * Note that closing the child's descriptor does not destroy the client
1217- * connection prematurely, since the parent (postmaster) process still
1218- * has the socket open.
1234+ * that are not needed by that child process. The postmaster still has
1235+ * them open, of course.
12191236 */
12201237static void
12211238ClosePostmasterPorts (void )
@@ -1685,9 +1702,7 @@ SignalChildren(int signal)
16851702/*
16861703 * BackendStartup -- start backend process
16871704 *
1688- * returns: STATUS_ERROR if the fork/exec failed, STATUS_OK
1689- *otherwise.
1690- *
1705+ * returns: STATUS_ERROR if the fork/exec failed, STATUS_OK otherwise.
16911706 */
16921707static int
16931708BackendStartup (Port * port )
@@ -1814,7 +1829,8 @@ split_opts(char **argv, int *argcp, char *s)
18141829}
18151830
18161831/*
1817- * DoBackend -- set up the backend's argument list and invoke backend main().
1832+ * DoBackend -- perform authentication, and if successful, set up the
1833+ *backend's argument list and invoke backend main().
18181834 *
18191835 * This used to perform an execv() but we no longer exec the backend;
18201836 * it's the same executable as the postmaster.
@@ -1849,6 +1865,9 @@ DoBackend(Port *port)
18491865 * Signal handlers setting is moved to tcop/postgres...
18501866 */
18511867
1868+ /* Close the postmaster's other sockets */
1869+ ClosePostmasterPorts ();
1870+
18521871SetProcessingMode (InitProcessing );
18531872
18541873/* Save port etc. for ps status */
@@ -1859,13 +1878,10 @@ DoBackend(Port *port)
18591878
18601879whereToSendOutput = Remote ;
18611880
1862- status = ProcessStartupPacket (port );
1881+ status = ProcessStartupPacket (port , false );
18631882if (status == 127 )
18641883return 0 ;/* cancel request processed */
18651884
1866- /* Close the postmaster's other sockets */
1867- ClosePostmasterPorts ();
1868-
18691885/*
18701886 * Don't want backend to be able to see the postmaster random number
18711887 * generator state. We have to clobber the static random_seed *and*