Index: src/backend/tcop/postgres.c =================================================================== RCS file: /cvsroot/pgsql-server/src/backend/tcop/postgres.c,v retrieving revision 1.346 diff -c -c -r1.346 postgres.c *** src/backend/tcop/postgres.c 27 May 2003 17:49:46 -0000 1.346 --- src/backend/tcop/postgres.c 11 Jun 2003 04:29:55 -0000 *************** *** 1921,1927 **** bool secure; int errs = 0; int debug_flag = 0; ! GucContext ctx; GucSource gucsource; char *tmp; int firstchar; --- 1921,1927 ---- bool secure; int errs = 0; int debug_flag = 0; ! GucContext ctx, debug_context; GucSource gucsource; char *tmp; int firstchar; *************** *** 1996,2002 **** /* all options are allowed until '-p' */ secure = true; ! ctx = PGC_POSTMASTER; gucsource = PGC_S_ARGV; /* initial switches came from command line */ while ((flag = getopt(argc, argv, "A:B:c:CD:d:Eef:FiNOPo:p:S:st:v:W:x:-:")) != -1) --- 1996,2002 ---- /* all options are allowed until '-p' */ secure = true; ! ctx = debug_context = PGC_POSTMASTER; gucsource = PGC_S_ARGV; /* initial switches came from command line */ while ((flag = getopt(argc, argv, "A:B:c:CD:d:Eef:FiNOPo:p:S:st:v:W:x:-:")) != -1) *************** *** 2033,2057 **** case 'd': /* debug level */ { ! debug_flag = atoi(optarg); ! /* Set server debugging level. */ ! if (atoi(optarg) != 0) { ! char *debugstr = palloc(strlen("debug") + strlen(optarg) + 1); ! ! sprintf(debugstr, "debug%s", optarg); ! SetConfigOption("log_min_messages", debugstr, ctx, gucsource); ! pfree(debugstr); ! } - else - /* - * -d0 allows user to prevent postmaster debug - * from propagating to backend. It would be nice - * to set it to the postgresql.conf value here. - */ - SetConfigOption("log_min_messages", "notice", - ctx, gucsource); } break; --- 2033,2066 ---- case 'd': /* debug level */ { ! /* ! * Client option can't decrease debug level. ! * We have to do the test here because we group priv and client ! * set GUC calls below, after we know the final debug value. ! */ ! if (ctx != PGC_BACKEND || atoi(optarg) > debug_flag) { ! debug_flag = atoi(optarg); ! debug_context = ctx; /* save context for use below */ ! /* Set server debugging level. */ ! if (debug_flag != 0) ! { ! char *debugstr = palloc(strlen("debug") + strlen(optarg) + 1); ! ! sprintf(debugstr, "debug%s", optarg); ! SetConfigOption("log_min_messages", debugstr, ctx, gucsource); ! pfree(debugstr); ! ! } ! else ! /* ! * -d0 allows user to prevent postmaster debug ! * from propagating to backend. It would be nice ! * to set it to the postgresql.conf value here. ! */ ! SetConfigOption("log_min_messages", "notice", ! ctx, gucsource); } } break; *************** *** 2301,2320 **** /* ! * -d is not the same as setting ! * log_min_messages because it enables other ! * output options. */ if (debug_flag >= 1) ! SetConfigOption("log_connections", "true", ctx, gucsource); if (debug_flag >= 2) ! SetConfigOption("log_statement", "true", ctx, gucsource); if (debug_flag >= 3) ! SetConfigOption("debug_print_parse", "true", ctx, gucsource); if (debug_flag >= 4) ! SetConfigOption("debug_print_plan", "true", ctx, gucsource); if (debug_flag >= 5) ! SetConfigOption("debug_print_rewritten", "true", ctx, gucsource); /* * Process any additional GUC variable settings passed in startup packet. --- 2310,2328 ---- /* ! * -d is not the same as setting log_min_messages because it enables ! * other output options. */ if (debug_flag >= 1) ! SetConfigOption("log_connections", "true", debug_context, gucsource); if (debug_flag >= 2) ! SetConfigOption("log_statement", "true", debug_context, gucsource); if (debug_flag >= 3) ! SetConfigOption("debug_print_parse", "true", debug_context, gucsource); if (debug_flag >= 4) ! SetConfigOption("debug_print_plan", "true", debug_context, gucsource); if (debug_flag >= 5) ! SetConfigOption("debug_print_rewritten", "true", debug_context, gucsource); /* * Process any additional GUC variable settings passed in startup packet. Index: src/backend/utils/misc/guc.c =================================================================== RCS file: /cvsroot/pgsql-server/src/backend/utils/misc/guc.c,v retrieving revision 1.127 diff -c -c -r1.127 guc.c *** src/backend/utils/misc/guc.c 28 May 2003 18:19:09 -0000 1.127 --- src/backend/utils/misc/guc.c 11 Jun 2003 04:30:01 -0000 *************** *** 406,416 **** }, { ! {"log_statement", PGC_SUSET}, &log_statement, false, NULL, NULL }, { ! {"log_duration", PGC_SUSET}, &log_duration, false, NULL, NULL }, { --- 406,416 ---- }, { ! {"log_statement", PGC_USERLIMIT}, &log_statement, false, NULL, NULL }, { ! {"log_duration", PGC_USERLIMIT}, &log_duration, false, NULL, NULL }, { *************** *** 431,449 **** }, { ! {"log_parser_stats", PGC_SUSET}, &log_parser_stats, false, NULL, NULL }, { ! {"log_planner_stats", PGC_SUSET}, &log_planner_stats, false, NULL, NULL }, { ! {"log_executor_stats", PGC_SUSET}, &log_executor_stats, false, NULL, NULL }, { ! {"log_statement_stats", PGC_SUSET}, &log_statement_stats, false, NULL, NULL }, #ifdef BTREE_BUILD_STATS --- 431,449 ---- }, { ! {"log_parser_stats", PGC_USERLIMIT}, &log_parser_stats, false, NULL, NULL }, { ! {"log_planner_stats", PGC_USERLIMIT}, &log_planner_stats, false, NULL, NULL }, { ! {"log_executor_stats", PGC_USERLIMIT}, &log_executor_stats, false, NULL, NULL }, { ! {"log_statement_stats", PGC_USERLIMIT}, &log_statement_stats, false, NULL, NULL }, #ifdef BTREE_BUILD_STATS *************** *** 797,803 **** }, { ! {"log_min_error_statement", PGC_SUSET}, &log_min_error_statement_str, "panic", assign_min_error_statement, NULL }, --- 797,803 ---- }, { ! {"log_min_error_statement", PGC_USERLIMIT}, &log_min_error_statement_str, "panic", assign_min_error_statement, NULL }, *************** *** 884,890 **** }, { ! {"log_min_messages", PGC_SUSET}, &log_min_messages_str, "notice", assign_log_min_messages, NULL }, --- 884,890 ---- }, { ! {"log_min_messages", PGC_USERLIMIT}, &log_min_messages_str, "notice", assign_log_min_messages, NULL }, *************** *** 1180,1185 **** --- 1180,1189 ---- struct config_string *conf = (struct config_string *) gconf; char *str; + Assert(conf->gen.context != PGC_USERLIMIT || + conf->assign_hook == assign_log_min_messages || + conf->assign_hook == assign_client_min_messages || + conf->assign_hook == assign_min_error_statement); *conf->variable = NULL; conf->reset_val = NULL; conf->session_val = NULL; *************** *** 1276,1282 **** struct config_generic *gconf = guc_variables[i]; /* Don't reset non-SET-able values */ ! if (gconf->context != PGC_SUSET && gconf->context != PGC_USERSET) continue; /* Don't reset if special exclusion from RESET ALL */ if (gconf->flags & GUC_NO_RESET_ALL) --- 1280,1288 ---- struct config_generic *gconf = guc_variables[i]; /* Don't reset non-SET-able values */ ! if (gconf->context != PGC_SUSET && ! gconf->context != PGC_USERLIMIT && ! gconf->context != PGC_USERSET) continue; /* Don't reset if special exclusion from RESET ALL */ if (gconf->flags & GUC_NO_RESET_ALL) *************** *** 1810,1815 **** --- 1816,1822 ---- return false; } break; + case PGC_USERLIMIT: /* USERLIMIT permissions checked below */ case PGC_USERSET: /* always okay */ break; *************** *** 1861,1866 **** --- 1868,1889 ---- name); return false; } + /* Limit non-super user changes */ + if (record->context == PGC_USERLIMIT && + source > PGC_S_USERSTART && + newval < conf->reset_val && !superuser()) + { + elog(elevel, "'%s': permission denied\n" + "Only super-users can set this value to false.", + name); + return false; + } + /* Allow admin change to override user change */ + if (!DoIt && record->context == PGC_USERLIMIT && + source < PGC_S_USERSTART && + record->reset_source > PGC_S_USERSTART && + newval > conf->reset_val && !superuser()) + DoIt = true; } else { *************** *** 1932,1937 **** --- 1955,1976 ---- name, newval, conf->min, conf->max); return false; } + /* Limit non-super user changes */ + if (record->context == PGC_USERLIMIT && + source > PGC_S_USERSTART && + newval < conf->reset_val && !superuser()) + { + elog(elevel, "'%s': permission denied\n" + "Only super-users can increase this value.", + name); + return false; + } + /* Allow admin change to override user change */ + if (!DoIt && record->context == PGC_USERLIMIT && + source < PGC_S_USERSTART && + record->reset_source > PGC_S_USERSTART && + newval > conf->reset_val && !superuser()) + DoIt = true; } else { *************** *** 2003,2008 **** --- 2042,2063 ---- name, newval, conf->min, conf->max); return false; } + /* Limit non-super user changes */ + if (record->context == PGC_USERLIMIT && + source > PGC_S_USERSTART && + newval < conf->reset_val && !superuser()) + { + elog(elevel, "'%s': permission denied\n" + "Only super-users can increase this value.", + name); + return false; + } + /* Allow admin change to override user change */ + if (!DoIt && record->context == PGC_USERLIMIT && + source < PGC_S_USERSTART && + record->reset_source > PGC_S_USERSTART && + newval > conf->reset_val && !superuser()) + DoIt = true; } else { *************** *** 2067,2072 **** --- 2122,2151 ---- elog(elevel, "out of memory"); return false; } + + if (*conf->variable) + { + int old_int_value, new_int_value; + + /* Limit non-super user changes */ + assign_msglvl(&old_int_value, conf->reset_val, true, interactive); + assign_msglvl(&new_int_value, newval, true, interactive); + if (record->context == PGC_USERLIMIT && + source > PGC_S_USERSTART && + new_int_value > old_int_value && !superuser()) + { + elog(elevel, "'%s': permission denied\n" + "Only super-users can increase this value.", + name); + return false; + } + /* Allow admin change to override user change */ + if (!DoIt && record->context == PGC_USERLIMIT && + source < PGC_S_USERSTART && + record->reset_source > PGC_S_USERSTART && + newval > conf->reset_val && !superuser()) + DoIt = true; + } } else if (conf->reset_val) { *************** *** 3454,3457 **** #include "guc-file.c" - --- 3533,3535 ---- Index: src/include/utils/guc.h =================================================================== RCS file: /cvsroot/pgsql-server/src/include/utils/guc.h,v retrieving revision 1.31 diff -c -c -r1.31 guc.h *** src/include/utils/guc.h 6 May 2003 20:26:28 -0000 1.31 --- src/include/utils/guc.h 11 Jun 2003 04:30:02 -0000 *************** *** 48,53 **** --- 48,56 ---- * be set in the connection startup packet, because when it is processed * we don't yet know if the user is a superuser. * + * USERLIMIT options can only be manipulated in certain ways by + * non-super users. + * * USERSET options can be set by anyone any time. */ typedef enum *************** *** 57,62 **** --- 60,66 ---- PGC_SIGHUP, PGC_BACKEND, PGC_SUSET, + PGC_USERLIMIT, PGC_USERSET } GucContext; *************** *** 76,86 **** PGC_S_ENV_VAR = 1, /* postmaster environment variable */ PGC_S_FILE = 2, /* postgresql.conf */ PGC_S_ARGV = 3, /* postmaster command line */ ! PGC_S_DATABASE = 4, /* per-database setting */ ! PGC_S_USER = 5, /* per-user setting */ ! PGC_S_CLIENT = 6, /* from client connection request */ ! PGC_S_OVERRIDE = 7, /* special case to forcibly set default */ ! PGC_S_SESSION = 8 /* SET command */ } GucSource; --- 80,95 ---- PGC_S_ENV_VAR = 1, /* postmaster environment variable */ PGC_S_FILE = 2, /* postgresql.conf */ PGC_S_ARGV = 3, /* postmaster command line */ ! PGC_S_USERSTART=4, /* ! * Settings below are controlled by users. ! * This is used by PGC_USERLIMT to prevent ! * non-super users from changing certain settings. ! */ ! PGC_S_DATABASE = 5, /* per-database setting */ ! PGC_S_USER = 6, /* per-user setting */ ! PGC_S_CLIENT = 7, /* from client connection request */ ! PGC_S_OVERRIDE = 8, /* special case to forcibly set default */ ! PGC_S_SESSION = 9 /* SET command */ } GucSource;