1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-25 21:42:33 +03:00

Extend ALTER DEFAULT PRIVILEGES to define default privileges for large objects.

Previously, ALTER DEFAULT PRIVILEGES did not support large objects.
This meant that to grant privileges to users other than the owner,
permissions had to be manually assigned each time a large object
was created, which was inconvenient.

This commit extends ALTER DEFAULT PRIVILEGES to allow defining default
access privileges for large objects. With this change, specified privileges
will automatically apply to newly created large objects, making privilege
management more efficient.

As a side effect, this commit introduces the new keyword OBJECTS
since it's used in the syntax of ALTER DEFAULT PRIVILEGES.

Original patch by Haruka Takatsuka, with some fixes and tests by Yugo Nagata,
and rebased by Laurenz Albe.

Author: Takatsuka Haruka <harukat@sraoss.co.jp>
Co-authored-by: Yugo Nagata <nagata@sraoss.co.jp>
Co-authored-by: Laurenz Albe <laurenz.albe@cybertec.at>
Reviewed-by: Masao Fujii <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/20240424115242.236b499b2bed5b7a27f7a418@sraoss.co.jp
This commit is contained in:
Fujii Masao 2025-04-04 19:02:17 +09:00
parent 6e9c81836e
commit 0d6c477664
14 changed files with 217 additions and 13 deletions

View File

@ -3360,7 +3360,8 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
<literal>S</literal> = sequence, <literal>S</literal> = sequence,
<literal>f</literal> = function, <literal>f</literal> = function,
<literal>T</literal> = type, <literal>T</literal> = type,
<literal>n</literal> = schema <literal>n</literal> = schema,
<literal>L</literal> = large object
</para></entry> </para></entry>
</row> </row>

View File

