提交 aff700a1 编写于 作者: T Tom Lane

Avoid crashing when restoring a saved GUC session_authorization value

that refers to a now-deleted userid.  Per gripe from Chris Ochs.
上级 f79fbb2b
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -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 * 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 * 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 * NAMEDATALEN 'x's, followed by T or F to indicate superuserness, followed
* by the numeric userid --- this cannot conflict with any valid user name, * by the numeric userid, followed by a comma, followed by the user name.
* because of the NAMEDATALEN limit on names. * 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 * const char *
assign_session_authorization(const char *value, bool doit, GucSource source) assign_session_authorization(const char *value, bool doit, GucSource source)
{ {
AclId usesysid = 0; AclId usesysid = 0;
bool is_superuser = false; bool is_superuser = false;
const char *actual_username = NULL;
char *result; char *result;
if (strspn(value, "x") == NAMEDATALEN && if (strspn(value, "x") == NAMEDATALEN &&
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F')) (value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'))
{ {
/* might be a saved numeric userid */ /* might be a saved userid string */
AclId savedsysid;
char *endptr; 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'); is_superuser = (value[NAMEDATALEN] == 'T');
actual_username = endptr + 1;
} }
else
usesysid = 0;
} }
if (usesysid == 0) if (usesysid == 0)
...@@ -647,6 +653,7 @@ assign_session_authorization(const char *value, bool doit, GucSource source) ...@@ -647,6 +653,7 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid; usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
is_superuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper; is_superuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper;
actual_username = value;
ReleaseSysCache(userTup); ReleaseSysCache(userTup);
} }
...@@ -654,15 +661,16 @@ assign_session_authorization(const char *value, bool doit, GucSource source) ...@@ -654,15 +661,16 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
if (doit) if (doit)
SetSessionAuthorization(usesysid, is_superuser); SetSessionAuthorization(usesysid, is_superuser);
result = (char *) malloc(NAMEDATALEN + 32); result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_username));
if (!result) if (!result)
return NULL; return NULL;
memset(result, 'x', NAMEDATALEN); memset(result, 'x', NAMEDATALEN);
snprintf(result + NAMEDATALEN, 32, "%c%lu", sprintf(result + NAMEDATALEN, "%c%lu,%s",
is_superuser ? 'T' : 'F', is_superuser ? 'T' : 'F',
(unsigned long) usesysid); (unsigned long) usesysid,
actual_username);
return result; return result;
} }
...@@ -671,8 +679,19 @@ const char * ...@@ -671,8 +679,19 @@ const char *
show_session_authorization(void) 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 * 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;
} }
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * 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; ...@@ -175,7 +175,6 @@ static char *locale_ctype;
static char *regex_flavor_string; static char *regex_flavor_string;
static char *server_encoding_string; static char *server_encoding_string;
static char *server_version_string; static char *server_version_string;
static char *session_authorization_string;
static char *timezone_string; static char *timezone_string;
static char *XactIsoLevel_string; static char *XactIsoLevel_string;
static char *custom_variable_classes; static char *custom_variable_classes;
...@@ -184,6 +183,8 @@ static int max_index_keys; ...@@ -184,6 +183,8 @@ static int max_index_keys;
static int max_identifier_length; static int max_identifier_length;
static int block_size; static int block_size;
static bool integer_datetimes; static bool integer_datetimes;
/* should be static, but commands/variable.c needs to get at it */
char *session_authorization_string;
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册