summaryrefslogtreecommitdiff
path: root/src/backend/commands/variable.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-08-11 21:10:37 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-08-11 21:10:37 +0000
commitaff700a16079b7f418f7557312eb281249c0e534 (patch)
tree827438ec8ceae598fe2fab84895a05dab5e19928 /src/backend/commands/variable.c
parentf79fbb2bec3bf44c7b980f059ce0f0540b5f669f (diff)
downloadpostgresql-aff700a16079b7f418f7557312eb281249c0e534.tar.gz
Avoid crashing when restoring a saved GUC session_authorization value
that refers to a now-deleted userid. Per gripe from Chris Ochs.
Diffstat (limited to 'src/backend/commands/variable.c')
-rw-r--r--src/backend/commands/variable.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index dfa3f7121e..f5ae5a5990 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -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;
}