@ -51,6 +51,11 @@ GRANT { { USAGE | CREATE }
ON SCHEMAS ON SCHEMAS
TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECTS
TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN } { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN }
[, ...] | ALL [ PRIVILEGES ] } [, ...] | ALL [ PRIVILEGES ] }
@ -83,6 +88,13 @@ REVOKE [ GRANT OPTION FOR ]
ON SCHEMAS ON SCHEMAS
FROM { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] FROM { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...]
[ CASCADE | RESTRICT ] [ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ { SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECTS
FROM { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
@ -117,8 +129,8 @@ REVOKE [ GRANT OPTION FOR ]
<para> <para>
Currently, Currently,
only the privileges for schemas, tables (including views and foreign only the privileges for schemas, tables (including views and foreign
tables), sequences, functions, and types (including domains) can be tables), sequences, functions, types (including domains), and large objects
altered. For this command, functions include aggregates and procedures. can be altered. For this command, functions include aggregates and procedures.
The words <literal>FUNCTIONS</literal> and <literal>ROUTINES</literal> are The words <literal>FUNCTIONS</literal> and <literal>ROUTINES</literal> are
equivalent in this command. (<literal>ROUTINES</literal> is preferred equivalent in this command. (<literal>ROUTINES</literal> is preferred
going forward as the standard term for functions and procedures taken going forward as the standard term for functions and procedures taken
@ -161,7 +173,8 @@ REVOKE [ GRANT OPTION FOR ]
If <literal>IN SCHEMA</literal> is omitted, the global default privileges If <literal>IN SCHEMA</literal> is omitted, the global default privileges
are altered. are altered.
<literal>IN SCHEMA</literal> is not allowed when setting privileges <literal>IN SCHEMA</literal> is not allowed when setting privileges
for schemas, since schemas can't be nested. for schemas and large objects, since schemas can't be nested and
large objects don't belong to a schema.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -1005,6 +1005,10 @@ ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *s
all_privileges = ACL_ALL_RIGHTS_SCHEMA; all_privileges = ACL_ALL_RIGHTS_SCHEMA;
errormsg = gettext_noop("invalid privilege type %s for schema"); errormsg = gettext_noop("invalid privilege type %s for schema");
break; break;
case OBJECT_LARGEOBJECT:
all_privileges = ACL_ALL_RIGHTS_LARGEOBJECT;
errormsg = gettext_noop("invalid privilege type %s for large object");
break;
default: default:
elog(ERROR, "unrecognized GrantStmt.objtype: %d", elog(ERROR, "unrecognized GrantStmt.objtype: %d",
(int) action->objtype); (int) action->objtype);
@ -1196,6 +1200,16 @@ SetDefaultACL(InternalDefaultACL *iacls)
this_privileges = ACL_ALL_RIGHTS_SCHEMA; this_privileges = ACL_ALL_RIGHTS_SCHEMA;
break; break;
case OBJECT_LARGEOBJECT:
if (OidIsValid(iacls->nspid))
ereport(ERROR,
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
errmsg("cannot use IN SCHEMA clause when using GRANT/REVOKE ON LARGE OBJECTS")));
objtype = DEFACLOBJ_LARGEOBJECT;
if (iacls->all_privs && this_privileges == ACL_NO_RIGHTS)
this_privileges = ACL_ALL_RIGHTS_LARGEOBJECT;
break;
default: default:
elog(ERROR, "unrecognized object type: %d", elog(ERROR, "unrecognized object type: %d",
(int) iacls->objtype); (int) iacls->objtype);
@ -1439,6 +1453,9 @@ RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
case DEFACLOBJ_NAMESPACE: case DEFACLOBJ_NAMESPACE:
iacls.objtype = OBJECT_SCHEMA; iacls.objtype = OBJECT_SCHEMA;
break; break;
case DEFACLOBJ_LARGEOBJECT:
iacls.objtype = OBJECT_LARGEOBJECT;
break;
default: default:
/* Shouldn't get here */ /* Shouldn't get here */
elog(ERROR, "unexpected default ACL type: %d", elog(ERROR, "unexpected default ACL type: %d",
@ -4250,6 +4267,10 @@ get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid)
defaclobjtype = DEFACLOBJ_NAMESPACE; defaclobjtype = DEFACLOBJ_NAMESPACE;
break; break;
case OBJECT_LARGEOBJECT:
defaclobjtype = DEFACLOBJ_LARGEOBJECT;
break;
default: default:
return NULL; return NULL;
} }

View File

@ -2005,16 +2005,20 @@ get_object_address_defacl(List *object, bool missing_ok)
case DEFACLOBJ_NAMESPACE: case DEFACLOBJ_NAMESPACE:
objtype_str = "schemas"; objtype_str = "schemas";
break; break;
case DEFACLOBJ_LARGEOBJECT:
objtype_str = "large objects";
break;
default: default:
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized default ACL object type \"%c\"", objtype), errmsg("unrecognized default ACL object type \"%c\"", objtype),
errhint("Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\".", errhint("Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\", \"%c\".",
DEFACLOBJ_RELATION, DEFACLOBJ_RELATION,
DEFACLOBJ_SEQUENCE, DEFACLOBJ_SEQUENCE,
DEFACLOBJ_FUNCTION, DEFACLOBJ_FUNCTION,
DEFACLOBJ_TYPE, DEFACLOBJ_TYPE,
DEFACLOBJ_NAMESPACE))); DEFACLOBJ_NAMESPACE,
DEFACLOBJ_LARGEOBJECT)));
} }
/* /*
@ -3844,6 +3848,12 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok)
_("default privileges on new schemas belonging to role %s"), _("default privileges on new schemas belonging to role %s"),
rolename); rolename);
break; break;
case DEFACLOBJ_LARGEOBJECT:
Assert(!nspname);
appendStringInfo(&buffer,
_("default privileges on new large objects belonging to role %s"),
rolename);
break;
default: default:
/* shouldn't get here */ /* shouldn't get here */
if (nspname) if (nspname)
@ -5766,6 +5776,10 @@ getObjectIdentityParts(const ObjectAddress *object,
appendStringInfoString(&buffer, appendStringInfoString(&buffer,
" on schemas"); " on schemas");
break; break;
case DEFACLOBJ_LARGEOBJECT:
appendStringInfoString(&buffer,
" on large objects");
break;
} }
if (objname) if (objname)

