1 /*-------------------------------------------------------------------------
2  *
3  * main.c
4  *	  Stub main() routine for the postgres executable.
5  *
6  * This does some essential startup tasks for any incarnation of postgres
7  * (postmaster, standalone backend, standalone bootstrap process, or a
8  * separately exec'd child of a postmaster) and then dispatches to the
9  * proper FooMain() routine for the incarnation.
10  *
11  *
12  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
13  * Portions Copyright (c) 1994, Regents of the University of California
14  *
15  *
16  * IDENTIFICATION
17  *	  src/backend/main/main.c
18  *
19  *-------------------------------------------------------------------------
20  */
21 #include "postgres.h"
22 
23 #include <unistd.h>
24 
25 #if defined(__NetBSD__)
26 #include <sys/param.h>
27 #endif
28 
29 #if defined(_M_AMD64) && _MSC_VER == 1800
30 #include <math.h>
31 #include <versionhelpers.h>
32 #endif
33 
34 #include "bootstrap/bootstrap.h"
35 #include "common/username.h"
36 #include "port/atomics.h"
37 #include "postmaster/postmaster.h"
38 #include "storage/spin.h"
39 #include "tcop/tcopprot.h"
40 #include "utils/help_config.h"
41 #include "utils/memutils.h"
42 #include "utils/pg_locale.h"
43 #include "utils/ps_status.h"
44 
45 
46 const char *progname;
47 
48 
49 static void startup_hacks(const char *progname);
50 static void init_locale(const char *categoryname, int category, const char *locale);
51 static void help(const char *progname);
52 static void check_root(const char *progname);
53 
54 
55 /*
56  * Any Postgres server process begins execution here.
57  */
58 int
main(int argc,char * argv[])59 main(int argc, char *argv[])
60 {
61 	bool		do_check_root = true;
62 
63 	/*
64 	 * If supported on the current platform, set up a handler to be called if
65 	 * the backend/postmaster crashes with a fatal signal or exception.
66 	 */
67 #if defined(WIN32) && defined(HAVE_MINIDUMP_TYPE)
68 	pgwin32_install_crashdump_handler();
69 #endif
70 
71 	progname = get_progname(argv[0]);
72 
73 	/*
74 	 * Platform-specific startup hacks
75 	 */
76 	startup_hacks(progname);
77 
78 	/*
79 	 * Remember the physical location of the initially given argv[] array for
80 	 * possible use by ps display.  On some platforms, the argv[] storage must
81 	 * be overwritten in order to set the process title for ps. In such cases
82 	 * save_ps_display_args makes and returns a new copy of the argv[] array.
83 	 *
84 	 * save_ps_display_args may also move the environment strings to make
85 	 * extra room. Therefore this should be done as early as possible during
86 	 * startup, to avoid entanglements with code that might save a getenv()
87 	 * result pointer.
88 	 */
89 	argv = save_ps_display_args(argc, argv);
90 
91 	/*
92 	 * Fire up essential subsystems: error and memory management
93 	 *
94 	 * Code after this point is allowed to use elog/ereport, though
95 	 * localization of messages may not work right away, and messages won't go
96 	 * anywhere but stderr until GUC settings get loaded.
97 	 */
98 	MemoryContextInit();
99 
100 	/*
101 	 * Set up locale information
102 	 */
103 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
104 
105 	/*
106 	 * In the postmaster, absorb the environment values for LC_COLLATE and
107 	 * LC_CTYPE.  Individual backends will change these later to settings
108 	 * taken from pg_database, but the postmaster cannot do that.  If we leave
109 	 * these set to "C" then message localization might not work well in the
110 	 * postmaster.
111 	 */
112 	init_locale("LC_COLLATE", LC_COLLATE, "");
113 	init_locale("LC_CTYPE", LC_CTYPE, "");
114 
115 	/*
116 	 * LC_MESSAGES will get set later during GUC option processing, but we set
117 	 * it here to allow startup error messages to be localized.
118 	 */
119 #ifdef LC_MESSAGES
120 	init_locale("LC_MESSAGES", LC_MESSAGES, "");
121 #endif
122 
123 	/*
124 	 * We keep these set to "C" always, except transiently in pg_locale.c; see
125 	 * that file for explanations.
126 	 */
127 	init_locale("LC_MONETARY", LC_MONETARY, "C");
128 	init_locale("LC_NUMERIC", LC_NUMERIC, "C");
129 	init_locale("LC_TIME", LC_TIME, "C");
130 
131 	/*
132 	 * Now that we have absorbed as much as we wish to from the locale
133 	 * environment, remove any LC_ALL setting, so that the environment
134 	 * variables installed by pg_perm_setlocale have force.
135 	 */
136 	unsetenv("LC_ALL");
137 
138 	check_strxfrm_bug();
139 
140 	/*
141 	 * Catch standard options before doing much else, in particular before we
142 	 * insist on not being root.
143 	 */
144 	if (argc > 1)
145 	{
146 		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
147 		{
148 			help(progname);
149 			exit(0);
150 		}
151 		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
152 		{
153 			fputs(PG_BACKEND_VERSIONSTR, stdout);
154 			exit(0);
155 		}
156 
157 		/*
158 		 * In addition to the above, we allow "--describe-config" and "-C var"
159 		 * to be called by root.  This is reasonably safe since these are
160 		 * read-only activities.  The -C case is important because pg_ctl may
161 		 * try to invoke it while still holding administrator privileges on
162 		 * Windows.  Note that while -C can normally be in any argv position,
163 		 * if you want to bypass the root check you must put it first.  This
164 		 * reduces the risk that we might misinterpret some other mode's -C
165 		 * switch as being the postmaster/postgres one.
166 		 */
167 		if (strcmp(argv[1], "--describe-config") == 0)
168 			do_check_root = false;
169 		else if (argc > 2 && strcmp(argv[1], "-C") == 0)
170 			do_check_root = false;
171 	}
172 
173 	/*
174 	 * Make sure we are not running as root, unless it's safe for the selected
175 	 * option.
176 	 */
177 	if (do_check_root)
178 		check_root(progname);
179 
180 	/*
181 	 * Dispatch to one of various subprograms depending on first argument.
182 	 */
183 
184 #ifdef EXEC_BACKEND
185 	if (argc > 1 && strncmp(argv[1], "--fork", 6) == 0)
186 		SubPostmasterMain(argc, argv);	/* does not return */
187 #endif
188 
189 #ifdef WIN32
190 
191 	/*
192 	 * Start our win32 signal implementation
193 	 *
194 	 * SubPostmasterMain() will do this for itself, but the remaining modes
195 	 * need it here
196 	 */
197 	pgwin32_signal_initialize();
198 #endif
199 
200 	if (argc > 1 && strcmp(argv[1], "--boot") == 0)
201 		AuxiliaryProcessMain(argc, argv);	/* does not return */
202 	else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
203 		GucInfoMain();			/* does not return */
204 	else if (argc > 1 && strcmp(argv[1], "--single") == 0)
205 		PostgresMain(argc, argv,
206 					 NULL,		/* no dbname */
207 					 strdup(get_user_name_or_exit(progname)));	/* does not return */
208 	else
209 		PostmasterMain(argc, argv); /* does not return */
210 	abort();					/* should not get here */
211 }
212 
213 
214 
215 /*
216  * Place platform-specific startup hacks here.  This is the right
217  * place to put code that must be executed early in the launch of any new
218  * server process.  Note that this code will NOT be executed when a backend
219  * or sub-bootstrap process is forked, unless we are in a fork/exec
220  * environment (ie EXEC_BACKEND is defined).
221  *
222  * XXX The need for code here is proof that the platform in question
223  * is too brain-dead to provide a standard C execution environment
224  * without help.  Avoid adding more here, if you can.
225  */
226 static void
startup_hacks(const char * progname)227 startup_hacks(const char *progname)
228 {
229 	/*
230 	 * Windows-specific execution environment hacking.
231 	 */
232 #ifdef WIN32
233 	{
234 		WSADATA		wsaData;
235 		int			err;
236 
237 		/* Make output streams unbuffered by default */
238 		setvbuf(stdout, NULL, _IONBF, 0);
239 		setvbuf(stderr, NULL, _IONBF, 0);
240 
241 		/* Prepare Winsock */
242 		err = WSAStartup(MAKEWORD(2, 2), &wsaData);
243 		if (err != 0)
244 		{
245 			write_stderr("%s: WSAStartup failed: %d\n",
246 						 progname, err);
247 			exit(1);
248 		}
249 
250 		/* In case of general protection fault, don't show GUI popup box */
251 		SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
252 
253 #if defined(_M_AMD64) && _MSC_VER == 1800
254 
255 		/*----------
256 		 * Avoid crashing in certain floating-point operations if we were
257 		 * compiled for x64 with MS Visual Studio 2013 and are running on
258 		 * Windows prior to 7/2008R2 SP1 on an AVX2-capable CPU.
259 		 *
260 		 * Ref: https://connect.microsoft.com/VisualStudio/feedback/details/811093/visual-studio-2013-rtm-c-x64-code-generation-bug-for-avx2-instructions
261 		 *----------
262 		 */
263 		if (!IsWindows7SP1OrGreater())
264 		{
265 			_set_FMA3_enable(0);
266 		}
267 #endif							/* defined(_M_AMD64) && _MSC_VER == 1800 */
268 
269 	}
270 #endif							/* WIN32 */
271 
272 	/*
273 	 * Initialize dummy_spinlock, in case we are on a platform where we have
274 	 * to use the fallback implementation of pg_memory_barrier().
275 	 */
276 	SpinLockInit(&dummy_spinlock);
277 }
278 
279 
280 /*
281  * Make the initial permanent setting for a locale category.  If that fails,
282  * perhaps due to LC_foo=invalid in the environment, use locale C.  If even
283  * that fails, perhaps due to out-of-memory, the entire startup fails with it.
284  * When this returns, we are guaranteed to have a setting for the given
285  * category's environment variable.
286  */
287 static void
init_locale(const char * categoryname,int category,const char * locale)288 init_locale(const char *categoryname, int category, const char *locale)
289 {
290 	if (pg_perm_setlocale(category, locale) == NULL &&
291 		pg_perm_setlocale(category, "C") == NULL)
292 		elog(FATAL, "could not adopt \"%s\" locale nor C locale for %s",
293 			 locale, categoryname);
294 }
295 
296 
297 
298 /*
299  * Help display should match the options accepted by PostmasterMain()
300  * and PostgresMain().
301  *
302  * XXX On Windows, non-ASCII localizations of these messages only display
303  * correctly if the console output code page covers the necessary characters.
304  * Messages emitted in write_console() do not exhibit this problem.
305  */
306 static void
help(const char * progname)307 help(const char *progname)
308 {
309 	printf(_("%s is the PostgreSQL server.\n\n"), progname);
310 	printf(_("Usage:\n  %s [OPTION]...\n\n"), progname);
311 	printf(_("Options:\n"));
312 	printf(_("  -B NBUFFERS        number of shared buffers\n"));
313 	printf(_("  -c NAME=VALUE      set run-time parameter\n"));
314 	printf(_("  -C NAME            print value of run-time parameter, then exit\n"));
315 	printf(_("  -d 1-5             debugging level\n"));
316 	printf(_("  -D DATADIR         database directory\n"));
317 	printf(_("  -e                 use European date input format (DMY)\n"));
318 	printf(_("  -F                 turn fsync off\n"));
319 	printf(_("  -h HOSTNAME        host name or IP address to listen on\n"));
320 	printf(_("  -i                 enable TCP/IP connections\n"));
321 	printf(_("  -k DIRECTORY       Unix-domain socket location\n"));
322 #ifdef USE_SSL
323 	printf(_("  -l                 enable SSL connections\n"));
324 #endif
325 	printf(_("  -N MAX-CONNECT     maximum number of allowed connections\n"));
326 	printf(_("  -p PORT            port number to listen on\n"));
327 	printf(_("  -s                 show statistics after each query\n"));
328 	printf(_("  -S WORK-MEM        set amount of memory for sorts (in kB)\n"));
329 	printf(_("  -V, --version      output version information, then exit\n"));
330 	printf(_("  --NAME=VALUE       set run-time parameter\n"));
331 	printf(_("  --describe-config  describe configuration parameters, then exit\n"));
332 	printf(_("  -?, --help         show this help, then exit\n"));
333 
334 	printf(_("\nDeveloper options:\n"));
335 	printf(_("  -f s|i|n|m|h       forbid use of some plan types\n"));
336 	printf(_("  -n                 do not reinitialize shared memory after abnormal exit\n"));
337 	printf(_("  -O                 allow system table structure changes\n"));
338 	printf(_("  -P                 disable system indexes\n"));
339 	printf(_("  -t pa|pl|ex        show timings after each query\n"));
340 	printf(_("  -T                 send SIGSTOP to all backend processes if one dies\n"));
341 	printf(_("  -W NUM             wait NUM seconds to allow attach from a debugger\n"));
342 
343 	printf(_("\nOptions for single-user mode:\n"));
344 	printf(_("  --single           selects single-user mode (must be first argument)\n"));
345 	printf(_("  DBNAME             database name (defaults to user name)\n"));
346 	printf(_("  -d 0-5             override debugging level\n"));
347 	printf(_("  -E                 echo statement before execution\n"));
348 	printf(_("  -j                 do not use newline as interactive query delimiter\n"));
349 	printf(_("  -r FILENAME        send stdout and stderr to given file\n"));
350 
351 	printf(_("\nOptions for bootstrapping mode:\n"));
352 	printf(_("  --boot             selects bootstrapping mode (must be first argument)\n"));
353 	printf(_("  DBNAME             database name (mandatory argument in bootstrapping mode)\n"));
354 	printf(_("  -r FILENAME        send stdout and stderr to given file\n"));
355 	printf(_("  -x NUM             internal use\n"));
356 
357 	printf(_("\nPlease read the documentation for the complete list of run-time\n"
358 			 "configuration settings and how to set them on the command line or in\n"
359 			 "the configuration file.\n\n"
360 			 "Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
361 	printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
362 }
363 
364 
365 
366 static void
check_root(const char * progname)367 check_root(const char *progname)
368 {
369 #ifndef WIN32
370 	if (geteuid() == 0)
371 	{
372 		write_stderr("\"root\" execution of the PostgreSQL server is not permitted.\n"
373 					 "The server must be started under an unprivileged user ID to prevent\n"
374 					 "possible system security compromise.  See the documentation for\n"
375 					 "more information on how to properly start the server.\n");
376 		exit(1);
377 	}
378 
379 	/*
380 	 * Also make sure that real and effective uids are the same. Executing as
381 	 * a setuid program from a root shell is a security hole, since on many
382 	 * platforms a nefarious subroutine could setuid back to root if real uid
383 	 * is root.  (Since nobody actually uses postgres as a setuid program,
384 	 * trying to actively fix this situation seems more trouble than it's
385 	 * worth; we'll just expend the effort to check for it.)
386 	 */
387 	if (getuid() != geteuid())
388 	{
389 		write_stderr("%s: real and effective user IDs must match\n",
390 					 progname);
391 		exit(1);
392 	}
393 #else							/* WIN32 */
394 	if (pgwin32_is_admin())
395 	{
396 		write_stderr("Execution of PostgreSQL by a user with administrative permissions is not\n"
397 					 "permitted.\n"
398 					 "The server must be started under an unprivileged user ID to prevent\n"
399 					 "possible system security compromises.  See the documentation for\n"
400 					 "more information on how to properly start the server.\n");
401 		exit(1);
402 	}
403 #endif							/* WIN32 */
404 }
405