]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
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);
        }
 
        /*