Fix crasher bugs in previous commit

ALTER DEFAULT PRIVILEGES was trying to decode the list of roles in the
FOR clause as a list of names rather than of RoleSpecs; and the IN
clause in CREATE ROLE was doing the same thing.  This was evidenced by
crashes on some buildfarm machines, though on my platform this doesn't
cause a failure by mere chance; I can reproduce the failures only by
adding some padding in struct RoleSpecs.

Fix by dereferencing those lists as being of RoleSpecs, not string
Values.
This commit is contained in:
Alvaro Herrera 2015-03-09 17:00:43 -03:00
parent 31eae6028e
commit e3f1c24b99
2 changed files with 16 additions and 12 deletions

View File

@ -858,9 +858,9 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
GrantStmt *action = stmt->action; GrantStmt *action = stmt->action;
InternalDefaultACL iacls; InternalDefaultACL iacls;
ListCell *cell; ListCell *cell;
List *rolenames = NIL; List *rolespecs = NIL;
List *nspnames = NIL; List *nspnames = NIL;
DefElem *drolenames = NULL; DefElem *drolespecs = NULL;
DefElem *dnspnames = NULL; DefElem *dnspnames = NULL;
AclMode all_privileges; AclMode all_privileges;
const char *errormsg; const char *errormsg;
@ -880,11 +880,11 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
} }
else if (strcmp(defel->defname, "roles") == 0) else if (strcmp(defel->defname, "roles") == 0)
{ {
if (drolenames) if (drolespecs)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options"))); errmsg("conflicting or redundant options")));
drolenames = defel; drolespecs = defel;
} }
else else
elog(ERROR, "option \"%s\" not recognized", defel->defname); elog(ERROR, "option \"%s\" not recognized", defel->defname);
@ -892,8 +892,8 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
if (dnspnames) if (dnspnames)
nspnames = (List *) dnspnames->arg; nspnames = (List *) dnspnames->arg;
if (drolenames) if (drolespecs)
rolenames = (List *) drolenames->arg; rolespecs = (List *) drolespecs->arg;
/* Prepare the InternalDefaultACL representation of the statement */ /* Prepare the InternalDefaultACL representation of the statement */
/* roleid to be filled below */ /* roleid to be filled below */
@ -996,7 +996,7 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
} }
} }
if (rolenames == NIL) if (rolespecs == NIL)
{ {
/* Set permissions for myself */ /* Set permissions for myself */
iacls.roleid = GetUserId(); iacls.roleid = GetUserId();
@ -1008,11 +1008,11 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
/* Look up the role OIDs and do permissions checks */ /* Look up the role OIDs and do permissions checks */
ListCell *rolecell; ListCell *rolecell;
foreach(rolecell, rolenames) foreach(rolecell, rolespecs)
{ {
char *rolename = strVal(lfirst(rolecell)); RoleSpec *rolespec = lfirst(rolecell);
iacls.roleid = get_role_oid(rolename, false); iacls.roleid = get_rolespec_oid((Node *) rolespec, false);
/* /*
* We insist that calling user be a member of each target role. If * We insist that calling user be a member of each target role. If

View File

@ -429,13 +429,17 @@ CreateRole(CreateRoleStmt *stmt)
*/ */
foreach(item, addroleto) foreach(item, addroleto)
{ {
char *oldrolename = strVal(lfirst(item)); RoleSpec *oldrole = lfirst(item);
Oid oldroleid = get_role_oid(oldrolename, false); HeapTuple oldroletup = get_rolespec_tuple((Node *) oldrole);
Oid oldroleid = HeapTupleGetOid(oldroletup);
char *oldrolename = NameStr(((Form_pg_authid) GETSTRUCT(oldroletup))->rolname);
AddRoleMems(oldrolename, oldroleid, AddRoleMems(oldrolename, oldroleid,
list_make1(makeString(stmt->role)), list_make1(makeString(stmt->role)),
list_make1_oid(roleid), list_make1_oid(roleid),
GetUserId(), false); GetUserId(), false);
ReleaseSysCache(oldroletup);
} }
/* /*