Add is_superuser parameter reporting, soon to be used by psql.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 27 Jun 2003 19:08:38 +0000 (19:08 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 27 Jun 2003 19:08:38 +0000 (19:08 +0000)
doc/src/sgml/libpq.sgml
doc/src/sgml/protocol.sgml
doc/src/sgml/ref/show.sgml
src/backend/commands/variable.c
src/backend/utils/init/miscinit.c
src/backend/utils/misc/check_guc
src/backend/utils/misc/guc.c
src/include/miscadmin.h

index 0e112f47489b23b60c774c2ae9521d93be526c2d..af6deb15754575c4a5e3b492c125123e0574408a 100644 (file)
@@ -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>
 
index d8b4cb436c88bd4db8752bf10575109a30458b1d..9a0fca7979da25cd86ebf7f9f64fc81940a33363 100644 (file)
     <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
index 8dd9770cf38e3f347b3e30fcf3c61279ab885725..bf82174839865b68d4b79a9a054fd5a175f9ec91 100644 (file)
@@ -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>
index c843dce8afe9252503fde54a3bef1685a1912596..227b1c0d62ab21af2acaf0fc8cf490785882847a 100644 (file)
@@ -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;
 }
index 2837a07751404368ef8ec9e54d35288d1a1ee507..4685e3d0e914a184d5863672d832f67a4c185c1d 100644 (file)
@@ -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);
 }
 
 
index 7930d06f6e69eab77444728f99ac410a9096153a..5b545d5f4368586191e588951b2bd49197f384ca 100755 (executable)
 ## 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?
index fa7f5c93e2eb6cf5159f0e7d4a1f6972f873e25c..9617bab9f7648a857f5a9f8d756d328168e1b607 100644 (file)
@@ -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,
index 226d8ded49fc84efd901cde38275d132a175333a..e60e9d01670e875626a764c82a4df17b3da01ed4 100644 (file)
@@ -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);