Skip to content

Commit b762bbd

Browse files
committed
Allow makeaclitem() to accept multiple privilege names.
Interpret its privileges argument as a comma-separated list of privilege names, as in has_table_privilege and other functions. This is actually net less code, since the support routine to parse that already exists, and we can drop convert_priv_string() which had no other use-case. Robins Tharakan Discussion: https://postgr.es/m/e5a05dc54ba64408b3dd260171c1abaf@EX13D05UWC001.ant.amazon.com
1 parent b6a5158 commit b762bbd

File tree

4 files changed

+54
-47
lines changed

4 files changed

+54
-47
lines changed

doc/src/sgml/func.sgml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24236,7 +24236,8 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
2423624236
If the grantee is the pseudo-role PUBLIC, it is represented by zero in
2423724237
the <parameter>grantee</parameter> column. Each granted privilege is
2423824238
represented as <literal>SELECT</literal>, <literal>INSERT</literal>,
24239-
etc. Note that each privilege is broken out as a separate row, so
24239+
etc (see <xref linkend="privilege-abbrevs-table"/> for a full list).
24240+
Note that each privilege is broken out as a separate row, so
2424024241
only one keyword appears in the <parameter>privilege_type</parameter>
2424124242
column.
2424224243
</para></entry>
@@ -24256,6 +24257,12 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
2425624257
</para>
2425724258
<para>
2425824259
Constructs an <type>aclitem</type> with the given properties.
24260+
<parameter>privileges</parameter> is a comma-separated list of
24261+
privilege names such as <literal>SELECT</literal>,
24262+
<literal>INSERT</literal>, etc, all of which are set in the
24263+
result. (Case of the privilege string is not significant, and
24264+
extra whitespace is allowed between but not within privilege
24265+
names.)
2425924266
</para></entry>
2426024267
</row>
2426124268
</tbody>

src/backend/utils/adt/acl.c

Lines changed: 20 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ static void check_circularity(const Acl *old_acl, const AclItem *mod_aip,
8686
static Acl *recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs,
8787
Oid ownerId, DropBehavior behavior);
8888

89-
static AclMode convert_priv_string(text *priv_type_text);
9089
static AclMode convert_any_priv_string(text *priv_type_text,
9190
const priv_map *privileges);
9291

@@ -1573,8 +1572,27 @@ makeaclitem(PG_FUNCTION_ARGS)
15731572
bool goption = PG_GETARG_BOOL(3);
15741573
AclItem *result;
15751574
AclMode priv;
1575+
static const priv_map any_priv_map[] = {
1576+
{"SELECT", ACL_SELECT},
1577+
{"INSERT", ACL_INSERT},
1578+
{"UPDATE", ACL_UPDATE},
1579+
{"DELETE", ACL_DELETE},
1580+
{"TRUNCATE", ACL_TRUNCATE},
1581+
{"REFERENCES", ACL_REFERENCES},
1582+
{"TRIGGER", ACL_TRIGGER},
1583+
{"EXECUTE", ACL_EXECUTE},
1584+
{"USAGE", ACL_USAGE},
1585+
{"CREATE", ACL_CREATE},
1586+
{"TEMP", ACL_CREATE_TEMP},
1587+
{"TEMPORARY", ACL_CREATE_TEMP},
1588+
{"CONNECT", ACL_CONNECT},
1589+
{"SET", ACL_SET},
1590+
{"ALTER SYSTEM", ACL_ALTER_SYSTEM},
1591+
{"RULE", 0}, /* ignore old RULE privileges */
1592+
{NULL, 0}
1593+
};
15761594

1577-
priv = convert_priv_string(privtext);
1595+
priv = convert_any_priv_string(privtext, any_priv_map);
15781596

15791597
result = (AclItem *) palloc(sizeof(AclItem));
15801598

@@ -1587,50 +1605,6 @@ makeaclitem(PG_FUNCTION_ARGS)
15871605
PG_RETURN_ACLITEM_P(result);
15881606
}
15891607

