Avoid crashing when restoring a saved GUC session_authorization value
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 11 Aug 2004 21:10:37 +0000 (21:10 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 11 Aug 2004 21:10:37 +0000 (21:10 +0000)
that refers to a now-deleted userid.  Per gripe from Chris Ochs.

src/backend/commands/variable.c
src/backend/utils/misc/guc.c

index dfa3f7121edb83c47b0c396d58cea09c86b2a9be..f5ae5a59903bcff2fa10a15498cfe6547ab788a2 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.98 2004/07/01 00:50:12 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.99 2004/08/11 21:10:36 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -591,31 +591,37 @@ assign_client_encoding(const char *value, bool doit, GucSource source)
  * 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 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.
+ * by the numeric userid, followed by a comma, followed by the user name.
+ * This cannot be confused with a plain user name because of the NAMEDATALEN
+ * limit on names, so we can tell whether we're being passed an initial
+ * username or a saved/restored value.
  */
+extern char *session_authorization_string; /* in guc.c */
+
 const char *
 assign_session_authorization(const char *value, bool doit, GucSource source)
 {
        AclId           usesysid = 0;
        bool            is_superuser = false;
+       const char *actual_username = NULL;
        char       *result;
 
        if (strspn(value, "x") == NAMEDATALEN &&
                (value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'))
        {
-               /* might be a saved numeric userid */
+               /* might be a saved userid string */
+               AclId           savedsysid;
                char       *endptr;
 
-               usesysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
+               savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
 
-               if (endptr != value + NAMEDATALEN + 1 && *endptr == '\0')
+               if (endptr != value + NAMEDATALEN + 1 && *endptr == ',')
                {
-                       /* syntactically valid, so use the numeric user ID and flag */
+                       /* syntactically valid, so break out the data */
+                       usesysid = savedsysid;
                        is_superuser = (value[NAMEDATALEN] == 'T');
+                       actual_username = endptr + 1;
                }
-               else
-                       usesysid = 0;
        }
 
        if (usesysid == 0)
@@ -647,6 +653,7 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
 
                usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
                is_superuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper;
+               actual_username = value;
 
                ReleaseSysCache(userTup);
        }
@@ -654,15 +661,16 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
        if (doit)
                SetSessionAuthorization(usesysid, is_superuser);
 
-       result = (char *) malloc(NAMEDATALEN + 32);
+       result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_username));
        if (!result)
                return NULL;
 
        memset(result, 'x', NAMEDATALEN);
 
-       snprintf(result + NAMEDATALEN, 32, "%c%lu",
-                        is_superuser ? 'T' : 'F',
-                        (unsigned long) usesysid);
+       sprintf(result + NAMEDATALEN, "%c%lu,%s",
+                       is_superuser ? 'T' : 'F',
+                       (unsigned long) usesysid,
+                       actual_username);
 
        return result;
 }
@@ -671,8 +679,19 @@ const char *
 show_session_authorization(void)
 {
        /*
-        * We can't use the stored string; see comments for
+        * Extract the user name from the stored string; see
         * assign_session_authorization
         */
-       return GetUserNameFromId(GetSessionUserId());
+       const char *value = session_authorization_string;
+       AclId           savedsysid;
+       char       *endptr;
+
+       Assert(strspn(value, "x") == NAMEDATALEN &&
+                  (value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'));
+
+       savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
+
+       Assert(endptr != value + NAMEDATALEN + 1 && *endptr == ',');
+
+       return endptr + 1;
 }
index 5c4908f27daced140687f95e4e3079db5ae8e456..d015629c3e790428836c3f3b68ddc67cd4cfd284 100644 (file)
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.230 2004/08/08 20:17:36 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.231 2004/08/11 21:10:37 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -175,7 +175,6 @@ static char *locale_ctype;
 static char *regex_flavor_string;
 static char *server_encoding_string;
 static char *server_version_string;
-static char *session_authorization_string;
 static char *timezone_string;
 static char *XactIsoLevel_string;
 static char *custom_variable_classes;
@@ -184,6 +183,8 @@ static int  max_index_keys;
 static int     max_identifier_length;
 static int     block_size;
 static bool integer_datetimes;
+/* should be static, but commands/variable.c needs to get at it */
+char *session_authorization_string;
 
 
 /*