Fix crasher bugs in previous commit
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 9 Mar 2015 20:00:43 +0000 (17:00 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 9 Mar 2015 20:00:43 +0000 (17:00 -0300)
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.

src/backend/catalog/aclchk.c
src/backend/commands/user.c

index 6c8780f794dbfd0764126cf2564c86058ff0dd88..8e75c2792056789cf2c742c2678933fd7cf76c2b 100644 (file)
@@ -858,9 +858,9 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
    GrantStmt  *action = stmt->action;
    InternalDefaultACL iacls;
    ListCell   *cell;
-   List       *rolenames = NIL;
+   List       *rolespecs = NIL;
    List       *nspnames = NIL;
-   DefElem    *drolenames = NULL;
+   DefElem    *drolespecs = NULL;
    DefElem    *dnspnames = NULL;
    AclMode     all_privileges;
    const char *errormsg;
@@ -880,11 +880,11 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
        }
        else if (strcmp(defel->defname, "roles") == 0)
        {
-           if (drolenames)
+           if (drolespecs)
                ereport(ERROR,
                        (errcode(ERRCODE_SYNTAX_ERROR),
                         errmsg("conflicting or redundant options")));
-           drolenames = defel;
+           drolespecs = defel;
        }
        else
            elog(ERROR, "option \"%s\" not recognized", defel->defname);
@@ -892,8 +892,8 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
 
    if (dnspnames)
        nspnames = (List *) dnspnames->arg;
-   if (drolenames)
-       rolenames = (List *) drolenames->arg;
+   if (drolespecs)
+       rolespecs = (List *) drolespecs->arg;
 
    /* Prepare the InternalDefaultACL representation of the statement */
    /* roleid to be filled below */
@@ -996,7 +996,7 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
        }
    }
 
-   if (rolenames == NIL)
+   if (rolespecs == NIL)
    {
        /* Set permissions for myself */
        iacls.roleid = GetUserId();
@@ -1008,11 +1008,11 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt)
        /* Look up the role OIDs and do permissions checks */
        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
index c14465eb87b6dfc9a73a6abed848a29bc8eac280..75f1b3cd4f264c712896151ee872e29c59f7c7ce 100644 (file)
@@ -429,13 +429,17 @@ CreateRole(CreateRoleStmt *stmt)
     */
    foreach(item, addroleto)
    {
-       char       *oldrolename = strVal(lfirst(item));
-       Oid         oldroleid = get_role_oid(oldrolename, false);
+       RoleSpec   *oldrole = lfirst(item);
+       HeapTuple   oldroletup = get_rolespec_tuple((Node *) oldrole);
+       Oid         oldroleid = HeapTupleGetOid(oldroletup);
+       char       *oldrolename = NameStr(((Form_pg_authid) GETSTRUCT(oldroletup))->rolname);
 
        AddRoleMems(oldrolename, oldroleid,
                    list_make1(makeString(stmt->role)),
                    list_make1_oid(roleid),
                    GetUserId(), false);
+
+       ReleaseSysCache(oldroletup);
    }
 
    /*