diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index b41ba1e172ca83e399bab19ef983dece70eba02e..ce70d6eb6bec5c41083cc0e0dd6b5f74ff011d5d 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.126 2003/06/22 00:29:29 tgl Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.127 2003/06/27 19:08:37 tgl Exp $ --> <chapter id="libpq"> @@ -812,7 +812,8 @@ is not known. Parameters reported as of the current release include <literal>server_version</> (cannot change after startup); <literal>server_encoding</> (also not presently changeable after start); -<literal>client_encoding</>, and +<literal>client_encoding</>, +<literal>is_superuser</>, and <literal>DateStyle</>. </para> diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml index 2d5b5d8c22255b5fbdae220fb1d3ff7a2645a9ce..75fe6b3982eb894ba2084d04aed08eeddec0d0ee 100644 --- a/doc/src/sgml/protocol.sgml +++ b/doc/src/sgml/protocol.sgml @@ -1,4 +1,4 @@ -<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.38 2003/05/08 14:35:24 tgl Exp $ --> +<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.39 2003/06/27 19:08:37 tgl Exp $ --> <chapter id="protocol"> <title>Frontend/Backend Protocol</title> @@ -998,7 +998,8 @@ <literal>server_version</> (a pseudo-parameter that cannot change after startup); <literal>server_encoding</> (also not presently changeable after start); - <literal>client_encoding</>, and + <literal>client_encoding</>, + <literal>is_superuser</>, and <literal>DateStyle</>. This set might change in the future, or even become configurable. Accordingly, a frontend should simply ignore ParameterStatus for diff --git a/doc/src/sgml/ref/show.sgml b/doc/src/sgml/ref/show.sgml index 0232d97dfce88c8ae2d39b132ffceb365dbd31c4..09619bb4827a772f4dcab0ed894dc1754946e3b2 100644 --- a/doc/src/sgml/ref/show.sgml +++ b/doc/src/sgml/ref/show.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/show.sgml,v 1.27 2003/05/14 03:26:00 tgl Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/show.sgml,v 1.28 2003/06/27 19:08:37 tgl Exp $ PostgreSQL documentation --> @@ -97,6 +97,16 @@ SHOW ALL </para> </listitem> </varlistentry> + + <varlistentry> + <term><literal>IS_SUPERUSER</literal></term> + <listitem> + <para> + True if the current session authorization identifier has + superuser privileges. + </para> + </listitem> + </varlistentry> </variablelist> </para> </listitem> diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 1b2f847752173f484d9560708e85a5bf1b88693f..3dd4724f7741dc687700d6806078490c07b828fc 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.78 2003/06/06 16:25:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.79 2003/06/27 19:08:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -721,25 +721,29 @@ assign_client_encoding(const char *value, bool doit, bool interactive) * When resetting session auth after an error, we can't expect to do catalog * lookups. Hence, the stored form of the value must provide a numeric userid * that can be re-used directly. We store the string in the form of - * NAMEDATALEN 'x's followed by the numeric userid --- this cannot conflict - * with any valid user name, because of the NAMEDATALEN limit on names. + * NAMEDATALEN 'x's, followed by T or F to indicate superuserness, followed + * by the numeric userid --- this cannot conflict with any valid user name, + * because of the NAMEDATALEN limit on names. */ const char * assign_session_authorization(const char *value, bool doit, bool interactive) { AclId usesysid = 0; + bool is_superuser = false; char *result; - if (strspn(value, "x") == NAMEDATALEN) + if (strspn(value, "x") == NAMEDATALEN && + (value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F')) { /* might be a saved numeric userid */ char *endptr; - usesysid = (AclId) strtoul(value + NAMEDATALEN, &endptr, 10); + usesysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10); - if (endptr != value + NAMEDATALEN && *endptr == '\0') + if (endptr != value + NAMEDATALEN + 1 && *endptr == '\0') { - /* syntactically valid, so use the numeric user ID */ + /* syntactically valid, so use the numeric user ID and flag */ + is_superuser = (value[NAMEDATALEN] == 'T'); } else usesysid = 0; @@ -771,12 +775,13 @@ assign_session_authorization(const char *value, bool doit, bool interactive) } usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid; - + is_superuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper; + ReleaseSysCache(userTup); } if (doit) - SetSessionAuthorization(usesysid); + SetSessionAuthorization(usesysid, is_superuser); result = (char *) malloc(NAMEDATALEN + 32); if (!result) @@ -784,7 +789,9 @@ assign_session_authorization(const char *value, bool doit, bool interactive) memset(result, 'x', NAMEDATALEN); - snprintf(result + NAMEDATALEN, 32, "%lu", (unsigned long) usesysid); + snprintf(result + NAMEDATALEN, 32, "%c%lu", + is_superuser ? 'T' : 'F', + (unsigned long) usesysid); return result; } diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index c3dc38f387db4e01d19a00d018f61dddc22fe4bd..4d65f619be443629b2d1ec230e67beb2159b9ebe 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.103 2003/06/27 14:45:30 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.104 2003/06/27 19:08:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -553,9 +553,12 @@ InitializeSessionUserId(const char *username) SetSessionUserId(usesysid); /* sets CurrentUserId too */ - /* Record username as a config option too */ + /* Record username and superuser status as GUC settings too */ SetConfigOption("session_authorization", username, PGC_BACKEND, PGC_S_OVERRIDE); + SetConfigOption("is_superuser", + AuthenticatedUserIsSuperuser ? "on" : "off", + PGC_INTERNAL, PGC_S_OVERRIDE); /* * Set up user-specific configuration variables. This is a good place @@ -594,10 +597,13 @@ InitializeSessionUserIdStandalone(void) /* * Change session auth ID while running * - * Only a superuser may set auth ID to something other than himself. + * Only a superuser may set auth ID to something other than himself. Note + * that in case of multiple SETs in a single session, the original userid's + * superuserness is what matters. But we set the GUC variable is_superuser + * to indicate whether the *current* session userid is a superuser. */ void -SetSessionAuthorization(AclId userid) +SetSessionAuthorization(AclId userid, bool is_superuser) { /* Must have authenticated already, else can't make permission check */ AssertState(AclIdIsValid(AuthenticatedUserId)); @@ -608,6 +614,10 @@ SetSessionAuthorization(AclId userid) SetSessionUserId(userid); SetUserId(userid); + + SetConfigOption("is_superuser", + is_superuser ? "on" : "off", + PGC_INTERNAL, PGC_S_OVERRIDE); } diff --git a/src/backend/utils/misc/check_guc b/src/backend/utils/misc/check_guc index 7930d06f6e69eab77444728f99ac410a9096153a..5b545d5f4368586191e588951b2bd49197f384ca 100755 --- a/src/backend/utils/misc/check_guc +++ b/src/backend/utils/misc/check_guc @@ -16,9 +16,12 @@ ## if an option is valid but shows up in only one file (guc.c but not ## postgresql.conf.sample), it should be listed here so that it ## can be ignored -INTENTIONALLY_NOT_INCLUDED="pre_auth_delay lc_messages lc_monetary \ -lc_numeric lc_time seed server_encoding session_authorization \ -transaction_isolation transaction_read_only zero_damaged_pages" +INTENTIONALLY_NOT_INCLUDED="autocommit debug_deadlocks exit_on_error \ +is_superuser lc_collate lc_ctype lc_messages lc_monetary lc_numeric lc_time \ +pre_auth_delay seed server_encoding server_version session_authorization \ +trace_lock_oidmin trace_lock_table trace_locks trace_lwlocks trace_notify \ +trace_userlocks transaction_isolation transaction_read_only \ +zero_damaged_pages" ### What options are listed in postgresql.conf.sample, but don't appear ### in guc.c? diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index f1582b8c5b54f5a3b05d0daa54ebd8dd16798349..dfdc4f82e7fd67c6f76e6b4d7e089e8e2046fa07 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut <peter_e@gmx.net>. * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.131 2003/06/11 22:13:22 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.132 2003/06/27 19:08:38 tgl Exp $ * *-------------------------------------------------------------------- */ @@ -138,6 +138,7 @@ static char *log_min_error_statement_str; static char *log_min_messages_str; static char *client_min_messages_str; static bool phony_autocommit; +static bool session_auth_is_superuser; static double phony_random_seed; static char *client_encoding_string; static char *datestyle_string; @@ -361,6 +362,13 @@ static struct config_bool true, NULL, NULL }, + /* Not for general use --- used by SET SESSION AUTHORIZATION */ + { + {"is_superuser", PGC_INTERNAL, GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL}, + &session_auth_is_superuser, + false, NULL, NULL + }, + { {"tcpip_socket", PGC_POSTMASTER}, &NetServer, false, NULL, NULL @@ -894,6 +902,7 @@ static struct config_string "SQL_ASCII", NULL, NULL }, + /* Can't be set in postgresql.conf */ { {"server_version", PGC_INTERNAL, GUC_REPORT}, &server_version_string, diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index f88b983504547071392303329f3936ff6d245f14..213d25813330f5902fe205b34612668b5ccf3701 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: miscadmin.h,v 1.124 2003/06/27 14:45:31 petere Exp $ + * $Id: miscadmin.h,v 1.125 2003/06/27 19:08:38 tgl Exp $ * * NOTES * some of the information in this file should be moved to @@ -208,7 +208,7 @@ extern AclId GetSessionUserId(void); extern void SetSessionUserId(AclId userid); extern void InitializeSessionUserId(const char *username); extern void InitializeSessionUserIdStandalone(void); -extern void SetSessionAuthorization(AclId userid); +extern void SetSessionAuthorization(AclId userid, bool is_superuser); extern void SetDataDir(const char *dir);