Index: backend/bootstrap/bootstrap.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/bootstrap/bootstrap.c,v retrieving revision 1.184 diff -c -c -r1.184 bootstrap.c *** backend/bootstrap/bootstrap.c 6 Jun 2004 00:41:26 -0000 1.184 --- backend/bootstrap/bootstrap.c 14 Jun 2004 19:20:38 -0000 *************** *** 328,334 **** { if (!potential_DataDir) { ! fprintf(stderr, gettext("%s does not know where to find the database system data.\n" "You must specify the directory that contains the database system\n" "either by specifying the -D invocation option or by setting the\n" --- 328,334 ---- { if (!potential_DataDir) { ! write_stderr( gettext("%s does not know where to find the database system data.\n" "You must specify the directory that contains the database system\n" "either by specifying the -D invocation option or by setting the\n" *************** *** 503,509 **** static void usage(void) { ! fprintf(stderr, gettext("Usage:\n" " postgres -boot [OPTION]... DBNAME\n" " -c NAME=VALUE set run-time parameter\n" --- 503,509 ---- static void usage(void) { ! write_stderr( gettext("Usage:\n" " postgres -boot [OPTION]... DBNAME\n" " -c NAME=VALUE set run-time parameter\n" Index: backend/main/main.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/main/main.c,v retrieving revision 1.86 diff -c -c -r1.86 main.c *** backend/main/main.c 3 Jun 2004 00:07:36 -0000 1.86 --- backend/main/main.c 14 Jun 2004 19:36:23 -0000 *************** *** 41,46 **** --- 41,47 ---- #include "tcop/tcopprot.h" #include "utils/help_config.h" #include "utils/ps_status.h" + #include "utils/elog.h" #ifdef WIN32 #include "libpq/pqsignal.h" #endif *************** *** 91,97 **** #if defined(__alpha) /* no __alpha__ ? */ if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL, (unsigned long) NULL) < 0) ! fprintf(stderr, gettext("%s: setsysinfo failed: %s\n"), argv[0], strerror(errno)); #endif #endif /* NOFIXADE || NOPRINTADE */ --- 92,98 ---- #if defined(__alpha) /* no __alpha__ ? */ if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL, (unsigned long) NULL) < 0) ! write_stderr(gettext("%s: setsysinfo failed: %s\n"), argv[0], strerror(errno)); #endif #endif /* NOFIXADE || NOPRINTADE */ *************** *** 109,115 **** err = WSAStartup(MAKEWORD(2, 2), &wsaData); if (err != 0) { ! fprintf(stderr, "%s: WSAStartup failed: %d\n", argv[0], err); exit(1); } --- 110,116 ---- err = WSAStartup(MAKEWORD(2, 2), &wsaData); if (err != 0) { ! write_stderr("%s: WSAStartup failed: %d\n", argv[0], err); exit(1); } *************** *** 212,218 **** */ if (geteuid() == 0) { ! fprintf(stderr, gettext("\"root\" execution of the PostgreSQL server is not permitted.\n" "The server must be started under an unprivileged user ID to prevent\n" "possible system security compromise. See the documentation for\n" --- 213,219 ---- */ if (geteuid() == 0) { ! write_stderr( gettext("\"root\" execution of the PostgreSQL server is not permitted.\n" "The server must be started under an unprivileged user ID to prevent\n" "possible system security compromise. See the documentation for\n" *************** *** 233,243 **** */ if (getuid() != geteuid()) { ! fprintf(stderr, gettext("%s: real and effective user IDs must match\n"), argv[0]); exit(1); } #endif /* !WIN32 */ } --- 234,254 ---- */ if (getuid() != geteuid()) { ! write_stderr( gettext("%s: real and effective user IDs must match\n"), argv[0]); exit(1); } + #else /* !WIN32 */ + if (pgwin32_is_admin()) { + write_stderr( + gettext("execution of PostgreSQL by a user with administrative permissions is not permitted.\n" + "The server must be started under an unprivileged user ID to prevent\n" + "possible system security compromise. See the documentation for\n" + "more information on how to properly start the server.\n" + )); + exit(1); + } #endif /* !WIN32 */ } *************** *** 292,298 **** pw = getpwuid(geteuid()); if (pw == NULL) { ! fprintf(stderr, gettext("%s: invalid effective UID: %d\n"), argv[0], (int) geteuid()); exit(1); } --- 303,309 ---- pw = getpwuid(geteuid()); if (pw == NULL) { ! write_stderr(gettext("%s: invalid effective UID: %d\n"), argv[0], (int) geteuid()); exit(1); } *************** *** 305,311 **** pw_name_persist = malloc(namesize); if (!GetUserName(pw_name_persist, &namesize)) { ! fprintf(stderr, gettext("%s: could not determine user name (GetUserName failed)\n"), argv[0]); exit(1); } --- 316,322 ---- pw_name_persist = malloc(namesize); if (!GetUserName(pw_name_persist, &namesize)) { ! write_stderr(gettext("%s: could not determine user name (GetUserName failed)\n"), argv[0]); exit(1); } Index: backend/port/win32/Makefile =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/port/win32/Makefile,v retrieving revision 1.4 diff -c -c -r1.4 Makefile *** backend/port/win32/Makefile 12 Apr 2004 16:19:18 -0000 1.4 --- backend/port/win32/Makefile 14 Jun 2004 18:34:51 -0000 *************** *** 12,18 **** top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global ! OBJS = sema.o shmem.o timer.o socket.o signal.o all: SUBSYS.o --- 12,18 ---- top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global ! OBJS = sema.o shmem.o timer.o socket.o signal.o security.o all: SUBSYS.o Index: backend/port/win32/signal.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/port/win32/signal.c,v retrieving revision 1.3 diff -c -c -r1.3 signal.c *** backend/port/win32/signal.c 27 May 2004 14:39:29 -0000 1.3 --- backend/port/win32/signal.c 14 Jun 2004 19:20:21 -0000 *************** *** 221,227 **** PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL); if (pipe == INVALID_HANDLE_VALUE) { ! fprintf(stderr, gettext("Failed to create signal listener pipe: %i. Retrying.\n"), (int) GetLastError()); SleepEx(500, FALSE); continue; } --- 221,227 ---- PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL); if (pipe == INVALID_HANDLE_VALUE) { ! write_stderr(gettext("Failed to create signal listener pipe: %i. Retrying.\n"), (int) GetLastError()); SleepEx(500, FALSE); continue; } *************** *** 233,239 **** (LPTHREAD_START_ROUTINE) pg_signal_dispatch_thread, (LPVOID) pipe, 0, NULL); if (hThread == INVALID_HANDLE_VALUE) ! fprintf(stderr, gettext("Failed to create signal dispatch thread: %i\n"), (int) GetLastError()); else CloseHandle(hThread); } --- 233,239 ---- (LPTHREAD_START_ROUTINE) pg_signal_dispatch_thread, (LPVOID) pipe, 0, NULL); if (hThread == INVALID_HANDLE_VALUE) ! write_stderr(gettext("Failed to create signal dispatch thread: %i\n"), (int) GetLastError()); else CloseHandle(hThread); } Index: backend/postmaster/postmaster.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v retrieving revision 1.404 diff -c -c -r1.404 postmaster.c *** backend/postmaster/postmaster.c 14 Jun 2004 18:08:19 -0000 1.404 --- backend/postmaster/postmaster.c 14 Jun 2004 19:32:39 -0000 *************** *** 380,386 **** #ifdef USE_ASSERT_CHECKING SetConfigOption("debug_assertions", optarg, PGC_POSTMASTER, PGC_S_ARGV); #else ! postmaster_error("assert checking is not compiled in"); #endif break; case 'a': --- 380,386 ---- #ifdef USE_ASSERT_CHECKING SetConfigOption("debug_assertions", optarg, PGC_POSTMASTER, PGC_S_ARGV); #else ! write_stderr("%s: assert checking is not compiled in\n", progname); #endif break; case 'a': *************** *** 503,509 **** } default: ! fprintf(stderr, gettext("Try \"%s --help\" for more information.\n"), progname); ExitPostmaster(1); --- 503,509 ---- } default: ! write_stderr( gettext("Try \"%s --help\" for more information.\n"), progname); ExitPostmaster(1); *************** *** 515,522 **** */ if (optind < argc) { ! postmaster_error("invalid argument: \"%s\"", argv[optind]); ! fprintf(stderr, gettext("Try \"%s --help\" for more information.\n"), progname); ExitPostmaster(1); --- 515,522 ---- */ if (optind < argc) { ! write_stderr("%s: invalid argument: \"%s\"\n", progname, argv[optind]); ! write_stderr( gettext("Try \"%s --help\" for more information.\n"), progname); ExitPostmaster(1); *************** *** 547,559 **** * for lack of buffers. The specific choices here are somewhat * arbitrary. */ ! postmaster_error("the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16"); ExitPostmaster(1); } if (ReservedBackends >= MaxBackends) { ! postmaster_error("superuser_reserved_connections must be less than max_connections"); ExitPostmaster(1); } --- 547,559 ---- * for lack of buffers. The specific choices here are somewhat * arbitrary. */ ! write_stderr("%s: the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16\n", progname); ExitPostmaster(1); } if (ReservedBackends >= MaxBackends) { ! write_stderr("%s: superuser_reserved_connections must be less than max_connections\n", progname); ExitPostmaster(1); } *************** *** 562,568 **** */ if (!CheckDateTokenTables()) { ! postmaster_error("invalid datetoken tables, please fix"); ExitPostmaster(1); } --- 562,568 ---- */ if (!CheckDateTokenTables()) { ! write_stderr("%s: invalid datetoken tables, please fix\n", progname); ExitPostmaster(1); } *************** *** 858,864 **** if (checkdir == NULL) { ! fprintf(stderr, gettext("%s does not know where to find the database system data.\n" "You must specify the directory that contains the database system\n" "either by specifying the -D invocation option or by setting the\n" --- 858,864 ---- if (checkdir == NULL) { ! write_stderr( gettext("%s does not know where to find the database system data.\n" "You must specify the directory that contains the database system\n" "either by specifying the -D invocation option or by setting the\n" *************** *** 905,911 **** fp = AllocateFile(path, PG_BINARY_R); if (fp == NULL) { ! fprintf(stderr, gettext("%s: could not find the database system\n" "Expected to find it in the directory \"%s\",\n" "but could not open file \"%s\": %s\n"), --- 905,911 ---- fp = AllocateFile(path, PG_BINARY_R); if (fp == NULL) { ! write_stderr( gettext("%s: could not find the database system\n" "Expected to find it in the directory \"%s\",\n" "but could not open file \"%s\": %s\n"), *************** *** 952,959 **** pid = fork(); if (pid == (pid_t) -1) { ! postmaster_error("could not fork background process: %s", ! strerror(errno)); ExitPostmaster(1); } else if (pid) --- 952,959 ---- pid = fork(); if (pid == (pid_t) -1) { ! write_stderr("%s: could not fork background process: %s\n", ! progname, strerror(errno)); ExitPostmaster(1); } else if (pid) *************** *** 974,981 **** #ifdef HAVE_SETSID if (setsid() < 0) { ! postmaster_error("could not dissociate from controlling TTY: %s", ! strerror(errno)); ExitPostmaster(1); } #endif --- 974,981 ---- #ifdef HAVE_SETSID if (setsid() < 0) { ! write_stderr("%s: could not dissociate from controlling TTY: %s\n", ! progname, strerror(errno)); ExitPostmaster(1); } #endif *************** *** 3152,3176 **** return true; } - /* - * This should be used only for reporting "interactive" errors (essentially, - * bogus arguments on the command line). Once the postmaster is launched, - * use ereport. In particular, don't use this for anything that occurs - * after pmdaemonize. - */ - static void - postmaster_error(const char *fmt,...) - { - va_list ap; - - fprintf(stderr, "%s: ", progname); - va_start(ap, fmt); - vfprintf(stderr, gettext(fmt), ap); - va_end(ap); - fprintf(stderr, "\n"); - } - - #ifdef EXEC_BACKEND /* --- 3152,3157 ---- *************** *** 3609,3615 **** if (r == WAIT_OBJECT_0) pg_queue_signal(SIGCHLD); else ! fprintf(stderr, "ERROR: failed to wait on child process handle: %d\n", (int) GetLastError()); CloseHandle(procHandle); return 0; --- 3590,3596 ---- if (r == WAIT_OBJECT_0) pg_queue_signal(SIGCHLD); else ! write_stderr("ERROR: failed to wait on child process handle: %d\n", (int) GetLastError()); CloseHandle(procHandle); return 0; Index: backend/tcop/postgres.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/tcop/postgres.c,v retrieving revision 1.420 diff -c -c -r1.420 postgres.c *** backend/tcop/postgres.c 11 Jun 2004 01:09:00 -0000 1.420 --- backend/tcop/postgres.c 14 Jun 2004 19:20:04 -0000 *************** *** 2578,2584 **** { if (!potential_DataDir) { ! fprintf(stderr, gettext("%s does not know where to find the database system data.\n" "You must specify the directory that contains the database system\n" "either by specifying the -D invocation option or by setting the\n" --- 2578,2584 ---- { if (!potential_DataDir) { ! write_stderr( gettext("%s does not know where to find the database system data.\n" "You must specify the directory that contains the database system\n" "either by specifying the -D invocation option or by setting the\n" Index: backend/utils/error/assert.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/error/assert.c,v retrieving revision 1.26 diff -c -c -r1.26 assert.c *** backend/utils/error/assert.c 19 Apr 2004 17:42:58 -0000 1.26 --- backend/utils/error/assert.c 14 Jun 2004 19:19:56 -0000 *************** *** 31,40 **** if (!PointerIsValid(conditionName) || !PointerIsValid(fileName) || !PointerIsValid(errorType)) ! fprintf(stderr, "TRAP: ExceptionalCondition: bad arguments\n"); else { ! fprintf(stderr, "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n", errorType, conditionName, fileName, lineNumber); } --- 31,40 ---- if (!PointerIsValid(conditionName) || !PointerIsValid(fileName) || !PointerIsValid(errorType)) ! write_stderr("TRAP: ExceptionalCondition: bad arguments\n"); else { ! write_stderr("TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n", errorType, conditionName, fileName, lineNumber); } Index: backend/utils/error/elog.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/error/elog.c,v retrieving revision 1.140 diff -c -c -r1.140 elog.c *** backend/utils/error/elog.c 3 Jun 2004 02:08:04 -0000 1.140 --- backend/utils/error/elog.c 14 Jun 2004 19:22:10 -0000 *************** *** 1755,1757 **** --- 1755,1790 ---- appendStringInfoCharMacro(buf, '\t'); } } + + + + /* + * Write errors to stderr (or by equal means when stderr is + * not available). Used before ereport/elog can be used + * safely (memory context, GUC load etc) + */ + extern void + write_stderr(const char *fmt,...) + { + va_list ap; + + va_start(ap, fmt); + #ifndef WIN32 + /* On Unix, we just fprintf to stderr */ + vfprintf(stderr, fmt, ap); + #else + /* On Win32, we print to stderr if running on a console, or write to + * eventlog if running as a service */ + if (/* FIXME: Running as service? */ 0) + { + char errbuf[2048]; /* Arbitrary size? */ + + vsnprintf(errbuf, sizeof(errbuf), fmt, ap); + + write_eventlog(EVENTLOG_ERROR_TYPE, errbuf); + } + else /* Not running as service, write to stderr */ + vfprintf(stderr, fmt, ap); + #endif + va_end(ap); + } Index: backend/utils/misc/help_config.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/misc/help_config.c,v retrieving revision 1.11 diff -c -c -r1.11 help_config.c *** backend/utils/misc/help_config.c 2 Jun 2004 18:09:32 -0000 1.11 --- backend/utils/misc/help_config.c 14 Jun 2004 19:22:22 -0000 *************** *** 122,128 **** break; default: ! fprintf(stderr, "internal error: unrecognized run-time parameter type\n"); break; } --- 122,128 ---- break; default: ! write_stderr("internal error: unrecognized run-time parameter type\n"); break; } Index: include/port/win32.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/port/win32.h,v retrieving revision 1.25 diff -c -c -r1.25 win32.h *** include/port/win32.h 27 May 2004 14:39:33 -0000 1.25 --- include/port/win32.h 14 Jun 2004 19:00:15 -0000 *************** *** 140,145 **** --- 140,147 ---- const char *pgwin32_socket_strerror(int err); #endif + /* in backend/port/win32/security.c */ + extern int pgwin32_is_admin(void); /* Some extra signals */ #define SIGHUP 1 Index: include/utils/elog.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/utils/elog.h,v retrieving revision 1.68 diff -c -c -r1.68 elog.h *** include/utils/elog.h 5 Apr 2004 03:02:10 -0000 1.68 --- include/utils/elog.h 14 Jun 2004 19:21:41 -0000 *************** *** 164,169 **** --- 164,180 ---- extern DLLIMPORT ErrorContextCallback *error_context_stack; + /* + * Write errors to stderr (or by equal means when stderr is + * not available). Used before ereport/elog can be used + * safely (memory context, GUC load etc) + */ + extern void + write_stderr(const char *fmt,...) + /* This extension allows gcc to check the format string for consistency with + the supplied arguments. */ + __attribute__((format(printf, 1, 2))); + /* GUC-configurable parameters */