Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d9a4cce

Browse files
committed
Fix error case for CREATE ROLE ... IN ROLE.
CreateRole() was passing a Value node, not a RoleSpec node, for the newly-created role name when adding the role as a member of existing roles for the IN ROLE syntax. This mistake went unnoticed because the node in question is used only for error messages and is not accessed on non-error paths. In older pg versions (such as 9.5 where this was found), this results in an "unexpected node type" error in place of the real error. That node type check was removed at some point, after which the code would accidentally fail to fail on 64-bit platforms (on which accessing the Value node as if it were a RoleSpec would be mostly harmless) or give an "unexpected role type" error on 32-bit platforms. Fix the code to pass the correct node type, and add an lfirst_node assertion just in case. Per report on irc from user m1chelangelo. Backpatch all the way, because this error has been around for a long time.
1 parent 6c5f916 commit d9a4cce

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

src/backend/commands/user.c

+24-13
Original file line numberDiff line numberDiff line change
@@ -470,20 +470,31 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
470470
/*
471471
* Add the new role to the specified existing roles.
472472
*/
473-
foreach(item, addroleto)
473+
if (addroleto)
474474
{
475-
RoleSpec *oldrole = lfirst(item);
476-
HeapTuple oldroletup = get_rolespec_tuple(oldrole);
477-
Form_pg_authid oldroleform = (Form_pg_authid) GETSTRUCT(oldroletup);
478-
Oid oldroleid = oldroleform->oid;
479-
char *oldrolename = NameStr(oldroleform->rolname);
480-
481-
AddRoleMems(oldrolename, oldroleid,
482-
list_make1(makeString(stmt->role)),
483-
list_make1_oid(roleid),
484-
GetUserId(), false);
475+
RoleSpec *thisrole = makeNode(RoleSpec);
476+
List *thisrole_list = list_make1(thisrole);
477+
List *thisrole_oidlist = list_make1_oid(roleid);
478+
479+
thisrole->roletype = ROLESPEC_CSTRING;
480+
thisrole->rolename = stmt->role;
481+
thisrole->location = -1;
485482

486-
ReleaseSysCache(oldroletup);
483+
foreach(item, addroleto)
484+
{
485+
RoleSpec *oldrole = lfirst(item);
486+
HeapTuple oldroletup = get_rolespec_tuple(oldrole);
487+
Form_pg_authid oldroleform = (Form_pg_authid) GETSTRUCT(oldroletup);
488+
Oid oldroleid = oldroleform->oid;
489+
char *oldrolename = NameStr(oldroleform->rolname);
490+
491+
AddRoleMems(oldrolename, oldroleid,
492+
thisrole_list,
493+
thisrole_oidlist,
494+
GetUserId(), false);
495+
496+
ReleaseSysCache(oldroletup);
497+
}
487498
}
488499

489500
/*
@@ -1503,7 +1514,7 @@ AddRoleMems(const char *rolename, Oid roleid,
15031514

15041515
forboth(specitem, memberSpecs, iditem, memberIds)
15051516
{
1506-
RoleSpec *memberRole = lfirst(specitem);
1517+
RoleSpec *memberRole = lfirst_node(RoleSpec, specitem);
15071518
Oid memberid = lfirst_oid(iditem);
15081519
HeapTuple authmem_tuple;
15091520
HeapTuple tuple;

0 commit comments

Comments
 (0)