View File

@ -20,6 +20,7 @@
#include "catalog/pg_largeobject.h" #include "catalog/pg_largeobject.h"
#include "catalog/pg_largeobject_metadata.h" #include "catalog/pg_largeobject_metadata.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/acl.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/rel.h" #include "utils/rel.h"
@ -39,6 +40,8 @@ LargeObjectCreate(Oid loid)
Oid loid_new; Oid loid_new;
Datum values[Natts_pg_largeobject_metadata]; Datum values[Natts_pg_largeobject_metadata];
bool nulls[Natts_pg_largeobject_metadata]; bool nulls[Natts_pg_largeobject_metadata];
Oid ownerId;
Acl *lomacl;
pg_lo_meta = table_open(LargeObjectMetadataRelationId, pg_lo_meta = table_open(LargeObjectMetadataRelationId,
RowExclusiveLock); RowExclusiveLock);
@ -55,11 +58,18 @@ LargeObjectCreate(Oid loid)
loid_new = GetNewOidWithIndex(pg_lo_meta, loid_new = GetNewOidWithIndex(pg_lo_meta,
LargeObjectMetadataOidIndexId, LargeObjectMetadataOidIndexId,
Anum_pg_largeobject_metadata_oid); Anum_pg_largeobject_metadata_oid);
ownerId = GetUserId();
lomacl = get_user_default_acl(OBJECT_LARGEOBJECT, ownerId, InvalidOid);
values[Anum_pg_largeobject_metadata_oid - 1] = ObjectIdGetDatum(loid_new); values[Anum_pg_largeobject_metadata_oid - 1] = ObjectIdGetDatum(loid_new);
values[Anum_pg_largeobject_metadata_lomowner - 1] values[Anum_pg_largeobject_metadata_lomowner - 1]
= ObjectIdGetDatum(GetUserId()); = ObjectIdGetDatum(ownerId);
nulls[Anum_pg_largeobject_metadata_lomacl - 1] = true;
if (lomacl != NULL)
values[Anum_pg_largeobject_metadata_lomacl - 1]
= PointerGetDatum(lomacl);
else
nulls[Anum_pg_largeobject_metadata_lomacl - 1] = true;
ntup = heap_form_tuple(RelationGetDescr(pg_lo_meta), ntup = heap_form_tuple(RelationGetDescr(pg_lo_meta),
values, nulls); values, nulls);
@ -70,6 +80,10 @@ LargeObjectCreate(Oid loid)
table_close(pg_lo_meta, RowExclusiveLock); table_close(pg_lo_meta, RowExclusiveLock);
/* dependencies on roles mentioned in default ACL */
recordDependencyOnNewAcl(LargeObjectRelationId, loid_new, 0,
ownerId, lomacl);
return loid_new; return loid_new;
} }

View File

@ -752,7 +752,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF
NULLS_P NUMERIC NULLS_P NUMERIC
OBJECT_P OF OFF OFFSET OIDS OLD OMIT ON ONLY OPERATOR OPTION OPTIONS OR OBJECT_P OBJECTS_P OF OFF OFFSET OIDS OLD OMIT ON ONLY OPERATOR OPTION OPTIONS OR
ORDER ORDINALITY OTHERS OUT_P OUTER_P ORDER ORDINALITY OTHERS OUT_P OUTER_P
OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER
@ -8177,6 +8177,7 @@ defacl_privilege_target:
| SEQUENCES { $$ = OBJECT_SEQUENCE; } | SEQUENCES { $$ = OBJECT_SEQUENCE; }
| TYPES_P { $$ = OBJECT_TYPE; } | TYPES_P { $$ = OBJECT_TYPE; }
| SCHEMAS { $$ = OBJECT_SCHEMA; } | SCHEMAS { $$ = OBJECT_SCHEMA; }
| LARGE_P OBJECTS_P { $$ = OBJECT_LARGEOBJECT; }
; ;
@ -17882,6 +17883,7 @@ unreserved_keyword:
| NOWAIT | NOWAIT
| NULLS_P | NULLS_P
| OBJECT_P | OBJECT_P
| OBJECTS_P
| OF | OF
| OFF | OFF
| OIDS | OIDS
@ -18504,6 +18506,7 @@ bare_label_keyword:
| NULLS_P | NULLS_P
| NUMERIC | NUMERIC
| OBJECT_P | OBJECT_P
| OBJECTS_P
| OF | OF
| OFF | OFF
| OIDS | OIDS

