|
35 | 35 | #include "catalog/pg_extension.h"
|
36 | 36 | #include "catalog/pg_foreign_data_wrapper.h"
|
37 | 37 | #include "catalog/pg_foreign_server.h"
|
| 38 | +#include "catalog/pg_init_privs.h" |
38 | 39 | #include "catalog/pg_language.h"
|
39 | 40 | #include "catalog/pg_largeobject.h"
|
40 | 41 | #include "catalog/pg_largeobject_metadata.h"
|
|
49 | 50 | #include "catalog/pg_ts_dict.h"
|
50 | 51 | #include "commands/dbcommands.h"
|
51 | 52 | #include "commands/event_trigger.h"
|
| 53 | +#include "commands/extension.h" |
52 | 54 | #include "commands/proclang.h"
|
53 | 55 | #include "commands/tablespace.h"
|
54 | 56 | #include "foreign/foreign.h"
|
@@ -119,6 +121,8 @@ static AclMode restrict_and_check_grant(bool is_grant, AclMode avail_goptions,
|
119 | 121 | AttrNumber att_number, const char *colname);
|
120 | 122 | static AclMode pg_aclmask(AclObjectKind objkind, Oid table_oid, AttrNumber attnum,
|
121 | 123 | Oid roleid, AclMode mask, AclMaskHow how);
|
| 124 | +static void recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid, |
| 125 | + Acl *new_acl); |
122 | 126 |
|
123 | 127 |
|
124 | 128 | #ifdef ACLDEBUG
|
@@ -1678,6 +1682,10 @@ ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname,
|
1678 | 1682 | /* keep the catalog indexes up to date */
|
1679 | 1683 | CatalogUpdateIndexes(attRelation, newtuple);
|
1680 | 1684 |
|
| 1685 | + /* Update initial privileges for extensions */ |
| 1686 | + recordExtensionInitPriv(relOid, RelationRelationId, attnum, |
| 1687 | + ACL_NUM(new_acl) > 0 ? new_acl : NULL); |
| 1688 | + |
1681 | 1689 | /* Update the shared dependency ACL info */
|
1682 | 1690 | updateAclDependencies(RelationRelationId, relOid, attnum,
|
1683 | 1691 | ownerId,
|
@@ -1939,6 +1947,9 @@ ExecGrant_Relation(InternalGrant *istmt)
|
1939 | 1947 | /* keep the catalog indexes up to date */
|
1940 | 1948 | CatalogUpdateIndexes(relation, newtuple);
|
1941 | 1949 |
|
| 1950 | + /* Update initial privileges for extensions */ |
| 1951 | + recordExtensionInitPriv(relOid, RelationRelationId, 0, new_acl); |
| 1952 | + |
1942 | 1953 | /* Update the shared dependency ACL info */
|
1943 | 1954 | updateAclDependencies(RelationRelationId, relOid, 0,
|
1944 | 1955 | ownerId,
|
@@ -2254,6 +2265,10 @@ ExecGrant_Fdw(InternalGrant *istmt)
|
2254 | 2265 | /* keep the catalog indexes up to date */
|
2255 | 2266 | CatalogUpdateIndexes(relation, newtuple);
|
2256 | 2267 |
|
| 2268 | + /* Update initial privileges for extensions */ |
| 2269 | + recordExtensionInitPriv(fdwid, ForeignDataWrapperRelationId, 0, |
| 2270 | + new_acl); |
| 2271 | + |
2257 | 2272 | /* Update the shared dependency ACL info */
|
2258 | 2273 | updateAclDependencies(ForeignDataWrapperRelationId,
|
2259 | 2274 | HeapTupleGetOid(tuple), 0,
|
@@ -2379,6 +2394,9 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
|
2379 | 2394 | /* keep the catalog indexes up to date */
|
2380 | 2395 | CatalogUpdateIndexes(relation, newtuple);
|
2381 | 2396 |
|
| 2397 | + /* Update initial privileges for extensions */ |
| 2398 | + recordExtensionInitPriv(srvid, ForeignServerRelationId, 0, new_acl); |
| 2399 | + |
2382 | 2400 | /* Update the shared dependency ACL info */
|
2383 | 2401 | updateAclDependencies(ForeignServerRelationId,
|
2384 | 2402 | HeapTupleGetOid(tuple), 0,
|
@@ -2503,6 +2521,9 @@ ExecGrant_Function(InternalGrant *istmt)
|
2503 | 2521 | /* keep the catalog indexes up to date */
|
2504 | 2522 | CatalogUpdateIndexes(relation, newtuple);
|
2505 | 2523 |
|
| 2524 | + /* Update initial privileges for extensions */ |
| 2525 | + recordExtensionInitPriv(funcId, ProcedureRelationId, 0, new_acl); |
| 2526 | + |
2506 | 2527 | /* Update the shared dependency ACL info */
|
2507 | 2528 | updateAclDependencies(ProcedureRelationId, funcId, 0,
|
2508 | 2529 | ownerId,
|
@@ -2633,6 +2654,9 @@ ExecGrant_Language(InternalGrant *istmt)
|
2633 | 2654 | /* keep the catalog indexes up to date */
|
2634 | 2655 | CatalogUpdateIndexes(relation, newtuple);
|
2635 | 2656 |
|
| 2657 | + /* Update initial privileges for extensions */ |
| 2658 | + recordExtensionInitPriv(langId, LanguageRelationId, 0, new_acl); |
| 2659 | + |
2636 | 2660 | /* Update the shared dependency ACL info */
|
2637 | 2661 | updateAclDependencies(LanguageRelationId, HeapTupleGetOid(tuple), 0,
|
2638 | 2662 | ownerId,
|
@@ -2772,6 +2796,9 @@ ExecGrant_Largeobject(InternalGrant *istmt)
|
2772 | 2796 | /* keep the catalog indexes up to date */
|
2773 | 2797 | CatalogUpdateIndexes(relation, newtuple);
|
2774 | 2798 |
|
| 2799 | + /* Update initial privileges for extensions */ |
| 2800 | + recordExtensionInitPriv(loid, LargeObjectRelationId, 0, new_acl); |
| 2801 | + |
2775 | 2802 | /* Update the shared dependency ACL info */
|
2776 | 2803 | updateAclDependencies(LargeObjectRelationId,
|
2777 | 2804 | HeapTupleGetOid(tuple), 0,
|
@@ -2897,6 +2924,9 @@ ExecGrant_Namespace(InternalGrant *istmt)
|
2897 | 2924 | /* keep the catalog indexes up to date */
|
2898 | 2925 | CatalogUpdateIndexes(relation, newtuple);
|
2899 | 2926 |
|
| 2927 | + /* Update initial privileges for extensions */ |
| 2928 | + recordExtensionInitPriv(nspid, NamespaceRelationId, 0, new_acl); |
| 2929 | + |
2900 | 2930 | /* Update the shared dependency ACL info */
|
2901 | 2931 | updateAclDependencies(NamespaceRelationId, HeapTupleGetOid(tuple), 0,
|
2902 | 2932 | ownerId,
|
@@ -3158,6 +3188,9 @@ ExecGrant_Type(InternalGrant *istmt)
|
3158 | 3188 | /* keep the catalog indexes up to date */
|
3159 | 3189 | CatalogUpdateIndexes(relation, newtuple);
|
3160 | 3190 |
|
| 3191 | + /* Update initial privileges for extensions */ |
| 3192 | + recordExtensionInitPriv(typId, TypeRelationId, 0, new_acl); |
| 3193 | + |
3161 | 3194 | /* Update the shared dependency ACL info */
|
3162 | 3195 | updateAclDependencies(TypeRelationId, typId, 0,
|
3163 | 3196 | ownerId,
|
@@ -5174,3 +5207,119 @@ get_user_default_acl(GrantObjectType objtype, Oid ownerId, Oid nsp_oid)
|
5174 | 5207 |
|
5175 | 5208 | return result;
|
5176 | 5209 | }
|
| 5210 | + |
| 5211 | +/* |
| 5212 | + * Record initial ACL for an extension object |
| 5213 | + * |
| 5214 | + * This will perform a wholesale replacement of the entire ACL for the object |
| 5215 | + * passed in, therefore be sure to pass in the complete new ACL to use. |
| 5216 | + * |
| 5217 | + * Can be called at any time, we check if 'creating_extension' is set and, if |
| 5218 | + * not, exit immediately. |
| 5219 | + * |
| 5220 | + * Pass in the object OID, the OID of the class (the OID of the table which |
| 5221 | + * the object is defined in) and the 'sub' id of the object (objsubid), if |
| 5222 | + * any. If there is no 'sub' id (they are currently only used for columns of |
| 5223 | + * tables) then pass in '0'. Finally, pass in the complete ACL to store. |
| 5224 | + * |
| 5225 | + * If an ACL already exists for this object/sub-object then we will replace |
| 5226 | + * it with what is passed in. |
| 5227 | + * |
| 5228 | + * Passing in NULL for 'new_acl' will result in the entry for the object being |
| 5229 | + * removed, if one is found. |
| 5230 | + */ |
| 5231 | +static void |
| 5232 | +recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid, Acl *new_acl) |
| 5233 | +{ |
| 5234 | + Relation relation; |
| 5235 | + ScanKeyData key[3]; |
| 5236 | + SysScanDesc scan; |
| 5237 | + HeapTuple tuple; |
| 5238 | + HeapTuple oldtuple; |
| 5239 | + |
| 5240 | + if (!creating_extension) |
| 5241 | + return; |
| 5242 | + |
| 5243 | + relation = heap_open(InitPrivsRelationId, RowExclusiveLock); |
| 5244 | + |
| 5245 | + ScanKeyInit(&key[0], |
| 5246 | + Anum_pg_init_privs_objoid, |
| 5247 | + BTEqualStrategyNumber, F_OIDEQ, |
| 5248 | + ObjectIdGetDatum(objoid)); |
| 5249 | + ScanKeyInit(&key[1], |
| 5250 | + Anum_pg_init_privs_classoid, |
| 5251 | + BTEqualStrategyNumber, F_OIDEQ, |
| 5252 | + ObjectIdGetDatum(classoid)); |
| 5253 | + ScanKeyInit(&key[2], |
| 5254 | + Anum_pg_init_privs_objsubid, |
| 5255 | + BTEqualStrategyNumber, F_INT4EQ, |
| 5256 | + Int32GetDatum(objsubid)); |
| 5257 | + |
| 5258 | + scan = systable_beginscan(relation, InitPrivsObjIndexId, true, |
| 5259 | + NULL, 3, key); |
| 5260 | + |
| 5261 | + /* There should exist only one entry or none. */ |
| 5262 | + oldtuple = systable_getnext(scan); |
| 5263 | + |
| 5264 | + systable_endscan(scan); |
| 5265 | + |
| 5266 | + /* If we find an entry, update it with the latest ACL. */ |
| 5267 | + if (HeapTupleIsValid(oldtuple)) |
| 5268 | + { |
| 5269 | + Datum values[Natts_pg_init_privs]; |
| 5270 | + bool nulls[Natts_pg_init_privs]; |
| 5271 | + bool replace[Natts_pg_init_privs]; |
| 5272 | + |
| 5273 | + /* If we have a new ACL to set, then update the row with it. */ |
| 5274 | + if (new_acl) |
| 5275 | + { |
| 5276 | + MemSet(values, 0, sizeof(values)); |
| 5277 | + MemSet(nulls, false, sizeof(nulls)); |
| 5278 | + MemSet(replace, false, sizeof(replace)); |
| 5279 | + |
| 5280 | + values[Anum_pg_init_privs_privs - 1] = PointerGetDatum(new_acl); |
| 5281 | + replace[Anum_pg_init_privs_privs - 1] = true; |
| 5282 | + |
| 5283 | + oldtuple = heap_modify_tuple(oldtuple, RelationGetDescr(relation), |
| 5284 | + values, nulls, replace); |
| 5285 | + |
| 5286 | + simple_heap_update(relation, &oldtuple->t_self, oldtuple); |
| 5287 | + |
| 5288 | + /* keep the catalog indexes up to date */ |
| 5289 | + CatalogUpdateIndexes(relation, oldtuple); |
| 5290 | + } |
| 5291 | + else |
| 5292 | + /* new_acl is NULL, so delete the entry we found. */ |
| 5293 | + simple_heap_delete(relation, &oldtuple->t_self); |
| 5294 | + } |
| 5295 | + else |
| 5296 | + { |
| 5297 | + /* No entry found, so add it. */ |
| 5298 | + Datum values[Natts_pg_init_privs]; |
| 5299 | + bool nulls[Natts_pg_init_privs]; |
| 5300 | + |
| 5301 | + MemSet(nulls, false, sizeof(nulls)); |
| 5302 | + |
| 5303 | + values[Anum_pg_init_privs_objoid - 1] = ObjectIdGetDatum(objoid); |
| 5304 | + values[Anum_pg_init_privs_classoid - 1] = ObjectIdGetDatum(classoid); |
| 5305 | + values[Anum_pg_init_privs_objsubid - 1] = Int32GetDatum(objsubid); |
| 5306 | + |
| 5307 | + /* This function only handles initial privileges of extensions */ |
| 5308 | + values[Anum_pg_init_privs_privtype - 1] = |
| 5309 | + CharGetDatum(INITPRIVS_EXTENSION); |
| 5310 | + |
| 5311 | + values[Anum_pg_init_privs_privs - 1] = PointerGetDatum(new_acl); |
| 5312 | + |
| 5313 | + tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls); |
| 5314 | + |
| 5315 | + simple_heap_insert(relation, tuple); |
| 5316 | + |
| 5317 | + /* keep the catalog indexes up to date */ |
| 5318 | + CatalogUpdateIndexes(relation, tuple); |
| 5319 | + } |
| 5320 | + |
| 5321 | + /* prevent error when processing objects multiple times */ |
| 5322 | + CommandCounterIncrement(); |
| 5323 | + |
| 5324 | + heap_close(relation, RowExclusiveLock); |
| 5325 | +} |
0 commit comments