diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 1999-05-22 17:47:54 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 1999-05-22 17:47:54 +0000 |
commit | cf1478982cbe5637f0e78f88a28bf5d8ecfb389f (patch) | |
tree | 712d801ce2b81e4c87f7b6e7f7ea9cab6c7f3168 /src/backend/tcop/postgres.c | |
parent | e9edb3ef92363b53c576767cae60847f94fac0c6 (diff) | |
download | postgresql-cf1478982cbe5637f0e78f88a28bf5d8ecfb389f.tar.gz postgresql-cf1478982cbe5637f0e78f88a28bf5d8ecfb389f.zip |
Modify backend switch parsing to prevent 'insecure' switches
from being accepted when they are passed from client connection request.
Get rid of a couple that no longer do anything (like -P).
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r-- | src/backend/tcop/postgres.c | 228 |
1 files changed, 122 insertions, 106 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index dbf0c0b9850..ab29054aa77 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.114 1999/05/22 02:55:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.115 1999/05/22 17:47:49 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -776,7 +776,7 @@ pg_exec_query_dest(char *query_string, /* string to execute */ * Some backend has bought the farm, * so we need to stop what we're doing and exit. * - * die() preforms an orderly cleanup via ExitPostgres() + * die() performs an orderly cleanup via ExitPostgres() * -------------------------------- */ @@ -832,7 +832,6 @@ QueryCancelHandler(SIGNAL_ARGS) void CancelQuery(void) { - /* * QueryCancel flag will be reset in main loop, which we reach by * longjmp from elog(). @@ -857,36 +856,42 @@ usage(char *progname) #ifdef LOCK_MGR_DEBUG fprintf(stderr, "\t-K lev\t\tset locking debug level [0|1|2]\n"); #endif + fprintf(stderr, "\t-L \t\tturn off locking\n"); + fprintf(stderr, "\t-N \t\tdon't use newline as interactive query delimiter\n"); fprintf(stderr, "\t-O \t\tallow system table structure changes\n"); - fprintf(stderr, "\t-P port\t\tset port file descriptor\n"); fprintf(stderr, "\t-Q \t\tsuppress informational messages\n"); - fprintf(stderr, "\t-S buffers\tset amount of sort memory available\n"); + fprintf(stderr, "\t-S kbytes\tset amount of memory for sorts (in kbytes)\n"); fprintf(stderr, "\t-T options\tspecify pg_options\n"); fprintf(stderr, "\t-W sec\t\twait N seconds to allow attach from a debugger\n"); fprintf(stderr, "\t-d [1|2|3]\tset debug level\n"); fprintf(stderr, "\t-e \t\tturn on European date format\n"); fprintf(stderr, "\t-f [s|i|n|m|h]\tforbid use of some plan types\n"); - fprintf(stderr, "\t-o file\t\tsend stdout and stderr to given filename \n"); + fprintf(stderr, "\t-i \t\tdon't execute queries\n"); + fprintf(stderr, "\t-o file\t\tsend stdout and stderr to given filename\n"); + fprintf(stderr, "\t-p database\tbackend is started under a postmaster\n"); fprintf(stderr, "\t-s \t\tshow stats after each query\n"); + fprintf(stderr, "\t-t [pa|pl|ex]\tshow timings after each query\n"); fprintf(stderr, "\t-v version\tset protocol version being used by frontend\n"); } /* ---------------------------------------------------------------- - * PostgresMain - * postgres main loop + * PostgresMain + * postgres main loop * all backends, interactive or otherwise start here + * + * argc/argv are the command line arguments to be used. When being forked + * by the postmaster, these are not the original argv array of the process. + * real_argc/real_argv point to the original argv array, which is needed by + * PS_INIT_STATUS on some platforms. * ---------------------------------------------------------------- */ int PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) { - bool flagC = false, - flagQ = false, - flagE = false, - flagEu = false; int flag; char *DBName = NULL; + bool secure = true; int errs = 0; char firstchar; @@ -903,25 +908,18 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) extern char *optarg; extern short DebugLvl; - /* ---------------- - * parse command line arguments - * ---------------- - */ - /* - * Set default values. + * Set default values for command-line options. */ + IsUnderPostmaster = false; ShowStats = 0; ShowParserStats = ShowPlannerStats = ShowExecutorStats = 0; DeadlockCheckTimer = DEADLOCK_CHECK_TIMER; + Noversion = false; + EchoQuery = false; #ifdef LOCK_MGR_DEBUG LockDebug = 0; #endif - - /* - * get hostname is either the environment variable PGHOST or NULL NULL - * means Unix-socket only - */ DataDir = getenv("PGDATA"); /* @@ -943,8 +941,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) DateStyle = USE_GERMAN_DATES; EuroDates = TRUE; } - - if (strcasecmp(DBDate, "NONEURO") == 0) + else if (strcasecmp(DBDate, "NONEURO") == 0) EuroDates = FALSE; else if (strcasecmp(DBDate, "EURO") == 0) EuroDates = TRUE; @@ -953,14 +950,30 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) /* * Read default pg_options from file $DATADIR/pg_options. */ - if(DataDir) { + if (DataDir) read_pg_options(0); - } - optind = 1; /* reset after postmaster usage */ + /* ---------------- + * parse command line arguments + * + * There are now two styles of command line layout for the backend: + * + * For interactive use (not started from postmaster) the format is + * postgres [switches] [databasename] + * If the databasename is omitted it is taken to be the user name. + * + * When started from the postmaster, the format is + * postgres [secure switches] -p databasename [insecure switches] + * Switches appearing after -p came from the client (via "options" + * field of connection request). For security reasons we restrict + * what these switches can do. + * ---------------- + */ + + optind = 1; /* reset after postmaster's usage */ while ((flag = getopt(argc, argv, - "A:B:CD:d:EeFf:iK:LMm:NOo:P:pQS:sT:t:v:W:x:")) + "A:B:CD:d:EeFf:iK:LNOo:p:QS:sT:t:v:W:x:")) != EOF) switch (flag) { @@ -981,28 +994,32 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) * specify the size of buffer pool * ---------------- */ - NBuffers = atoi(optarg); + if (secure) + NBuffers = atoi(optarg); break; case 'C': /* ---------------- - * don't print version string (don't know why this is 'C' --mao) + * don't print version string * ---------------- */ - flagC = true; + Noversion = true; break; case 'D': /* PGDATA directory */ - if (!DataDir) { - DataDir = optarg; - /* must be done after DataDir is defined */ - read_pg_options(0); + if (secure) + { + if (!DataDir) + { + DataDir = optarg; + /* must be done after DataDir is defined */ + read_pg_options(0); + } + DataDir = optarg; } - DataDir = optarg; break; case 'd': /* debug level */ - flagQ = false; DebugLvl = (short) atoi(optarg); if (DebugLvl >= 1) Verbose = DebugLvl; @@ -1029,7 +1046,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) * E - echo the query the user entered * ---------------- */ - flagE = true; + EchoQuery = true; break; case 'e': @@ -1037,7 +1054,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) * Use european date formats. * -------------------------- */ - flagEu = true; + EuroDates = true; break; case 'F': @@ -1045,7 +1062,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) * turn off fsync * -------------------- */ - disableFsync = true; + if (secure) + disableFsync = true; break; case 'f': @@ -1092,15 +1110,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) * turn off locking * -------------------- */ - lockingOff = 1; - break; - - case 'M': - exit(PostmasterMain(argc, argv)); - break; - - case 'm': - /* Multiplexed backends are no longer supported. */ + if (secure) + lockingOff = 1; break; case 'N': @@ -1116,7 +1127,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) * allow system table structure modifications * -------------------- */ - allowSystemTableMods = true; + if (secure) /* XXX safe to allow from client??? */ + allowSystemTableMods = true; break; case 'o': @@ -1124,26 +1136,22 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) * o - send output (stdout and stderr) to the given file * ---------------- */ - StrNCpy(OutputFileName, optarg, MAXPGPATH); + if (secure) + StrNCpy(OutputFileName, optarg, MAXPGPATH); break; - case 'p': /* started by postmaster */ + case 'p': /* ---------------- * p - special flag passed if backend was forked * by a postmaster. * ---------------- */ - IsUnderPostmaster = true; - break; - - case 'P': - /* ---------------- - * P - Use the passed file descriptor number as the port - * on which to communicate with the user. This is ONLY - * useful for debugging when fired up by the postmaster. - * ---------------- - */ - Portfd = atoi(optarg); + if (secure) + { + IsUnderPostmaster = true; + DBName = optarg; + secure = false; /* subsequent switches are NOT secure */ + } break; case 'Q': @@ -1151,7 +1159,6 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) * Q - set Quiet mode (reduce debugging output) * ---------------- */ - flagQ = true; Verbose = 0; break; @@ -1179,7 +1186,11 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) break; case 'T': - parse_options(optarg); + /* ---------------- + * T - tracing options + * ---------------- + */ + parse_options(optarg, secure); break; case 't': @@ -1214,7 +1225,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) break; case 'v': - FrontendProtocol = (ProtocolVersion) atoi(optarg); + if (secure) + FrontendProtocol = (ProtocolVersion) atoi(optarg); break; case 'W': @@ -1268,32 +1280,38 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) } /* ---------------- - * get user name and pathname and check command line validity + * get user name (needed now in case it is the default database name) + * and check command line validity * ---------------- */ SetPgUserName(); userName = GetPgUserName(); -#ifdef CYR_RECODE - SetCharSet(); -#endif - - if (FindExec(pg_pathname, argv[0], "postgres") < 0) - elog(FATAL, "%s: could not locate executable, bailing out...", - argv[0]); - - if (errs || argc - optind > 1) + if (IsUnderPostmaster) { - usage(argv[0]); - proc_exit(1); + /* noninteractive case: nothing should be left after switches */ + if (errs || argc != optind || DBName == NULL) + { + usage(argv[0]); + proc_exit(1); + } } - else if (argc - optind == 1) - DBName = argv[optind]; - else if ((DBName = userName) == NULL) + else { - fprintf(stderr, "%s: USER undefined and no database specified\n", - argv[0]); - proc_exit(1); + /* interactive case: database name can be last arg on command line */ + if (errs || argc - optind > 1) + { + usage(argv[0]); + proc_exit(1); + } + else if (argc - optind == 1) + DBName = argv[optind]; + else if ((DBName = userName) == NULL) + { + fprintf(stderr, "%s: USER undefined and no database specified\n", + argv[0]); + proc_exit(1); + } } if (ShowStats && @@ -1308,14 +1326,22 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) fprintf(stderr, "%s does not know where to find the database system " "data. You must specify the directory that contains the " "database system either by specifying the -D invocation " - "option or by setting the PGDATA environment variable.\n\n", + "option or by setting the PGDATA environment variable.\n\n", argv[0]); proc_exit(1); } - Noversion = flagC; - EchoQuery = flagE; - EuroDates = flagEu; + /* + * Set up additional info. + */ + +#ifdef CYR_RECODE + SetCharSet(); +#endif + + if (FindExec(pg_pathname, argv[0], "postgres") < 0) + elog(FATAL, "%s: could not locate executable, bailing out...", + argv[0]); /* * Find remote host name or address. @@ -1398,30 +1424,23 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) } /* ---------------- - * initialize portal file descriptors + * initialize I/O * ---------------- */ if (IsUnderPostmaster) { - if (Portfd < 0) - { - fprintf(stderr, - "Postmaster flag set: no port number specified, use /dev/null\n"); -#ifndef __CYGWIN32__ - Portfd = open(NULL_DEV, O_RDWR, 0666); -#else - Portfd = open(NULL_DEV, O_RDWR | O_BINARY, 0666); -#endif - } - pq_init(); /* reset libpq */ + pq_init(); /* initialize libpq at backend startup */ whereToSendOutput = Remote; } else whereToSendOutput = Debug; + /* ---------------- + * general initialization + * ---------------- + */ SetProcessingMode(InitProcessing); - /* initialize */ if (Verbose) TPRINTF(TRACE_VERBOSE, "InitPostgres"); @@ -1485,7 +1504,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.114 $ $Date: 1999/05/22 02:55:58 $\n"); + puts("$Revision: 1.115 $ $Date: 1999/05/22 17:47:49 $\n"); } /* ---------------- @@ -1493,9 +1512,6 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) * * if an exception is encountered, processing resumes here * so we abort the current transaction and start a new one. - * This must be done after we initialize the slave backends - * so that the slaves signal the master to abort the transaction - * rather than calling AbortCurrentTransaction() themselves. * * Note: elog(ERROR) does a siglongjmp() to transfer control here. * ---------------- |