View File

@ -506,7 +506,8 @@ do { \
CONVERT_PRIV('s', "SET"); CONVERT_PRIV('s', "SET");
CONVERT_PRIV('A', "ALTER SYSTEM"); CONVERT_PRIV('A', "ALTER SYSTEM");
} }
else if (strcmp(type, "LARGE OBJECT") == 0) else if (strcmp(type, "LARGE OBJECT") == 0 ||
strcmp(type, "LARGE OBJECTS") == 0)
{ {
CONVERT_PRIV('r', "SELECT"); CONVERT_PRIV('r', "SELECT");
CONVERT_PRIV('w', "UPDATE"); CONVERT_PRIV('w', "UPDATE");

View File

@ -15679,6 +15679,9 @@ dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
case DEFACLOBJ_NAMESPACE: case DEFACLOBJ_NAMESPACE:
type = "SCHEMAS"; type = "SCHEMAS";
break; break;
case DEFACLOBJ_LARGEOBJECT:
type = "LARGE OBJECTS";
break;
default: default:
/* shouldn't get here */ /* shouldn't get here */
pg_fatal("unrecognized object type in default privileges: %d", pg_fatal("unrecognized object type in default privileges: %d",

View File

@ -1222,7 +1222,9 @@ listDefaultACLs(const char *pattern)
printfPQExpBuffer(&buf, printfPQExpBuffer(&buf,
"SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \"%s\",\n" "SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \"%s\",\n"
" n.nspname AS \"%s\",\n" " n.nspname AS \"%s\",\n"
" CASE d.defaclobjtype WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' END AS \"%s\",\n" " CASE d.defaclobjtype "
" WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s'"
" WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' END AS \"%s\",\n"
" ", " ",
gettext_noop("Owner"), gettext_noop("Owner"),
gettext_noop("Schema"), gettext_noop("Schema"),
@ -1236,6 +1238,8 @@ listDefaultACLs(const char *pattern)
gettext_noop("type"), gettext_noop("type"),
DEFACLOBJ_NAMESPACE, DEFACLOBJ_NAMESPACE,
gettext_noop("schema"), gettext_noop("schema"),
DEFACLOBJ_LARGEOBJECT,
gettext_noop("large object"),
gettext_noop("Type")); gettext_noop("Type"));
printACLColumn(&buf, "d.defaclacl"); printACLColumn(&buf, "d.defaclacl");

View File

@ -4457,7 +4457,7 @@ match_previous_words(int pattern_id,
* objects supported. * objects supported.
*/ */
if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES")) if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
COMPLETE_WITH("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS"); COMPLETE_WITH("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS", "LARGE OBJECTS");
else else
COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_grantables, COMPLETE_WITH_SCHEMA_QUERY_PLUS(Query_for_list_of_grantables,
"ALL FUNCTIONS IN SCHEMA", "ALL FUNCTIONS IN SCHEMA",

View File

@ -68,6 +68,7 @@ MAKE_SYSCACHE(DEFACLROLENSPOBJ, pg_default_acl_role_nsp_obj_index, 8);
#define DEFACLOBJ_FUNCTION 'f' /* function */ #define DEFACLOBJ_FUNCTION 'f' /* function */
#define DEFACLOBJ_TYPE 'T' /* type */ #define DEFACLOBJ_TYPE 'T' /* type */
#define DEFACLOBJ_NAMESPACE 'n' /* namespace */ #define DEFACLOBJ_NAMESPACE 'n' /* namespace */
#define DEFACLOBJ_LARGEOBJECT 'L' /* large object */
#endif /* EXPOSE_TO_CLIENT_CODE */ #endif /* EXPOSE_TO_CLIENT_CODE */

View File

@ -308,6 +308,7 @@ PG_KEYWORD("nullif", NULLIF, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("nulls", NULLS_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("nulls", NULLS_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("numeric", NUMERIC, COL_NAME_KEYWORD, BARE_LABEL) PG_KEYWORD("numeric", NUMERIC, COL_NAME_KEYWORD, BARE_LABEL)
PG_KEYWORD("object", OBJECT_P, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("object", OBJECT_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("objects", OBJECTS_P, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("of", OF, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("of", OF, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("off", OFF, UNRESERVED_KEYWORD, BARE_LABEL) PG_KEYWORD("off", OFF, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("offset", OFFSET, RESERVED_KEYWORD, AS_LABEL) PG_KEYWORD("offset", OFFSET, RESERVED_KEYWORD, AS_LABEL)

View File

@ -2667,11 +2667,103 @@ SELECT has_schema_privilege('regress_priv_user2', 'testns4', 'CREATE'); -- yes
ALTER DEFAULT PRIVILEGES REVOKE ALL ON SCHEMAS FROM regress_priv_user2; ALTER DEFAULT PRIVILEGES REVOKE ALL ON SCHEMAS FROM regress_priv_user2;
COMMIT; COMMIT;
--
-- Test for default privileges on large objects. This is done in a
-- separate, rollbacked, transaction to avoid any trouble with other
-- regression sessions.
--
BEGIN;
SELECT lo_create(1007);
lo_create
-----------
1007
(1 row)
SELECT has_largeobject_privilege('regress_priv_user2', 1007, 'SELECT'); -- no
has_largeobject_privilege
---------------------------
f
(1 row)
SELECT has_largeobject_privilege('regress_priv_user2', 1007, 'UPDATE'); -- no
has_largeobject_privilege
---------------------------
f
(1 row)
ALTER DEFAULT PRIVILEGES GRANT SELECT ON LARGE OBJECTS TO regress_priv_user2;
SELECT lo_create(1008);
lo_create
-----------
1008
(1 row)
SELECT has_largeobject_privilege('regress_priv_user2', 1008, 'SELECT'); -- yes
has_largeobject_privilege
---------------------------
t
(1 row)
SELECT has_largeobject_privilege('regress_priv_user6', 1008, 'SELECT'); -- no
has_largeobject_privilege
---------------------------
f
(1 row)
SELECT has_largeobject_privilege('regress_priv_user2', 1008, 'UPDATE'); -- no
has_largeobject_privilege
---------------------------
f
(1 row)
ALTER DEFAULT PRIVILEGES GRANT ALL ON LARGE OBJECTS TO regress_priv_user2;
SELECT lo_create(1009);
lo_create
-----------
1009
(1 row)
SELECT has_largeobject_privilege('regress_priv_user2', 1009, 'SELECT'); -- true
has_largeobject_privilege
---------------------------
t
(1 row)
SELECT has_largeobject_privilege('regress_priv_user2', 1009, 'UPDATE'); -- true
has_largeobject_privilege
---------------------------
t
(1 row)
ALTER DEFAULT PRIVILEGES REVOKE UPDATE ON LARGE OBJECTS FROM regress_priv_user2;
SELECT lo_create(1010);
lo_create
-----------
1010
(1 row)
SELECT has_largeobject_privilege('regress_priv_user2', 1010, 'SELECT'); -- true
has_largeobject_privilege
---------------------------
t
(1 row)
SELECT has_largeobject_privilege('regress_priv_user2', 1010, 'UPDATE'); -- false
has_largeobject_privilege
---------------------------
f
(1 row)
ROLLBACK;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON LARGE OBJECTS TO public; -- error
ERROR: cannot use IN SCHEMA clause when using GRANT/REVOKE ON LARGE OBJECTS
\c -
-- Test for DROP OWNED BY with shared dependencies. This is done in a -- Test for DROP OWNED BY with shared dependencies. This is done in a
-- separate, rollbacked, transaction to avoid any trouble with other -- separate, rollbacked, transaction to avoid any trouble with other
-- regression sessions. -- regression sessions.
BEGIN; BEGIN;
ALTER DEFAULT PRIVILEGES GRANT ALL ON FUNCTIONS TO regress_priv_user2; ALTER DEFAULT PRIVILEGES GRANT ALL ON FUNCTIONS TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON LARGE OBJECTS TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO regress_priv_user2; ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON SEQUENCES TO regress_priv_user2; ALTER DEFAULT PRIVILEGES GRANT ALL ON SEQUENCES TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON TABLES TO regress_priv_user2; ALTER DEFAULT PRIVILEGES GRANT ALL ON TABLES TO regress_priv_user2;
@ -2682,7 +2774,7 @@ SELECT count(*) FROM pg_shdepend
classid = 'pg_default_acl'::regclass; classid = 'pg_default_acl'::regclass;
count count
------- -------
5 6
(1 row) (1 row)
DROP OWNED BY regress_priv_user2, regress_priv_user2; DROP OWNED BY regress_priv_user2, regress_priv_user2;

View File

@ -1586,11 +1586,47 @@ ALTER DEFAULT PRIVILEGES REVOKE ALL ON SCHEMAS FROM regress_priv_user2;
COMMIT; COMMIT;
--
-- Test for default privileges on large objects. This is done in a
-- separate, rollbacked, transaction to avoid any trouble with other
-- regression sessions.
--
BEGIN;
SELECT lo_create(1007);
SELECT has_largeobject_privilege('regress_priv_user2', 1007, 'SELECT'); -- no
SELECT has_largeobject_privilege('regress_priv_user2', 1007, 'UPDATE'); -- no
ALTER DEFAULT PRIVILEGES GRANT SELECT ON LARGE OBJECTS TO regress_priv_user2;
SELECT lo_create(1008);
SELECT has_largeobject_privilege('regress_priv_user2', 1008, 'SELECT'); -- yes
SELECT has_largeobject_privilege('regress_priv_user6', 1008, 'SELECT'); -- no
SELECT has_largeobject_privilege('regress_priv_user2', 1008, 'UPDATE'); -- no
ALTER DEFAULT PRIVILEGES GRANT ALL ON LARGE OBJECTS TO regress_priv_user2;
SELECT lo_create(1009);
SELECT has_largeobject_privilege('regress_priv_user2', 1009, 'SELECT'); -- true
SELECT has_largeobject_privilege('regress_priv_user2', 1009, 'UPDATE'); -- true
ALTER DEFAULT PRIVILEGES REVOKE UPDATE ON LARGE OBJECTS FROM regress_priv_user2;
SELECT lo_create(1010);
SELECT has_largeobject_privilege('regress_priv_user2', 1010, 'SELECT'); -- true
SELECT has_largeobject_privilege('regress_priv_user2', 1010, 'UPDATE'); -- false
ROLLBACK;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON LARGE OBJECTS TO public; -- error
\c -
-- Test for DROP OWNED BY with shared dependencies. This is done in a -- Test for DROP OWNED BY with shared dependencies. This is done in a
-- separate, rollbacked, transaction to avoid any trouble with other -- separate, rollbacked, transaction to avoid any trouble with other
-- regression sessions. -- regression sessions.
BEGIN; BEGIN;
ALTER DEFAULT PRIVILEGES GRANT ALL ON FUNCTIONS TO regress_priv_user2; ALTER DEFAULT PRIVILEGES GRANT ALL ON FUNCTIONS TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON LARGE OBJECTS TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO regress_priv_user2; ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON SEQUENCES TO regress_priv_user2; ALTER DEFAULT PRIVILEGES GRANT ALL ON SEQUENCES TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON TABLES TO regress_priv_user2; ALTER DEFAULT PRIVILEGES GRANT ALL ON TABLES TO regress_priv_user2;