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:
parent
6e9c81836e
commit
0d6c477664
@ -3360,7 +3360,8 @@ SCRAM-SHA-256$<replaceable><iteration count></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>
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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");
|
||||||
|
@ -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",
|
||||||
|
@ -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");
|
||||||
|
@ -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",
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user