Skip to content

Commit aff700a

Browse files
committed
Avoid crashing when restoring a saved GUC session_authorization value
that refers to a now-deleted userid. Per gripe from Chris Ochs.
1 parent f79fbb2 commit aff700a

File tree

2 files changed

+37
-17
lines changed

2 files changed

+37
-17
lines changed

src/backend/commands/variable.c

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.98 2004/07/01 00:50:12 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.99 2004/08/11 21:10:36 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -591,31 +591,37 @@ assign_client_encoding(const char *value, bool doit, GucSource source)
591591
* lookups. Hence, the stored form of the value must provide a numeric userid
592592
* that can be re-used directly. We store the string in the form of
593593
* NAMEDATALEN 'x's, followed by T or F to indicate superuserness, followed
594-
* by the numeric userid --- this cannot conflict with any valid user name,
595-
* because of the NAMEDATALEN limit on names.
594+
* by the numeric userid, followed by a comma, followed by the user name.
595+
* This cannot be confused with a plain user name because of the NAMEDATALEN
596+
* limit on names, so we can tell whether we're being passed an initial
597+
* username or a saved/restored value.
596598
*/
599+
extern char *session_authorization_string; /* in guc.c */
600+
597601
const char *
598602
assign_session_authorization(const char *value, bool doit, GucSource source)
599603
{
600604
AclId usesysid = 0;
601605
bool is_superuser = false;
606+
const char *actual_username = NULL;
602607
char *result;
603608

604609
if (strspn(value, "x") == NAMEDATALEN &&
605610
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'))
606611
{
607-
/* might be a saved numeric userid */
612+
/* might be a saved userid string */
613+
AclId savedsysid;
608614
char *endptr;
609615

610-
usesysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
616+
savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
611617

612-
if (endptr != value + NAMEDATALEN + 1 && *endptr == '\0')
618+
if (endptr != value + NAMEDATALEN + 1 && *endptr == ',')
613619
{
614-
/* syntactically valid, so use the numeric user ID and flag */
620+
/* syntactically valid, so break out the data */
621+
usesysid = savedsysid;
615622
is_superuser = (value[NAMEDATALEN] == 'T');
623+
actual_username = endptr + 1;
616624
}
617-
else
618-
usesysid = 0;
619625
}
620626

621627
if (usesysid == 0)
@@ -647,22 +653,24 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
647653

648654
usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
649655
is_superuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper;
656+
actual_username = value;
650657

651658
ReleaseSysCache(userTup);
652659
}
653660

654661
if (doit)
655662
SetSessionAuthorization(usesysid, is_superuser);
656663

657-
result = (char *) malloc(NAMEDATALEN + 32);
664+
result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_username));
658665
if (!result)
659666
return NULL;
660667

661668
memset(result, 'x', NAMEDATALEN);
662669

663-
snprintf(result + NAMEDATALEN, 32, "%c%lu",
664-
is_superuser ? 'T' : 'F',
665-
(unsigned long) usesysid);
670+
sprintf(result + NAMEDATALEN, "%c%lu,%s",
671+
is_superuser ? 'T' : 'F',
672+
(unsigned long) usesysid,
673+
actual_username);
666674

667675
return result;
668676
}
@@ -671,8 +679,19 @@ const char *
671679
show_session_authorization(void)
672680
{
673681
/*
674-
* We can't use the stored string; see comments for
682+
* Extract the user name from the stored string; see
675683
* assign_session_authorization
676684
*/
677-
return GetUserNameFromId(GetSessionUserId());
685+
const char *value = session_authorization_string;
686+
AclId savedsysid;
687+
char *endptr;
688+
689+
Assert(strspn(value, "x") == NAMEDATALEN &&
690+
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'));
691+
692+
savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
693+
694+
Assert(endptr != value + NAMEDATALEN + 1 && *endptr == ',');
695+
696+
return endptr + 1;
678697
}

src/backend/utils/misc/guc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Written by Peter Eisentraut <peter_e@gmx.net>.
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.230 2004/08/08 20:17:36 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.231 2004/08/11 21:10:37 tgl Exp $
1414
*
1515
*--------------------------------------------------------------------
1616
*/
@@ -175,7 +175,6 @@ static char *locale_ctype;
175175
static char *regex_flavor_string;
176176
static char *server_encoding_string;
177177
static char *server_version_string;
178-
static char *session_authorization_string;
179178
static char *timezone_string;
180179
static char *XactIsoLevel_string;
181180
static char *custom_variable_classes;
@@ -184,6 +183,8 @@ static int max_index_keys;
184183
static int max_identifier_length;
185184
static int block_size;
186185
static bool integer_datetimes;
186+
/* should be static, but commands/variable.c needs to get at it */
187+
char *session_authorization_string;
187188

188189

189190
/*

0 commit comments

Comments
 (0)