1590-
static AclMode
1591-
convert_priv_string(text *priv_type_text)
1592-
{
1593-
char *priv_type = text_to_cstring(priv_type_text);
1594-
1595-
if (pg_strcasecmp(priv_type, "SELECT") == 0)
1596-
return ACL_SELECT;
1597-
if (pg_strcasecmp(priv_type, "INSERT") == 0)
1598-
return ACL_INSERT;
1599-
if (pg_strcasecmp(priv_type, "UPDATE") == 0)
1600-
return ACL_UPDATE;
1601-
if (pg_strcasecmp(priv_type, "DELETE") == 0)
1602-
return ACL_DELETE;
1603-
if (pg_strcasecmp(priv_type, "TRUNCATE") == 0)
1604-
return ACL_TRUNCATE;
1605-
if (pg_strcasecmp(priv_type, "REFERENCES") == 0)
1606-
return ACL_REFERENCES;
1607-
if (pg_strcasecmp(priv_type, "TRIGGER") == 0)
1608-
return ACL_TRIGGER;
1609-
if (pg_strcasecmp(priv_type, "EXECUTE") == 0)
1610-
return ACL_EXECUTE;
1611-
if (pg_strcasecmp(priv_type, "USAGE") == 0)
1612-
return ACL_USAGE;
1613-
if (pg_strcasecmp(priv_type, "CREATE") == 0)
1614-
return ACL_CREATE;
1615-
if (pg_strcasecmp(priv_type, "TEMP") == 0)
1616-
return ACL_CREATE_TEMP;
1617-
if (pg_strcasecmp(priv_type, "TEMPORARY") == 0)
1618-
return ACL_CREATE_TEMP;
1619-
if (pg_strcasecmp(priv_type, "CONNECT") == 0)
1620-
return ACL_CONNECT;
1621-
if (pg_strcasecmp(priv_type, "SET") == 0)
1622-
return ACL_SET;
1623-
if (pg_strcasecmp(priv_type, "ALTER SYSTEM") == 0)
1624-
return ACL_ALTER_SYSTEM;
1625-
if (pg_strcasecmp(priv_type, "RULE") == 0)
1626-
return 0; /* ignore old RULE privileges */
1627-
1628-
ereport(ERROR,
1629-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1630-
errmsg("unrecognized privilege type: \"%s\"", priv_type)));
1631-
return ACL_NO_RIGHTS; /* keep compiler quiet */
1632-
}
1633-
16341608

16351609
/*
16361610
* convert_any_priv_string: recognize privilege strings for has_foo_privilege

src/test/regress/expected/privileges.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,6 +2099,24 @@ SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); -
20992099
ALTER DEFAULT PRIVILEGES FOR ROLE regress_priv_user1 REVOKE EXECUTE ON FUNCTIONS FROM public;
21002100
ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON SCHEMAS TO regress_priv_user2; -- error
21012101
ERROR: cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS
2102+
-- Test makeaclitem()
2103+
SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole,
2104+
'SELECT', TRUE); -- single privilege
2105+
makeaclitem
2106+
------------------------------------------
2107+
regress_priv_user1=r*/regress_priv_user2
2108+
(1 row)
2109+
2110+
SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole,
2111+
'SELECT, INSERT, UPDATE , DELETE ', FALSE); -- multiple privileges
2112+
makeaclitem
2113+
--------------------------------------------
2114+
regress_priv_user1=arwd/regress_priv_user2
2115+
(1 row)
2116+
2117+
SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole,
2118+
'SELECT, fake_privilege', FALSE); -- error
2119+
ERROR: unrecognized privilege type: "fake_privilege"
21022120
--
21032121
-- Testing blanket default grants is very hazardous since it might change
21042122
-- the privileges attached to objects created by concurrent regression tests.

src/test/regress/sql/privileges.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,14 @@ ALTER DEFAULT PRIVILEGES FOR ROLE regress_priv_user1 REVOKE EXECUTE ON FUNCTIONS
13391339

13401340
ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON SCHEMAS TO regress_priv_user2; -- error
13411341

1342+
-- Test makeaclitem()
1343+
SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole,
1344+
'SELECT', TRUE); -- single privilege
1345+
SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole,
1346+
'SELECT, INSERT, UPDATE , DELETE ', FALSE); -- multiple privileges
1347+
SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole,
1348+
'SELECT, fake_privilege', FALSE); -- error
1349+
13421350
--
13431351
-- Testing blanket default grants is very hazardous since it might change
13441352
-- the privileges attached to objects created by concurrent regression tests.

0 commit comments

Comments
 (0)